LLVM  10.0.0svn
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"
17 #include "SystemZMCInstLower.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/MC/MCStreamer.h"
26 
27 using namespace llvm;
28 
29 // Return an RI instruction like MI with opcode Opcode, but with the
30 // GR64 register operands turned into GR32s.
31 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
32  if (MI->isCompare())
33  return MCInstBuilder(Opcode)
35  .addImm(MI->getOperand(1).getImm());
36  else
37  return MCInstBuilder(Opcode)
40  .addImm(MI->getOperand(2).getImm());
41 }
42 
43 // Return an RI instruction like MI with opcode Opcode, but with the
44 // GR64 register operands turned into GRH32s.
45 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
46  if (MI->isCompare())
47  return MCInstBuilder(Opcode)
49  .addImm(MI->getOperand(1).getImm());
50  else
51  return MCInstBuilder(Opcode)
54  .addImm(MI->getOperand(2).getImm());
55 }
56 
57 // Return an RI instruction like MI with opcode Opcode, but with the
58 // R2 register turned into a GR64.
59 static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
60  return MCInstBuilder(Opcode)
61  .addReg(MI->getOperand(0).getReg())
62  .addReg(MI->getOperand(1).getReg())
63  .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
64  .addImm(MI->getOperand(3).getImm())
65  .addImm(MI->getOperand(4).getImm())
66  .addImm(MI->getOperand(5).getImm());
67 }
68 
70  StringRef Name = "__tls_get_offset";
71  return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
73  Context);
74 }
75 
77  StringRef Name = "_GLOBAL_OFFSET_TABLE_";
78  return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
80  Context);
81 }
82 
83 // MI is an instruction that accepts an optional alignment hint,
84 // and which was already lowered to LoweredMI. If the alignment
85 // of the original memory operand is known, update LoweredMI to
86 // an instruction with the corresponding hint set.
87 static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI,
88  unsigned Opcode) {
89  if (!MI->hasOneMemOperand())
90  return;
91  const MachineMemOperand *MMO = *MI->memoperands_begin();
92  unsigned AlignmentHint = 0;
93  if (MMO->getAlignment() >= 16)
94  AlignmentHint = 4;
95  else if (MMO->getAlignment() >= 8)
96  AlignmentHint = 3;
97  if (AlignmentHint == 0)
98  return;
99 
100  LoweredMI.setOpcode(Opcode);
101  LoweredMI.addOperand(MCOperand::createImm(AlignmentHint));
102 }
103 
104 // MI loads the high part of a vector from memory. Return an instruction
105 // that uses replicating vector load Opcode to do the same thing.
106 static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
107  return MCInstBuilder(Opcode)
109  .addReg(MI->getOperand(1).getReg())
110  .addImm(MI->getOperand(2).getImm())
111  .addReg(MI->getOperand(3).getReg());
112 }
113 
114 // MI stores the high part of a vector to memory. Return an instruction
115 // that uses elemental vector store Opcode to do the same thing.
116 static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
117  return MCInstBuilder(Opcode)
119  .addReg(MI->getOperand(1).getReg())
120  .addImm(MI->getOperand(2).getImm())
121  .addReg(MI->getOperand(3).getReg())
122  .addImm(0);
123 }
124 
127  MCInst LoweredMI;
128  switch (MI->getOpcode()) {
129  case SystemZ::Return:
130  LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
131  break;
132 
133  case SystemZ::CondReturn:
134  LoweredMI = MCInstBuilder(SystemZ::BCR)
135  .addImm(MI->getOperand(0).getImm())
136  .addImm(MI->getOperand(1).getImm())
137  .addReg(SystemZ::R14D);
138  break;
139 
140  case SystemZ::CRBReturn:
141  LoweredMI = MCInstBuilder(SystemZ::CRB)
142  .addReg(MI->getOperand(0).getReg())
143  .addReg(MI->getOperand(1).getReg())
144  .addImm(MI->getOperand(2).getImm())
145  .addReg(SystemZ::R14D)
146  .addImm(0);
147  break;
148 
149  case SystemZ::CGRBReturn:
150  LoweredMI = MCInstBuilder(SystemZ::CGRB)
151  .addReg(MI->getOperand(0).getReg())
152  .addReg(MI->getOperand(1).getReg())
153  .addImm(MI->getOperand(2).getImm())
154  .addReg(SystemZ::R14D)
155  .addImm(0);
156  break;
157 
158  case SystemZ::CIBReturn:
159  LoweredMI = MCInstBuilder(SystemZ::CIB)
160  .addReg(MI->getOperand(0).getReg())
161  .addImm(MI->getOperand(1).getImm())
162  .addImm(MI->getOperand(2).getImm())
163  .addReg(SystemZ::R14D)
164  .addImm(0);
165  break;
166 
167  case SystemZ::CGIBReturn:
168  LoweredMI = MCInstBuilder(SystemZ::CGIB)
169  .addReg(MI->getOperand(0).getReg())
170  .addImm(MI->getOperand(1).getImm())
171  .addImm(MI->getOperand(2).getImm())
172  .addReg(SystemZ::R14D)
173  .addImm(0);
174  break;
175 
176  case SystemZ::CLRBReturn:
177  LoweredMI = MCInstBuilder(SystemZ::CLRB)
178  .addReg(MI->getOperand(0).getReg())
179  .addReg(MI->getOperand(1).getReg())
180  .addImm(MI->getOperand(2).getImm())
181  .addReg(SystemZ::R14D)
182  .addImm(0);
183  break;
184 
185  case SystemZ::CLGRBReturn:
186  LoweredMI = MCInstBuilder(SystemZ::CLGRB)
187  .addReg(MI->getOperand(0).getReg())
188  .addReg(MI->getOperand(1).getReg())
189  .addImm(MI->getOperand(2).getImm())
190  .addReg(SystemZ::R14D)
191  .addImm(0);
192  break;
193 
194  case SystemZ::CLIBReturn:
195  LoweredMI = MCInstBuilder(SystemZ::CLIB)
196  .addReg(MI->getOperand(0).getReg())
197  .addImm(MI->getOperand(1).getImm())
198  .addImm(MI->getOperand(2).getImm())
199  .addReg(SystemZ::R14D)
200  .addImm(0);
201  break;
202 
203  case SystemZ::CLGIBReturn:
204  LoweredMI = MCInstBuilder(SystemZ::CLGIB)
205  .addReg(MI->getOperand(0).getReg())
206  .addImm(MI->getOperand(1).getImm())
207  .addImm(MI->getOperand(2).getImm())
208  .addReg(SystemZ::R14D)
209  .addImm(0);
210  break;
211 
212  case SystemZ::CallBRASL:
213  LoweredMI = MCInstBuilder(SystemZ::BRASL)
214  .addReg(SystemZ::R14D)
215  .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
216  break;
217 
218  case SystemZ::CallBASR:
219  LoweredMI = MCInstBuilder(SystemZ::BASR)
220  .addReg(SystemZ::R14D)
221  .addReg(MI->getOperand(0).getReg());
222  break;
223 
224  case SystemZ::CallJG:
225  LoweredMI = MCInstBuilder(SystemZ::JG)
226  .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
227  break;
228 
229  case SystemZ::CallBRCL:
230  LoweredMI = MCInstBuilder(SystemZ::BRCL)
231  .addImm(MI->getOperand(0).getImm())
232  .addImm(MI->getOperand(1).getImm())
233  .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
234  break;
235 
236  case SystemZ::CallBR:
237  LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
238  break;
239 
240  case SystemZ::CallBCR:
241  LoweredMI = MCInstBuilder(SystemZ::BCR)
242  .addImm(MI->getOperand(0).getImm())
243  .addImm(MI->getOperand(1).getImm())
244  .addReg(SystemZ::R1D);
245  break;
246 
247  case SystemZ::CRBCall:
248  LoweredMI = MCInstBuilder(SystemZ::CRB)
249  .addReg(MI->getOperand(0).getReg())
250  .addReg(MI->getOperand(1).getReg())
251  .addImm(MI->getOperand(2).getImm())
252  .addReg(SystemZ::R1D)
253  .addImm(0);
254  break;
255 
256  case SystemZ::CGRBCall:
257  LoweredMI = MCInstBuilder(SystemZ::CGRB)
258  .addReg(MI->getOperand(0).getReg())
259  .addReg(MI->getOperand(1).getReg())
260  .addImm(MI->getOperand(2).getImm())
261  .addReg(SystemZ::R1D)
262  .addImm(0);
263  break;
264 
265  case SystemZ::CIBCall:
266  LoweredMI = MCInstBuilder(SystemZ::CIB)
267  .addReg(MI->getOperand(0).getReg())
268  .addImm(MI->getOperand(1).getImm())
269  .addImm(MI->getOperand(2).getImm())
270  .addReg(SystemZ::R1D)
271  .addImm(0);
272  break;
273 
274  case SystemZ::CGIBCall:
275  LoweredMI = MCInstBuilder(SystemZ::CGIB)
276  .addReg(MI->getOperand(0).getReg())
277  .addImm(MI->getOperand(1).getImm())
278  .addImm(MI->getOperand(2).getImm())
279  .addReg(SystemZ::R1D)
280  .addImm(0);
281  break;
282 
283  case SystemZ::CLRBCall:
284  LoweredMI = MCInstBuilder(SystemZ::CLRB)
285  .addReg(MI->getOperand(0).getReg())
286  .addReg(MI->getOperand(1).getReg())
287  .addImm(MI->getOperand(2).getImm())
288  .addReg(SystemZ::R1D)
289  .addImm(0);
290  break;
291 
292  case SystemZ::CLGRBCall:
293  LoweredMI = MCInstBuilder(SystemZ::CLGRB)
294  .addReg(MI->getOperand(0).getReg())
295  .addReg(MI->getOperand(1).getReg())
296  .addImm(MI->getOperand(2).getImm())
297  .addReg(SystemZ::R1D)
298  .addImm(0);
299  break;
300 
301  case SystemZ::CLIBCall:
302  LoweredMI = MCInstBuilder(SystemZ::CLIB)
303  .addReg(MI->getOperand(0).getReg())
304  .addImm(MI->getOperand(1).getImm())
305  .addImm(MI->getOperand(2).getImm())
306  .addReg(SystemZ::R1D)
307  .addImm(0);
308  break;
309 
310  case SystemZ::CLGIBCall:
311  LoweredMI = MCInstBuilder(SystemZ::CLGIB)
312  .addReg(MI->getOperand(0).getReg())
313  .addImm(MI->getOperand(1).getImm())
314  .addImm(MI->getOperand(2).getImm())
315  .addReg(SystemZ::R1D)
316  .addImm(0);
317  break;
318 
319  case SystemZ::TLS_GDCALL:
320  LoweredMI = MCInstBuilder(SystemZ::BRASL)
321  .addReg(SystemZ::R14D)
324  break;
325 
326  case SystemZ::TLS_LDCALL:
327  LoweredMI = MCInstBuilder(SystemZ::BRASL)
328  .addReg(SystemZ::R14D)
331  break;
332 
333  case SystemZ::GOT:
334  LoweredMI = MCInstBuilder(SystemZ::LARL)
335  .addReg(MI->getOperand(0).getReg())
336  .addExpr(getGlobalOffsetTable(MF->getContext()));
337  break;
338 
339  case SystemZ::IILF64:
340  LoweredMI = MCInstBuilder(SystemZ::IILF)
342  .addImm(MI->getOperand(2).getImm());
343  break;
344 
345  case SystemZ::IIHF64:
346  LoweredMI = MCInstBuilder(SystemZ::IIHF)
348  .addImm(MI->getOperand(2).getImm());
349  break;
350 
351  case SystemZ::RISBHH:
352  case SystemZ::RISBHL:
353  LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
354  break;
355 
356  case SystemZ::RISBLH:
357  case SystemZ::RISBLL:
358  LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
359  break;
360 
361  case SystemZ::VLVGP32:
362  LoweredMI = MCInstBuilder(SystemZ::VLVGP)
363  .addReg(MI->getOperand(0).getReg())
364  .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
366  break;
367 
368  case SystemZ::VLR32:
369  case SystemZ::VLR64:
370  LoweredMI = MCInstBuilder(SystemZ::VLR)
373  break;
374 
375  case SystemZ::VL:
376  Lower.lower(MI, LoweredMI);
377  lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign);
378  break;
379 
380  case SystemZ::VST:
381  Lower.lower(MI, LoweredMI);
382  lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign);
383  break;
384 
385  case SystemZ::VLM:
386  Lower.lower(MI, LoweredMI);
387  lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign);
388  break;
389 
390  case SystemZ::VSTM:
391  Lower.lower(MI, LoweredMI);
392  lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign);
393  break;
394 
395  case SystemZ::VL32:
396  LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
397  break;
398 
399  case SystemZ::VL64:
400  LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
401  break;
402 
403  case SystemZ::VST32:
404  LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
405  break;
406 
407  case SystemZ::VST64:
408  LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
409  break;
410 
411  case SystemZ::LFER:
412  LoweredMI = MCInstBuilder(SystemZ::VLGVF)
415  .addReg(0).addImm(0);
416  break;
417 
418  case SystemZ::LEFR:
419  LoweredMI = MCInstBuilder(SystemZ::VLVGF)
422  .addReg(MI->getOperand(1).getReg())
423  .addReg(0).addImm(0);
424  break;
425 
426 #define LOWER_LOW(NAME) \
427  case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
428 
429  LOWER_LOW(IILL);
430  LOWER_LOW(IILH);
431  LOWER_LOW(TMLL);
432  LOWER_LOW(TMLH);
433  LOWER_LOW(NILL);
434  LOWER_LOW(NILH);
435  LOWER_LOW(NILF);
436  LOWER_LOW(OILL);
437  LOWER_LOW(OILH);
438  LOWER_LOW(OILF);
439  LOWER_LOW(XILF);
440 
441 #undef LOWER_LOW
442 
443 #define LOWER_HIGH(NAME) \
444  case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
445 
446  LOWER_HIGH(IIHL);
447  LOWER_HIGH(IIHH);
448  LOWER_HIGH(TMHL);
449  LOWER_HIGH(TMHH);
450  LOWER_HIGH(NIHL);
451  LOWER_HIGH(NIHH);
452  LOWER_HIGH(NIHF);
453  LOWER_HIGH(OIHL);
454  LOWER_HIGH(OIHH);
455  LOWER_HIGH(OIHF);
456  LOWER_HIGH(XIHF);
457 
458 #undef LOWER_HIGH
459 
460  case SystemZ::Serialize:
462  LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
463  .addImm(14).addReg(SystemZ::R0D);
464  else
465  LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
466  .addImm(15).addReg(SystemZ::R0D);
467  break;
468 
469  // Emit nothing here but a comment if we can.
470  case SystemZ::MemBarrier:
471  OutStreamer->emitRawComment("MEMBARRIER");
472  return;
473 
474  // We want to emit "j .+2" for traps, jumping to the relative immediate field
475  // of the jump instruction, which is an illegal instruction. We cannot emit a
476  // "." symbol, so create and emit a temp label before the instruction and use
477  // that instead.
478  case SystemZ::Trap: {
480  OutStreamer->EmitLabel(DotSym);
481 
482  const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
483  const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
484  LoweredMI = MCInstBuilder(SystemZ::J)
485  .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
486  }
487  break;
488 
489  // Conditional traps will create a branch on condition instruction that jumps
490  // to the relative immediate field of the jump instruction. (eg. "jo .+2")
491  case SystemZ::CondTrap: {
493  OutStreamer->EmitLabel(DotSym);
494 
495  const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
496  const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
497  LoweredMI = MCInstBuilder(SystemZ::BRC)
498  .addImm(MI->getOperand(0).getImm())
499  .addImm(MI->getOperand(1).getImm())
500  .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
501  }
502  break;
503 
504  case TargetOpcode::FENTRY_CALL:
505  LowerFENTRY_CALL(*MI, Lower);
506  return;
507 
508  case TargetOpcode::STACKMAP:
509  LowerSTACKMAP(*MI);
510  return;
511 
512  case TargetOpcode::PATCHPOINT:
513  LowerPATCHPOINT(*MI, Lower);
514  return;
515 
516  default:
517  Lower.lower(MI, LoweredMI);
518  break;
519  }
520  EmitToStreamer(*OutStreamer, LoweredMI);
521 }
522 
523 
524 // Emit the largest nop instruction smaller than or equal to NumBytes
525 // bytes. Return the size of nop emitted.
527  unsigned NumBytes, const MCSubtargetInfo &STI) {
528  if (NumBytes < 2) {
529  llvm_unreachable("Zero nops?");
530  return 0;
531  }
532  else if (NumBytes < 4) {
533  OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm)
534  .addImm(0).addReg(SystemZ::R0D), STI);
535  return 2;
536  }
537  else if (NumBytes < 6) {
538  OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm)
539  .addImm(0).addReg(0).addImm(0).addReg(0),
540  STI);
541  return 4;
542  }
543  else {
544  MCSymbol *DotSym = OutContext.createTempSymbol();
545  const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
546  OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm)
547  .addImm(0).addExpr(Dot), STI);
548  OutStreamer.EmitLabel(DotSym);
549  return 6;
550  }
551 }
552 
553 void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
555  MCContext &Ctx = MF->getContext();
556  if (MF->getFunction().getFnAttribute("mnop-mcount")
557  .getValueAsString() == "true") {
558  EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo());
559  return;
560  }
561 
562  MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
563  const MCSymbolRefExpr *Op =
565  OutStreamer->EmitInstruction(MCInstBuilder(SystemZ::BRASL)
566  .addReg(SystemZ::R0D).addExpr(Op), getSubtargetInfo());
567 }
568 
569 void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
570  const SystemZInstrInfo *TII =
571  static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
572 
573  unsigned NumNOPBytes = MI.getOperand(1).getImm();
574 
575  SM.recordStackMap(MI);
576  assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
577 
578  // Scan ahead to trim the shadow.
579  unsigned ShadowBytes = 0;
580  const MachineBasicBlock &MBB = *MI.getParent();
582  ++MII;
583  while (ShadowBytes < NumNOPBytes) {
584  if (MII == MBB.end() ||
585  MII->getOpcode() == TargetOpcode::PATCHPOINT ||
586  MII->getOpcode() == TargetOpcode::STACKMAP)
587  break;
588  ShadowBytes += TII->getInstSizeInBytes(*MII);
589  if (MII->isCall())
590  break;
591  ++MII;
592  }
593 
594  // Emit nops.
595  while (ShadowBytes < NumNOPBytes)
596  ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
597  getSubtargetInfo());
598 }
599 
600 // Lower a patchpoint of the form:
601 // [<def>], <id>, <numBytes>, <target>, <numArgs>
602 void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
603  SystemZMCInstLower &Lower) {
604  SM.recordPatchPoint(MI);
605  PatchPointOpers Opers(&MI);
606 
607  unsigned EncodedBytes = 0;
608  const MachineOperand &CalleeMO = Opers.getCallTarget();
609 
610  if (CalleeMO.isImm()) {
611  uint64_t CallTarget = CalleeMO.getImm();
612  if (CallTarget) {
613  unsigned ScratchIdx = -1;
614  unsigned ScratchReg = 0;
615  do {
616  ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
617  ScratchReg = MI.getOperand(ScratchIdx).getReg();
618  } while (ScratchReg == SystemZ::R0D);
619 
620  // Materialize the call target address
621  EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
622  .addReg(ScratchReg)
623  .addImm(CallTarget & 0xFFFFFFFF));
624  EncodedBytes += 6;
625  if (CallTarget >> 32) {
626  EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
627  .addReg(ScratchReg)
628  .addImm(CallTarget >> 32));
629  EncodedBytes += 6;
630  }
631 
632  EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
633  .addReg(SystemZ::R14D)
634  .addReg(ScratchReg));
635  EncodedBytes += 2;
636  }
637  } else if (CalleeMO.isGlobal()) {
638  const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
639  EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
640  .addReg(SystemZ::R14D)
641  .addExpr(Expr));
642  EncodedBytes += 6;
643  }
644 
645  // Emit padding.
646  unsigned NumBytes = Opers.getNumPatchBytes();
647  assert(NumBytes >= EncodedBytes &&
648  "Patchpoint can't request size less than the length of a call.");
649  assert((NumBytes - EncodedBytes) % 2 == 0 &&
650  "Invalid number of NOP bytes requested!");
651  while (EncodedBytes < NumBytes)
652  EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
653  getSubtargetInfo());
654 }
655 
656 // Convert a SystemZ-specific constant pool modifier into the associated
657 // MCSymbolRefExpr variant kind.
660  switch (Modifier) {
665  }
666  llvm_unreachable("Invalid SystemCPModifier!");
667 }
668 
671  auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
672 
673  const MCExpr *Expr =
674  MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
675  getModifierVariantKind(ZCPV->getModifier()),
676  OutContext);
677  uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
678 
679  OutStreamer->EmitValue(Expr, Size);
680 }
681 
682 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
683  const char *ExtraCode,
684  raw_ostream &OS) {
685  if (ExtraCode)
686  return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
688  MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
690  return false;
691 }
692 
694  unsigned OpNo,
695  const char *ExtraCode,
696  raw_ostream &OS) {
698  MI->getOperand(OpNo + 1).getImm(),
699  MI->getOperand(OpNo + 2).getReg(), OS);
700  return false;
701 }
702 
704  emitStackMaps(SM);
705 }
706 
707 // Force static initialization.
710 }
#define LOWER_LOW(NAME)
void EmitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
unsigned getNextScratchIdx(unsigned StartIdx=0) const
Get the next scratch register operand index.
Definition: StackMaps.cpp:69
LLVMContext & Context
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:93
static void printAddress(unsigned Base, int64_t Disp, unsigned Index, raw_ostream &O)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:327
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:88
bool hasFastSerialization() const
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:230
void LLVMInitializeSystemZAsmPrinter()
static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, unsigned NumBytes, const MCSubtargetInfo &STI)
static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, unsigned Opcode)
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:96
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode)
A description of a memory reference used in the backend.
unsigned getRegAsGRH32(unsigned Reg)
const HexagonInstrInfo * TII
unsigned getRegAsGR32(unsigned Reg)
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:169
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override
Context object for machine code objects.
Definition: MCContext.h:65
RegisterAsmPrinter - Helper template for registering a target specific assembly printer, for use in the target machine initialization function.
virtual const TargetInstrInfo * getInstrInfo() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:465
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:49
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false)
Definition: MCExpr.cpp:169
MCOperand lowerOperand(const MachineOperand &MO) const
MCContext & getContext() const
static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode)
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...
Streaming machine code generation interface.
Definition: MCStreamer.h:190
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
Definition: MCInstBuilder.h:31
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:658
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
Definition: MCContext.cpp:225
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:84
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
Definition: MachineInstr.h:718
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode)
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:487
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode)
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
Definition: MachineInstr.h:567
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
MI-level patchpoint operands.
Definition: StackMaps.h:76
void emitStackMaps(StackMaps &SM)
Emit the stack maps.
Abstract base class for all machine specific constantpool value subclasses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t getAlignment() const
Return the minimum known alignment in bytes of the actual memory reference.
static const MCSymbolRefExpr * getTLSGetOffset(MCContext &Context)
void recordPatchPoint(const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
Definition: StackMaps.cpp:372
void setOpcode(unsigned Op)
Definition: MCInst.h:170
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:552
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:449
MachineOperand class - Representation of each machine instruction operand.
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:235
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...
static MCSymbolRefExpr::VariantKind getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier)
unsigned getRegAsGR64(unsigned Reg)
unsigned getRegAsVR128(unsigned Reg)
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode)
void recordStackMap(const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
Definition: StackMaps.cpp:363
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
Target & getTheSystemZTarget()
Representation of each machine instruction.
Definition: MachineInstr.h:64
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:129
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:223
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...
void EmitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
static const MCSymbolRefExpr * getGlobalOffsetTable(MCContext &Context)
Generic base class for all target subtargets.
uint32_t Size
Definition: Profile.cpp:46
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Definition: StackMaps.h:104
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void printOperand(const MCOperand &MO, const MCAsmInfo *MAI, raw_ostream &O)
#define LOWER_HIGH(NAME)
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:399
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:333
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
A SystemZ-specific constant pool value.
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:220
IRTranslator LLVM IR MI
const MachineOperand & getCallTarget() const
Returns the target of the underlying call.
Definition: StackMaps.h:109
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:122
const MCExpr * getExpr(const MachineOperand &MO, MCSymbolRefExpr::VariantKind Kind) const