LLVM 24.0.0git
SystemZAsmPrinter.cpp
Go to the documentation of this file.
1//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Streams SystemZ assembly language and associated data, in the form of
10// MCInsts and MCExprs respectively.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SystemZAsmPrinter.h"
20#include "SystemZMCInstLower.h"
21#include "SystemZSubtarget.h"
25#include "llvm/MC/MCExpr.h"
27#include "llvm/MC/MCStreamer.h"
30
31using namespace llvm;
32
33// Return an RI instruction like MI with opcode Opcode, but with the
34// GR64 register operands turned into GR32s.
35static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
36 if (MI->isCompare())
37 return MCInstBuilder(Opcode)
38 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39 .addImm(MI->getOperand(1).getImm());
40 else
41 return MCInstBuilder(Opcode)
42 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
43 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
44 .addImm(MI->getOperand(2).getImm());
45}
46
47// Return an RI instruction like MI with opcode Opcode, but with the
48// GR64 register operands turned into GRH32s.
49static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
50 if (MI->isCompare())
51 return MCInstBuilder(Opcode)
52 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
53 .addImm(MI->getOperand(1).getImm());
54 else
55 return MCInstBuilder(Opcode)
56 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
57 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
58 .addImm(MI->getOperand(2).getImm());
59}
60
61// Return an RI instruction like MI with opcode Opcode, but with the
62// R2 register turned into a GR64.
63static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
64 return MCInstBuilder(Opcode)
65 .addReg(MI->getOperand(0).getReg())
66 .addReg(MI->getOperand(1).getReg())
67 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
68 .addImm(MI->getOperand(3).getImm())
69 .addImm(MI->getOperand(4).getImm())
70 .addImm(MI->getOperand(5).getImm());
71}
72
73// MI is an instruction that accepts an optional alignment hint,
74// and which was already lowered to LoweredMI. If the alignment
75// of the original memory operand is known, update LoweredMI to
76// an instruction with the corresponding hint set.
77static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI,
78 unsigned Opcode) {
79 if (MI->memoperands_empty())
80 return;
81
82 Align Alignment = Align(16);
83 for (const MachineMemOperand *MMO : MI->memoperands())
84 if (MMO->getAlign() < Alignment)
85 Alignment = MMO->getAlign();
86
87 unsigned AlignmentHint = 0;
88 if (Alignment >= Align(16))
89 AlignmentHint = 4;
90 else if (Alignment >= Align(8))
91 AlignmentHint = 3;
92 if (AlignmentHint == 0)
93 return;
94
95 LoweredMI.setOpcode(Opcode);
96 LoweredMI.addOperand(MCOperand::createImm(AlignmentHint));
97}
98
99// MI loads the high part of a vector from memory. Return an instruction
100// that uses replicating vector load Opcode to do the same thing.
101static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
102 return MCInstBuilder(Opcode)
103 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
104 .addReg(MI->getOperand(1).getReg())
105 .addImm(MI->getOperand(2).getImm())
106 .addReg(MI->getOperand(3).getReg());
107}
108
109// MI stores the high part of a vector to memory. Return an instruction
110// that uses elemental vector store Opcode to do the same thing.
111static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
112 return MCInstBuilder(Opcode)
113 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
114 .addReg(MI->getOperand(1).getReg())
115 .addImm(MI->getOperand(2).getImm())
116 .addReg(MI->getOperand(3).getReg())
117 .addImm(0);
118}
119
120// MI extracts the first element of the source vector.
121static MCInst lowerVecEltExtraction(const MachineInstr *MI, unsigned Opcode) {
122 return MCInstBuilder(Opcode)
123 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
124 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
125 .addReg(0)
126 .addImm(0);
127}
128
129// MI inserts value into the first element of the destination vector.
130static MCInst lowerVecEltInsertion(const MachineInstr *MI, unsigned Opcode) {
131 return MCInstBuilder(Opcode)
132 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
133 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
134 .addReg(MI->getOperand(1).getReg())
135 .addReg(0)
136 .addImm(0);
137}
138
140 SystemZ_MC::verifyInstructionPredicates(MI->getOpcode(),
141 getSubtargetInfo().getFeatureBits());
142
143 SystemZMCInstLower Lower(MF->getContext(), *this);
144 MCInst LoweredMI;
145 switch (MI->getOpcode()) {
146 case SystemZ::Return:
147 LoweredMI = MCInstBuilder(SystemZ::BR)
148 .addReg(SystemZ::R14D);
149 break;
150
151 case SystemZ::CondReturn:
152 LoweredMI = MCInstBuilder(SystemZ::BCR)
153 .addImm(MI->getOperand(0).getImm())
154 .addImm(MI->getOperand(1).getImm())
155 .addReg(SystemZ::R14D);
156 break;
157
158 case SystemZ::CRBReturn:
159 LoweredMI = MCInstBuilder(SystemZ::CRB)
160 .addReg(MI->getOperand(0).getReg())
161 .addReg(MI->getOperand(1).getReg())
162 .addImm(MI->getOperand(2).getImm())
163 .addReg(SystemZ::R14D)
164 .addImm(0);
165 break;
166
167 case SystemZ::CGRBReturn:
168 LoweredMI = MCInstBuilder(SystemZ::CGRB)
169 .addReg(MI->getOperand(0).getReg())
170 .addReg(MI->getOperand(1).getReg())
171 .addImm(MI->getOperand(2).getImm())
172 .addReg(SystemZ::R14D)
173 .addImm(0);
174 break;
175
176 case SystemZ::CIBReturn:
177 LoweredMI = MCInstBuilder(SystemZ::CIB)
178 .addReg(MI->getOperand(0).getReg())
179 .addImm(MI->getOperand(1).getImm())
180 .addImm(MI->getOperand(2).getImm())
181 .addReg(SystemZ::R14D)
182 .addImm(0);
183 break;
184
185 case SystemZ::CGIBReturn:
186 LoweredMI = MCInstBuilder(SystemZ::CGIB)
187 .addReg(MI->getOperand(0).getReg())
188 .addImm(MI->getOperand(1).getImm())
189 .addImm(MI->getOperand(2).getImm())
190 .addReg(SystemZ::R14D)
191 .addImm(0);
192 break;
193
194 case SystemZ::CLRBReturn:
195 LoweredMI = MCInstBuilder(SystemZ::CLRB)
196 .addReg(MI->getOperand(0).getReg())
197 .addReg(MI->getOperand(1).getReg())
198 .addImm(MI->getOperand(2).getImm())
199 .addReg(SystemZ::R14D)
200 .addImm(0);
201 break;
202
203 case SystemZ::CLGRBReturn:
204 LoweredMI = MCInstBuilder(SystemZ::CLGRB)
205 .addReg(MI->getOperand(0).getReg())
206 .addReg(MI->getOperand(1).getReg())
207 .addImm(MI->getOperand(2).getImm())
208 .addReg(SystemZ::R14D)
209 .addImm(0);
210 break;
211
212 case SystemZ::CLIBReturn:
213 LoweredMI = MCInstBuilder(SystemZ::CLIB)
214 .addReg(MI->getOperand(0).getReg())
215 .addImm(MI->getOperand(1).getImm())
216 .addImm(MI->getOperand(2).getImm())
217 .addReg(SystemZ::R14D)
218 .addImm(0);
219 break;
220
221 case SystemZ::CLGIBReturn:
222 LoweredMI = MCInstBuilder(SystemZ::CLGIB)
223 .addReg(MI->getOperand(0).getReg())
224 .addImm(MI->getOperand(1).getImm())
225 .addImm(MI->getOperand(2).getImm())
226 .addReg(SystemZ::R14D)
227 .addImm(0);
228 break;
229
230 case SystemZ::CallBR:
231 LoweredMI = MCInstBuilder(SystemZ::BR)
232 .addReg(MI->getOperand(0).getReg());
233 break;
234
235 case SystemZ::CallBCR:
236 LoweredMI = MCInstBuilder(SystemZ::BCR)
237 .addImm(MI->getOperand(0).getImm())
238 .addImm(MI->getOperand(1).getImm())
239 .addReg(MI->getOperand(2).getReg());
240 break;
241
242 case SystemZ::CRBCall:
243 LoweredMI = MCInstBuilder(SystemZ::CRB)
244 .addReg(MI->getOperand(0).getReg())
245 .addReg(MI->getOperand(1).getReg())
246 .addImm(MI->getOperand(2).getImm())
247 .addReg(MI->getOperand(3).getReg())
248 .addImm(0);
249 break;
250
251 case SystemZ::CGRBCall:
252 LoweredMI = MCInstBuilder(SystemZ::CGRB)
253 .addReg(MI->getOperand(0).getReg())
254 .addReg(MI->getOperand(1).getReg())
255 .addImm(MI->getOperand(2).getImm())
256 .addReg(MI->getOperand(3).getReg())
257 .addImm(0);
258 break;
259
260 case SystemZ::CIBCall:
261 LoweredMI = MCInstBuilder(SystemZ::CIB)
262 .addReg(MI->getOperand(0).getReg())
263 .addImm(MI->getOperand(1).getImm())
264 .addImm(MI->getOperand(2).getImm())
265 .addReg(MI->getOperand(3).getReg())
266 .addImm(0);
267 break;
268
269 case SystemZ::CGIBCall:
270 LoweredMI = MCInstBuilder(SystemZ::CGIB)
271 .addReg(MI->getOperand(0).getReg())
272 .addImm(MI->getOperand(1).getImm())
273 .addImm(MI->getOperand(2).getImm())
274 .addReg(MI->getOperand(3).getReg())
275 .addImm(0);
276 break;
277
278 case SystemZ::CLRBCall:
279 LoweredMI = MCInstBuilder(SystemZ::CLRB)
280 .addReg(MI->getOperand(0).getReg())
281 .addReg(MI->getOperand(1).getReg())
282 .addImm(MI->getOperand(2).getImm())
283 .addReg(MI->getOperand(3).getReg())
284 .addImm(0);
285 break;
286
287 case SystemZ::CLGRBCall:
288 LoweredMI = MCInstBuilder(SystemZ::CLGRB)
289 .addReg(MI->getOperand(0).getReg())
290 .addReg(MI->getOperand(1).getReg())
291 .addImm(MI->getOperand(2).getImm())
292 .addReg(MI->getOperand(3).getReg())
293 .addImm(0);
294 break;
295
296 case SystemZ::CLIBCall:
297 LoweredMI = MCInstBuilder(SystemZ::CLIB)
298 .addReg(MI->getOperand(0).getReg())
299 .addImm(MI->getOperand(1).getImm())
300 .addImm(MI->getOperand(2).getImm())
301 .addReg(MI->getOperand(3).getReg())
302 .addImm(0);
303 break;
304
305 case SystemZ::CLGIBCall:
306 LoweredMI = MCInstBuilder(SystemZ::CLGIB)
307 .addReg(MI->getOperand(0).getReg())
308 .addImm(MI->getOperand(1).getImm())
309 .addImm(MI->getOperand(2).getImm())
310 .addReg(MI->getOperand(3).getReg())
311 .addImm(0);
312 break;
313
314 case SystemZ::IILF64:
315 LoweredMI = MCInstBuilder(SystemZ::IILF)
316 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
317 .addImm(MI->getOperand(2).getImm());
318 break;
319
320 case SystemZ::IIHF64:
321 LoweredMI = MCInstBuilder(SystemZ::IIHF)
322 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
323 .addImm(MI->getOperand(2).getImm());
324 break;
325
326 case SystemZ::RISBHH:
327 case SystemZ::RISBHL:
328 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
329 break;
330
331 case SystemZ::RISBLH:
332 case SystemZ::RISBLL:
333 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
334 break;
335
336 case SystemZ::VLVGP32:
337 LoweredMI = MCInstBuilder(SystemZ::VLVGP)
338 .addReg(MI->getOperand(0).getReg())
339 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
340 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
341 break;
342
343 case SystemZ::VLR16:
344 case SystemZ::VLR32:
345 case SystemZ::VLR64:
346 LoweredMI = MCInstBuilder(SystemZ::VLR)
347 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
348 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
349 break;
350
351 case SystemZ::VL:
352 Lower.lower(MI, LoweredMI);
353 lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign);
354 break;
355
356 case SystemZ::VST:
357 Lower.lower(MI, LoweredMI);
358 lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign);
359 break;
360
361 case SystemZ::VLM:
362 Lower.lower(MI, LoweredMI);
363 lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign);
364 break;
365
366 case SystemZ::VSTM:
367 Lower.lower(MI, LoweredMI);
368 lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign);
369 break;
370
371 case SystemZ::VL16:
372 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPH);
373 break;
374
375 case SystemZ::VL32:
376 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
377 break;
378
379 case SystemZ::VL64:
380 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
381 break;
382
383 case SystemZ::VST16:
384 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEH);
385 break;
386
387 case SystemZ::VST32:
388 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
389 break;
390
391 case SystemZ::VST64:
392 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
393 break;
394
395 case SystemZ::LFER:
396 LoweredMI = lowerVecEltExtraction(MI, SystemZ::VLGVF);
397 break;
398
399 case SystemZ::LFER_16:
400 LoweredMI = lowerVecEltExtraction(MI, SystemZ::VLGVH);
401 break;
402
403 case SystemZ::LEFR:
404 LoweredMI = lowerVecEltInsertion(MI, SystemZ::VLVGF);
405 break;
406
407 case SystemZ::LEFR_16:
408 LoweredMI = lowerVecEltInsertion(MI, SystemZ::VLVGH);
409 break;
410
411#define LOWER_LOW(NAME) \
412 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
413
414 LOWER_LOW(IILL);
415 LOWER_LOW(IILH);
416 LOWER_LOW(TMLL);
417 LOWER_LOW(TMLH);
418 LOWER_LOW(NILL);
419 LOWER_LOW(NILH);
420 LOWER_LOW(NILF);
421 LOWER_LOW(OILL);
422 LOWER_LOW(OILH);
423 LOWER_LOW(OILF);
424 LOWER_LOW(XILF);
425
426#undef LOWER_LOW
427
428#define LOWER_HIGH(NAME) \
429 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
430
431 LOWER_HIGH(IIHL);
432 LOWER_HIGH(IIHH);
433 LOWER_HIGH(TMHL);
434 LOWER_HIGH(TMHH);
435 LOWER_HIGH(NIHL);
436 LOWER_HIGH(NIHH);
437 LOWER_HIGH(NIHF);
438 LOWER_HIGH(OIHL);
439 LOWER_HIGH(OIHH);
440 LOWER_HIGH(OIHF);
441 LOWER_HIGH(XIHF);
442
443#undef LOWER_HIGH
444
445 case SystemZ::Serialize:
446 if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
447 LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
448 .addImm(14).addReg(SystemZ::R0D);
449 else
450 LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
451 .addImm(15).addReg(SystemZ::R0D);
452 break;
453
454 // We want to emit "j .+2" for traps, jumping to the relative immediate field
455 // of the jump instruction, which is an illegal instruction. We cannot emit a
456 // "." symbol, so create and emit a temp label before the instruction and use
457 // that instead.
458 case SystemZ::Trap: {
459 MCSymbol *DotSym = OutContext.createTempSymbol();
460 OutStreamer->emitLabel(DotSym);
461
463 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
464 LoweredMI = MCInstBuilder(SystemZ::J)
465 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
466 }
467 break;
468
469 // Conditional traps will create a branch on condition instruction that jumps
470 // to the relative immediate field of the jump instruction. (eg. "jo .+2")
471 case SystemZ::CondTrap: {
472 MCSymbol *DotSym = OutContext.createTempSymbol();
473 OutStreamer->emitLabel(DotSym);
474
476 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
477 LoweredMI = MCInstBuilder(SystemZ::BRC)
478 .addImm(MI->getOperand(0).getImm())
479 .addImm(MI->getOperand(1).getImm())
480 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
481 }
482 break;
483
484 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
485 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
486
487 case TargetOpcode::PATCHABLE_TAIL_CALL:
488 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
489 // normal function exit from a tail exit.
490 llvm_unreachable("Tail call is handled in the normal case. See comments "
491 "around this assert.");
492
493 case SystemZ::EXRL_Pseudo: {
494 unsigned TargetInsOpc = MI->getOperand(0).getImm();
495 Register LenMinus1Reg = MI->getOperand(1).getReg();
496 Register DestReg = MI->getOperand(2).getReg();
497 int64_t DestDisp = MI->getOperand(3).getImm();
498 Register SrcReg = MI->getOperand(4).getReg();
499 int64_t SrcDisp = MI->getOperand(5).getImm();
500
501 SystemZTargetStreamer *TS = getTargetStreamer();
502 MCInst ET = MCInstBuilder(TargetInsOpc)
503 .addReg(DestReg)
504 .addImm(DestDisp)
505 .addImm(1)
506 .addReg(SrcReg)
507 .addImm(SrcDisp);
508 SystemZTargetStreamer::MCInstSTIPair ET_STI(ET, &MF->getSubtarget());
509 auto [It, Inserted] = TS->EXRLTargets2Sym.try_emplace(ET_STI);
510 if (Inserted)
511 It->second = OutContext.createTempSymbol();
512 MCSymbol *DotSym = It->second;
516 MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot));
517 return;
518 }
519
520 case SystemZ::FENCE:
521 OutStreamer->emitRawComment("FENCE");
522 return;
523
524 // EH_SjLj_Setup is a dummy terminator instruction of size 0.
525 // It is used to handle the clobber register for builtin setjmp.
526 case SystemZ::EH_SjLj_Setup:
527 return;
528
529 default:
530 Lower.lower(MI, LoweredMI);
531 break;
532 }
533 EmitToStreamer(*OutStreamer, LoweredMI);
534}
535
536static void printFormattedRegName(const MCAsmInfo *MAI, unsigned RegNo,
537 raw_ostream &OS) {
538 const char *RegName;
539 if (MAI->getAssemblerDialect() == AD_HLASM) {
541 // Skip register prefix so that only register number is left
542 assert(isalpha(RegName[0]) && isdigit(RegName[1]));
543 OS << (RegName + 1);
544 } else {
546 OS << '%' << RegName;
547 }
548}
549
550static void printReg(unsigned Reg, const MCAsmInfo *MAI, raw_ostream &OS) {
551 if (!Reg)
552 OS << '0';
553 else
554 printFormattedRegName(MAI, Reg, OS);
555}
556
557static void printOperand(const MCOperand &MCOp, const MCAsmInfo *MAI,
558 raw_ostream &OS) {
559 if (MCOp.isReg())
560 printReg(MCOp.getReg(), MAI, OS);
561 else if (MCOp.isImm())
562 OS << MCOp.getImm();
563 else if (MCOp.isExpr())
564 MAI->printExpr(OS, *MCOp.getExpr());
565 else
566 llvm_unreachable("Invalid operand");
567}
568
569static void printAddress(const MCAsmInfo *MAI, unsigned Base,
570 const MCOperand &DispMO, unsigned Index,
571 raw_ostream &OS) {
572 printOperand(DispMO, MAI, OS);
573 if (Base || Index) {
574 OS << '(';
575 if (Index) {
576 printFormattedRegName(MAI, Index, OS);
577 if (Base)
578 OS << ',';
579 }
580 if (Base)
581 printFormattedRegName(MAI, Base, OS);
582 OS << ')';
583 }
584}
585
587 const char *ExtraCode,
588 raw_ostream &OS) {
589 const MCRegisterInfo &MRI = TM.getMCRegisterInfo();
590 const MachineOperand &MO = MI->getOperand(OpNo);
591 MCOperand MCOp;
592 if (ExtraCode) {
593 if ((ExtraCode[0] == 'N' || ExtraCode[0] == 'M') && !ExtraCode[1] &&
594 MO.isReg() && SystemZ::GR128BitRegClass.contains(MO.getReg()))
595 MCOp =
596 MCOperand::createReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64));
597 else
598 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
599 } else {
600 SystemZMCInstLower Lower(MF->getContext(), *this);
601 MCOp = Lower.lowerOperand(MO);
602 }
603 printOperand(MCOp, &MAI, OS);
604 return false;
605}
606
608 unsigned OpNo,
609 const char *ExtraCode,
610 raw_ostream &OS) {
611 if (ExtraCode && ExtraCode[0] && !ExtraCode[1]) {
612 switch (ExtraCode[0]) {
613 case 'A':
614 // Unlike EmitMachineNode(), EmitSpecialNode(INLINEASM) does not call
615 // setMemRefs(), so MI->memoperands() is empty and the alignment
616 // information is not available.
617 return false;
618 case 'O':
619 OS << MI->getOperand(OpNo + 1).getImm();
620 return false;
621 case 'R':
622 ::printReg(MI->getOperand(OpNo).getReg(), &MAI, OS);
623 return false;
624 }
625 }
626 printAddress(&MAI, MI->getOperand(OpNo).getReg(),
627 MCOperand::createImm(MI->getOperand(OpNo + 1).getImm()),
628 MI->getOperand(OpNo + 2).getReg(), OS);
629 return false;
630}
631
632char SystemZAsmPrinter::ID = 0;
633
634INITIALIZE_PASS(SystemZAsmPrinter, "systemz-asm-printer",
635 "SystemZ Assembly Printer", false, false)
636
637static AsmPrinter *
638createSystemZAsmPrinter(TargetMachine &TM,
639 std::unique_ptr<MCStreamer> &&Streamer) {
640 if (TM.getTargetTriple().isOSzOS())
641 return new SystemZXPLINKAsmPrinter(TM, std::move(Streamer));
642 return new SystemZELFAsmPrinter(TM, std::move(Streamer));
643}
644
645// Force static initialization.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
#define RegName(no)
Register Reg
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
static MCInst lowerVecEltExtraction(const MachineInstr *MI, unsigned Opcode)
std::unique_ptr< MCStreamer > && Streamer
return new SystemZELFAsmPrinter(TM, std::move(Streamer))
#define LOWER_LOW(NAME)
static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, unsigned Opcode)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter()
#define LOWER_HIGH(NAME)
static void printFormattedRegName(const MCAsmInfo *MAI, unsigned RegNo, raw_ostream &OS)
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode)
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode)
static void printAddress(const MCAsmInfo *MAI, unsigned Base, const MCOperand &DispMO, unsigned Index, raw_ostream &OS)
static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode)
static MCInst lowerVecEltInsertion(const MachineInstr *MI, unsigned Opcode)
static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode)
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode)
This class is intended to be used as a driving class for all asm writers.
Definition AsmPrinter.h:91
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
TargetMachine & TM
Target machine description.
Definition AsmPrinter.h:94
MachineFunction * MF
The current machine function.
Definition AsmPrinter.h:109
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition AsmPrinter.h:101
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition AsmPrinter.h:106
const MCAsmInfo & MAI
Target Asm Printer information.
Definition AsmPrinter.h:97
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:67
unsigned getAssemblerDialect() const
Definition MCAsmInfo.h:577
void printExpr(raw_ostream &, const MCExpr &) const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:342
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
void addOperand(const MCOperand Op)
Definition MCInst.h:215
void setOpcode(unsigned Op)
Definition MCInst.h:201
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Streaming machine code generation interface.
Definition MCStreamer.h:222
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
Representation of each machine instruction.
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
static const char * getRegisterName(MCRegister Reg)
static const char * getRegisterName(MCRegister Reg)
std::pair< MCInst, const MCSubtargetInfo * > MCInstSTIPair
Primary interface to the complete machine description for the target machine.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getRegAsGR32(unsigned Reg)
unsigned getRegAsGRH32(unsigned Reg)
unsigned getRegAsVR128(unsigned Reg)
unsigned getRegAsGR64(unsigned Reg)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSystemZTarget()
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn)
RegisterAsmPrinter - Register an AsmPrinter implementation for the given target.