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"
15 #include "MCTargetDesc/SystemZInstPrinter.h"
16 #include "SystemZConstantPoolValue.h"
17 #include "SystemZMCInstLower.h"
18 #include "TargetInfo/SystemZTargetInfo.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
21 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
22 #include "llvm/IR/Mangler.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInstBuilder.h"
25 #include "llvm/MC/MCSectionELF.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/TargetRegistry.h"
28 
29 using namespace llvm;
30 
31 // Return an RI instruction like MI with opcode Opcode, but with the
32 // GR64 register operands turned into GR32s.
33 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
34   if (MI->isCompare())
35     return MCInstBuilder(Opcode)
36       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
37       .addImm(MI->getOperand(1).getImm());
38   else
39     return MCInstBuilder(Opcode)
40       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
41       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
42       .addImm(MI->getOperand(2).getImm());
43 }
44 
45 // Return an RI instruction like MI with opcode Opcode, but with the
46 // GR64 register operands turned into GRH32s.
47 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
48   if (MI->isCompare())
49     return MCInstBuilder(Opcode)
50       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
51       .addImm(MI->getOperand(1).getImm());
52   else
53     return MCInstBuilder(Opcode)
54       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
55       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
56       .addImm(MI->getOperand(2).getImm());
57 }
58 
59 // Return an RI instruction like MI with opcode Opcode, but with the
60 // R2 register turned into a GR64.
61 static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
62   return MCInstBuilder(Opcode)
63     .addReg(MI->getOperand(0).getReg())
64     .addReg(MI->getOperand(1).getReg())
65     .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
66     .addImm(MI->getOperand(3).getImm())
67     .addImm(MI->getOperand(4).getImm())
68     .addImm(MI->getOperand(5).getImm());
69 }
70 
71 static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
72   StringRef Name = "__tls_get_offset";
73   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
74                                  MCSymbolRefExpr::VK_PLT,
75                                  Context);
76 }
77 
78 static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
79   StringRef Name = "_GLOBAL_OFFSET_TABLE_";
80   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
81                                  MCSymbolRefExpr::VK_None,
82                                  Context);
83 }
84 
85 // MI is an instruction that accepts an optional alignment hint,
86 // and which was already lowered to LoweredMI.  If the alignment
87 // of the original memory operand is known, update LoweredMI to
88 // an instruction with the corresponding hint set.
89 static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI,
90                                unsigned Opcode) {
91   if (MI->memoperands_empty())
92     return;
93 
94   Align Alignment = Align(16);
95   for (MachineInstr::mmo_iterator MMOI = MI->memoperands_begin(),
96          EE = MI->memoperands_end(); MMOI != EE; ++MMOI)
97     if ((*MMOI)->getAlign() < Alignment)
98       Alignment = (*MMOI)->getAlign();
99 
100   unsigned AlignmentHint = 0;
101   if (Alignment >= Align(16))
102     AlignmentHint = 4;
103   else if (Alignment >= Align(8))
104     AlignmentHint = 3;
105   if (AlignmentHint == 0)
106     return;
107 
108   LoweredMI.setOpcode(Opcode);
109   LoweredMI.addOperand(MCOperand::createImm(AlignmentHint));
110 }
111 
112 // MI loads the high part of a vector from memory.  Return an instruction
113 // that uses replicating vector load Opcode to do the same thing.
114 static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
115   return MCInstBuilder(Opcode)
116     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
117     .addReg(MI->getOperand(1).getReg())
118     .addImm(MI->getOperand(2).getImm())
119     .addReg(MI->getOperand(3).getReg());
120 }
121 
122 // MI stores the high part of a vector to memory.  Return an instruction
123 // that uses elemental vector store Opcode to do the same thing.
124 static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
125   return MCInstBuilder(Opcode)
126     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
127     .addReg(MI->getOperand(1).getReg())
128     .addImm(MI->getOperand(2).getImm())
129     .addReg(MI->getOperand(3).getReg())
130     .addImm(0);
131 }
132 
133 // The XPLINK ABI requires that a no-op encoding the call type is emitted after
134 // each call to a subroutine. This information can be used by the called
135 // function to determine its entry point, e.g. for generating a backtrace. The
136 // call type is encoded as a register number in the bcr instruction. See
137 // enumeration CallType for the possible values.
138 void SystemZAsmPrinter::emitCallInformation(CallType CT) {
139   EmitToStreamer(*OutStreamer,
140                  MCInstBuilder(SystemZ::BCRAsm)
141                      .addImm(0)
142                      .addReg(SystemZMC::GR64Regs[static_cast<unsigned>(CT)]));
143 }
144 
145 void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
146   SystemZMCInstLower Lower(MF->getContext(), *this);
147   MCInst LoweredMI;
148   switch (MI->getOpcode()) {
149   case SystemZ::Return:
150     LoweredMI = MCInstBuilder(SystemZ::BR)
151       .addReg(SystemZ::R14D);
152     break;
153 
154   case SystemZ::Return_XPLINK:
155     LoweredMI = MCInstBuilder(SystemZ::B)
156       .addReg(SystemZ::R7D)
157       .addImm(2)
158       .addReg(0);
159     break;
160 
161   case SystemZ::CondReturn:
162     LoweredMI = MCInstBuilder(SystemZ::BCR)
163       .addImm(MI->getOperand(0).getImm())
164       .addImm(MI->getOperand(1).getImm())
165       .addReg(SystemZ::R14D);
166     break;
167 
168   case SystemZ::CondReturn_XPLINK:
169     LoweredMI = MCInstBuilder(SystemZ::BC)
170       .addImm(MI->getOperand(0).getImm())
171       .addImm(MI->getOperand(1).getImm())
172       .addReg(SystemZ::R7D)
173       .addImm(2)
174       .addReg(0);
175     break;
176 
177   case SystemZ::CRBReturn:
178     LoweredMI = MCInstBuilder(SystemZ::CRB)
179       .addReg(MI->getOperand(0).getReg())
180       .addReg(MI->getOperand(1).getReg())
181       .addImm(MI->getOperand(2).getImm())
182       .addReg(SystemZ::R14D)
183       .addImm(0);
184     break;
185 
186   case SystemZ::CGRBReturn:
187     LoweredMI = MCInstBuilder(SystemZ::CGRB)
188       .addReg(MI->getOperand(0).getReg())
189       .addReg(MI->getOperand(1).getReg())
190       .addImm(MI->getOperand(2).getImm())
191       .addReg(SystemZ::R14D)
192       .addImm(0);
193     break;
194 
195   case SystemZ::CIBReturn:
196     LoweredMI = MCInstBuilder(SystemZ::CIB)
197       .addReg(MI->getOperand(0).getReg())
198       .addImm(MI->getOperand(1).getImm())
199       .addImm(MI->getOperand(2).getImm())
200       .addReg(SystemZ::R14D)
201       .addImm(0);
202     break;
203 
204   case SystemZ::CGIBReturn:
205     LoweredMI = MCInstBuilder(SystemZ::CGIB)
206       .addReg(MI->getOperand(0).getReg())
207       .addImm(MI->getOperand(1).getImm())
208       .addImm(MI->getOperand(2).getImm())
209       .addReg(SystemZ::R14D)
210       .addImm(0);
211     break;
212 
213   case SystemZ::CLRBReturn:
214     LoweredMI = MCInstBuilder(SystemZ::CLRB)
215       .addReg(MI->getOperand(0).getReg())
216       .addReg(MI->getOperand(1).getReg())
217       .addImm(MI->getOperand(2).getImm())
218       .addReg(SystemZ::R14D)
219       .addImm(0);
220     break;
221 
222   case SystemZ::CLGRBReturn:
223     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
224       .addReg(MI->getOperand(0).getReg())
225       .addReg(MI->getOperand(1).getReg())
226       .addImm(MI->getOperand(2).getImm())
227       .addReg(SystemZ::R14D)
228       .addImm(0);
229     break;
230 
231   case SystemZ::CLIBReturn:
232     LoweredMI = MCInstBuilder(SystemZ::CLIB)
233       .addReg(MI->getOperand(0).getReg())
234       .addImm(MI->getOperand(1).getImm())
235       .addImm(MI->getOperand(2).getImm())
236       .addReg(SystemZ::R14D)
237       .addImm(0);
238     break;
239 
240   case SystemZ::CLGIBReturn:
241     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
242       .addReg(MI->getOperand(0).getReg())
243       .addImm(MI->getOperand(1).getImm())
244       .addImm(MI->getOperand(2).getImm())
245       .addReg(SystemZ::R14D)
246       .addImm(0);
247     break;
248 
249   case SystemZ::CallBRASL_XPLINK64:
250     EmitToStreamer(*OutStreamer,
251                    MCInstBuilder(SystemZ::BRASL)
252                        .addReg(SystemZ::R7D)
253                        .addExpr(Lower.getExpr(MI->getOperand(0),
254                                               MCSymbolRefExpr::VK_PLT)));
255     emitCallInformation(CallType::BRASL7);
256     return;
257 
258   case SystemZ::CallBASR_XPLINK64:
259     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
260                                      .addReg(SystemZ::R7D)
261                                      .addReg(MI->getOperand(0).getReg()));
262     emitCallInformation(CallType::BASR76);
263     return;
264 
265   case SystemZ::CallBASR_STACKEXT:
266     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
267                                      .addReg(SystemZ::R3D)
268                                      .addReg(MI->getOperand(0).getReg()));
269     emitCallInformation(CallType::BASR33);
270     return;
271 
272   case SystemZ::CallBRASL:
273     LoweredMI = MCInstBuilder(SystemZ::BRASL)
274       .addReg(SystemZ::R14D)
275       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
276     break;
277 
278   case SystemZ::CallBASR:
279     LoweredMI = MCInstBuilder(SystemZ::BASR)
280       .addReg(SystemZ::R14D)
281       .addReg(MI->getOperand(0).getReg());
282     break;
283 
284   case SystemZ::CallJG:
285     LoweredMI = MCInstBuilder(SystemZ::JG)
286       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
287     break;
288 
289   case SystemZ::CallBRCL:
290     LoweredMI = MCInstBuilder(SystemZ::BRCL)
291       .addImm(MI->getOperand(0).getImm())
292       .addImm(MI->getOperand(1).getImm())
293       .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
294     break;
295 
296   case SystemZ::CallBR:
297     LoweredMI = MCInstBuilder(SystemZ::BR)
298       .addReg(MI->getOperand(0).getReg());
299     break;
300 
301   case SystemZ::CallBCR:
302     LoweredMI = MCInstBuilder(SystemZ::BCR)
303       .addImm(MI->getOperand(0).getImm())
304       .addImm(MI->getOperand(1).getImm())
305       .addReg(MI->getOperand(2).getReg());
306     break;
307 
308   case SystemZ::CRBCall:
309     LoweredMI = MCInstBuilder(SystemZ::CRB)
310       .addReg(MI->getOperand(0).getReg())
311       .addReg(MI->getOperand(1).getReg())
312       .addImm(MI->getOperand(2).getImm())
313       .addReg(MI->getOperand(3).getReg())
314       .addImm(0);
315     break;
316 
317   case SystemZ::CGRBCall:
318     LoweredMI = MCInstBuilder(SystemZ::CGRB)
319       .addReg(MI->getOperand(0).getReg())
320       .addReg(MI->getOperand(1).getReg())
321       .addImm(MI->getOperand(2).getImm())
322       .addReg(MI->getOperand(3).getReg())
323       .addImm(0);
324     break;
325 
326   case SystemZ::CIBCall:
327     LoweredMI = MCInstBuilder(SystemZ::CIB)
328       .addReg(MI->getOperand(0).getReg())
329       .addImm(MI->getOperand(1).getImm())
330       .addImm(MI->getOperand(2).getImm())
331       .addReg(MI->getOperand(3).getReg())
332       .addImm(0);
333     break;
334 
335   case SystemZ::CGIBCall:
336     LoweredMI = MCInstBuilder(SystemZ::CGIB)
337       .addReg(MI->getOperand(0).getReg())
338       .addImm(MI->getOperand(1).getImm())
339       .addImm(MI->getOperand(2).getImm())
340       .addReg(MI->getOperand(3).getReg())
341       .addImm(0);
342     break;
343 
344   case SystemZ::CLRBCall:
345     LoweredMI = MCInstBuilder(SystemZ::CLRB)
346       .addReg(MI->getOperand(0).getReg())
347       .addReg(MI->getOperand(1).getReg())
348       .addImm(MI->getOperand(2).getImm())
349       .addReg(MI->getOperand(3).getReg())
350       .addImm(0);
351     break;
352 
353   case SystemZ::CLGRBCall:
354     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
355       .addReg(MI->getOperand(0).getReg())
356       .addReg(MI->getOperand(1).getReg())
357       .addImm(MI->getOperand(2).getImm())
358       .addReg(MI->getOperand(3).getReg())
359       .addImm(0);
360     break;
361 
362   case SystemZ::CLIBCall:
363     LoweredMI = MCInstBuilder(SystemZ::CLIB)
364       .addReg(MI->getOperand(0).getReg())
365       .addImm(MI->getOperand(1).getImm())
366       .addImm(MI->getOperand(2).getImm())
367       .addReg(MI->getOperand(3).getReg())
368       .addImm(0);
369     break;
370 
371   case SystemZ::CLGIBCall:
372     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
373       .addReg(MI->getOperand(0).getReg())
374       .addImm(MI->getOperand(1).getImm())
375       .addImm(MI->getOperand(2).getImm())
376       .addReg(MI->getOperand(3).getReg())
377       .addImm(0);
378     break;
379 
380   case SystemZ::TLS_GDCALL:
381     LoweredMI = MCInstBuilder(SystemZ::BRASL)
382       .addReg(SystemZ::R14D)
383       .addExpr(getTLSGetOffset(MF->getContext()))
384       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
385     break;
386 
387   case SystemZ::TLS_LDCALL:
388     LoweredMI = MCInstBuilder(SystemZ::BRASL)
389       .addReg(SystemZ::R14D)
390       .addExpr(getTLSGetOffset(MF->getContext()))
391       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
392     break;
393 
394   case SystemZ::GOT:
395     LoweredMI = MCInstBuilder(SystemZ::LARL)
396       .addReg(MI->getOperand(0).getReg())
397       .addExpr(getGlobalOffsetTable(MF->getContext()));
398     break;
399 
400   case SystemZ::IILF64:
401     LoweredMI = MCInstBuilder(SystemZ::IILF)
402       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
403       .addImm(MI->getOperand(2).getImm());
404     break;
405 
406   case SystemZ::IIHF64:
407     LoweredMI = MCInstBuilder(SystemZ::IIHF)
408       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
409       .addImm(MI->getOperand(2).getImm());
410     break;
411 
412   case SystemZ::RISBHH:
413   case SystemZ::RISBHL:
414     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
415     break;
416 
417   case SystemZ::RISBLH:
418   case SystemZ::RISBLL:
419     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
420     break;
421 
422   case SystemZ::VLVGP32:
423     LoweredMI = MCInstBuilder(SystemZ::VLVGP)
424       .addReg(MI->getOperand(0).getReg())
425       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
426       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
427     break;
428 
429   case SystemZ::VLR32:
430   case SystemZ::VLR64:
431     LoweredMI = MCInstBuilder(SystemZ::VLR)
432       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
433       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
434     break;
435 
436   case SystemZ::VL:
437     Lower.lower(MI, LoweredMI);
438     lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign);
439     break;
440 
441   case SystemZ::VST:
442     Lower.lower(MI, LoweredMI);
443     lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign);
444     break;
445 
446   case SystemZ::VLM:
447     Lower.lower(MI, LoweredMI);
448     lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign);
449     break;
450 
451   case SystemZ::VSTM:
452     Lower.lower(MI, LoweredMI);
453     lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign);
454     break;
455 
456   case SystemZ::VL32:
457     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
458     break;
459 
460   case SystemZ::VL64:
461     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
462     break;
463 
464   case SystemZ::VST32:
465     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
466     break;
467 
468   case SystemZ::VST64:
469     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
470     break;
471 
472   case SystemZ::LFER:
473     LoweredMI = MCInstBuilder(SystemZ::VLGVF)
474       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
475       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
476       .addReg(0).addImm(0);
477     break;
478 
479   case SystemZ::LEFR:
480     LoweredMI = MCInstBuilder(SystemZ::VLVGF)
481       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
482       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
483       .addReg(MI->getOperand(1).getReg())
484       .addReg(0).addImm(0);
485     break;
486 
487 #define LOWER_LOW(NAME)                                                 \
488   case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
489 
490   LOWER_LOW(IILL);
491   LOWER_LOW(IILH);
492   LOWER_LOW(TMLL);
493   LOWER_LOW(TMLH);
494   LOWER_LOW(NILL);
495   LOWER_LOW(NILH);
496   LOWER_LOW(NILF);
497   LOWER_LOW(OILL);
498   LOWER_LOW(OILH);
499   LOWER_LOW(OILF);
500   LOWER_LOW(XILF);
501 
502 #undef LOWER_LOW
503 
504 #define LOWER_HIGH(NAME) \
505   case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
506 
507   LOWER_HIGH(IIHL);
508   LOWER_HIGH(IIHH);
509   LOWER_HIGH(TMHL);
510   LOWER_HIGH(TMHH);
511   LOWER_HIGH(NIHL);
512   LOWER_HIGH(NIHH);
513   LOWER_HIGH(NIHF);
514   LOWER_HIGH(OIHL);
515   LOWER_HIGH(OIHH);
516   LOWER_HIGH(OIHF);
517   LOWER_HIGH(XIHF);
518 
519 #undef LOWER_HIGH
520 
521   case SystemZ::Serialize:
522     if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
523       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
524         .addImm(14).addReg(SystemZ::R0D);
525     else
526       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
527         .addImm(15).addReg(SystemZ::R0D);
528     break;
529 
530   // Emit nothing here but a comment if we can.
531   case SystemZ::MemBarrier:
532     OutStreamer->emitRawComment("MEMBARRIER");
533     return;
534 
535   // We want to emit "j .+2" for traps, jumping to the relative immediate field
536   // of the jump instruction, which is an illegal instruction. We cannot emit a
537   // "." symbol, so create and emit a temp label before the instruction and use
538   // that instead.
539   case SystemZ::Trap: {
540     MCSymbol *DotSym = OutContext.createTempSymbol();
541     OutStreamer->emitLabel(DotSym);
542 
543     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
544     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
545     LoweredMI = MCInstBuilder(SystemZ::J)
546       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
547     }
548     break;
549 
550   // Conditional traps will create a branch on condition instruction that jumps
551   // to the relative immediate field of the jump instruction. (eg. "jo .+2")
552   case SystemZ::CondTrap: {
553     MCSymbol *DotSym = OutContext.createTempSymbol();
554     OutStreamer->emitLabel(DotSym);
555 
556     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
557     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
558     LoweredMI = MCInstBuilder(SystemZ::BRC)
559       .addImm(MI->getOperand(0).getImm())
560       .addImm(MI->getOperand(1).getImm())
561       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
562     }
563     break;
564 
565   case TargetOpcode::FENTRY_CALL:
566     LowerFENTRY_CALL(*MI, Lower);
567     return;
568 
569   case TargetOpcode::STACKMAP:
570     LowerSTACKMAP(*MI);
571     return;
572 
573   case TargetOpcode::PATCHPOINT:
574     LowerPATCHPOINT(*MI, Lower);
575     return;
576 
577   case SystemZ::EXRL_Pseudo: {
578     unsigned TargetInsOpc = MI->getOperand(0).getImm();
579     Register LenMinus1Reg = MI->getOperand(1).getReg();
580     Register DestReg = MI->getOperand(2).getReg();
581     int64_t DestDisp = MI->getOperand(3).getImm();
582     Register SrcReg = MI->getOperand(4).getReg();
583     int64_t SrcDisp = MI->getOperand(5).getImm();
584 
585     SystemZTargetStreamer *TS = getTargetStreamer();
586     MCSymbol *DotSym = nullptr;
587     MCInst ET = MCInstBuilder(TargetInsOpc).addReg(DestReg)
588       .addImm(DestDisp).addImm(1).addReg(SrcReg).addImm(SrcDisp);
589     SystemZTargetStreamer::MCInstSTIPair ET_STI(ET, &MF->getSubtarget());
590     SystemZTargetStreamer::EXRLT2SymMap::iterator I =
591         TS->EXRLTargets2Sym.find(ET_STI);
592     if (I != TS->EXRLTargets2Sym.end())
593       DotSym = I->second;
594     else
595       TS->EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol();
596     const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
597     EmitToStreamer(
598         *OutStreamer,
599         MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot));
600     return;
601   }
602 
603   default:
604     Lower.lower(MI, LoweredMI);
605     break;
606   }
607   EmitToStreamer(*OutStreamer, LoweredMI);
608 }
609 
610 // Emit the largest nop instruction smaller than or equal to NumBytes
611 // bytes.  Return the size of nop emitted.
612 static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
613                         unsigned NumBytes, const MCSubtargetInfo &STI) {
614   if (NumBytes < 2) {
615     llvm_unreachable("Zero nops?");
616     return 0;
617   }
618   else if (NumBytes < 4) {
619     OutStreamer.emitInstruction(
620         MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI);
621     return 2;
622   }
623   else if (NumBytes < 6) {
624     OutStreamer.emitInstruction(
625         MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0),
626         STI);
627     return 4;
628   }
629   else {
630     MCSymbol *DotSym = OutContext.createTempSymbol();
631     const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
632     OutStreamer.emitLabel(DotSym);
633     OutStreamer.emitInstruction(
634         MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI);
635     return 6;
636   }
637 }
638 
639 void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
640                                          SystemZMCInstLower &Lower) {
641   MCContext &Ctx = MF->getContext();
642   if (MF->getFunction().hasFnAttribute("mrecord-mcount")) {
643     MCSymbol *DotSym = OutContext.createTempSymbol();
644     OutStreamer->PushSection();
645     OutStreamer->SwitchSection(
646         Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC));
647     OutStreamer->emitSymbolValue(DotSym, 8);
648     OutStreamer->PopSection();
649     OutStreamer->emitLabel(DotSym);
650   }
651 
652   if (MF->getFunction().hasFnAttribute("mnop-mcount")) {
653     EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo());
654     return;
655   }
656 
657   MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
658   const MCSymbolRefExpr *Op =
659       MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx);
660   OutStreamer->emitInstruction(
661       MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op),
662       getSubtargetInfo());
663 }
664 
665 void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
666   const SystemZInstrInfo *TII =
667     static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
668 
669   unsigned NumNOPBytes = MI.getOperand(1).getImm();
670 
671   auto &Ctx = OutStreamer->getContext();
672   MCSymbol *MILabel = Ctx.createTempSymbol();
673   OutStreamer->emitLabel(MILabel);
674 
675   SM.recordStackMap(*MILabel, MI);
676   assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
677 
678   // Scan ahead to trim the shadow.
679   unsigned ShadowBytes = 0;
680   const MachineBasicBlock &MBB = *MI.getParent();
681   MachineBasicBlock::const_iterator MII(MI);
682   ++MII;
683   while (ShadowBytes < NumNOPBytes) {
684     if (MII == MBB.end() ||
685         MII->getOpcode() == TargetOpcode::PATCHPOINT ||
686         MII->getOpcode() == TargetOpcode::STACKMAP)
687       break;
688     ShadowBytes += TII->getInstSizeInBytes(*MII);
689     if (MII->isCall())
690       break;
691     ++MII;
692   }
693 
694   // Emit nops.
695   while (ShadowBytes < NumNOPBytes)
696     ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
697                            getSubtargetInfo());
698 }
699 
700 // Lower a patchpoint of the form:
701 // [<def>], <id>, <numBytes>, <target>, <numArgs>
702 void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
703                                         SystemZMCInstLower &Lower) {
704   auto &Ctx = OutStreamer->getContext();
705   MCSymbol *MILabel = Ctx.createTempSymbol();
706   OutStreamer->emitLabel(MILabel);
707 
708   SM.recordPatchPoint(*MILabel, MI);
709   PatchPointOpers Opers(&MI);
710 
711   unsigned EncodedBytes = 0;
712   const MachineOperand &CalleeMO = Opers.getCallTarget();
713 
714   if (CalleeMO.isImm()) {
715     uint64_t CallTarget = CalleeMO.getImm();
716     if (CallTarget) {
717       unsigned ScratchIdx = -1;
718       unsigned ScratchReg = 0;
719       do {
720         ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
721         ScratchReg = MI.getOperand(ScratchIdx).getReg();
722       } while (ScratchReg == SystemZ::R0D);
723 
724       // Materialize the call target address
725       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
726                                       .addReg(ScratchReg)
727                                       .addImm(CallTarget & 0xFFFFFFFF));
728       EncodedBytes += 6;
729       if (CallTarget >> 32) {
730         EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
731                                         .addReg(ScratchReg)
732                                         .addImm(CallTarget >> 32));
733         EncodedBytes += 6;
734       }
735 
736       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
737                                      .addReg(SystemZ::R14D)
738                                      .addReg(ScratchReg));
739       EncodedBytes += 2;
740     }
741   } else if (CalleeMO.isGlobal()) {
742     const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
743     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
744                                    .addReg(SystemZ::R14D)
745                                    .addExpr(Expr));
746     EncodedBytes += 6;
747   }
748 
749   // Emit padding.
750   unsigned NumBytes = Opers.getNumPatchBytes();
751   assert(NumBytes >= EncodedBytes &&
752          "Patchpoint can't request size less than the length of a call.");
753   assert((NumBytes - EncodedBytes) % 2 == 0 &&
754          "Invalid number of NOP bytes requested!");
755   while (EncodedBytes < NumBytes)
756     EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
757                             getSubtargetInfo());
758 }
759 
760 // Convert a SystemZ-specific constant pool modifier into the associated
761 // MCSymbolRefExpr variant kind.
762 static MCSymbolRefExpr::VariantKind
763 getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
764   switch (Modifier) {
765   case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
766   case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
767   case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
768   case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
769   }
770   llvm_unreachable("Invalid SystemCPModifier!");
771 }
772 
773 void SystemZAsmPrinter::emitMachineConstantPoolValue(
774     MachineConstantPoolValue *MCPV) {
775   auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
776 
777   const MCExpr *Expr =
778     MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
779                             getModifierVariantKind(ZCPV->getModifier()),
780                             OutContext);
781   uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
782 
783   OutStreamer->emitValue(Expr, Size);
784 }
785 
786 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
787                                         const char *ExtraCode,
788                                         raw_ostream &OS) {
789   const MCRegisterInfo &MRI = *TM.getMCRegisterInfo();
790   const MachineOperand &MO = MI->getOperand(OpNo);
791   MCOperand MCOp;
792   if (ExtraCode) {
793     if (ExtraCode[0] == 'N' && !ExtraCode[1] && MO.isReg() &&
794         SystemZ::GR128BitRegClass.contains(MO.getReg()))
795       MCOp =
796           MCOperand::createReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64));
797     else
798       return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
799   } else {
800     SystemZMCInstLower Lower(MF->getContext(), *this);
801     MCOp = Lower.lowerOperand(MO);
802   }
803   SystemZInstPrinter::printOperand(MCOp, MAI, OS);
804   return false;
805 }
806 
807 bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
808                                               unsigned OpNo,
809                                               const char *ExtraCode,
810                                               raw_ostream &OS) {
811   SystemZInstPrinter::
812     printAddress(MAI, MI->getOperand(OpNo).getReg(),
813                  MCOperand::createImm(MI->getOperand(OpNo + 1).getImm()),
814                  MI->getOperand(OpNo + 2).getReg(), OS);
815   return false;
816 }
817 
818 void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
819   emitStackMaps(SM);
820 }
821 
822 void SystemZAsmPrinter::emitFunctionBodyEnd() {
823   if (TM.getTargetTriple().isOSzOS()) {
824     // Emit symbol for the end of function if the z/OS target streamer
825     // is used. This is needed to calculate the size of the function.
826     MCSymbol *FnEndSym = createTempSymbol("func_end");
827     OutStreamer->emitLabel(FnEndSym);
828 
829     OutStreamer->PushSection();
830     OutStreamer->SwitchSection(getObjFileLowering().getPPA1Section());
831     emitPPA1(FnEndSym);
832     OutStreamer->PopSection();
833 
834     CurrentFnPPA1Sym = nullptr;
835     CurrentFnEPMarkerSym = nullptr;
836   }
837 }
838 
839 static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
840                           bool StackProtector, bool FPRMask, bool VRMask) {
841   enum class PPA1Flag1 : uint8_t {
842     DSA64Bit = (0x80 >> 0),
843     VarArg = (0x80 >> 7),
844     LLVM_MARK_AS_BITMASK_ENUM(DSA64Bit)
845   };
846   enum class PPA1Flag2 : uint8_t {
847     ExternalProcedure = (0x80 >> 0),
848     STACKPROTECTOR = (0x80 >> 3),
849     LLVM_MARK_AS_BITMASK_ENUM(ExternalProcedure)
850   };
851   enum class PPA1Flag3 : uint8_t {
852     FPRMask = (0x80 >> 2),
853     LLVM_MARK_AS_BITMASK_ENUM(FPRMask)
854   };
855   enum class PPA1Flag4 : uint8_t {
856     EPMOffsetPresent = (0x80 >> 0),
857     VRMask = (0x80 >> 2),
858     ProcedureNamePresent = (0x80 >> 7),
859     LLVM_MARK_AS_BITMASK_ENUM(EPMOffsetPresent)
860   };
861 
862   // Declare optional section flags that can be modified.
863   auto Flags1 = PPA1Flag1(0);
864   auto Flags2 = PPA1Flag2::ExternalProcedure;
865   auto Flags3 = PPA1Flag3(0);
866   auto Flags4 = PPA1Flag4::EPMOffsetPresent | PPA1Flag4::ProcedureNamePresent;
867 
868   Flags1 |= PPA1Flag1::DSA64Bit;
869 
870   if (VarArg)
871     Flags1 |= PPA1Flag1::VarArg;
872 
873   if (StackProtector)
874     Flags2 |= PPA1Flag2::STACKPROTECTOR;
875 
876   // SavedGPRMask, SavedFPRMask, and SavedVRMask are precomputed in.
877   if (FPRMask)
878     Flags3 |= PPA1Flag3::FPRMask; // Add emit FPR mask flag.
879 
880   if (VRMask)
881     Flags4 |= PPA1Flag4::VRMask; // Add emit VR mask flag.
882 
883   OutStreamer->AddComment("PPA1 Flags 1");
884   if ((Flags1 & PPA1Flag1::DSA64Bit) == PPA1Flag1::DSA64Bit)
885     OutStreamer->AddComment("  Bit 0: 1 = 64-bit DSA");
886   else
887     OutStreamer->AddComment("  Bit 0: 0 = 32-bit DSA");
888   if ((Flags1 & PPA1Flag1::VarArg) == PPA1Flag1::VarArg)
889     OutStreamer->AddComment("  Bit 7: 1 = Vararg function");
890   OutStreamer->emitInt8(static_cast<uint8_t>(Flags1)); // Flags 1.
891 
892   OutStreamer->AddComment("PPA1 Flags 2");
893   if ((Flags2 & PPA1Flag2::ExternalProcedure) == PPA1Flag2::ExternalProcedure)
894     OutStreamer->AddComment("  Bit 0: 1 = External procedure");
895   if ((Flags2 & PPA1Flag2::STACKPROTECTOR) == PPA1Flag2::STACKPROTECTOR)
896     OutStreamer->AddComment("  Bit 3: 1 = STACKPROTECT is enabled");
897   else
898     OutStreamer->AddComment("  Bit 3: 0 = STACKPROTECT is not enabled");
899   OutStreamer->emitInt8(static_cast<uint8_t>(Flags2)); // Flags 2.
900 
901   OutStreamer->AddComment("PPA1 Flags 3");
902   if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask)
903     OutStreamer->AddComment("  Bit 2: 1 = FP Reg Mask is in optional area");
904   OutStreamer->emitInt8(
905       static_cast<uint8_t>(Flags3)); // Flags 3 (optional sections).
906 
907   OutStreamer->AddComment("PPA1 Flags 4");
908   if ((Flags4 & PPA1Flag4::VRMask) == PPA1Flag4::VRMask)
909     OutStreamer->AddComment("  Bit 2: 1 = Vector Reg Mask is in optional area");
910   OutStreamer->emitInt8(static_cast<uint8_t>(
911       Flags4)); // Flags 4 (optional sections, always emit these).
912 }
913 
914 void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) {
915   const TargetRegisterInfo *TRI = MF->getRegInfo().getTargetRegisterInfo();
916   const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
917   const auto TargetHasVector = Subtarget.hasVector();
918 
919   const SystemZMachineFunctionInfo *ZFI =
920       MF->getInfo<SystemZMachineFunctionInfo>();
921   const auto *ZFL = static_cast<const SystemZXPLINKFrameLowering *>(
922       Subtarget.getFrameLowering());
923   const MachineFrameInfo &MFFrame = MF->getFrameInfo();
924 
925   // Get saved GPR/FPR/VPR masks.
926   const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
927   uint16_t SavedGPRMask = 0;
928   uint16_t SavedFPRMask = 0;
929   uint8_t SavedVRMask = 0;
930   int64_t OffsetFPR = 0;
931   int64_t OffsetVR = 0;
932   const int64_t TopOfStack =
933       MFFrame.getOffsetAdjustment() + MFFrame.getStackSize();
934 
935   // Loop over the spilled registers. The CalleeSavedInfo can't be used because
936   // it does not contain all spilled registers.
937   for (unsigned I = ZFI->getSpillGPRRegs().LowGPR,
938                 E = ZFI->getSpillGPRRegs().HighGPR;
939        I && E && I <= E; ++I) {
940     unsigned V = TRI->getEncodingValue((Register)I);
941     assert(V < 16 && "GPR index out of range");
942     SavedGPRMask |= 1 << (15 - V);
943   }
944 
945   for (auto &CS : CSI) {
946     unsigned Reg = CS.getReg();
947     unsigned I = TRI->getEncodingValue(Reg);
948 
949     if (SystemZ::FP64BitRegClass.contains(Reg)) {
950       assert(I < 16 && "FPR index out of range");
951       SavedFPRMask |= 1 << (15 - I);
952       int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
953       if (Temp < OffsetFPR)
954         OffsetFPR = Temp;
955     } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
956       assert(I >= 16 && I <= 23 && "VPR index out of range");
957       unsigned BitNum = I - 16;
958       SavedVRMask |= 1 << (7 - BitNum);
959       int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
960       if (Temp < OffsetVR)
961         OffsetVR = Temp;
962     }
963   }
964 
965   // Adjust the offset.
966   OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0;
967   OffsetVR += (OffsetVR < 0) ? TopOfStack : 0;
968 
969   // Get alloca register.
970   uint8_t FrameReg = TRI->getEncodingValue(TRI->getFrameRegister(*MF));
971   uint8_t AllocaReg = ZFL->hasFP(*MF) ? FrameReg : 0;
972   assert(AllocaReg < 16 && "Can't have alloca register larger than 15");
973   (void)AllocaReg;
974 
975   // Build FPR save area offset.
976   uint32_t FrameAndFPROffset = 0;
977   if (SavedFPRMask) {
978     uint64_t FPRSaveAreaOffset = OffsetFPR;
979     assert(FPRSaveAreaOffset < 0x10000000 && "Offset out of range");
980 
981     FrameAndFPROffset = FPRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
982     FrameAndFPROffset |= FrameReg << 28;                // Put into top 4 bits.
983   }
984 
985   // Build VR save area offset.
986   uint32_t FrameAndVROffset = 0;
987   if (TargetHasVector && SavedVRMask) {
988     uint64_t VRSaveAreaOffset = OffsetVR;
989     assert(VRSaveAreaOffset < 0x10000000 && "Offset out of range");
990 
991     FrameAndVROffset = VRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
992     FrameAndVROffset |= FrameReg << 28;               // Put into top 4 bits.
993   }
994 
995   // Emit PPA1 section.
996   OutStreamer->AddComment("PPA1");
997   OutStreamer->emitLabel(CurrentFnPPA1Sym);
998   OutStreamer->AddComment("Version");
999   OutStreamer->emitInt8(0x02); // Version.
1000   OutStreamer->AddComment("LE Signature X'CE'");
1001   OutStreamer->emitInt8(0xCE); // CEL signature.
1002   OutStreamer->AddComment("Saved GPR Mask");
1003   OutStreamer->emitInt16(SavedGPRMask);
1004 
1005   emitPPA1Flags(OutStreamer, MF->getFunction().isVarArg(),
1006                 MFFrame.hasStackProtectorIndex(), SavedFPRMask != 0,
1007                 TargetHasVector && SavedVRMask != 0);
1008 
1009   OutStreamer->AddComment("Length/4 of Parms");
1010   OutStreamer->emitInt16(
1011       static_cast<uint16_t>(MFFrame.getMaxCallFrameSize() / 4)); // Parms/4.
1012   OutStreamer->AddComment("Length of Code");
1013   OutStreamer->emitAbsoluteSymbolDiff(FnEndSym, CurrentFnEPMarkerSym, 4);
1014 
1015   // Emit saved FPR mask and offset to FPR save area (0x20 of flags 3).
1016   if (SavedFPRMask) {
1017     OutStreamer->AddComment("FPR mask");
1018     OutStreamer->emitInt16(SavedFPRMask);
1019     OutStreamer->AddComment("AR mask");
1020     OutStreamer->emitInt16(0); // AR Mask, unused currently.
1021     OutStreamer->AddComment("FPR Save Area Locator");
1022     OutStreamer->AddComment(Twine("  Bit 0-3: Register R")
1023                                 .concat(utostr(FrameAndFPROffset >> 28))
1024                                 .str());
1025     OutStreamer->AddComment(Twine("  Bit 4-31: Offset ")
1026                                 .concat(utostr(FrameAndFPROffset & 0x0FFFFFFF))
1027                                 .str());
1028     OutStreamer->emitInt32(FrameAndFPROffset); // Offset to FPR save area with
1029                                                // register to add value to
1030                                                // (alloca reg).
1031   }
1032 
1033   // Emit saved VR mask to VR save area.
1034   if (TargetHasVector && SavedVRMask) {
1035     OutStreamer->AddComment("VR mask");
1036     OutStreamer->emitInt8(SavedVRMask);
1037     OutStreamer->emitInt8(0);  // Reserved.
1038     OutStreamer->emitInt16(0); // Also reserved.
1039     OutStreamer->AddComment("VR Save Area Locator");
1040     OutStreamer->AddComment(Twine("  Bit 0-3: Register R")
1041                                 .concat(utostr(FrameAndVROffset >> 28))
1042                                 .str());
1043     OutStreamer->AddComment(Twine("  Bit 4-31: Offset ")
1044                                 .concat(utostr(FrameAndVROffset & 0x0FFFFFFF))
1045                                 .str());
1046     OutStreamer->emitInt32(FrameAndVROffset);
1047   }
1048 
1049   // Emit offset to entry point optional section (0x80 of flags 4).
1050   OutStreamer->emitAbsoluteSymbolDiff(CurrentFnEPMarkerSym, CurrentFnPPA1Sym,
1051                                       4);
1052 }
1053 
1054 void SystemZAsmPrinter::emitFunctionEntryLabel() {
1055   const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
1056 
1057   if (Subtarget.getTargetTriple().isOSzOS()) {
1058     MCContext &OutContext = OutStreamer->getContext();
1059 
1060     // Save information for later use.
1061     std::string N(MF->getFunction().hasName()
1062                       ? Twine(MF->getFunction().getName()).concat("_").str()
1063                       : "");
1064 
1065     CurrentFnEPMarkerSym =
1066         OutContext.createTempSymbol(Twine("EPM_").concat(N).str(), true);
1067     CurrentFnPPA1Sym =
1068         OutContext.createTempSymbol(Twine("PPA1_").concat(N).str(), true);
1069 
1070     // EntryPoint Marker
1071     const MachineFrameInfo &MFFrame = MF->getFrameInfo();
1072     bool IsUsingAlloca = MFFrame.hasVarSizedObjects();
1073 
1074     // Set Flags
1075     uint8_t Flags = 0;
1076     if (IsUsingAlloca)
1077       Flags |= 0x04;
1078 
1079     uint32_t DSASize = MFFrame.getStackSize();
1080 
1081     // Combine into top 27 bits of DSASize and bottom 5 bits of Flags.
1082     uint32_t DSAAndFlags = DSASize & 0xFFFFFFE0; // (x/32) << 5
1083     DSAAndFlags |= Flags;
1084 
1085     // Emit entry point marker section.
1086     OutStreamer->AddComment("XPLINK Routine Layout Entry");
1087     OutStreamer->emitLabel(CurrentFnEPMarkerSym);
1088     OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
1089     OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher.
1090     OutStreamer->AddComment("Mark Type C'1'");
1091     OutStreamer->emitInt8(0xF1); // Mark Type.
1092     OutStreamer->AddComment("Offset to PPA1");
1093     OutStreamer->emitAbsoluteSymbolDiff(CurrentFnPPA1Sym, CurrentFnEPMarkerSym,
1094                                         4);
1095     if (OutStreamer->isVerboseAsm()) {
1096       OutStreamer->AddComment("DSA Size 0x" + Twine::utohexstr(DSASize));
1097       OutStreamer->AddComment("Entry Flags");
1098       if (Flags & 0x04)
1099         OutStreamer->AddComment("  Bit 2: 1 = Uses alloca");
1100       else
1101         OutStreamer->AddComment("  Bit 2: 0 = Does not use alloca");
1102     }
1103     OutStreamer->emitInt32(DSAAndFlags);
1104   }
1105 
1106   AsmPrinter::emitFunctionEntryLabel();
1107 }
1108 
1109 // Force static initialization.
1110 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter() {
1111   RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
1112 }
1113