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