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