1284c1978SDimitry Andric //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2284c1978SDimitry Andric //
3284c1978SDimitry Andric //                     The LLVM Compiler Infrastructure
4284c1978SDimitry Andric //
5284c1978SDimitry Andric // This file is distributed under the University of Illinois Open Source
6284c1978SDimitry Andric // License. See LICENSE.TXT for details.
7284c1978SDimitry Andric //
8284c1978SDimitry Andric //===----------------------------------------------------------------------===//
9284c1978SDimitry Andric //
10284c1978SDimitry Andric // Streams SystemZ assembly language and associated data, in the form of
11284c1978SDimitry Andric // MCInsts and MCExprs respectively.
12284c1978SDimitry Andric //
13284c1978SDimitry Andric //===----------------------------------------------------------------------===//
14284c1978SDimitry Andric 
15284c1978SDimitry Andric #include "SystemZAsmPrinter.h"
16284c1978SDimitry Andric #include "InstPrinter/SystemZInstPrinter.h"
17284c1978SDimitry Andric #include "SystemZConstantPoolValue.h"
18284c1978SDimitry Andric #include "SystemZMCInstLower.h"
19284c1978SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20284c1978SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
2191bc56edSDimitry Andric #include "llvm/IR/Mangler.h"
22284c1978SDimitry Andric #include "llvm/MC/MCExpr.h"
23f785676fSDimitry Andric #include "llvm/MC/MCInstBuilder.h"
24284c1978SDimitry Andric #include "llvm/MC/MCStreamer.h"
25284c1978SDimitry Andric #include "llvm/Support/TargetRegistry.h"
26284c1978SDimitry Andric 
27284c1978SDimitry Andric using namespace llvm;
28284c1978SDimitry Andric 
29f785676fSDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
30f785676fSDimitry Andric // GR64 register operands turned into GR32s.
lowerRILow(const MachineInstr * MI,unsigned Opcode)31f785676fSDimitry Andric static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
32f785676fSDimitry Andric   if (MI->isCompare())
33f785676fSDimitry Andric     return MCInstBuilder(Opcode)
34f785676fSDimitry Andric       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
35f785676fSDimitry Andric       .addImm(MI->getOperand(1).getImm());
36f785676fSDimitry Andric   else
37f785676fSDimitry Andric     return MCInstBuilder(Opcode)
38f785676fSDimitry Andric       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39f785676fSDimitry Andric       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
40f785676fSDimitry Andric       .addImm(MI->getOperand(2).getImm());
41f785676fSDimitry Andric }
42f785676fSDimitry Andric 
43f785676fSDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
44f785676fSDimitry Andric // GR64 register operands turned into GRH32s.
lowerRIHigh(const MachineInstr * MI,unsigned Opcode)45f785676fSDimitry Andric static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
46f785676fSDimitry Andric   if (MI->isCompare())
47f785676fSDimitry Andric     return MCInstBuilder(Opcode)
48f785676fSDimitry Andric       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
49f785676fSDimitry Andric       .addImm(MI->getOperand(1).getImm());
50f785676fSDimitry Andric   else
51f785676fSDimitry Andric     return MCInstBuilder(Opcode)
52f785676fSDimitry Andric       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
53f785676fSDimitry Andric       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
54f785676fSDimitry Andric       .addImm(MI->getOperand(2).getImm());
55f785676fSDimitry Andric }
56f785676fSDimitry Andric 
57f785676fSDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
58f785676fSDimitry Andric // R2 register turned into a GR64.
lowerRIEfLow(const MachineInstr * MI,unsigned Opcode)59f785676fSDimitry Andric static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
60f785676fSDimitry Andric   return MCInstBuilder(Opcode)
61f785676fSDimitry Andric     .addReg(MI->getOperand(0).getReg())
62f785676fSDimitry Andric     .addReg(MI->getOperand(1).getReg())
63f785676fSDimitry Andric     .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
64f785676fSDimitry Andric     .addImm(MI->getOperand(3).getImm())
65f785676fSDimitry Andric     .addImm(MI->getOperand(4).getImm())
66f785676fSDimitry Andric     .addImm(MI->getOperand(5).getImm());
67f785676fSDimitry Andric }
68f785676fSDimitry Andric 
getTLSGetOffset(MCContext & Context)69ff0cc061SDimitry Andric static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
70ff0cc061SDimitry Andric   StringRef Name = "__tls_get_offset";
7197bc6c73SDimitry Andric   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
72ff0cc061SDimitry Andric                                  MCSymbolRefExpr::VK_PLT,
73ff0cc061SDimitry Andric                                  Context);
74ff0cc061SDimitry Andric }
75ff0cc061SDimitry Andric 
getGlobalOffsetTable(MCContext & Context)76ff0cc061SDimitry Andric static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
77ff0cc061SDimitry Andric   StringRef Name = "_GLOBAL_OFFSET_TABLE_";
7897bc6c73SDimitry Andric   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
79ff0cc061SDimitry Andric                                  MCSymbolRefExpr::VK_None,
80ff0cc061SDimitry Andric                                  Context);
81ff0cc061SDimitry Andric }
82ff0cc061SDimitry Andric 
83ff0cc061SDimitry Andric // MI loads the high part of a vector from memory.  Return an instruction
84ff0cc061SDimitry Andric // that uses replicating vector load Opcode to do the same thing.
lowerSubvectorLoad(const MachineInstr * MI,unsigned Opcode)85ff0cc061SDimitry Andric static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
86ff0cc061SDimitry Andric   return MCInstBuilder(Opcode)
87ff0cc061SDimitry Andric     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
88ff0cc061SDimitry Andric     .addReg(MI->getOperand(1).getReg())
89ff0cc061SDimitry Andric     .addImm(MI->getOperand(2).getImm())
90ff0cc061SDimitry Andric     .addReg(MI->getOperand(3).getReg());
91ff0cc061SDimitry Andric }
92ff0cc061SDimitry Andric 
93ff0cc061SDimitry Andric // MI stores the high part of a vector to memory.  Return an instruction
94ff0cc061SDimitry Andric // that uses elemental vector store Opcode to do the same thing.
lowerSubvectorStore(const MachineInstr * MI,unsigned Opcode)95ff0cc061SDimitry Andric static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
96ff0cc061SDimitry Andric   return MCInstBuilder(Opcode)
97ff0cc061SDimitry Andric     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
98ff0cc061SDimitry Andric     .addReg(MI->getOperand(1).getReg())
99ff0cc061SDimitry Andric     .addImm(MI->getOperand(2).getImm())
100ff0cc061SDimitry Andric     .addReg(MI->getOperand(3).getReg())
101ff0cc061SDimitry Andric     .addImm(0);
102ff0cc061SDimitry Andric }
103ff0cc061SDimitry Andric 
EmitInstruction(const MachineInstr * MI)104284c1978SDimitry Andric void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
105f785676fSDimitry Andric   SystemZMCInstLower Lower(MF->getContext(), *this);
106284c1978SDimitry Andric   MCInst LoweredMI;
107f785676fSDimitry Andric   switch (MI->getOpcode()) {
108f785676fSDimitry Andric   case SystemZ::Return:
109f785676fSDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
110f785676fSDimitry Andric     break;
111f785676fSDimitry Andric 
1123ca95b02SDimitry Andric   case SystemZ::CondReturn:
1133ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BCR)
1143ca95b02SDimitry Andric       .addImm(MI->getOperand(0).getImm())
1153ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
1163ca95b02SDimitry Andric       .addReg(SystemZ::R14D);
1173ca95b02SDimitry Andric     break;
1183ca95b02SDimitry Andric 
1193ca95b02SDimitry Andric   case SystemZ::CRBReturn:
1203ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CRB)
1213ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
1223ca95b02SDimitry Andric       .addReg(MI->getOperand(1).getReg())
1233ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
1243ca95b02SDimitry Andric       .addReg(SystemZ::R14D)
1253ca95b02SDimitry Andric       .addImm(0);
1263ca95b02SDimitry Andric     break;
1273ca95b02SDimitry Andric 
1283ca95b02SDimitry Andric   case SystemZ::CGRBReturn:
1293ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CGRB)
1303ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
1313ca95b02SDimitry Andric       .addReg(MI->getOperand(1).getReg())
1323ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
1333ca95b02SDimitry Andric       .addReg(SystemZ::R14D)
1343ca95b02SDimitry Andric       .addImm(0);
1353ca95b02SDimitry Andric     break;
1363ca95b02SDimitry Andric 
1373ca95b02SDimitry Andric   case SystemZ::CIBReturn:
1383ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CIB)
1393ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
1403ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
1413ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
1423ca95b02SDimitry Andric       .addReg(SystemZ::R14D)
1433ca95b02SDimitry Andric       .addImm(0);
1443ca95b02SDimitry Andric     break;
1453ca95b02SDimitry Andric 
1463ca95b02SDimitry Andric   case SystemZ::CGIBReturn:
1473ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CGIB)
1483ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
1493ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
1503ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
1513ca95b02SDimitry Andric       .addReg(SystemZ::R14D)
1523ca95b02SDimitry Andric       .addImm(0);
1533ca95b02SDimitry Andric     break;
1543ca95b02SDimitry Andric 
1553ca95b02SDimitry Andric   case SystemZ::CLRBReturn:
1563ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLRB)
1573ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
1583ca95b02SDimitry Andric       .addReg(MI->getOperand(1).getReg())
1593ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
1603ca95b02SDimitry Andric       .addReg(SystemZ::R14D)
1613ca95b02SDimitry Andric       .addImm(0);
1623ca95b02SDimitry Andric     break;
1633ca95b02SDimitry Andric 
1643ca95b02SDimitry Andric   case SystemZ::CLGRBReturn:
1653ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
1663ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
1673ca95b02SDimitry Andric       .addReg(MI->getOperand(1).getReg())
1683ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
1693ca95b02SDimitry Andric       .addReg(SystemZ::R14D)
1703ca95b02SDimitry Andric       .addImm(0);
1713ca95b02SDimitry Andric     break;
1723ca95b02SDimitry Andric 
1733ca95b02SDimitry Andric   case SystemZ::CLIBReturn:
1743ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLIB)
1753ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
1763ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
1773ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
1783ca95b02SDimitry Andric       .addReg(SystemZ::R14D)
1793ca95b02SDimitry Andric       .addImm(0);
1803ca95b02SDimitry Andric     break;
1813ca95b02SDimitry Andric 
1823ca95b02SDimitry Andric   case SystemZ::CLGIBReturn:
1833ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
1843ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
1853ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
1863ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
1873ca95b02SDimitry Andric       .addReg(SystemZ::R14D)
1883ca95b02SDimitry Andric       .addImm(0);
1893ca95b02SDimitry Andric     break;
1903ca95b02SDimitry Andric 
191f785676fSDimitry Andric   case SystemZ::CallBRASL:
192f785676fSDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRASL)
193f785676fSDimitry Andric       .addReg(SystemZ::R14D)
194f785676fSDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
195f785676fSDimitry Andric     break;
196f785676fSDimitry Andric 
197f785676fSDimitry Andric   case SystemZ::CallBASR:
198f785676fSDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BASR)
199f785676fSDimitry Andric       .addReg(SystemZ::R14D)
200f785676fSDimitry Andric       .addReg(MI->getOperand(0).getReg());
201f785676fSDimitry Andric     break;
202f785676fSDimitry Andric 
203f785676fSDimitry Andric   case SystemZ::CallJG:
204f785676fSDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::JG)
205f785676fSDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
206f785676fSDimitry Andric     break;
207f785676fSDimitry Andric 
2083ca95b02SDimitry Andric   case SystemZ::CallBRCL:
2093ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRCL)
2103ca95b02SDimitry Andric       .addImm(MI->getOperand(0).getImm())
2113ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
2123ca95b02SDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
2133ca95b02SDimitry Andric     break;
2143ca95b02SDimitry Andric 
215f785676fSDimitry Andric   case SystemZ::CallBR:
216f785676fSDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
217f785676fSDimitry Andric     break;
218f785676fSDimitry Andric 
2193ca95b02SDimitry Andric   case SystemZ::CallBCR:
2203ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BCR)
2213ca95b02SDimitry Andric       .addImm(MI->getOperand(0).getImm())
2223ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
2233ca95b02SDimitry Andric       .addReg(SystemZ::R1D);
2243ca95b02SDimitry Andric     break;
2253ca95b02SDimitry Andric 
2263ca95b02SDimitry Andric   case SystemZ::CRBCall:
2273ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CRB)
2283ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
2293ca95b02SDimitry Andric       .addReg(MI->getOperand(1).getReg())
2303ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
2313ca95b02SDimitry Andric       .addReg(SystemZ::R1D)
2323ca95b02SDimitry Andric       .addImm(0);
2333ca95b02SDimitry Andric     break;
2343ca95b02SDimitry Andric 
2353ca95b02SDimitry Andric   case SystemZ::CGRBCall:
2363ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CGRB)
2373ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
2383ca95b02SDimitry Andric       .addReg(MI->getOperand(1).getReg())
2393ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
2403ca95b02SDimitry Andric       .addReg(SystemZ::R1D)
2413ca95b02SDimitry Andric       .addImm(0);
2423ca95b02SDimitry Andric     break;
2433ca95b02SDimitry Andric 
2443ca95b02SDimitry Andric   case SystemZ::CIBCall:
2453ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CIB)
2463ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
2473ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
2483ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
2493ca95b02SDimitry Andric       .addReg(SystemZ::R1D)
2503ca95b02SDimitry Andric       .addImm(0);
2513ca95b02SDimitry Andric     break;
2523ca95b02SDimitry Andric 
2533ca95b02SDimitry Andric   case SystemZ::CGIBCall:
2543ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CGIB)
2553ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
2563ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
2573ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
2583ca95b02SDimitry Andric       .addReg(SystemZ::R1D)
2593ca95b02SDimitry Andric       .addImm(0);
2603ca95b02SDimitry Andric     break;
2613ca95b02SDimitry Andric 
2623ca95b02SDimitry Andric   case SystemZ::CLRBCall:
2633ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLRB)
2643ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
2653ca95b02SDimitry Andric       .addReg(MI->getOperand(1).getReg())
2663ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
2673ca95b02SDimitry Andric       .addReg(SystemZ::R1D)
2683ca95b02SDimitry Andric       .addImm(0);
2693ca95b02SDimitry Andric     break;
2703ca95b02SDimitry Andric 
2713ca95b02SDimitry Andric   case SystemZ::CLGRBCall:
2723ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
2733ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
2743ca95b02SDimitry Andric       .addReg(MI->getOperand(1).getReg())
2753ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
2763ca95b02SDimitry Andric       .addReg(SystemZ::R1D)
2773ca95b02SDimitry Andric       .addImm(0);
2783ca95b02SDimitry Andric     break;
2793ca95b02SDimitry Andric 
2803ca95b02SDimitry Andric   case SystemZ::CLIBCall:
2813ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLIB)
2823ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
2833ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
2843ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
2853ca95b02SDimitry Andric       .addReg(SystemZ::R1D)
2863ca95b02SDimitry Andric       .addImm(0);
2873ca95b02SDimitry Andric     break;
2883ca95b02SDimitry Andric 
2893ca95b02SDimitry Andric   case SystemZ::CLGIBCall:
2903ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
2913ca95b02SDimitry Andric       .addReg(MI->getOperand(0).getReg())
2923ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
2933ca95b02SDimitry Andric       .addImm(MI->getOperand(2).getImm())
2943ca95b02SDimitry Andric       .addReg(SystemZ::R1D)
2953ca95b02SDimitry Andric       .addImm(0);
2963ca95b02SDimitry Andric     break;
2973ca95b02SDimitry Andric 
298ff0cc061SDimitry Andric   case SystemZ::TLS_GDCALL:
299ff0cc061SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRASL)
300ff0cc061SDimitry Andric       .addReg(SystemZ::R14D)
301ff0cc061SDimitry Andric       .addExpr(getTLSGetOffset(MF->getContext()))
302ff0cc061SDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
303ff0cc061SDimitry Andric     break;
304ff0cc061SDimitry Andric 
305ff0cc061SDimitry Andric   case SystemZ::TLS_LDCALL:
306ff0cc061SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRASL)
307ff0cc061SDimitry Andric       .addReg(SystemZ::R14D)
308ff0cc061SDimitry Andric       .addExpr(getTLSGetOffset(MF->getContext()))
309ff0cc061SDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
310ff0cc061SDimitry Andric     break;
311ff0cc061SDimitry Andric 
312ff0cc061SDimitry Andric   case SystemZ::GOT:
313ff0cc061SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::LARL)
314ff0cc061SDimitry Andric       .addReg(MI->getOperand(0).getReg())
315ff0cc061SDimitry Andric       .addExpr(getGlobalOffsetTable(MF->getContext()));
316ff0cc061SDimitry Andric     break;
317ff0cc061SDimitry Andric 
318f785676fSDimitry Andric   case SystemZ::IILF64:
319f785676fSDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::IILF)
320f785676fSDimitry Andric       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
321f785676fSDimitry Andric       .addImm(MI->getOperand(2).getImm());
322f785676fSDimitry Andric     break;
323f785676fSDimitry Andric 
324f785676fSDimitry Andric   case SystemZ::IIHF64:
325f785676fSDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::IIHF)
326f785676fSDimitry Andric       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
327f785676fSDimitry Andric       .addImm(MI->getOperand(2).getImm());
328f785676fSDimitry Andric     break;
329f785676fSDimitry Andric 
330f785676fSDimitry Andric   case SystemZ::RISBHH:
331f785676fSDimitry Andric   case SystemZ::RISBHL:
332f785676fSDimitry Andric     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
333f785676fSDimitry Andric     break;
334f785676fSDimitry Andric 
335f785676fSDimitry Andric   case SystemZ::RISBLH:
336f785676fSDimitry Andric   case SystemZ::RISBLL:
337f785676fSDimitry Andric     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
338f785676fSDimitry Andric     break;
339f785676fSDimitry Andric 
340ff0cc061SDimitry Andric   case SystemZ::VLVGP32:
341ff0cc061SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::VLVGP)
342ff0cc061SDimitry Andric       .addReg(MI->getOperand(0).getReg())
343ff0cc061SDimitry Andric       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
344ff0cc061SDimitry Andric       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
345ff0cc061SDimitry Andric     break;
346ff0cc061SDimitry Andric 
347ff0cc061SDimitry Andric   case SystemZ::VLR32:
348ff0cc061SDimitry Andric   case SystemZ::VLR64:
349ff0cc061SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::VLR)
350ff0cc061SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
351ff0cc061SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
352ff0cc061SDimitry Andric     break;
353ff0cc061SDimitry Andric 
354ff0cc061SDimitry Andric   case SystemZ::VL32:
355ff0cc061SDimitry Andric     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
356ff0cc061SDimitry Andric     break;
357ff0cc061SDimitry Andric 
358ff0cc061SDimitry Andric   case SystemZ::VL64:
359ff0cc061SDimitry Andric     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
360ff0cc061SDimitry Andric     break;
361ff0cc061SDimitry Andric 
362ff0cc061SDimitry Andric   case SystemZ::VST32:
363ff0cc061SDimitry Andric     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
364ff0cc061SDimitry Andric     break;
365ff0cc061SDimitry Andric 
366ff0cc061SDimitry Andric   case SystemZ::VST64:
367ff0cc061SDimitry Andric     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
368ff0cc061SDimitry Andric     break;
369ff0cc061SDimitry Andric 
370ff0cc061SDimitry Andric   case SystemZ::LFER:
371ff0cc061SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::VLGVF)
372ff0cc061SDimitry Andric       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
373ff0cc061SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
374ff0cc061SDimitry Andric       .addReg(0).addImm(0);
375ff0cc061SDimitry Andric     break;
376ff0cc061SDimitry Andric 
377ff0cc061SDimitry Andric   case SystemZ::LEFR:
378ff0cc061SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::VLVGF)
379ff0cc061SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
380ff0cc061SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
381ff0cc061SDimitry Andric       .addReg(MI->getOperand(1).getReg())
382ff0cc061SDimitry Andric       .addReg(0).addImm(0);
383ff0cc061SDimitry Andric     break;
384ff0cc061SDimitry Andric 
385f785676fSDimitry Andric #define LOWER_LOW(NAME)                                                 \
386f785676fSDimitry Andric   case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
387f785676fSDimitry Andric 
388f785676fSDimitry Andric   LOWER_LOW(IILL);
389f785676fSDimitry Andric   LOWER_LOW(IILH);
390f785676fSDimitry Andric   LOWER_LOW(TMLL);
391f785676fSDimitry Andric   LOWER_LOW(TMLH);
392f785676fSDimitry Andric   LOWER_LOW(NILL);
393f785676fSDimitry Andric   LOWER_LOW(NILH);
394f785676fSDimitry Andric   LOWER_LOW(NILF);
395f785676fSDimitry Andric   LOWER_LOW(OILL);
396f785676fSDimitry Andric   LOWER_LOW(OILH);
397f785676fSDimitry Andric   LOWER_LOW(OILF);
398f785676fSDimitry Andric   LOWER_LOW(XILF);
399f785676fSDimitry Andric 
400f785676fSDimitry Andric #undef LOWER_LOW
401f785676fSDimitry Andric 
402f785676fSDimitry Andric #define LOWER_HIGH(NAME) \
403f785676fSDimitry Andric   case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
404f785676fSDimitry Andric 
405f785676fSDimitry Andric   LOWER_HIGH(IIHL);
406f785676fSDimitry Andric   LOWER_HIGH(IIHH);
407f785676fSDimitry Andric   LOWER_HIGH(TMHL);
408f785676fSDimitry Andric   LOWER_HIGH(TMHH);
409f785676fSDimitry Andric   LOWER_HIGH(NIHL);
410f785676fSDimitry Andric   LOWER_HIGH(NIHH);
411f785676fSDimitry Andric   LOWER_HIGH(NIHF);
412f785676fSDimitry Andric   LOWER_HIGH(OIHL);
413f785676fSDimitry Andric   LOWER_HIGH(OIHH);
414f785676fSDimitry Andric   LOWER_HIGH(OIHF);
415f785676fSDimitry Andric   LOWER_HIGH(XIHF);
416f785676fSDimitry Andric 
417f785676fSDimitry Andric #undef LOWER_HIGH
418f785676fSDimitry Andric 
41991bc56edSDimitry Andric   case SystemZ::Serialize:
420ff0cc061SDimitry Andric     if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
421d88c1a5aSDimitry Andric       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
42291bc56edSDimitry Andric         .addImm(14).addReg(SystemZ::R0D);
42391bc56edSDimitry Andric     else
424d88c1a5aSDimitry Andric       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
42591bc56edSDimitry Andric         .addImm(15).addReg(SystemZ::R0D);
42691bc56edSDimitry Andric     break;
42791bc56edSDimitry Andric 
4283ca95b02SDimitry Andric   // Emit nothing here but a comment if we can.
4293ca95b02SDimitry Andric   case SystemZ::MemBarrier:
4303ca95b02SDimitry Andric     OutStreamer->emitRawComment("MEMBARRIER");
4313ca95b02SDimitry Andric     return;
4323ca95b02SDimitry Andric 
4333ca95b02SDimitry Andric   // We want to emit "j .+2" for traps, jumping to the relative immediate field
4343ca95b02SDimitry Andric   // of the jump instruction, which is an illegal instruction. We cannot emit a
4353ca95b02SDimitry Andric   // "." symbol, so create and emit a temp label before the instruction and use
4363ca95b02SDimitry Andric   // that instead.
4373ca95b02SDimitry Andric   case SystemZ::Trap: {
4383ca95b02SDimitry Andric     MCSymbol *DotSym = OutContext.createTempSymbol();
4393ca95b02SDimitry Andric     OutStreamer->EmitLabel(DotSym);
4403ca95b02SDimitry Andric 
4413ca95b02SDimitry Andric     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
4423ca95b02SDimitry Andric     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
4433ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::J)
4443ca95b02SDimitry Andric       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
4453ca95b02SDimitry Andric     }
4463ca95b02SDimitry Andric     break;
4473ca95b02SDimitry Andric 
4483ca95b02SDimitry Andric   // Conditional traps will create a branch on condition instruction that jumps
4493ca95b02SDimitry Andric   // to the relative immediate field of the jump instruction. (eg. "jo .+2")
4503ca95b02SDimitry Andric   case SystemZ::CondTrap: {
4513ca95b02SDimitry Andric     MCSymbol *DotSym = OutContext.createTempSymbol();
4523ca95b02SDimitry Andric     OutStreamer->EmitLabel(DotSym);
4533ca95b02SDimitry Andric 
4543ca95b02SDimitry Andric     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
4553ca95b02SDimitry Andric     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
4563ca95b02SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRC)
4573ca95b02SDimitry Andric       .addImm(MI->getOperand(0).getImm())
4583ca95b02SDimitry Andric       .addImm(MI->getOperand(1).getImm())
4593ca95b02SDimitry Andric       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
4603ca95b02SDimitry Andric     }
4613ca95b02SDimitry Andric     break;
4623ca95b02SDimitry Andric 
4634ba319b5SDimitry Andric   case TargetOpcode::STACKMAP:
4644ba319b5SDimitry Andric     LowerSTACKMAP(*MI);
4654ba319b5SDimitry Andric     return;
4664ba319b5SDimitry Andric 
4674ba319b5SDimitry Andric   case TargetOpcode::PATCHPOINT:
4684ba319b5SDimitry Andric     LowerPATCHPOINT(*MI, Lower);
4694ba319b5SDimitry Andric     return;
4704ba319b5SDimitry Andric 
471f785676fSDimitry Andric   default:
472284c1978SDimitry Andric     Lower.lower(MI, LoweredMI);
473f785676fSDimitry Andric     break;
474f785676fSDimitry Andric   }
475ff0cc061SDimitry Andric   EmitToStreamer(*OutStreamer, LoweredMI);
476284c1978SDimitry Andric }
477284c1978SDimitry Andric 
4784ba319b5SDimitry Andric 
4794ba319b5SDimitry Andric // Emit the largest nop instruction smaller than or equal to NumBytes
4804ba319b5SDimitry Andric // bytes.  Return the size of nop emitted.
EmitNop(MCContext & OutContext,MCStreamer & OutStreamer,unsigned NumBytes,const MCSubtargetInfo & STI)4814ba319b5SDimitry Andric static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
4824ba319b5SDimitry Andric                         unsigned NumBytes, const MCSubtargetInfo &STI) {
4834ba319b5SDimitry Andric   if (NumBytes < 2) {
4844ba319b5SDimitry Andric     llvm_unreachable("Zero nops?");
4854ba319b5SDimitry Andric     return 0;
4864ba319b5SDimitry Andric   }
4874ba319b5SDimitry Andric   else if (NumBytes < 4) {
4884ba319b5SDimitry Andric     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm)
4894ba319b5SDimitry Andric                                   .addImm(0).addReg(SystemZ::R0D), STI);
4904ba319b5SDimitry Andric     return 2;
4914ba319b5SDimitry Andric   }
4924ba319b5SDimitry Andric   else if (NumBytes < 6) {
4934ba319b5SDimitry Andric     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm)
4944ba319b5SDimitry Andric                                   .addImm(0).addReg(0).addImm(0).addReg(0),
4954ba319b5SDimitry Andric                                 STI);
4964ba319b5SDimitry Andric     return 4;
4974ba319b5SDimitry Andric   }
4984ba319b5SDimitry Andric   else {
4994ba319b5SDimitry Andric     MCSymbol *DotSym = OutContext.createTempSymbol();
5004ba319b5SDimitry Andric     const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
5014ba319b5SDimitry Andric     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm)
5024ba319b5SDimitry Andric                                   .addImm(0).addExpr(Dot), STI);
5034ba319b5SDimitry Andric     OutStreamer.EmitLabel(DotSym);
5044ba319b5SDimitry Andric     return 6;
5054ba319b5SDimitry Andric   }
5064ba319b5SDimitry Andric }
5074ba319b5SDimitry Andric 
LowerSTACKMAP(const MachineInstr & MI)5084ba319b5SDimitry Andric void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
5094ba319b5SDimitry Andric   const SystemZInstrInfo *TII =
5104ba319b5SDimitry Andric     static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
5114ba319b5SDimitry Andric 
5124ba319b5SDimitry Andric   unsigned NumNOPBytes = MI.getOperand(1).getImm();
5134ba319b5SDimitry Andric 
5144ba319b5SDimitry Andric   SM.recordStackMap(MI);
5154ba319b5SDimitry Andric   assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
5164ba319b5SDimitry Andric 
5174ba319b5SDimitry Andric   // Scan ahead to trim the shadow.
5184ba319b5SDimitry Andric   unsigned ShadowBytes = 0;
5194ba319b5SDimitry Andric   const MachineBasicBlock &MBB = *MI.getParent();
5204ba319b5SDimitry Andric   MachineBasicBlock::const_iterator MII(MI);
5214ba319b5SDimitry Andric   ++MII;
5224ba319b5SDimitry Andric   while (ShadowBytes < NumNOPBytes) {
5234ba319b5SDimitry Andric     if (MII == MBB.end() ||
5244ba319b5SDimitry Andric         MII->getOpcode() == TargetOpcode::PATCHPOINT ||
5254ba319b5SDimitry Andric         MII->getOpcode() == TargetOpcode::STACKMAP)
5264ba319b5SDimitry Andric       break;
5274ba319b5SDimitry Andric     ShadowBytes += TII->getInstSizeInBytes(*MII);
5284ba319b5SDimitry Andric     if (MII->isCall())
5294ba319b5SDimitry Andric       break;
5304ba319b5SDimitry Andric     ++MII;
5314ba319b5SDimitry Andric   }
5324ba319b5SDimitry Andric 
5334ba319b5SDimitry Andric   // Emit nops.
5344ba319b5SDimitry Andric   while (ShadowBytes < NumNOPBytes)
5354ba319b5SDimitry Andric     ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
5364ba319b5SDimitry Andric                            getSubtargetInfo());
5374ba319b5SDimitry Andric }
5384ba319b5SDimitry Andric 
5394ba319b5SDimitry Andric // Lower a patchpoint of the form:
5404ba319b5SDimitry Andric // [<def>], <id>, <numBytes>, <target>, <numArgs>
LowerPATCHPOINT(const MachineInstr & MI,SystemZMCInstLower & Lower)5414ba319b5SDimitry Andric void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
5424ba319b5SDimitry Andric                                         SystemZMCInstLower &Lower) {
5434ba319b5SDimitry Andric   SM.recordPatchPoint(MI);
5444ba319b5SDimitry Andric   PatchPointOpers Opers(&MI);
5454ba319b5SDimitry Andric 
5464ba319b5SDimitry Andric   unsigned EncodedBytes = 0;
5474ba319b5SDimitry Andric   const MachineOperand &CalleeMO = Opers.getCallTarget();
5484ba319b5SDimitry Andric 
5494ba319b5SDimitry Andric   if (CalleeMO.isImm()) {
5504ba319b5SDimitry Andric     uint64_t CallTarget = CalleeMO.getImm();
5514ba319b5SDimitry Andric     if (CallTarget) {
5524ba319b5SDimitry Andric       unsigned ScratchIdx = -1;
5534ba319b5SDimitry Andric       unsigned ScratchReg = 0;
5544ba319b5SDimitry Andric       do {
5554ba319b5SDimitry Andric         ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
5564ba319b5SDimitry Andric         ScratchReg = MI.getOperand(ScratchIdx).getReg();
5574ba319b5SDimitry Andric       } while (ScratchReg == SystemZ::R0D);
5584ba319b5SDimitry Andric 
5594ba319b5SDimitry Andric       // Materialize the call target address
5604ba319b5SDimitry Andric       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
5614ba319b5SDimitry Andric                                       .addReg(ScratchReg)
5624ba319b5SDimitry Andric                                       .addImm(CallTarget & 0xFFFFFFFF));
5634ba319b5SDimitry Andric       EncodedBytes += 6;
5644ba319b5SDimitry Andric       if (CallTarget >> 32) {
5654ba319b5SDimitry Andric         EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
5664ba319b5SDimitry Andric                                         .addReg(ScratchReg)
5674ba319b5SDimitry Andric                                         .addImm(CallTarget >> 32));
5684ba319b5SDimitry Andric         EncodedBytes += 6;
5694ba319b5SDimitry Andric       }
5704ba319b5SDimitry Andric 
5714ba319b5SDimitry Andric       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
5724ba319b5SDimitry Andric                                      .addReg(SystemZ::R14D)
5734ba319b5SDimitry Andric                                      .addReg(ScratchReg));
5744ba319b5SDimitry Andric       EncodedBytes += 2;
5754ba319b5SDimitry Andric     }
5764ba319b5SDimitry Andric   } else if (CalleeMO.isGlobal()) {
5774ba319b5SDimitry Andric     const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
5784ba319b5SDimitry Andric     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
5794ba319b5SDimitry Andric                                    .addReg(SystemZ::R14D)
5804ba319b5SDimitry Andric                                    .addExpr(Expr));
5814ba319b5SDimitry Andric     EncodedBytes += 6;
5824ba319b5SDimitry Andric   }
5834ba319b5SDimitry Andric 
5844ba319b5SDimitry Andric   // Emit padding.
5854ba319b5SDimitry Andric   unsigned NumBytes = Opers.getNumPatchBytes();
5864ba319b5SDimitry Andric   assert(NumBytes >= EncodedBytes &&
5874ba319b5SDimitry Andric          "Patchpoint can't request size less than the length of a call.");
5884ba319b5SDimitry Andric   assert((NumBytes - EncodedBytes) % 2 == 0 &&
5894ba319b5SDimitry Andric          "Invalid number of NOP bytes requested!");
5904ba319b5SDimitry Andric   while (EncodedBytes < NumBytes)
5914ba319b5SDimitry Andric     EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
5924ba319b5SDimitry Andric                             getSubtargetInfo());
5934ba319b5SDimitry Andric }
5944ba319b5SDimitry Andric 
595284c1978SDimitry Andric // Convert a SystemZ-specific constant pool modifier into the associated
596284c1978SDimitry Andric // MCSymbolRefExpr variant kind.
597284c1978SDimitry Andric static MCSymbolRefExpr::VariantKind
getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier)598284c1978SDimitry Andric getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
599284c1978SDimitry Andric   switch (Modifier) {
600ff0cc061SDimitry Andric   case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
601ff0cc061SDimitry Andric   case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
602ff0cc061SDimitry Andric   case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
603284c1978SDimitry Andric   case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
604284c1978SDimitry Andric   }
605284c1978SDimitry Andric   llvm_unreachable("Invalid SystemCPModifier!");
606284c1978SDimitry Andric }
607284c1978SDimitry Andric 
608284c1978SDimitry Andric void SystemZAsmPrinter::
EmitMachineConstantPoolValue(MachineConstantPoolValue * MCPV)609284c1978SDimitry Andric EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
61091bc56edSDimitry Andric   auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
611284c1978SDimitry Andric 
612284c1978SDimitry Andric   const MCExpr *Expr =
61397bc6c73SDimitry Andric     MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
614284c1978SDimitry Andric                             getModifierVariantKind(ZCPV->getModifier()),
615284c1978SDimitry Andric                             OutContext);
6167d523365SDimitry Andric   uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
617284c1978SDimitry Andric 
618ff0cc061SDimitry Andric   OutStreamer->EmitValue(Expr, Size);
619284c1978SDimitry Andric }
620284c1978SDimitry Andric 
PrintAsmOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & OS)621284c1978SDimitry Andric bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
622284c1978SDimitry Andric                                         unsigned OpNo,
623284c1978SDimitry Andric                                         unsigned AsmVariant,
624284c1978SDimitry Andric                                         const char *ExtraCode,
625284c1978SDimitry Andric                                         raw_ostream &OS) {
626284c1978SDimitry Andric   if (ExtraCode && *ExtraCode == 'n') {
627284c1978SDimitry Andric     if (!MI->getOperand(OpNo).isImm())
628284c1978SDimitry Andric       return true;
629284c1978SDimitry Andric     OS << -int64_t(MI->getOperand(OpNo).getImm());
630284c1978SDimitry Andric   } else {
631f785676fSDimitry Andric     SystemZMCInstLower Lower(MF->getContext(), *this);
632284c1978SDimitry Andric     MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
63397bc6c73SDimitry Andric     SystemZInstPrinter::printOperand(MO, MAI, OS);
634284c1978SDimitry Andric   }
635284c1978SDimitry Andric   return false;
636284c1978SDimitry Andric }
637284c1978SDimitry Andric 
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & OS)638284c1978SDimitry Andric bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
639284c1978SDimitry Andric                                               unsigned OpNo,
640284c1978SDimitry Andric                                               unsigned AsmVariant,
641284c1978SDimitry Andric                                               const char *ExtraCode,
642284c1978SDimitry Andric                                               raw_ostream &OS) {
643284c1978SDimitry Andric   SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
644284c1978SDimitry Andric                                    MI->getOperand(OpNo + 1).getImm(),
645284c1978SDimitry Andric                                    MI->getOperand(OpNo + 2).getReg(), OS);
646284c1978SDimitry Andric   return false;
647284c1978SDimitry Andric }
648284c1978SDimitry Andric 
EmitEndOfAsmFile(Module & M)6494ba319b5SDimitry Andric void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
650*b5893f02SDimitry Andric   emitStackMaps(SM);
6514ba319b5SDimitry Andric }
6524ba319b5SDimitry Andric 
653284c1978SDimitry Andric // Force static initialization.
LLVMInitializeSystemZAsmPrinter()654284c1978SDimitry Andric extern "C" void LLVMInitializeSystemZAsmPrinter() {
655d88c1a5aSDimitry Andric   RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
656284c1978SDimitry Andric }
657