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