]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / SystemZ / SystemZAsmPrinter.cpp
1 //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Streams SystemZ assembly language and associated data, in the form of
11 // MCInsts and MCExprs respectively.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "SystemZAsmPrinter.h"
16 #include "InstPrinter/SystemZInstPrinter.h"
17 #include "SystemZConstantPoolValue.h"
18 #include "SystemZMCInstLower.h"
19 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.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"
25 #include "llvm/Support/TargetRegistry.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)
34       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
35       .addImm(MI->getOperand(1).getImm());
36   else
37     return MCInstBuilder(Opcode)
38       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
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)
48       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
49       .addImm(MI->getOperand(1).getImm());
50   else
51     return MCInstBuilder(Opcode)
52       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
53       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
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
69 static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
70   StringRef Name = "__tls_get_offset";
71   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
72                                  MCSymbolRefExpr::VK_PLT,
73                                  Context);
74 }
75
76 static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
77   StringRef Name = "_GLOBAL_OFFSET_TABLE_";
78   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
79                                  MCSymbolRefExpr::VK_None,
80                                  Context);
81 }
82
83 // MI loads the high part of a vector from memory.  Return an instruction
84 // that uses replicating vector load Opcode to do the same thing.
85 static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
86   return MCInstBuilder(Opcode)
87     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
88     .addReg(MI->getOperand(1).getReg())
89     .addImm(MI->getOperand(2).getImm())
90     .addReg(MI->getOperand(3).getReg());
91 }
92
93 // MI stores the high part of a vector to memory.  Return an instruction
94 // that uses elemental vector store Opcode to do the same thing.
95 static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
96   return MCInstBuilder(Opcode)
97     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
98     .addReg(MI->getOperand(1).getReg())
99     .addImm(MI->getOperand(2).getImm())
100     .addReg(MI->getOperand(3).getReg())
101     .addImm(0);
102 }
103
104 void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
105   SystemZMCInstLower Lower(MF->getContext(), *this);
106   MCInst LoweredMI;
107   switch (MI->getOpcode()) {
108   case SystemZ::Return:
109     LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
110     break;
111
112   case SystemZ::CondReturn:
113     LoweredMI = MCInstBuilder(SystemZ::BCR)
114       .addImm(MI->getOperand(0).getImm())
115       .addImm(MI->getOperand(1).getImm())
116       .addReg(SystemZ::R14D);
117     break;
118
119   case SystemZ::CRBReturn:
120     LoweredMI = MCInstBuilder(SystemZ::CRB)
121       .addReg(MI->getOperand(0).getReg())
122       .addReg(MI->getOperand(1).getReg())
123       .addImm(MI->getOperand(2).getImm())
124       .addReg(SystemZ::R14D)
125       .addImm(0);
126     break;
127
128   case SystemZ::CGRBReturn:
129     LoweredMI = MCInstBuilder(SystemZ::CGRB)
130       .addReg(MI->getOperand(0).getReg())
131       .addReg(MI->getOperand(1).getReg())
132       .addImm(MI->getOperand(2).getImm())
133       .addReg(SystemZ::R14D)
134       .addImm(0);
135     break;
136
137   case SystemZ::CIBReturn:
138     LoweredMI = MCInstBuilder(SystemZ::CIB)
139       .addReg(MI->getOperand(0).getReg())
140       .addImm(MI->getOperand(1).getImm())
141       .addImm(MI->getOperand(2).getImm())
142       .addReg(SystemZ::R14D)
143       .addImm(0);
144     break;
145
146   case SystemZ::CGIBReturn:
147     LoweredMI = MCInstBuilder(SystemZ::CGIB)
148       .addReg(MI->getOperand(0).getReg())
149       .addImm(MI->getOperand(1).getImm())
150       .addImm(MI->getOperand(2).getImm())
151       .addReg(SystemZ::R14D)
152       .addImm(0);
153     break;
154
155   case SystemZ::CLRBReturn:
156     LoweredMI = MCInstBuilder(SystemZ::CLRB)
157       .addReg(MI->getOperand(0).getReg())
158       .addReg(MI->getOperand(1).getReg())
159       .addImm(MI->getOperand(2).getImm())
160       .addReg(SystemZ::R14D)
161       .addImm(0);
162     break;
163
164   case SystemZ::CLGRBReturn:
165     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
166       .addReg(MI->getOperand(0).getReg())
167       .addReg(MI->getOperand(1).getReg())
168       .addImm(MI->getOperand(2).getImm())
169       .addReg(SystemZ::R14D)
170       .addImm(0);
171     break;
172
173   case SystemZ::CLIBReturn:
174     LoweredMI = MCInstBuilder(SystemZ::CLIB)
175       .addReg(MI->getOperand(0).getReg())
176       .addImm(MI->getOperand(1).getImm())
177       .addImm(MI->getOperand(2).getImm())
178       .addReg(SystemZ::R14D)
179       .addImm(0);
180     break;
181
182   case SystemZ::CLGIBReturn:
183     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
184       .addReg(MI->getOperand(0).getReg())
185       .addImm(MI->getOperand(1).getImm())
186       .addImm(MI->getOperand(2).getImm())
187       .addReg(SystemZ::R14D)
188       .addImm(0);
189     break;
190
191   case SystemZ::CallBRASL:
192     LoweredMI = MCInstBuilder(SystemZ::BRASL)
193       .addReg(SystemZ::R14D)
194       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
195     break;
196
197   case SystemZ::CallBASR:
198     LoweredMI = MCInstBuilder(SystemZ::BASR)
199       .addReg(SystemZ::R14D)
200       .addReg(MI->getOperand(0).getReg());
201     break;
202
203   case SystemZ::CallJG:
204     LoweredMI = MCInstBuilder(SystemZ::JG)
205       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
206     break;
207
208   case SystemZ::CallBRCL:
209     LoweredMI = MCInstBuilder(SystemZ::BRCL)
210       .addImm(MI->getOperand(0).getImm())
211       .addImm(MI->getOperand(1).getImm())
212       .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
213     break;
214
215   case SystemZ::CallBR:
216     LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
217     break;
218
219   case SystemZ::CallBCR:
220     LoweredMI = MCInstBuilder(SystemZ::BCR)
221       .addImm(MI->getOperand(0).getImm())
222       .addImm(MI->getOperand(1).getImm())
223       .addReg(SystemZ::R1D);
224     break;
225
226   case SystemZ::CRBCall:
227     LoweredMI = MCInstBuilder(SystemZ::CRB)
228       .addReg(MI->getOperand(0).getReg())
229       .addReg(MI->getOperand(1).getReg())
230       .addImm(MI->getOperand(2).getImm())
231       .addReg(SystemZ::R1D)
232       .addImm(0);
233     break;
234
235   case SystemZ::CGRBCall:
236     LoweredMI = MCInstBuilder(SystemZ::CGRB)
237       .addReg(MI->getOperand(0).getReg())
238       .addReg(MI->getOperand(1).getReg())
239       .addImm(MI->getOperand(2).getImm())
240       .addReg(SystemZ::R1D)
241       .addImm(0);
242     break;
243
244   case SystemZ::CIBCall:
245     LoweredMI = MCInstBuilder(SystemZ::CIB)
246       .addReg(MI->getOperand(0).getReg())
247       .addImm(MI->getOperand(1).getImm())
248       .addImm(MI->getOperand(2).getImm())
249       .addReg(SystemZ::R1D)
250       .addImm(0);
251     break;
252
253   case SystemZ::CGIBCall:
254     LoweredMI = MCInstBuilder(SystemZ::CGIB)
255       .addReg(MI->getOperand(0).getReg())
256       .addImm(MI->getOperand(1).getImm())
257       .addImm(MI->getOperand(2).getImm())
258       .addReg(SystemZ::R1D)
259       .addImm(0);
260     break;
261
262   case SystemZ::CLRBCall:
263     LoweredMI = MCInstBuilder(SystemZ::CLRB)
264       .addReg(MI->getOperand(0).getReg())
265       .addReg(MI->getOperand(1).getReg())
266       .addImm(MI->getOperand(2).getImm())
267       .addReg(SystemZ::R1D)
268       .addImm(0);
269     break;
270
271   case SystemZ::CLGRBCall:
272     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
273       .addReg(MI->getOperand(0).getReg())
274       .addReg(MI->getOperand(1).getReg())
275       .addImm(MI->getOperand(2).getImm())
276       .addReg(SystemZ::R1D)
277       .addImm(0);
278     break;
279
280   case SystemZ::CLIBCall:
281     LoweredMI = MCInstBuilder(SystemZ::CLIB)
282       .addReg(MI->getOperand(0).getReg())
283       .addImm(MI->getOperand(1).getImm())
284       .addImm(MI->getOperand(2).getImm())
285       .addReg(SystemZ::R1D)
286       .addImm(0);
287     break;
288
289   case SystemZ::CLGIBCall:
290     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
291       .addReg(MI->getOperand(0).getReg())
292       .addImm(MI->getOperand(1).getImm())
293       .addImm(MI->getOperand(2).getImm())
294       .addReg(SystemZ::R1D)
295       .addImm(0);
296     break;
297
298   case SystemZ::TLS_GDCALL:
299     LoweredMI = MCInstBuilder(SystemZ::BRASL)
300       .addReg(SystemZ::R14D)
301       .addExpr(getTLSGetOffset(MF->getContext()))
302       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
303     break;
304
305   case SystemZ::TLS_LDCALL:
306     LoweredMI = MCInstBuilder(SystemZ::BRASL)
307       .addReg(SystemZ::R14D)
308       .addExpr(getTLSGetOffset(MF->getContext()))
309       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
310     break;
311
312   case SystemZ::GOT:
313     LoweredMI = MCInstBuilder(SystemZ::LARL)
314       .addReg(MI->getOperand(0).getReg())
315       .addExpr(getGlobalOffsetTable(MF->getContext()));
316     break;
317
318   case SystemZ::IILF64:
319     LoweredMI = MCInstBuilder(SystemZ::IILF)
320       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
321       .addImm(MI->getOperand(2).getImm());
322     break;
323
324   case SystemZ::IIHF64:
325     LoweredMI = MCInstBuilder(SystemZ::IIHF)
326       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
327       .addImm(MI->getOperand(2).getImm());
328     break;
329
330   case SystemZ::RISBHH:
331   case SystemZ::RISBHL:
332     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
333     break;
334
335   case SystemZ::RISBLH:
336   case SystemZ::RISBLL:
337     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
338     break;
339
340   case SystemZ::VLVGP32:
341     LoweredMI = MCInstBuilder(SystemZ::VLVGP)
342       .addReg(MI->getOperand(0).getReg())
343       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
344       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
345     break;
346
347   case SystemZ::VLR32:
348   case SystemZ::VLR64:
349     LoweredMI = MCInstBuilder(SystemZ::VLR)
350       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
351       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
352     break;
353
354   case SystemZ::VL32:
355     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
356     break;
357
358   case SystemZ::VL64:
359     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
360     break;
361
362   case SystemZ::VST32:
363     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
364     break;
365
366   case SystemZ::VST64:
367     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
368     break;
369
370   case SystemZ::LFER:
371     LoweredMI = MCInstBuilder(SystemZ::VLGVF)
372       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
373       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
374       .addReg(0).addImm(0);
375     break;
376
377   case SystemZ::LEFR:
378     LoweredMI = MCInstBuilder(SystemZ::VLVGF)
379       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
380       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
381       .addReg(MI->getOperand(1).getReg())
382       .addReg(0).addImm(0);
383     break;
384
385 #define LOWER_LOW(NAME)                                                 \
386   case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
387
388   LOWER_LOW(IILL);
389   LOWER_LOW(IILH);
390   LOWER_LOW(TMLL);
391   LOWER_LOW(TMLH);
392   LOWER_LOW(NILL);
393   LOWER_LOW(NILH);
394   LOWER_LOW(NILF);
395   LOWER_LOW(OILL);
396   LOWER_LOW(OILH);
397   LOWER_LOW(OILF);
398   LOWER_LOW(XILF);
399
400 #undef LOWER_LOW
401
402 #define LOWER_HIGH(NAME) \
403   case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
404
405   LOWER_HIGH(IIHL);
406   LOWER_HIGH(IIHH);
407   LOWER_HIGH(TMHL);
408   LOWER_HIGH(TMHH);
409   LOWER_HIGH(NIHL);
410   LOWER_HIGH(NIHH);
411   LOWER_HIGH(NIHF);
412   LOWER_HIGH(OIHL);
413   LOWER_HIGH(OIHH);
414   LOWER_HIGH(OIHF);
415   LOWER_HIGH(XIHF);
416
417 #undef LOWER_HIGH
418
419   case SystemZ::Serialize:
420     if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
421       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
422         .addImm(14).addReg(SystemZ::R0D);
423     else
424       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
425         .addImm(15).addReg(SystemZ::R0D);
426     break;
427
428   // Emit nothing here but a comment if we can.
429   case SystemZ::MemBarrier:
430     OutStreamer->emitRawComment("MEMBARRIER");
431     return;
432
433   // We want to emit "j .+2" for traps, jumping to the relative immediate field
434   // of the jump instruction, which is an illegal instruction. We cannot emit a
435   // "." symbol, so create and emit a temp label before the instruction and use
436   // that instead.
437   case SystemZ::Trap: {
438     MCSymbol *DotSym = OutContext.createTempSymbol();
439     OutStreamer->EmitLabel(DotSym);
440
441     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
442     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
443     LoweredMI = MCInstBuilder(SystemZ::J)
444       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
445     }
446     break;
447
448   // Conditional traps will create a branch on condition instruction that jumps
449   // to the relative immediate field of the jump instruction. (eg. "jo .+2")
450   case SystemZ::CondTrap: {
451     MCSymbol *DotSym = OutContext.createTempSymbol();
452     OutStreamer->EmitLabel(DotSym);
453
454     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
455     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
456     LoweredMI = MCInstBuilder(SystemZ::BRC)
457       .addImm(MI->getOperand(0).getImm())
458       .addImm(MI->getOperand(1).getImm())
459       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
460     }
461     break;
462
463   case TargetOpcode::STACKMAP:
464     LowerSTACKMAP(*MI);
465     return;
466
467   case TargetOpcode::PATCHPOINT:
468     LowerPATCHPOINT(*MI, Lower);
469     return;
470
471   default:
472     Lower.lower(MI, LoweredMI);
473     break;
474   }
475   EmitToStreamer(*OutStreamer, LoweredMI);
476 }
477
478
479 // Emit the largest nop instruction smaller than or equal to NumBytes
480 // bytes.  Return the size of nop emitted.
481 static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
482                         unsigned NumBytes, const MCSubtargetInfo &STI) {
483   if (NumBytes < 2) {
484     llvm_unreachable("Zero nops?");
485     return 0;
486   }
487   else if (NumBytes < 4) {
488     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm)
489                                   .addImm(0).addReg(SystemZ::R0D), STI);
490     return 2;
491   }
492   else if (NumBytes < 6) {
493     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm)
494                                   .addImm(0).addReg(0).addImm(0).addReg(0),
495                                 STI);
496     return 4;
497   }
498   else {
499     MCSymbol *DotSym = OutContext.createTempSymbol();
500     const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
501     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm)
502                                   .addImm(0).addExpr(Dot), STI);
503     OutStreamer.EmitLabel(DotSym);
504     return 6;
505   }
506 }
507
508 void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
509   const SystemZInstrInfo *TII =
510     static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
511
512   unsigned NumNOPBytes = MI.getOperand(1).getImm();
513
514   SM.recordStackMap(MI);
515   assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
516
517   // Scan ahead to trim the shadow.
518   unsigned ShadowBytes = 0;
519   const MachineBasicBlock &MBB = *MI.getParent();
520   MachineBasicBlock::const_iterator MII(MI);
521   ++MII;
522   while (ShadowBytes < NumNOPBytes) {
523     if (MII == MBB.end() ||
524         MII->getOpcode() == TargetOpcode::PATCHPOINT ||
525         MII->getOpcode() == TargetOpcode::STACKMAP)
526       break;
527     ShadowBytes += TII->getInstSizeInBytes(*MII);
528     if (MII->isCall())
529       break;
530     ++MII;
531   }
532
533   // Emit nops.
534   while (ShadowBytes < NumNOPBytes)
535     ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
536                            getSubtargetInfo());
537 }
538
539 // Lower a patchpoint of the form:
540 // [<def>], <id>, <numBytes>, <target>, <numArgs>
541 void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
542                                         SystemZMCInstLower &Lower) {
543   SM.recordPatchPoint(MI);
544   PatchPointOpers Opers(&MI);
545
546   unsigned EncodedBytes = 0;
547   const MachineOperand &CalleeMO = Opers.getCallTarget();
548
549   if (CalleeMO.isImm()) {
550     uint64_t CallTarget = CalleeMO.getImm();
551     if (CallTarget) {
552       unsigned ScratchIdx = -1;
553       unsigned ScratchReg = 0;
554       do {
555         ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
556         ScratchReg = MI.getOperand(ScratchIdx).getReg();
557       } while (ScratchReg == SystemZ::R0D);
558
559       // Materialize the call target address
560       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
561                                       .addReg(ScratchReg)
562                                       .addImm(CallTarget & 0xFFFFFFFF));
563       EncodedBytes += 6;
564       if (CallTarget >> 32) {
565         EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
566                                         .addReg(ScratchReg)
567                                         .addImm(CallTarget >> 32));
568         EncodedBytes += 6;
569       }
570
571       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
572                                      .addReg(SystemZ::R14D)
573                                      .addReg(ScratchReg));
574       EncodedBytes += 2;
575     }
576   } else if (CalleeMO.isGlobal()) {
577     const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
578     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
579                                    .addReg(SystemZ::R14D)
580                                    .addExpr(Expr));
581     EncodedBytes += 6;
582   }
583
584   // Emit padding.
585   unsigned NumBytes = Opers.getNumPatchBytes();
586   assert(NumBytes >= EncodedBytes &&
587          "Patchpoint can't request size less than the length of a call.");
588   assert((NumBytes - EncodedBytes) % 2 == 0 &&
589          "Invalid number of NOP bytes requested!");
590   while (EncodedBytes < NumBytes)
591     EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
592                             getSubtargetInfo());
593 }
594
595 // Convert a SystemZ-specific constant pool modifier into the associated
596 // MCSymbolRefExpr variant kind.
597 static MCSymbolRefExpr::VariantKind
598 getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
599   switch (Modifier) {
600   case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
601   case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
602   case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
603   case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
604   }
605   llvm_unreachable("Invalid SystemCPModifier!");
606 }
607
608 void SystemZAsmPrinter::
609 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
610   auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
611
612   const MCExpr *Expr =
613     MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
614                             getModifierVariantKind(ZCPV->getModifier()),
615                             OutContext);
616   uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
617
618   OutStreamer->EmitValue(Expr, Size);
619 }
620
621 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
622                                         unsigned OpNo,
623                                         unsigned AsmVariant,
624                                         const char *ExtraCode,
625                                         raw_ostream &OS) {
626   if (ExtraCode && *ExtraCode == 'n') {
627     if (!MI->getOperand(OpNo).isImm())
628       return true;
629     OS << -int64_t(MI->getOperand(OpNo).getImm());
630   } else {
631     SystemZMCInstLower Lower(MF->getContext(), *this);
632     MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
633     SystemZInstPrinter::printOperand(MO, MAI, OS);
634   }
635   return false;
636 }
637
638 bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
639                                               unsigned OpNo,
640                                               unsigned AsmVariant,
641                                               const char *ExtraCode,
642                                               raw_ostream &OS) {
643   SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
644                                    MI->getOperand(OpNo + 1).getImm(),
645                                    MI->getOperand(OpNo + 2).getReg(), OS);
646   return false;
647 }
648
649 void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
650   emitStackMaps(SM);
651 }
652
653 // Force static initialization.
654 extern "C" void LLVMInitializeSystemZAsmPrinter() {
655   RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
656 }