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