xref: /llvm-project/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp (revision 6512a8dd8c0ac255a082c93d66e29606f4546fee)
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/SystemZGNUInstPrinter.h"
16 #include "MCTargetDesc/SystemZHLASMInstPrinter.h"
17 #include "MCTargetDesc/SystemZMCExpr.h"
18 #include "SystemZConstantPoolValue.h"
19 #include "SystemZMCInstLower.h"
20 #include "TargetInfo/SystemZTargetInfo.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/BinaryFormat/ELF.h"
23 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
24 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
25 #include "llvm/IR/Mangler.h"
26 #include "llvm/IR/Module.h"
27 #include "llvm/MC/MCExpr.h"
28 #include "llvm/MC/MCInstBuilder.h"
29 #include "llvm/MC/MCSectionELF.h"
30 #include "llvm/MC/MCStreamer.h"
31 #include "llvm/MC/TargetRegistry.h"
32 #include "llvm/Support/Chrono.h"
33 #include "llvm/Support/ConvertEBCDIC.h"
34 #include "llvm/Support/FormatProviders.h"
35 #include "llvm/Support/FormatVariadic.h"
36 
37 using namespace llvm;
38 
39 // Return an RI instruction like MI with opcode Opcode, but with the
40 // GR64 register operands turned into GR32s.
41 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
42   if (MI->isCompare())
43     return MCInstBuilder(Opcode)
44       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
45       .addImm(MI->getOperand(1).getImm());
46   else
47     return MCInstBuilder(Opcode)
48       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
49       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
50       .addImm(MI->getOperand(2).getImm());
51 }
52 
53 // Return an RI instruction like MI with opcode Opcode, but with the
54 // GR64 register operands turned into GRH32s.
55 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
56   if (MI->isCompare())
57     return MCInstBuilder(Opcode)
58       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
59       .addImm(MI->getOperand(1).getImm());
60   else
61     return MCInstBuilder(Opcode)
62       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
63       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
64       .addImm(MI->getOperand(2).getImm());
65 }
66 
67 // Return an RI instruction like MI with opcode Opcode, but with the
68 // R2 register turned into a GR64.
69 static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
70   return MCInstBuilder(Opcode)
71     .addReg(MI->getOperand(0).getReg())
72     .addReg(MI->getOperand(1).getReg())
73     .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
74     .addImm(MI->getOperand(3).getImm())
75     .addImm(MI->getOperand(4).getImm())
76     .addImm(MI->getOperand(5).getImm());
77 }
78 
79 static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
80   StringRef Name = "__tls_get_offset";
81   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
82                                  MCSymbolRefExpr::VK_PLT,
83                                  Context);
84 }
85 
86 static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
87   StringRef Name = "_GLOBAL_OFFSET_TABLE_";
88   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
89                                  MCSymbolRefExpr::VK_None,
90                                  Context);
91 }
92 
93 // MI is an instruction that accepts an optional alignment hint,
94 // and which was already lowered to LoweredMI.  If the alignment
95 // of the original memory operand is known, update LoweredMI to
96 // an instruction with the corresponding hint set.
97 static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI,
98                                unsigned Opcode) {
99   if (MI->memoperands_empty())
100     return;
101 
102   Align Alignment = Align(16);
103   for (MachineInstr::mmo_iterator MMOI = MI->memoperands_begin(),
104          EE = MI->memoperands_end(); MMOI != EE; ++MMOI)
105     if ((*MMOI)->getAlign() < Alignment)
106       Alignment = (*MMOI)->getAlign();
107 
108   unsigned AlignmentHint = 0;
109   if (Alignment >= Align(16))
110     AlignmentHint = 4;
111   else if (Alignment >= Align(8))
112     AlignmentHint = 3;
113   if (AlignmentHint == 0)
114     return;
115 
116   LoweredMI.setOpcode(Opcode);
117   LoweredMI.addOperand(MCOperand::createImm(AlignmentHint));
118 }
119 
120 // MI loads the high part of a vector from memory.  Return an instruction
121 // that uses replicating vector load Opcode to do the same thing.
122 static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
123   return MCInstBuilder(Opcode)
124     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
125     .addReg(MI->getOperand(1).getReg())
126     .addImm(MI->getOperand(2).getImm())
127     .addReg(MI->getOperand(3).getReg());
128 }
129 
130 // MI stores the high part of a vector to memory.  Return an instruction
131 // that uses elemental vector store Opcode to do the same thing.
132 static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
133   return MCInstBuilder(Opcode)
134     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
135     .addReg(MI->getOperand(1).getReg())
136     .addImm(MI->getOperand(2).getImm())
137     .addReg(MI->getOperand(3).getReg())
138     .addImm(0);
139 }
140 
141 // The XPLINK ABI requires that a no-op encoding the call type is emitted after
142 // each call to a subroutine. This information can be used by the called
143 // function to determine its entry point, e.g. for generating a backtrace. The
144 // call type is encoded as a register number in the bcr instruction. See
145 // enumeration CallType for the possible values.
146 void SystemZAsmPrinter::emitCallInformation(CallType CT) {
147   EmitToStreamer(*OutStreamer,
148                  MCInstBuilder(SystemZ::BCRAsm)
149                      .addImm(0)
150                      .addReg(SystemZMC::GR64Regs[static_cast<unsigned>(CT)]));
151 }
152 
153 uint32_t SystemZAsmPrinter::AssociatedDataAreaTable::insert(const MCSymbol *Sym,
154                                                             unsigned SlotKind) {
155   auto Key = std::make_pair(Sym, SlotKind);
156   auto It = Displacements.find(Key);
157 
158   if (It != Displacements.end())
159     return (*It).second;
160 
161   // Determine length of descriptor.
162   uint32_t Length;
163   switch (SlotKind) {
164   case SystemZII::MO_ADA_DIRECT_FUNC_DESC:
165     Length = 2 * PointerSize;
166     break;
167   default:
168     Length = PointerSize;
169     break;
170   }
171 
172   uint32_t Displacement = NextDisplacement;
173   Displacements[std::make_pair(Sym, SlotKind)] = NextDisplacement;
174   NextDisplacement += Length;
175 
176   return Displacement;
177 }
178 
179 uint32_t
180 SystemZAsmPrinter::AssociatedDataAreaTable::insert(const MachineOperand MO) {
181   MCSymbol *Sym;
182   if (MO.getType() == MachineOperand::MO_GlobalAddress) {
183     const GlobalValue *GV = MO.getGlobal();
184     Sym = MO.getParent()->getMF()->getTarget().getSymbol(GV);
185     assert(Sym && "No symbol");
186   } else if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
187     const char *SymName = MO.getSymbolName();
188     Sym = MO.getParent()->getMF()->getContext().getOrCreateSymbol(SymName);
189     assert(Sym && "No symbol");
190   } else
191     llvm_unreachable("Unexpected operand type");
192 
193   unsigned ADAslotType = MO.getTargetFlags();
194   return insert(Sym, ADAslotType);
195 }
196 
197 void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
198   SystemZ_MC::verifyInstructionPredicates(MI->getOpcode(),
199                                           getSubtargetInfo().getFeatureBits());
200 
201   SystemZMCInstLower Lower(MF->getContext(), *this);
202   MCInst LoweredMI;
203   switch (MI->getOpcode()) {
204   case SystemZ::Return:
205     LoweredMI = MCInstBuilder(SystemZ::BR)
206       .addReg(SystemZ::R14D);
207     break;
208 
209   case SystemZ::Return_XPLINK:
210     LoweredMI = MCInstBuilder(SystemZ::B)
211       .addReg(SystemZ::R7D)
212       .addImm(2)
213       .addReg(0);
214     break;
215 
216   case SystemZ::CondReturn:
217     LoweredMI = MCInstBuilder(SystemZ::BCR)
218       .addImm(MI->getOperand(0).getImm())
219       .addImm(MI->getOperand(1).getImm())
220       .addReg(SystemZ::R14D);
221     break;
222 
223   case SystemZ::CondReturn_XPLINK:
224     LoweredMI = MCInstBuilder(SystemZ::BC)
225       .addImm(MI->getOperand(0).getImm())
226       .addImm(MI->getOperand(1).getImm())
227       .addReg(SystemZ::R7D)
228       .addImm(2)
229       .addReg(0);
230     break;
231 
232   case SystemZ::CRBReturn:
233     LoweredMI = MCInstBuilder(SystemZ::CRB)
234       .addReg(MI->getOperand(0).getReg())
235       .addReg(MI->getOperand(1).getReg())
236       .addImm(MI->getOperand(2).getImm())
237       .addReg(SystemZ::R14D)
238       .addImm(0);
239     break;
240 
241   case SystemZ::CGRBReturn:
242     LoweredMI = MCInstBuilder(SystemZ::CGRB)
243       .addReg(MI->getOperand(0).getReg())
244       .addReg(MI->getOperand(1).getReg())
245       .addImm(MI->getOperand(2).getImm())
246       .addReg(SystemZ::R14D)
247       .addImm(0);
248     break;
249 
250   case SystemZ::CIBReturn:
251     LoweredMI = MCInstBuilder(SystemZ::CIB)
252       .addReg(MI->getOperand(0).getReg())
253       .addImm(MI->getOperand(1).getImm())
254       .addImm(MI->getOperand(2).getImm())
255       .addReg(SystemZ::R14D)
256       .addImm(0);
257     break;
258 
259   case SystemZ::CGIBReturn:
260     LoweredMI = MCInstBuilder(SystemZ::CGIB)
261       .addReg(MI->getOperand(0).getReg())
262       .addImm(MI->getOperand(1).getImm())
263       .addImm(MI->getOperand(2).getImm())
264       .addReg(SystemZ::R14D)
265       .addImm(0);
266     break;
267 
268   case SystemZ::CLRBReturn:
269     LoweredMI = MCInstBuilder(SystemZ::CLRB)
270       .addReg(MI->getOperand(0).getReg())
271       .addReg(MI->getOperand(1).getReg())
272       .addImm(MI->getOperand(2).getImm())
273       .addReg(SystemZ::R14D)
274       .addImm(0);
275     break;
276 
277   case SystemZ::CLGRBReturn:
278     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
279       .addReg(MI->getOperand(0).getReg())
280       .addReg(MI->getOperand(1).getReg())
281       .addImm(MI->getOperand(2).getImm())
282       .addReg(SystemZ::R14D)
283       .addImm(0);
284     break;
285 
286   case SystemZ::CLIBReturn:
287     LoweredMI = MCInstBuilder(SystemZ::CLIB)
288       .addReg(MI->getOperand(0).getReg())
289       .addImm(MI->getOperand(1).getImm())
290       .addImm(MI->getOperand(2).getImm())
291       .addReg(SystemZ::R14D)
292       .addImm(0);
293     break;
294 
295   case SystemZ::CLGIBReturn:
296     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
297       .addReg(MI->getOperand(0).getReg())
298       .addImm(MI->getOperand(1).getImm())
299       .addImm(MI->getOperand(2).getImm())
300       .addReg(SystemZ::R14D)
301       .addImm(0);
302     break;
303 
304   case SystemZ::CallBRASL_XPLINK64:
305     EmitToStreamer(*OutStreamer,
306                    MCInstBuilder(SystemZ::BRASL)
307                        .addReg(SystemZ::R7D)
308                        .addExpr(Lower.getExpr(MI->getOperand(0),
309                                               MCSymbolRefExpr::VK_PLT)));
310     emitCallInformation(CallType::BRASL7);
311     return;
312 
313   case SystemZ::CallBASR_XPLINK64:
314     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
315                                      .addReg(SystemZ::R7D)
316                                      .addReg(MI->getOperand(0).getReg()));
317     emitCallInformation(CallType::BASR76);
318     return;
319 
320   case SystemZ::CallBASR_STACKEXT:
321     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
322                                      .addReg(SystemZ::R3D)
323                                      .addReg(MI->getOperand(0).getReg()));
324     emitCallInformation(CallType::BASR33);
325     return;
326 
327   case SystemZ::ADA_ENTRY_VALUE:
328   case SystemZ::ADA_ENTRY: {
329     const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
330     const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
331     uint32_t Disp = ADATable.insert(MI->getOperand(1));
332     Register TargetReg = MI->getOperand(0).getReg();
333 
334     Register ADAReg = MI->getOperand(2).getReg();
335     Disp += MI->getOperand(3).getImm();
336     bool LoadAddr = MI->getOpcode() == SystemZ::ADA_ENTRY;
337 
338     unsigned Op0 = LoadAddr ? SystemZ::LA : SystemZ::LG;
339     unsigned Op = TII->getOpcodeForOffset(Op0, Disp);
340 
341     Register IndexReg = 0;
342     if (!Op) {
343       if (TargetReg != ADAReg) {
344         IndexReg = TargetReg;
345         // Use TargetReg to store displacement.
346         EmitToStreamer(
347             *OutStreamer,
348             MCInstBuilder(SystemZ::LLILF).addReg(TargetReg).addImm(Disp));
349       } else
350         EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::ALGFI)
351                                          .addReg(TargetReg)
352                                          .addReg(TargetReg)
353                                          .addImm(Disp));
354       Disp = 0;
355       Op = Op0;
356     }
357     EmitToStreamer(*OutStreamer, MCInstBuilder(Op)
358                                      .addReg(TargetReg)
359                                      .addReg(ADAReg)
360                                      .addImm(Disp)
361                                      .addReg(IndexReg));
362 
363     return;
364   }
365   case SystemZ::CallBRASL:
366     LoweredMI = MCInstBuilder(SystemZ::BRASL)
367       .addReg(SystemZ::R14D)
368       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
369     break;
370 
371   case SystemZ::CallBASR:
372     LoweredMI = MCInstBuilder(SystemZ::BASR)
373       .addReg(SystemZ::R14D)
374       .addReg(MI->getOperand(0).getReg());
375     break;
376 
377   case SystemZ::CallJG:
378     LoweredMI = MCInstBuilder(SystemZ::JG)
379       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
380     break;
381 
382   case SystemZ::CallBRCL:
383     LoweredMI = MCInstBuilder(SystemZ::BRCL)
384       .addImm(MI->getOperand(0).getImm())
385       .addImm(MI->getOperand(1).getImm())
386       .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
387     break;
388 
389   case SystemZ::CallBR:
390     LoweredMI = MCInstBuilder(SystemZ::BR)
391       .addReg(MI->getOperand(0).getReg());
392     break;
393 
394   case SystemZ::CallBCR:
395     LoweredMI = MCInstBuilder(SystemZ::BCR)
396       .addImm(MI->getOperand(0).getImm())
397       .addImm(MI->getOperand(1).getImm())
398       .addReg(MI->getOperand(2).getReg());
399     break;
400 
401   case SystemZ::CRBCall:
402     LoweredMI = MCInstBuilder(SystemZ::CRB)
403       .addReg(MI->getOperand(0).getReg())
404       .addReg(MI->getOperand(1).getReg())
405       .addImm(MI->getOperand(2).getImm())
406       .addReg(MI->getOperand(3).getReg())
407       .addImm(0);
408     break;
409 
410   case SystemZ::CGRBCall:
411     LoweredMI = MCInstBuilder(SystemZ::CGRB)
412       .addReg(MI->getOperand(0).getReg())
413       .addReg(MI->getOperand(1).getReg())
414       .addImm(MI->getOperand(2).getImm())
415       .addReg(MI->getOperand(3).getReg())
416       .addImm(0);
417     break;
418 
419   case SystemZ::CIBCall:
420     LoweredMI = MCInstBuilder(SystemZ::CIB)
421       .addReg(MI->getOperand(0).getReg())
422       .addImm(MI->getOperand(1).getImm())
423       .addImm(MI->getOperand(2).getImm())
424       .addReg(MI->getOperand(3).getReg())
425       .addImm(0);
426     break;
427 
428   case SystemZ::CGIBCall:
429     LoweredMI = MCInstBuilder(SystemZ::CGIB)
430       .addReg(MI->getOperand(0).getReg())
431       .addImm(MI->getOperand(1).getImm())
432       .addImm(MI->getOperand(2).getImm())
433       .addReg(MI->getOperand(3).getReg())
434       .addImm(0);
435     break;
436 
437   case SystemZ::CLRBCall:
438     LoweredMI = MCInstBuilder(SystemZ::CLRB)
439       .addReg(MI->getOperand(0).getReg())
440       .addReg(MI->getOperand(1).getReg())
441       .addImm(MI->getOperand(2).getImm())
442       .addReg(MI->getOperand(3).getReg())
443       .addImm(0);
444     break;
445 
446   case SystemZ::CLGRBCall:
447     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
448       .addReg(MI->getOperand(0).getReg())
449       .addReg(MI->getOperand(1).getReg())
450       .addImm(MI->getOperand(2).getImm())
451       .addReg(MI->getOperand(3).getReg())
452       .addImm(0);
453     break;
454 
455   case SystemZ::CLIBCall:
456     LoweredMI = MCInstBuilder(SystemZ::CLIB)
457       .addReg(MI->getOperand(0).getReg())
458       .addImm(MI->getOperand(1).getImm())
459       .addImm(MI->getOperand(2).getImm())
460       .addReg(MI->getOperand(3).getReg())
461       .addImm(0);
462     break;
463 
464   case SystemZ::CLGIBCall:
465     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
466       .addReg(MI->getOperand(0).getReg())
467       .addImm(MI->getOperand(1).getImm())
468       .addImm(MI->getOperand(2).getImm())
469       .addReg(MI->getOperand(3).getReg())
470       .addImm(0);
471     break;
472 
473   case SystemZ::TLS_GDCALL:
474     LoweredMI = MCInstBuilder(SystemZ::BRASL)
475       .addReg(SystemZ::R14D)
476       .addExpr(getTLSGetOffset(MF->getContext()))
477       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
478     break;
479 
480   case SystemZ::TLS_LDCALL:
481     LoweredMI = MCInstBuilder(SystemZ::BRASL)
482       .addReg(SystemZ::R14D)
483       .addExpr(getTLSGetOffset(MF->getContext()))
484       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
485     break;
486 
487   case SystemZ::GOT:
488     LoweredMI = MCInstBuilder(SystemZ::LARL)
489       .addReg(MI->getOperand(0).getReg())
490       .addExpr(getGlobalOffsetTable(MF->getContext()));
491     break;
492 
493   case SystemZ::IILF64:
494     LoweredMI = MCInstBuilder(SystemZ::IILF)
495       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
496       .addImm(MI->getOperand(2).getImm());
497     break;
498 
499   case SystemZ::IIHF64:
500     LoweredMI = MCInstBuilder(SystemZ::IIHF)
501       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
502       .addImm(MI->getOperand(2).getImm());
503     break;
504 
505   case SystemZ::RISBHH:
506   case SystemZ::RISBHL:
507     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
508     break;
509 
510   case SystemZ::RISBLH:
511   case SystemZ::RISBLL:
512     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
513     break;
514 
515   case SystemZ::VLVGP32:
516     LoweredMI = MCInstBuilder(SystemZ::VLVGP)
517       .addReg(MI->getOperand(0).getReg())
518       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
519       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
520     break;
521 
522   case SystemZ::VLR32:
523   case SystemZ::VLR64:
524     LoweredMI = MCInstBuilder(SystemZ::VLR)
525       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
526       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
527     break;
528 
529   case SystemZ::VL:
530     Lower.lower(MI, LoweredMI);
531     lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign);
532     break;
533 
534   case SystemZ::VST:
535     Lower.lower(MI, LoweredMI);
536     lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign);
537     break;
538 
539   case SystemZ::VLM:
540     Lower.lower(MI, LoweredMI);
541     lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign);
542     break;
543 
544   case SystemZ::VSTM:
545     Lower.lower(MI, LoweredMI);
546     lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign);
547     break;
548 
549   case SystemZ::VL32:
550     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
551     break;
552 
553   case SystemZ::VL64:
554     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
555     break;
556 
557   case SystemZ::VST32:
558     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
559     break;
560 
561   case SystemZ::VST64:
562     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
563     break;
564 
565   case SystemZ::LFER:
566     LoweredMI = MCInstBuilder(SystemZ::VLGVF)
567       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
568       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
569       .addReg(0).addImm(0);
570     break;
571 
572   case SystemZ::LEFR:
573     LoweredMI = MCInstBuilder(SystemZ::VLVGF)
574       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
575       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
576       .addReg(MI->getOperand(1).getReg())
577       .addReg(0).addImm(0);
578     break;
579 
580 #define LOWER_LOW(NAME)                                                 \
581   case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
582 
583   LOWER_LOW(IILL);
584   LOWER_LOW(IILH);
585   LOWER_LOW(TMLL);
586   LOWER_LOW(TMLH);
587   LOWER_LOW(NILL);
588   LOWER_LOW(NILH);
589   LOWER_LOW(NILF);
590   LOWER_LOW(OILL);
591   LOWER_LOW(OILH);
592   LOWER_LOW(OILF);
593   LOWER_LOW(XILF);
594 
595 #undef LOWER_LOW
596 
597 #define LOWER_HIGH(NAME) \
598   case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
599 
600   LOWER_HIGH(IIHL);
601   LOWER_HIGH(IIHH);
602   LOWER_HIGH(TMHL);
603   LOWER_HIGH(TMHH);
604   LOWER_HIGH(NIHL);
605   LOWER_HIGH(NIHH);
606   LOWER_HIGH(NIHF);
607   LOWER_HIGH(OIHL);
608   LOWER_HIGH(OIHH);
609   LOWER_HIGH(OIHF);
610   LOWER_HIGH(XIHF);
611 
612 #undef LOWER_HIGH
613 
614   case SystemZ::Serialize:
615     if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
616       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
617         .addImm(14).addReg(SystemZ::R0D);
618     else
619       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
620         .addImm(15).addReg(SystemZ::R0D);
621     break;
622 
623   // We want to emit "j .+2" for traps, jumping to the relative immediate field
624   // of the jump instruction, which is an illegal instruction. We cannot emit a
625   // "." symbol, so create and emit a temp label before the instruction and use
626   // that instead.
627   case SystemZ::Trap: {
628     MCSymbol *DotSym = OutContext.createTempSymbol();
629     OutStreamer->emitLabel(DotSym);
630 
631     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
632     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
633     LoweredMI = MCInstBuilder(SystemZ::J)
634       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
635     }
636     break;
637 
638   // Conditional traps will create a branch on condition instruction that jumps
639   // to the relative immediate field of the jump instruction. (eg. "jo .+2")
640   case SystemZ::CondTrap: {
641     MCSymbol *DotSym = OutContext.createTempSymbol();
642     OutStreamer->emitLabel(DotSym);
643 
644     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
645     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
646     LoweredMI = MCInstBuilder(SystemZ::BRC)
647       .addImm(MI->getOperand(0).getImm())
648       .addImm(MI->getOperand(1).getImm())
649       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
650     }
651     break;
652 
653   case TargetOpcode::FENTRY_CALL:
654     LowerFENTRY_CALL(*MI, Lower);
655     return;
656 
657   case TargetOpcode::STACKMAP:
658     LowerSTACKMAP(*MI);
659     return;
660 
661   case TargetOpcode::PATCHPOINT:
662     LowerPATCHPOINT(*MI, Lower);
663     return;
664 
665   case SystemZ::EXRL_Pseudo: {
666     unsigned TargetInsOpc = MI->getOperand(0).getImm();
667     Register LenMinus1Reg = MI->getOperand(1).getReg();
668     Register DestReg = MI->getOperand(2).getReg();
669     int64_t DestDisp = MI->getOperand(3).getImm();
670     Register SrcReg = MI->getOperand(4).getReg();
671     int64_t SrcDisp = MI->getOperand(5).getImm();
672 
673     SystemZTargetStreamer *TS = getTargetStreamer();
674     MCSymbol *DotSym = nullptr;
675     MCInst ET = MCInstBuilder(TargetInsOpc).addReg(DestReg)
676       .addImm(DestDisp).addImm(1).addReg(SrcReg).addImm(SrcDisp);
677     SystemZTargetStreamer::MCInstSTIPair ET_STI(ET, &MF->getSubtarget());
678     SystemZTargetStreamer::EXRLT2SymMap::iterator I =
679         TS->EXRLTargets2Sym.find(ET_STI);
680     if (I != TS->EXRLTargets2Sym.end())
681       DotSym = I->second;
682     else
683       TS->EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol();
684     const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
685     EmitToStreamer(
686         *OutStreamer,
687         MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot));
688     return;
689   }
690 
691   default:
692     Lower.lower(MI, LoweredMI);
693     break;
694   }
695   EmitToStreamer(*OutStreamer, LoweredMI);
696 }
697 
698 // Emit the largest nop instruction smaller than or equal to NumBytes
699 // bytes.  Return the size of nop emitted.
700 static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
701                         unsigned NumBytes, const MCSubtargetInfo &STI) {
702   if (NumBytes < 2) {
703     llvm_unreachable("Zero nops?");
704     return 0;
705   }
706   else if (NumBytes < 4) {
707     OutStreamer.emitInstruction(
708         MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI);
709     return 2;
710   }
711   else if (NumBytes < 6) {
712     OutStreamer.emitInstruction(
713         MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0),
714         STI);
715     return 4;
716   }
717   else {
718     MCSymbol *DotSym = OutContext.createTempSymbol();
719     const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
720     OutStreamer.emitLabel(DotSym);
721     OutStreamer.emitInstruction(
722         MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI);
723     return 6;
724   }
725 }
726 
727 void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
728                                          SystemZMCInstLower &Lower) {
729   MCContext &Ctx = MF->getContext();
730   if (MF->getFunction().hasFnAttribute("mrecord-mcount")) {
731     MCSymbol *DotSym = OutContext.createTempSymbol();
732     OutStreamer->pushSection();
733     OutStreamer->switchSection(
734         Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC));
735     OutStreamer->emitSymbolValue(DotSym, 8);
736     OutStreamer->popSection();
737     OutStreamer->emitLabel(DotSym);
738   }
739 
740   if (MF->getFunction().hasFnAttribute("mnop-mcount")) {
741     EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo());
742     return;
743   }
744 
745   MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
746   const MCSymbolRefExpr *Op =
747       MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx);
748   OutStreamer->emitInstruction(
749       MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op),
750       getSubtargetInfo());
751 }
752 
753 void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
754   auto *TII = MF->getSubtarget<SystemZSubtarget>().getInstrInfo();
755 
756   unsigned NumNOPBytes = MI.getOperand(1).getImm();
757 
758   auto &Ctx = OutStreamer->getContext();
759   MCSymbol *MILabel = Ctx.createTempSymbol();
760   OutStreamer->emitLabel(MILabel);
761 
762   SM.recordStackMap(*MILabel, MI);
763   assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
764 
765   // Scan ahead to trim the shadow.
766   unsigned ShadowBytes = 0;
767   const MachineBasicBlock &MBB = *MI.getParent();
768   MachineBasicBlock::const_iterator MII(MI);
769   ++MII;
770   while (ShadowBytes < NumNOPBytes) {
771     if (MII == MBB.end() ||
772         MII->getOpcode() == TargetOpcode::PATCHPOINT ||
773         MII->getOpcode() == TargetOpcode::STACKMAP)
774       break;
775     ShadowBytes += TII->getInstSizeInBytes(*MII);
776     if (MII->isCall())
777       break;
778     ++MII;
779   }
780 
781   // Emit nops.
782   while (ShadowBytes < NumNOPBytes)
783     ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
784                            getSubtargetInfo());
785 }
786 
787 // Lower a patchpoint of the form:
788 // [<def>], <id>, <numBytes>, <target>, <numArgs>
789 void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
790                                         SystemZMCInstLower &Lower) {
791   auto &Ctx = OutStreamer->getContext();
792   MCSymbol *MILabel = Ctx.createTempSymbol();
793   OutStreamer->emitLabel(MILabel);
794 
795   SM.recordPatchPoint(*MILabel, MI);
796   PatchPointOpers Opers(&MI);
797 
798   unsigned EncodedBytes = 0;
799   const MachineOperand &CalleeMO = Opers.getCallTarget();
800 
801   if (CalleeMO.isImm()) {
802     uint64_t CallTarget = CalleeMO.getImm();
803     if (CallTarget) {
804       unsigned ScratchIdx = -1;
805       unsigned ScratchReg = 0;
806       do {
807         ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
808         ScratchReg = MI.getOperand(ScratchIdx).getReg();
809       } while (ScratchReg == SystemZ::R0D);
810 
811       // Materialize the call target address
812       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
813                                       .addReg(ScratchReg)
814                                       .addImm(CallTarget & 0xFFFFFFFF));
815       EncodedBytes += 6;
816       if (CallTarget >> 32) {
817         EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
818                                         .addReg(ScratchReg)
819                                         .addImm(CallTarget >> 32));
820         EncodedBytes += 6;
821       }
822 
823       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
824                                      .addReg(SystemZ::R14D)
825                                      .addReg(ScratchReg));
826       EncodedBytes += 2;
827     }
828   } else if (CalleeMO.isGlobal()) {
829     const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
830     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
831                                    .addReg(SystemZ::R14D)
832                                    .addExpr(Expr));
833     EncodedBytes += 6;
834   }
835 
836   // Emit padding.
837   unsigned NumBytes = Opers.getNumPatchBytes();
838   assert(NumBytes >= EncodedBytes &&
839          "Patchpoint can't request size less than the length of a call.");
840   assert((NumBytes - EncodedBytes) % 2 == 0 &&
841          "Invalid number of NOP bytes requested!");
842   while (EncodedBytes < NumBytes)
843     EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
844                             getSubtargetInfo());
845 }
846 
847 // The *alignment* of 128-bit vector types is different between the software
848 // and hardware vector ABIs. If the there is an externally visible use of a
849 // vector type in the module it should be annotated with an attribute.
850 void SystemZAsmPrinter::emitAttributes(Module &M) {
851   if (M.getModuleFlag("s390x-visible-vector-ABI")) {
852     bool HasVectorFeature =
853       TM.getMCSubtargetInfo()->hasFeature(SystemZ::FeatureVector);
854     OutStreamer->emitGNUAttribute(8, HasVectorFeature ? 2 : 1);
855   }
856 }
857 
858 // Convert a SystemZ-specific constant pool modifier into the associated
859 // MCSymbolRefExpr variant kind.
860 static MCSymbolRefExpr::VariantKind
861 getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
862   switch (Modifier) {
863   case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
864   case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
865   case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
866   case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
867   }
868   llvm_unreachable("Invalid SystemCPModifier!");
869 }
870 
871 void SystemZAsmPrinter::emitMachineConstantPoolValue(
872     MachineConstantPoolValue *MCPV) {
873   auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
874 
875   const MCExpr *Expr =
876     MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
877                             getModifierVariantKind(ZCPV->getModifier()),
878                             OutContext);
879   uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
880 
881   OutStreamer->emitValue(Expr, Size);
882 }
883 
884 static void printFormattedRegName(const MCAsmInfo *MAI, unsigned RegNo,
885                                   raw_ostream &OS) {
886   const char *RegName;
887   if (MAI->getAssemblerDialect() == AD_HLASM) {
888     RegName = SystemZHLASMInstPrinter::getRegisterName(RegNo);
889     // Skip register prefix so that only register number is left
890     assert(isalpha(RegName[0]) && isdigit(RegName[1]));
891     OS << (RegName + 1);
892   } else {
893     RegName = SystemZGNUInstPrinter::getRegisterName(RegNo);
894     OS << '%' << RegName;
895   }
896 }
897 
898 static void printReg(unsigned Reg, const MCAsmInfo *MAI, raw_ostream &OS) {
899   if (!Reg)
900     OS << '0';
901   else
902     printFormattedRegName(MAI, Reg, OS);
903 }
904 
905 static void printOperand(const MCOperand &MCOp, const MCAsmInfo *MAI,
906                          raw_ostream &OS) {
907   if (MCOp.isReg())
908     printReg(MCOp.getReg(), MAI, OS);
909   else if (MCOp.isImm())
910     OS << MCOp.getImm();
911   else if (MCOp.isExpr())
912     MCOp.getExpr()->print(OS, MAI);
913   else
914     llvm_unreachable("Invalid operand");
915 }
916 
917 static void printAddress(const MCAsmInfo *MAI, unsigned Base,
918                          const MCOperand &DispMO, unsigned Index,
919                          raw_ostream &OS) {
920   printOperand(DispMO, MAI, OS);
921   if (Base || Index) {
922     OS << '(';
923     if (Index) {
924       printFormattedRegName(MAI, Index, OS);
925       if (Base)
926         OS << ',';
927     }
928     if (Base)
929       printFormattedRegName(MAI, Base, OS);
930     OS << ')';
931   }
932 }
933 
934 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
935                                         const char *ExtraCode,
936                                         raw_ostream &OS) {
937   const MCRegisterInfo &MRI = *TM.getMCRegisterInfo();
938   const MachineOperand &MO = MI->getOperand(OpNo);
939   MCOperand MCOp;
940   if (ExtraCode) {
941     if (ExtraCode[0] == 'N' && !ExtraCode[1] && MO.isReg() &&
942         SystemZ::GR128BitRegClass.contains(MO.getReg()))
943       MCOp =
944           MCOperand::createReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64));
945     else
946       return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
947   } else {
948     SystemZMCInstLower Lower(MF->getContext(), *this);
949     MCOp = Lower.lowerOperand(MO);
950   }
951   printOperand(MCOp, MAI, OS);
952   return false;
953 }
954 
955 bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
956                                               unsigned OpNo,
957                                               const char *ExtraCode,
958                                               raw_ostream &OS) {
959   if (ExtraCode && ExtraCode[0] && !ExtraCode[1]) {
960     switch (ExtraCode[0]) {
961     case 'A':
962       // Unlike EmitMachineNode(), EmitSpecialNode(INLINEASM) does not call
963       // setMemRefs(), so MI->memoperands() is empty and the alignment
964       // information is not available.
965       return false;
966     case 'O':
967       OS << MI->getOperand(OpNo + 1).getImm();
968       return false;
969     case 'R':
970       ::printReg(MI->getOperand(OpNo).getReg(), MAI, OS);
971       return false;
972     }
973   }
974   printAddress(MAI, MI->getOperand(OpNo).getReg(),
975                MCOperand::createImm(MI->getOperand(OpNo + 1).getImm()),
976                MI->getOperand(OpNo + 2).getReg(), OS);
977   return false;
978 }
979 
980 void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
981   auto TT = OutContext.getTargetTriple();
982   if (TT.isOSzOS()) {
983     emitADASection();
984     emitIDRLSection(M);
985   }
986   emitAttributes(M);
987 }
988 
989 void SystemZAsmPrinter::emitADASection() {
990   OutStreamer->pushSection();
991 
992   const unsigned PointerSize = getDataLayout().getPointerSize();
993   OutStreamer->switchSection(getObjFileLowering().getADASection());
994 
995   unsigned EmittedBytes = 0;
996   for (auto &Entry : ADATable.getTable()) {
997     const MCSymbol *Sym;
998     unsigned SlotKind;
999     std::tie(Sym, SlotKind) = Entry.first;
1000     unsigned Offset = Entry.second;
1001     assert(Offset == EmittedBytes && "Offset not as expected");
1002     (void)EmittedBytes;
1003 #define EMIT_COMMENT(Str)                                                      \
1004   OutStreamer->AddComment(Twine("Offset ")                                     \
1005                               .concat(utostr(Offset))                          \
1006                               .concat(" " Str " ")                             \
1007                               .concat(Sym->getName()));
1008     switch (SlotKind) {
1009     case SystemZII::MO_ADA_DIRECT_FUNC_DESC:
1010       // Language Environment DLL logic requires function descriptors, for
1011       // imported functions, that are placed in the ADA to be 8 byte aligned.
1012       EMIT_COMMENT("function descriptor of");
1013       OutStreamer->emitValue(
1014           SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_RCon,
1015                                 MCSymbolRefExpr::create(Sym, OutContext),
1016                                 OutContext),
1017           PointerSize);
1018       OutStreamer->emitValue(
1019           SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
1020                                 MCSymbolRefExpr::create(Sym, OutContext),
1021                                 OutContext),
1022           PointerSize);
1023       EmittedBytes += PointerSize * 2;
1024       break;
1025     case SystemZII::MO_ADA_DATA_SYMBOL_ADDR:
1026       EMIT_COMMENT("pointer to data symbol");
1027       OutStreamer->emitValue(
1028           SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_None,
1029                                 MCSymbolRefExpr::create(Sym, OutContext),
1030                                 OutContext),
1031           PointerSize);
1032       EmittedBytes += PointerSize;
1033       break;
1034     case SystemZII::MO_ADA_INDIRECT_FUNC_DESC: {
1035       MCSymbol *Alias = OutContext.createTempSymbol(
1036           Twine(Sym->getName()).concat("@indirect"));
1037       OutStreamer->emitAssignment(Alias,
1038                                   MCSymbolRefExpr::create(Sym, OutContext));
1039       OutStreamer->emitSymbolAttribute(Alias, MCSA_IndirectSymbol);
1040 
1041       EMIT_COMMENT("pointer to function descriptor");
1042       OutStreamer->emitValue(
1043           SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
1044                                 MCSymbolRefExpr::create(Alias, OutContext),
1045                                 OutContext),
1046           PointerSize);
1047       EmittedBytes += PointerSize;
1048       break;
1049     }
1050     default:
1051       llvm_unreachable("Unexpected slot kind");
1052     }
1053 #undef EMIT_COMMENT
1054   }
1055   OutStreamer->popSection();
1056 }
1057 
1058 static std::string getProductID(Module &M) {
1059   std::string ProductID;
1060   if (auto *MD = M.getModuleFlag("zos_product_id"))
1061     ProductID = cast<MDString>(MD)->getString().str();
1062   if (ProductID.empty())
1063     ProductID = "LLVM";
1064   return ProductID;
1065 }
1066 
1067 static uint32_t getProductVersion(Module &M) {
1068   if (auto *VersionVal = mdconst::extract_or_null<ConstantInt>(
1069           M.getModuleFlag("zos_product_major_version")))
1070     return VersionVal->getZExtValue();
1071   return LLVM_VERSION_MAJOR;
1072 }
1073 
1074 static uint32_t getProductRelease(Module &M) {
1075   if (auto *ReleaseVal = mdconst::extract_or_null<ConstantInt>(
1076           M.getModuleFlag("zos_product_minor_version")))
1077     return ReleaseVal->getZExtValue();
1078   return LLVM_VERSION_MINOR;
1079 }
1080 
1081 static uint32_t getProductPatch(Module &M) {
1082   if (auto *PatchVal = mdconst::extract_or_null<ConstantInt>(
1083           M.getModuleFlag("zos_product_patchlevel")))
1084     return PatchVal->getZExtValue();
1085   return LLVM_VERSION_PATCH;
1086 }
1087 
1088 static time_t getTranslationTime(Module &M) {
1089   std::time_t Time = 0;
1090   if (auto *Val = mdconst::extract_or_null<ConstantInt>(
1091           M.getModuleFlag("zos_translation_time"))) {
1092     long SecondsSinceEpoch = Val->getSExtValue();
1093     Time = static_cast<time_t>(SecondsSinceEpoch);
1094   }
1095   return Time;
1096 }
1097 
1098 void SystemZAsmPrinter::emitIDRLSection(Module &M) {
1099   OutStreamer->pushSection();
1100   OutStreamer->switchSection(getObjFileLowering().getIDRLSection());
1101   constexpr unsigned IDRLDataLength = 30;
1102   std::time_t Time = getTranslationTime(M);
1103 
1104   uint32_t ProductVersion = getProductVersion(M);
1105   uint32_t ProductRelease = getProductRelease(M);
1106 
1107   std::string ProductID = getProductID(M);
1108 
1109   SmallString<IDRLDataLength + 1> TempStr;
1110   raw_svector_ostream O(TempStr);
1111   O << formatv("{0,-10}{1,0-2:d}{2,0-2:d}{3:%Y%m%d%H%M%S}{4,0-2}",
1112                ProductID.substr(0, 10).c_str(), ProductVersion, ProductRelease,
1113                llvm::sys::toUtcTime(Time), "0");
1114   SmallString<IDRLDataLength> Data;
1115   ConverterEBCDIC::convertToEBCDIC(TempStr, Data);
1116 
1117   OutStreamer->emitInt8(0);               // Reserved.
1118   OutStreamer->emitInt8(3);               // Format.
1119   OutStreamer->emitInt16(IDRLDataLength); // Length.
1120   OutStreamer->emitBytes(Data.str());
1121   OutStreamer->popSection();
1122 }
1123 
1124 void SystemZAsmPrinter::emitFunctionBodyEnd() {
1125   if (TM.getTargetTriple().isOSzOS()) {
1126     // Emit symbol for the end of function if the z/OS target streamer
1127     // is used. This is needed to calculate the size of the function.
1128     MCSymbol *FnEndSym = createTempSymbol("func_end");
1129     OutStreamer->emitLabel(FnEndSym);
1130 
1131     OutStreamer->pushSection();
1132     OutStreamer->switchSection(getObjFileLowering().getPPA1Section());
1133     emitPPA1(FnEndSym);
1134     OutStreamer->popSection();
1135 
1136     CurrentFnPPA1Sym = nullptr;
1137     CurrentFnEPMarkerSym = nullptr;
1138   }
1139 }
1140 
1141 static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
1142                           bool StackProtector, bool FPRMask, bool VRMask,
1143                           bool EHBlock, bool HasName) {
1144   enum class PPA1Flag1 : uint8_t {
1145     DSA64Bit = (0x80 >> 0),
1146     VarArg = (0x80 >> 7),
1147     LLVM_MARK_AS_BITMASK_ENUM(DSA64Bit)
1148   };
1149   enum class PPA1Flag2 : uint8_t {
1150     ExternalProcedure = (0x80 >> 0),
1151     STACKPROTECTOR = (0x80 >> 3),
1152     LLVM_MARK_AS_BITMASK_ENUM(ExternalProcedure)
1153   };
1154   enum class PPA1Flag3 : uint8_t {
1155     FPRMask = (0x80 >> 2),
1156     LLVM_MARK_AS_BITMASK_ENUM(FPRMask)
1157   };
1158   enum class PPA1Flag4 : uint8_t {
1159     EPMOffsetPresent = (0x80 >> 0),
1160     VRMask = (0x80 >> 2),
1161     EHBlock = (0x80 >> 3),
1162     ProcedureNamePresent = (0x80 >> 7),
1163     LLVM_MARK_AS_BITMASK_ENUM(EPMOffsetPresent)
1164   };
1165 
1166   // Declare optional section flags that can be modified.
1167   auto Flags1 = PPA1Flag1(0);
1168   auto Flags2 = PPA1Flag2::ExternalProcedure;
1169   auto Flags3 = PPA1Flag3(0);
1170   auto Flags4 = PPA1Flag4::EPMOffsetPresent;
1171 
1172   Flags1 |= PPA1Flag1::DSA64Bit;
1173 
1174   if (VarArg)
1175     Flags1 |= PPA1Flag1::VarArg;
1176 
1177   if (StackProtector)
1178     Flags2 |= PPA1Flag2::STACKPROTECTOR;
1179 
1180   // SavedGPRMask, SavedFPRMask, and SavedVRMask are precomputed in.
1181   if (FPRMask)
1182     Flags3 |= PPA1Flag3::FPRMask; // Add emit FPR mask flag.
1183 
1184   if (VRMask)
1185     Flags4 |= PPA1Flag4::VRMask; // Add emit VR mask flag.
1186 
1187   if (EHBlock)
1188     Flags4 |= PPA1Flag4::EHBlock; // Add optional EH block.
1189 
1190   if (HasName)
1191     Flags4 |= PPA1Flag4::ProcedureNamePresent; // Add optional name block.
1192 
1193   OutStreamer->AddComment("PPA1 Flags 1");
1194   if ((Flags1 & PPA1Flag1::DSA64Bit) == PPA1Flag1::DSA64Bit)
1195     OutStreamer->AddComment("  Bit 0: 1 = 64-bit DSA");
1196   else
1197     OutStreamer->AddComment("  Bit 0: 0 = 32-bit DSA");
1198   if ((Flags1 & PPA1Flag1::VarArg) == PPA1Flag1::VarArg)
1199     OutStreamer->AddComment("  Bit 7: 1 = Vararg function");
1200   OutStreamer->emitInt8(static_cast<uint8_t>(Flags1)); // Flags 1.
1201 
1202   OutStreamer->AddComment("PPA1 Flags 2");
1203   if ((Flags2 & PPA1Flag2::ExternalProcedure) == PPA1Flag2::ExternalProcedure)
1204     OutStreamer->AddComment("  Bit 0: 1 = External procedure");
1205   if ((Flags2 & PPA1Flag2::STACKPROTECTOR) == PPA1Flag2::STACKPROTECTOR)
1206     OutStreamer->AddComment("  Bit 3: 1 = STACKPROTECT is enabled");
1207   else
1208     OutStreamer->AddComment("  Bit 3: 0 = STACKPROTECT is not enabled");
1209   OutStreamer->emitInt8(static_cast<uint8_t>(Flags2)); // Flags 2.
1210 
1211   OutStreamer->AddComment("PPA1 Flags 3");
1212   if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask)
1213     OutStreamer->AddComment("  Bit 2: 1 = FP Reg Mask is in optional area");
1214   OutStreamer->emitInt8(
1215       static_cast<uint8_t>(Flags3)); // Flags 3 (optional sections).
1216 
1217   OutStreamer->AddComment("PPA1 Flags 4");
1218   if ((Flags4 & PPA1Flag4::VRMask) == PPA1Flag4::VRMask)
1219     OutStreamer->AddComment("  Bit 2: 1 = Vector Reg Mask is in optional area");
1220   if ((Flags4 & PPA1Flag4::EHBlock) == PPA1Flag4::EHBlock)
1221     OutStreamer->AddComment("  Bit 3: 1 = C++ EH block");
1222   if ((Flags4 & PPA1Flag4::ProcedureNamePresent) ==
1223       PPA1Flag4::ProcedureNamePresent)
1224     OutStreamer->AddComment("  Bit 7: 1 = Name Length and Name");
1225   OutStreamer->emitInt8(static_cast<uint8_t>(
1226       Flags4)); // Flags 4 (optional sections, always emit these).
1227 }
1228 
1229 static void emitPPA1Name(std::unique_ptr<MCStreamer> &OutStreamer,
1230                          StringRef OutName) {
1231   size_t NameSize = OutName.size();
1232   uint16_t OutSize;
1233   if (NameSize < UINT16_MAX) {
1234     OutSize = static_cast<uint16_t>(NameSize);
1235   } else {
1236     OutName = OutName.substr(0, UINT16_MAX);
1237     OutSize = UINT16_MAX;
1238   }
1239   // Emit padding to ensure that the next optional field word-aligned.
1240   uint8_t ExtraZeros = 4 - ((2 + OutSize) % 4);
1241 
1242   SmallString<512> OutnameConv;
1243   ConverterEBCDIC::convertToEBCDIC(OutName, OutnameConv);
1244   OutName = OutnameConv.str();
1245 
1246   OutStreamer->AddComment("Length of Name");
1247   OutStreamer->emitInt16(OutSize);
1248   OutStreamer->AddComment("Name of Function");
1249   OutStreamer->emitBytes(OutName);
1250   OutStreamer->emitZeros(ExtraZeros);
1251 }
1252 
1253 void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) {
1254   assert(PPA2Sym != nullptr && "PPA2 Symbol not defined");
1255 
1256   const TargetRegisterInfo *TRI = MF->getRegInfo().getTargetRegisterInfo();
1257   const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
1258   const auto TargetHasVector = Subtarget.hasVector();
1259 
1260   const SystemZMachineFunctionInfo *ZFI =
1261       MF->getInfo<SystemZMachineFunctionInfo>();
1262   const auto *ZFL = static_cast<const SystemZXPLINKFrameLowering *>(
1263       Subtarget.getFrameLowering());
1264   const MachineFrameInfo &MFFrame = MF->getFrameInfo();
1265 
1266   // Get saved GPR/FPR/VPR masks.
1267   const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
1268   uint16_t SavedGPRMask = 0;
1269   uint16_t SavedFPRMask = 0;
1270   uint8_t SavedVRMask = 0;
1271   int64_t OffsetFPR = 0;
1272   int64_t OffsetVR = 0;
1273   const int64_t TopOfStack =
1274       MFFrame.getOffsetAdjustment() + MFFrame.getStackSize();
1275 
1276   // Loop over the spilled registers. The CalleeSavedInfo can't be used because
1277   // it does not contain all spilled registers.
1278   for (unsigned I = ZFI->getSpillGPRRegs().LowGPR,
1279                 E = ZFI->getSpillGPRRegs().HighGPR;
1280        I && E && I <= E; ++I) {
1281     unsigned V = TRI->getEncodingValue((Register)I);
1282     assert(V < 16 && "GPR index out of range");
1283     SavedGPRMask |= 1 << (15 - V);
1284   }
1285 
1286   for (auto &CS : CSI) {
1287     unsigned Reg = CS.getReg();
1288     unsigned I = TRI->getEncodingValue(Reg);
1289 
1290     if (SystemZ::FP64BitRegClass.contains(Reg)) {
1291       assert(I < 16 && "FPR index out of range");
1292       SavedFPRMask |= 1 << (15 - I);
1293       int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
1294       if (Temp < OffsetFPR)
1295         OffsetFPR = Temp;
1296     } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
1297       assert(I >= 16 && I <= 23 && "VPR index out of range");
1298       unsigned BitNum = I - 16;
1299       SavedVRMask |= 1 << (7 - BitNum);
1300       int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
1301       if (Temp < OffsetVR)
1302         OffsetVR = Temp;
1303     }
1304   }
1305 
1306   // Adjust the offset.
1307   OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0;
1308   OffsetVR += (OffsetVR < 0) ? TopOfStack : 0;
1309 
1310   // Get alloca register.
1311   uint8_t FrameReg = TRI->getEncodingValue(TRI->getFrameRegister(*MF));
1312   uint8_t AllocaReg = ZFL->hasFP(*MF) ? FrameReg : 0;
1313   assert(AllocaReg < 16 && "Can't have alloca register larger than 15");
1314   (void)AllocaReg;
1315 
1316   // Build FPR save area offset.
1317   uint32_t FrameAndFPROffset = 0;
1318   if (SavedFPRMask) {
1319     uint64_t FPRSaveAreaOffset = OffsetFPR;
1320     assert(FPRSaveAreaOffset < 0x10000000 && "Offset out of range");
1321 
1322     FrameAndFPROffset = FPRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
1323     FrameAndFPROffset |= FrameReg << 28;                // Put into top 4 bits.
1324   }
1325 
1326   // Build VR save area offset.
1327   uint32_t FrameAndVROffset = 0;
1328   if (TargetHasVector && SavedVRMask) {
1329     uint64_t VRSaveAreaOffset = OffsetVR;
1330     assert(VRSaveAreaOffset < 0x10000000 && "Offset out of range");
1331 
1332     FrameAndVROffset = VRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
1333     FrameAndVROffset |= FrameReg << 28;               // Put into top 4 bits.
1334   }
1335 
1336   // Emit PPA1 section.
1337   OutStreamer->AddComment("PPA1");
1338   OutStreamer->emitLabel(CurrentFnPPA1Sym);
1339   OutStreamer->AddComment("Version");
1340   OutStreamer->emitInt8(0x02); // Version.
1341   OutStreamer->AddComment("LE Signature X'CE'");
1342   OutStreamer->emitInt8(0xCE); // CEL signature.
1343   OutStreamer->AddComment("Saved GPR Mask");
1344   OutStreamer->emitInt16(SavedGPRMask);
1345   OutStreamer->AddComment("Offset to PPA2");
1346   OutStreamer->emitAbsoluteSymbolDiff(PPA2Sym, CurrentFnPPA1Sym, 4);
1347 
1348   bool NeedEmitEHBlock = !MF->getLandingPads().empty();
1349 
1350   bool HasName =
1351       MF->getFunction().hasName() && MF->getFunction().getName().size() > 0;
1352 
1353   emitPPA1Flags(OutStreamer, MF->getFunction().isVarArg(),
1354                 MFFrame.hasStackProtectorIndex(), SavedFPRMask != 0,
1355                 TargetHasVector && SavedVRMask != 0, NeedEmitEHBlock, HasName);
1356 
1357   OutStreamer->AddComment("Length/4 of Parms");
1358   OutStreamer->emitInt16(
1359       static_cast<uint16_t>(ZFI->getSizeOfFnParams() / 4)); // Parms/4.
1360   OutStreamer->AddComment("Length of Code");
1361   OutStreamer->emitAbsoluteSymbolDiff(FnEndSym, CurrentFnEPMarkerSym, 4);
1362 
1363   // Emit saved FPR mask and offset to FPR save area (0x20 of flags 3).
1364   if (SavedFPRMask) {
1365     OutStreamer->AddComment("FPR mask");
1366     OutStreamer->emitInt16(SavedFPRMask);
1367     OutStreamer->AddComment("AR mask");
1368     OutStreamer->emitInt16(0); // AR Mask, unused currently.
1369     OutStreamer->AddComment("FPR Save Area Locator");
1370     OutStreamer->AddComment(Twine("  Bit 0-3: Register R")
1371                                 .concat(utostr(FrameAndFPROffset >> 28))
1372                                 .str());
1373     OutStreamer->AddComment(Twine("  Bit 4-31: Offset ")
1374                                 .concat(utostr(FrameAndFPROffset & 0x0FFFFFFF))
1375                                 .str());
1376     OutStreamer->emitInt32(FrameAndFPROffset); // Offset to FPR save area with
1377                                                // register to add value to
1378                                                // (alloca reg).
1379   }
1380 
1381   // Emit saved VR mask to VR save area.
1382   if (TargetHasVector && SavedVRMask) {
1383     OutStreamer->AddComment("VR mask");
1384     OutStreamer->emitInt8(SavedVRMask);
1385     OutStreamer->emitInt8(0);  // Reserved.
1386     OutStreamer->emitInt16(0); // Also reserved.
1387     OutStreamer->AddComment("VR Save Area Locator");
1388     OutStreamer->AddComment(Twine("  Bit 0-3: Register R")
1389                                 .concat(utostr(FrameAndVROffset >> 28))
1390                                 .str());
1391     OutStreamer->AddComment(Twine("  Bit 4-31: Offset ")
1392                                 .concat(utostr(FrameAndVROffset & 0x0FFFFFFF))
1393                                 .str());
1394     OutStreamer->emitInt32(FrameAndVROffset);
1395   }
1396 
1397   // Emit C++ EH information block
1398   const Function *Per = nullptr;
1399   if (NeedEmitEHBlock) {
1400     Per = dyn_cast<Function>(
1401         MF->getFunction().getPersonalityFn()->stripPointerCasts());
1402     MCSymbol *PersonalityRoutine =
1403         Per ? MF->getTarget().getSymbol(Per) : nullptr;
1404     assert(PersonalityRoutine && "Missing personality routine");
1405 
1406     OutStreamer->AddComment("Version");
1407     OutStreamer->emitInt32(1);
1408     OutStreamer->AddComment("Flags");
1409     OutStreamer->emitInt32(0); // LSDA field is a WAS offset
1410     OutStreamer->AddComment("Personality routine");
1411     OutStreamer->emitInt64(ADATable.insert(
1412         PersonalityRoutine, SystemZII::MO_ADA_INDIRECT_FUNC_DESC));
1413     OutStreamer->AddComment("LSDA location");
1414     MCSymbol *GCCEH = MF->getContext().getOrCreateSymbol(
1415         Twine("GCC_except_table") + Twine(MF->getFunctionNumber()));
1416     OutStreamer->emitInt64(
1417         ADATable.insert(GCCEH, SystemZII::MO_ADA_DATA_SYMBOL_ADDR));
1418   }
1419 
1420   // Emit name length and name optional section (0x01 of flags 4)
1421   if (HasName)
1422     emitPPA1Name(OutStreamer, MF->getFunction().getName());
1423 
1424   // Emit offset to entry point optional section (0x80 of flags 4).
1425   OutStreamer->emitAbsoluteSymbolDiff(CurrentFnEPMarkerSym, CurrentFnPPA1Sym,
1426                                       4);
1427 }
1428 
1429 void SystemZAsmPrinter::emitStartOfAsmFile(Module &M) {
1430   if (TM.getTargetTriple().isOSzOS())
1431     emitPPA2(M);
1432   AsmPrinter::emitStartOfAsmFile(M);
1433 }
1434 
1435 void SystemZAsmPrinter::emitPPA2(Module &M) {
1436   OutStreamer->pushSection();
1437   OutStreamer->switchSection(getObjFileLowering().getPPA2Section());
1438   MCContext &OutContext = OutStreamer->getContext();
1439   // Make CELQSTRT symbol.
1440   const char *StartSymbolName = "CELQSTRT";
1441   MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
1442 
1443   // Create symbol and assign to class field for use in PPA1.
1444   PPA2Sym = OutContext.createTempSymbol("PPA2", false);
1445   MCSymbol *DateVersionSym = OutContext.createTempSymbol("DVS", false);
1446 
1447   std::time_t Time = getTranslationTime(M);
1448   SmallString<15> CompilationTime; // 14 + null
1449   raw_svector_ostream O(CompilationTime);
1450   O << formatv("{0:%Y%m%d%H%M%S}", llvm::sys::toUtcTime(Time));
1451 
1452   uint32_t ProductVersion = getProductVersion(M),
1453            ProductRelease = getProductRelease(M),
1454            ProductPatch = getProductPatch(M);
1455 
1456   SmallString<7> Version; // 6 + null
1457   raw_svector_ostream ostr(Version);
1458   ostr << formatv("{0,0-2:d}{1,0-2:d}{2,0-2:d}", ProductVersion, ProductRelease,
1459                   ProductPatch);
1460 
1461   // Drop 0 during conversion.
1462   SmallString<sizeof(CompilationTime) - 1> CompilationTimeStr;
1463   SmallString<sizeof(Version) - 1> VersionStr;
1464 
1465   ConverterEBCDIC::convertToEBCDIC(CompilationTime, CompilationTimeStr);
1466   ConverterEBCDIC::convertToEBCDIC(Version, VersionStr);
1467 
1468   enum class PPA2MemberId : uint8_t {
1469     // See z/OS Language Environment Vendor Interfaces v2r5, p.23, for
1470     // complete list. Only the C runtime is supported by this backend.
1471     LE_C_Runtime = 3,
1472   };
1473   enum class PPA2MemberSubId : uint8_t {
1474     // List of languages using the LE C runtime implementation.
1475     C = 0x00,
1476     CXX = 0x01,
1477     Swift = 0x03,
1478     Go = 0x60,
1479     LLVMBasedLang = 0xe7,
1480   };
1481   // PPA2 Flags
1482   enum class PPA2Flags : uint8_t {
1483     CompileForBinaryFloatingPoint = 0x80,
1484     CompiledWithXPLink = 0x01,
1485     CompiledUnitASCII = 0x04,
1486     HasServiceInfo = 0x20,
1487   };
1488 
1489   PPA2MemberSubId MemberSubId = PPA2MemberSubId::LLVMBasedLang;
1490   if (auto *MD = M.getModuleFlag("zos_cu_language")) {
1491     StringRef Language = cast<MDString>(MD)->getString();
1492     MemberSubId = StringSwitch<PPA2MemberSubId>(Language)
1493                       .Case("C", PPA2MemberSubId::C)
1494                       .Case("C++", PPA2MemberSubId::CXX)
1495                       .Case("Swift", PPA2MemberSubId::Swift)
1496                       .Case("Go", PPA2MemberSubId::Go)
1497                       .Default(PPA2MemberSubId::LLVMBasedLang);
1498   }
1499 
1500   // Emit PPA2 section.
1501   OutStreamer->emitLabel(PPA2Sym);
1502   OutStreamer->emitInt8(static_cast<uint8_t>(PPA2MemberId::LE_C_Runtime));
1503   OutStreamer->emitInt8(static_cast<uint8_t>(MemberSubId));
1504   OutStreamer->emitInt8(0x22); // Member defined, c370_plist+c370_env
1505   OutStreamer->emitInt8(0x04); // Control level 4 (XPLink)
1506   OutStreamer->emitAbsoluteSymbolDiff(CELQSTRT, PPA2Sym, 4);
1507   OutStreamer->emitInt32(0x00000000);
1508   OutStreamer->emitAbsoluteSymbolDiff(DateVersionSym, PPA2Sym, 4);
1509   OutStreamer->emitInt32(
1510       0x00000000); // Offset to main entry point, always 0 (so says TR).
1511   uint8_t Flgs = static_cast<uint8_t>(PPA2Flags::CompileForBinaryFloatingPoint);
1512   Flgs |= static_cast<uint8_t>(PPA2Flags::CompiledWithXPLink);
1513 
1514   if (auto *MD = M.getModuleFlag("zos_le_char_mode")) {
1515     const StringRef &CharMode = cast<MDString>(MD)->getString();
1516     if (CharMode == "ascii") {
1517       Flgs |= static_cast<uint8_t>(
1518           PPA2Flags::CompiledUnitASCII); // Setting bit for ASCII char. mode.
1519     } else if (CharMode != "ebcdic") {
1520       report_fatal_error(
1521           "Only ascii or ebcdic are valid values for zos_le_char_mode "
1522           "metadata");
1523     }
1524   }
1525 
1526   OutStreamer->emitInt8(Flgs);
1527   OutStreamer->emitInt8(0x00);    // Reserved.
1528                                   // No MD5 signature before timestamp.
1529                                   // No FLOAT(AFP(VOLATILE)).
1530                                   // Remaining 5 flag bits reserved.
1531   OutStreamer->emitInt16(0x0000); // 16 Reserved flag bits.
1532 
1533   // Emit date and version section.
1534   OutStreamer->emitLabel(DateVersionSym);
1535   OutStreamer->emitBytes(CompilationTimeStr.str());
1536   OutStreamer->emitBytes(VersionStr.str());
1537 
1538   OutStreamer->emitInt16(0x0000); // Service level string length.
1539 
1540   // The binder requires that the offset to the PPA2 be emitted in a different,
1541   // specially-named section.
1542   OutStreamer->switchSection(getObjFileLowering().getPPA2ListSection());
1543   // Emit 8 byte alignment.
1544   // Emit pointer to PPA2 label.
1545   OutStreamer->AddComment("A(PPA2-CELQSTRT)");
1546   OutStreamer->emitAbsoluteSymbolDiff(PPA2Sym, CELQSTRT, 8);
1547   OutStreamer->popSection();
1548 }
1549 
1550 void SystemZAsmPrinter::emitFunctionEntryLabel() {
1551   const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
1552 
1553   if (Subtarget.getTargetTriple().isOSzOS()) {
1554     MCContext &OutContext = OutStreamer->getContext();
1555 
1556     // Save information for later use.
1557     std::string N(MF->getFunction().hasName()
1558                       ? Twine(MF->getFunction().getName()).concat("_").str()
1559                       : "");
1560 
1561     CurrentFnEPMarkerSym =
1562         OutContext.createTempSymbol(Twine("EPM_").concat(N).str(), true);
1563     CurrentFnPPA1Sym =
1564         OutContext.createTempSymbol(Twine("PPA1_").concat(N).str(), true);
1565 
1566     // EntryPoint Marker
1567     const MachineFrameInfo &MFFrame = MF->getFrameInfo();
1568     bool IsUsingAlloca = MFFrame.hasVarSizedObjects();
1569     uint32_t DSASize = MFFrame.getStackSize();
1570     bool IsLeaf = DSASize == 0 && MFFrame.getCalleeSavedInfo().empty();
1571 
1572     // Set Flags.
1573     uint8_t Flags = 0;
1574     if (IsLeaf)
1575       Flags |= 0x08;
1576     if (IsUsingAlloca)
1577       Flags |= 0x04;
1578 
1579     // Combine into top 27 bits of DSASize and bottom 5 bits of Flags.
1580     uint32_t DSAAndFlags = DSASize & 0xFFFFFFE0; // (x/32) << 5
1581     DSAAndFlags |= Flags;
1582 
1583     // Emit entry point marker section.
1584     OutStreamer->AddComment("XPLINK Routine Layout Entry");
1585     OutStreamer->emitLabel(CurrentFnEPMarkerSym);
1586     OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
1587     OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher.
1588     OutStreamer->AddComment("Mark Type C'1'");
1589     OutStreamer->emitInt8(0xF1); // Mark Type.
1590     OutStreamer->AddComment("Offset to PPA1");
1591     OutStreamer->emitAbsoluteSymbolDiff(CurrentFnPPA1Sym, CurrentFnEPMarkerSym,
1592                                         4);
1593     if (OutStreamer->isVerboseAsm()) {
1594       OutStreamer->AddComment("DSA Size 0x" + Twine::utohexstr(DSASize));
1595       OutStreamer->AddComment("Entry Flags");
1596       if (Flags & 0x08)
1597         OutStreamer->AddComment("  Bit 1: 1 = Leaf function");
1598       else
1599         OutStreamer->AddComment("  Bit 1: 0 = Non-leaf function");
1600       if (Flags & 0x04)
1601         OutStreamer->AddComment("  Bit 2: 1 = Uses alloca");
1602       else
1603         OutStreamer->AddComment("  Bit 2: 0 = Does not use alloca");
1604     }
1605     OutStreamer->emitInt32(DSAAndFlags);
1606   }
1607 
1608   AsmPrinter::emitFunctionEntryLabel();
1609 }
1610 
1611 // Force static initialization.
1612 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter() {
1613   RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
1614 }
1615