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