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