1*9880d681SAndroid Build Coastguard Worker //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Streams SystemZ assembly language and associated data, in the form of
11*9880d681SAndroid Build Coastguard Worker // MCInsts and MCExprs respectively.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "SystemZAsmPrinter.h"
16*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/SystemZInstPrinter.h"
17*9880d681SAndroid Build Coastguard Worker #include "SystemZConstantPoolValue.h"
18*9880d681SAndroid Build Coastguard Worker #include "SystemZMCInstLower.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstBuilder.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker using namespace llvm;
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker // Return an RI instruction like MI with opcode Opcode, but with the
30*9880d681SAndroid Build Coastguard Worker // GR64 register operands turned into GR32s.
lowerRILow(const MachineInstr * MI,unsigned Opcode)31*9880d681SAndroid Build Coastguard Worker static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
32*9880d681SAndroid Build Coastguard Worker if (MI->isCompare())
33*9880d681SAndroid Build Coastguard Worker return MCInstBuilder(Opcode)
34*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
35*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm());
36*9880d681SAndroid Build Coastguard Worker else
37*9880d681SAndroid Build Coastguard Worker return MCInstBuilder(Opcode)
38*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
40*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm());
41*9880d681SAndroid Build Coastguard Worker }
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker // Return an RI instruction like MI with opcode Opcode, but with the
44*9880d681SAndroid Build Coastguard Worker // GR64 register operands turned into GRH32s.
lowerRIHigh(const MachineInstr * MI,unsigned Opcode)45*9880d681SAndroid Build Coastguard Worker static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
46*9880d681SAndroid Build Coastguard Worker if (MI->isCompare())
47*9880d681SAndroid Build Coastguard Worker return MCInstBuilder(Opcode)
48*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
49*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm());
50*9880d681SAndroid Build Coastguard Worker else
51*9880d681SAndroid Build Coastguard Worker return MCInstBuilder(Opcode)
52*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
53*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
54*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm());
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker // Return an RI instruction like MI with opcode Opcode, but with the
58*9880d681SAndroid Build Coastguard Worker // R2 register turned into a GR64.
lowerRIEfLow(const MachineInstr * MI,unsigned Opcode)59*9880d681SAndroid Build Coastguard Worker static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
60*9880d681SAndroid Build Coastguard Worker return MCInstBuilder(Opcode)
61*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
62*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
63*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
64*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(3).getImm())
65*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(4).getImm())
66*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(5).getImm());
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker
getTLSGetOffset(MCContext & Context)69*9880d681SAndroid Build Coastguard Worker static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
70*9880d681SAndroid Build Coastguard Worker StringRef Name = "__tls_get_offset";
71*9880d681SAndroid Build Coastguard Worker return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
72*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::VK_PLT,
73*9880d681SAndroid Build Coastguard Worker Context);
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker
getGlobalOffsetTable(MCContext & Context)76*9880d681SAndroid Build Coastguard Worker static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
77*9880d681SAndroid Build Coastguard Worker StringRef Name = "_GLOBAL_OFFSET_TABLE_";
78*9880d681SAndroid Build Coastguard Worker return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
79*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::VK_None,
80*9880d681SAndroid Build Coastguard Worker Context);
81*9880d681SAndroid Build Coastguard Worker }
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker // MI loads the high part of a vector from memory. Return an instruction
84*9880d681SAndroid Build Coastguard Worker // that uses replicating vector load Opcode to do the same thing.
lowerSubvectorLoad(const MachineInstr * MI,unsigned Opcode)85*9880d681SAndroid Build Coastguard Worker static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
86*9880d681SAndroid Build Coastguard Worker return MCInstBuilder(Opcode)
87*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
88*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
89*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
90*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(3).getReg());
91*9880d681SAndroid Build Coastguard Worker }
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker // MI stores the high part of a vector to memory. Return an instruction
94*9880d681SAndroid Build Coastguard Worker // that uses elemental vector store Opcode to do the same thing.
lowerSubvectorStore(const MachineInstr * MI,unsigned Opcode)95*9880d681SAndroid Build Coastguard Worker static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
96*9880d681SAndroid Build Coastguard Worker return MCInstBuilder(Opcode)
97*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
98*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
99*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
100*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(3).getReg())
101*9880d681SAndroid Build Coastguard Worker .addImm(0);
102*9880d681SAndroid Build Coastguard Worker }
103*9880d681SAndroid Build Coastguard Worker
EmitInstruction(const MachineInstr * MI)104*9880d681SAndroid Build Coastguard Worker void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
105*9880d681SAndroid Build Coastguard Worker SystemZMCInstLower Lower(MF->getContext(), *this);
106*9880d681SAndroid Build Coastguard Worker MCInst LoweredMI;
107*9880d681SAndroid Build Coastguard Worker switch (MI->getOpcode()) {
108*9880d681SAndroid Build Coastguard Worker case SystemZ::Return:
109*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
110*9880d681SAndroid Build Coastguard Worker break;
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker case SystemZ::CondReturn:
113*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BCR)
114*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(0).getImm())
115*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
116*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D);
117*9880d681SAndroid Build Coastguard Worker break;
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker case SystemZ::CRBReturn:
120*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CRB)
121*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
122*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
123*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
124*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
125*9880d681SAndroid Build Coastguard Worker .addImm(0);
126*9880d681SAndroid Build Coastguard Worker break;
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker case SystemZ::CGRBReturn:
129*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CGRB)
130*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
131*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
132*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
133*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
134*9880d681SAndroid Build Coastguard Worker .addImm(0);
135*9880d681SAndroid Build Coastguard Worker break;
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker case SystemZ::CIBReturn:
138*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CIB)
139*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
140*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
141*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
142*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
143*9880d681SAndroid Build Coastguard Worker .addImm(0);
144*9880d681SAndroid Build Coastguard Worker break;
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker case SystemZ::CGIBReturn:
147*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CGIB)
148*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
149*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
150*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
151*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
152*9880d681SAndroid Build Coastguard Worker .addImm(0);
153*9880d681SAndroid Build Coastguard Worker break;
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker case SystemZ::CLRBReturn:
156*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CLRB)
157*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
158*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
159*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
160*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
161*9880d681SAndroid Build Coastguard Worker .addImm(0);
162*9880d681SAndroid Build Coastguard Worker break;
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker case SystemZ::CLGRBReturn:
165*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CLGRB)
166*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
167*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
168*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
169*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
170*9880d681SAndroid Build Coastguard Worker .addImm(0);
171*9880d681SAndroid Build Coastguard Worker break;
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker case SystemZ::CLIBReturn:
174*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CLIB)
175*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
176*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
177*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
178*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
179*9880d681SAndroid Build Coastguard Worker .addImm(0);
180*9880d681SAndroid Build Coastguard Worker break;
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker case SystemZ::CLGIBReturn:
183*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CLGIB)
184*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
185*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
186*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
187*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
188*9880d681SAndroid Build Coastguard Worker .addImm(0);
189*9880d681SAndroid Build Coastguard Worker break;
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker case SystemZ::CallBRASL:
192*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BRASL)
193*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
194*9880d681SAndroid Build Coastguard Worker .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
195*9880d681SAndroid Build Coastguard Worker break;
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker case SystemZ::CallBASR:
198*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BASR)
199*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
200*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg());
201*9880d681SAndroid Build Coastguard Worker break;
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker case SystemZ::CallJG:
204*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::JG)
205*9880d681SAndroid Build Coastguard Worker .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
206*9880d681SAndroid Build Coastguard Worker break;
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker case SystemZ::CallBRCL:
209*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BRCL)
210*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(0).getImm())
211*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
212*9880d681SAndroid Build Coastguard Worker .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
213*9880d681SAndroid Build Coastguard Worker break;
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker case SystemZ::CallBR:
216*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
217*9880d681SAndroid Build Coastguard Worker break;
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker case SystemZ::CallBCR:
220*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BCR)
221*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(0).getImm())
222*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
223*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D);
224*9880d681SAndroid Build Coastguard Worker break;
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Worker case SystemZ::CRBCall:
227*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CRB)
228*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
229*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
230*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
231*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D)
232*9880d681SAndroid Build Coastguard Worker .addImm(0);
233*9880d681SAndroid Build Coastguard Worker break;
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker case SystemZ::CGRBCall:
236*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CGRB)
237*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
238*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
239*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
240*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D)
241*9880d681SAndroid Build Coastguard Worker .addImm(0);
242*9880d681SAndroid Build Coastguard Worker break;
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker case SystemZ::CIBCall:
245*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CIB)
246*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
247*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
248*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
249*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D)
250*9880d681SAndroid Build Coastguard Worker .addImm(0);
251*9880d681SAndroid Build Coastguard Worker break;
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard Worker case SystemZ::CGIBCall:
254*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CGIB)
255*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
256*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
257*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
258*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D)
259*9880d681SAndroid Build Coastguard Worker .addImm(0);
260*9880d681SAndroid Build Coastguard Worker break;
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker case SystemZ::CLRBCall:
263*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CLRB)
264*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
265*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
266*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
267*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D)
268*9880d681SAndroid Build Coastguard Worker .addImm(0);
269*9880d681SAndroid Build Coastguard Worker break;
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker case SystemZ::CLGRBCall:
272*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CLGRB)
273*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
274*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
275*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
276*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D)
277*9880d681SAndroid Build Coastguard Worker .addImm(0);
278*9880d681SAndroid Build Coastguard Worker break;
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker case SystemZ::CLIBCall:
281*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CLIB)
282*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
283*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
284*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
285*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D)
286*9880d681SAndroid Build Coastguard Worker .addImm(0);
287*9880d681SAndroid Build Coastguard Worker break;
288*9880d681SAndroid Build Coastguard Worker
289*9880d681SAndroid Build Coastguard Worker case SystemZ::CLGIBCall:
290*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::CLGIB)
291*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
292*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
293*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm())
294*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R1D)
295*9880d681SAndroid Build Coastguard Worker .addImm(0);
296*9880d681SAndroid Build Coastguard Worker break;
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker case SystemZ::TLS_GDCALL:
299*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BRASL)
300*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
301*9880d681SAndroid Build Coastguard Worker .addExpr(getTLSGetOffset(MF->getContext()))
302*9880d681SAndroid Build Coastguard Worker .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
303*9880d681SAndroid Build Coastguard Worker break;
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker case SystemZ::TLS_LDCALL:
306*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BRASL)
307*9880d681SAndroid Build Coastguard Worker .addReg(SystemZ::R14D)
308*9880d681SAndroid Build Coastguard Worker .addExpr(getTLSGetOffset(MF->getContext()))
309*9880d681SAndroid Build Coastguard Worker .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
310*9880d681SAndroid Build Coastguard Worker break;
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Worker case SystemZ::GOT:
313*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::LARL)
314*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
315*9880d681SAndroid Build Coastguard Worker .addExpr(getGlobalOffsetTable(MF->getContext()));
316*9880d681SAndroid Build Coastguard Worker break;
317*9880d681SAndroid Build Coastguard Worker
318*9880d681SAndroid Build Coastguard Worker case SystemZ::IILF64:
319*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::IILF)
320*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
321*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm());
322*9880d681SAndroid Build Coastguard Worker break;
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Worker case SystemZ::IIHF64:
325*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::IIHF)
326*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
327*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(2).getImm());
328*9880d681SAndroid Build Coastguard Worker break;
329*9880d681SAndroid Build Coastguard Worker
330*9880d681SAndroid Build Coastguard Worker case SystemZ::RISBHH:
331*9880d681SAndroid Build Coastguard Worker case SystemZ::RISBHL:
332*9880d681SAndroid Build Coastguard Worker LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
333*9880d681SAndroid Build Coastguard Worker break;
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker case SystemZ::RISBLH:
336*9880d681SAndroid Build Coastguard Worker case SystemZ::RISBLL:
337*9880d681SAndroid Build Coastguard Worker LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
338*9880d681SAndroid Build Coastguard Worker break;
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker case SystemZ::VLVGP32:
341*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::VLVGP)
342*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(0).getReg())
343*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
344*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
345*9880d681SAndroid Build Coastguard Worker break;
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Worker case SystemZ::VLR32:
348*9880d681SAndroid Build Coastguard Worker case SystemZ::VLR64:
349*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::VLR)
350*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
351*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
352*9880d681SAndroid Build Coastguard Worker break;
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker case SystemZ::VL32:
355*9880d681SAndroid Build Coastguard Worker LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
356*9880d681SAndroid Build Coastguard Worker break;
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker case SystemZ::VL64:
359*9880d681SAndroid Build Coastguard Worker LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
360*9880d681SAndroid Build Coastguard Worker break;
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker case SystemZ::VST32:
363*9880d681SAndroid Build Coastguard Worker LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
364*9880d681SAndroid Build Coastguard Worker break;
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker case SystemZ::VST64:
367*9880d681SAndroid Build Coastguard Worker LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
368*9880d681SAndroid Build Coastguard Worker break;
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker case SystemZ::LFER:
371*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::VLGVF)
372*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
373*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
374*9880d681SAndroid Build Coastguard Worker .addReg(0).addImm(0);
375*9880d681SAndroid Build Coastguard Worker break;
376*9880d681SAndroid Build Coastguard Worker
377*9880d681SAndroid Build Coastguard Worker case SystemZ::LEFR:
378*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::VLVGF)
379*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
380*9880d681SAndroid Build Coastguard Worker .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
381*9880d681SAndroid Build Coastguard Worker .addReg(MI->getOperand(1).getReg())
382*9880d681SAndroid Build Coastguard Worker .addReg(0).addImm(0);
383*9880d681SAndroid Build Coastguard Worker break;
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker #define LOWER_LOW(NAME) \
386*9880d681SAndroid Build Coastguard Worker case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
387*9880d681SAndroid Build Coastguard Worker
388*9880d681SAndroid Build Coastguard Worker LOWER_LOW(IILL);
389*9880d681SAndroid Build Coastguard Worker LOWER_LOW(IILH);
390*9880d681SAndroid Build Coastguard Worker LOWER_LOW(TMLL);
391*9880d681SAndroid Build Coastguard Worker LOWER_LOW(TMLH);
392*9880d681SAndroid Build Coastguard Worker LOWER_LOW(NILL);
393*9880d681SAndroid Build Coastguard Worker LOWER_LOW(NILH);
394*9880d681SAndroid Build Coastguard Worker LOWER_LOW(NILF);
395*9880d681SAndroid Build Coastguard Worker LOWER_LOW(OILL);
396*9880d681SAndroid Build Coastguard Worker LOWER_LOW(OILH);
397*9880d681SAndroid Build Coastguard Worker LOWER_LOW(OILF);
398*9880d681SAndroid Build Coastguard Worker LOWER_LOW(XILF);
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker #undef LOWER_LOW
401*9880d681SAndroid Build Coastguard Worker
402*9880d681SAndroid Build Coastguard Worker #define LOWER_HIGH(NAME) \
403*9880d681SAndroid Build Coastguard Worker case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
404*9880d681SAndroid Build Coastguard Worker
405*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(IIHL);
406*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(IIHH);
407*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(TMHL);
408*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(TMHH);
409*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(NIHL);
410*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(NIHH);
411*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(NIHF);
412*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(OIHL);
413*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(OIHH);
414*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(OIHF);
415*9880d681SAndroid Build Coastguard Worker LOWER_HIGH(XIHF);
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Worker #undef LOWER_HIGH
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker case SystemZ::Serialize:
420*9880d681SAndroid Build Coastguard Worker if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
421*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
422*9880d681SAndroid Build Coastguard Worker .addImm(14).addReg(SystemZ::R0D);
423*9880d681SAndroid Build Coastguard Worker else
424*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
425*9880d681SAndroid Build Coastguard Worker .addImm(15).addReg(SystemZ::R0D);
426*9880d681SAndroid Build Coastguard Worker break;
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Worker // Emit nothing here but a comment if we can.
429*9880d681SAndroid Build Coastguard Worker case SystemZ::MemBarrier:
430*9880d681SAndroid Build Coastguard Worker OutStreamer->emitRawComment("MEMBARRIER");
431*9880d681SAndroid Build Coastguard Worker return;
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker // We want to emit "j .+2" for traps, jumping to the relative immediate field
434*9880d681SAndroid Build Coastguard Worker // of the jump instruction, which is an illegal instruction. We cannot emit a
435*9880d681SAndroid Build Coastguard Worker // "." symbol, so create and emit a temp label before the instruction and use
436*9880d681SAndroid Build Coastguard Worker // that instead.
437*9880d681SAndroid Build Coastguard Worker case SystemZ::Trap: {
438*9880d681SAndroid Build Coastguard Worker MCSymbol *DotSym = OutContext.createTempSymbol();
439*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitLabel(DotSym);
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
442*9880d681SAndroid Build Coastguard Worker const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
443*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::J)
444*9880d681SAndroid Build Coastguard Worker .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker break;
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker // Conditional traps will create a branch on condition instruction that jumps
449*9880d681SAndroid Build Coastguard Worker // to the relative immediate field of the jump instruction. (eg. "jo .+2")
450*9880d681SAndroid Build Coastguard Worker case SystemZ::CondTrap: {
451*9880d681SAndroid Build Coastguard Worker MCSymbol *DotSym = OutContext.createTempSymbol();
452*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitLabel(DotSym);
453*9880d681SAndroid Build Coastguard Worker
454*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
455*9880d681SAndroid Build Coastguard Worker const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
456*9880d681SAndroid Build Coastguard Worker LoweredMI = MCInstBuilder(SystemZ::BRC)
457*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(0).getImm())
458*9880d681SAndroid Build Coastguard Worker .addImm(MI->getOperand(1).getImm())
459*9880d681SAndroid Build Coastguard Worker .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
460*9880d681SAndroid Build Coastguard Worker }
461*9880d681SAndroid Build Coastguard Worker break;
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Worker default:
464*9880d681SAndroid Build Coastguard Worker Lower.lower(MI, LoweredMI);
465*9880d681SAndroid Build Coastguard Worker break;
466*9880d681SAndroid Build Coastguard Worker }
467*9880d681SAndroid Build Coastguard Worker EmitToStreamer(*OutStreamer, LoweredMI);
468*9880d681SAndroid Build Coastguard Worker }
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard Worker // Convert a SystemZ-specific constant pool modifier into the associated
471*9880d681SAndroid Build Coastguard Worker // MCSymbolRefExpr variant kind.
472*9880d681SAndroid Build Coastguard Worker static MCSymbolRefExpr::VariantKind
getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier)473*9880d681SAndroid Build Coastguard Worker getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
474*9880d681SAndroid Build Coastguard Worker switch (Modifier) {
475*9880d681SAndroid Build Coastguard Worker case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
476*9880d681SAndroid Build Coastguard Worker case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
477*9880d681SAndroid Build Coastguard Worker case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
478*9880d681SAndroid Build Coastguard Worker case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
479*9880d681SAndroid Build Coastguard Worker }
480*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid SystemCPModifier!");
481*9880d681SAndroid Build Coastguard Worker }
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Worker void SystemZAsmPrinter::
EmitMachineConstantPoolValue(MachineConstantPoolValue * MCPV)484*9880d681SAndroid Build Coastguard Worker EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
485*9880d681SAndroid Build Coastguard Worker auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr =
488*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
489*9880d681SAndroid Build Coastguard Worker getModifierVariantKind(ZCPV->getModifier()),
490*9880d681SAndroid Build Coastguard Worker OutContext);
491*9880d681SAndroid Build Coastguard Worker uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
492*9880d681SAndroid Build Coastguard Worker
493*9880d681SAndroid Build Coastguard Worker OutStreamer->EmitValue(Expr, Size);
494*9880d681SAndroid Build Coastguard Worker }
495*9880d681SAndroid Build Coastguard Worker
PrintAsmOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & OS)496*9880d681SAndroid Build Coastguard Worker bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
497*9880d681SAndroid Build Coastguard Worker unsigned OpNo,
498*9880d681SAndroid Build Coastguard Worker unsigned AsmVariant,
499*9880d681SAndroid Build Coastguard Worker const char *ExtraCode,
500*9880d681SAndroid Build Coastguard Worker raw_ostream &OS) {
501*9880d681SAndroid Build Coastguard Worker if (ExtraCode && *ExtraCode == 'n') {
502*9880d681SAndroid Build Coastguard Worker if (!MI->getOperand(OpNo).isImm())
503*9880d681SAndroid Build Coastguard Worker return true;
504*9880d681SAndroid Build Coastguard Worker OS << -int64_t(MI->getOperand(OpNo).getImm());
505*9880d681SAndroid Build Coastguard Worker } else {
506*9880d681SAndroid Build Coastguard Worker SystemZMCInstLower Lower(MF->getContext(), *this);
507*9880d681SAndroid Build Coastguard Worker MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
508*9880d681SAndroid Build Coastguard Worker SystemZInstPrinter::printOperand(MO, MAI, OS);
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker return false;
511*9880d681SAndroid Build Coastguard Worker }
512*9880d681SAndroid Build Coastguard Worker
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & OS)513*9880d681SAndroid Build Coastguard Worker bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
514*9880d681SAndroid Build Coastguard Worker unsigned OpNo,
515*9880d681SAndroid Build Coastguard Worker unsigned AsmVariant,
516*9880d681SAndroid Build Coastguard Worker const char *ExtraCode,
517*9880d681SAndroid Build Coastguard Worker raw_ostream &OS) {
518*9880d681SAndroid Build Coastguard Worker SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
519*9880d681SAndroid Build Coastguard Worker MI->getOperand(OpNo + 1).getImm(),
520*9880d681SAndroid Build Coastguard Worker MI->getOperand(OpNo + 2).getReg(), OS);
521*9880d681SAndroid Build Coastguard Worker return false;
522*9880d681SAndroid Build Coastguard Worker }
523*9880d681SAndroid Build Coastguard Worker
524*9880d681SAndroid Build Coastguard Worker // Force static initialization.
LLVMInitializeSystemZAsmPrinter()525*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeSystemZAsmPrinter() {
526*9880d681SAndroid Build Coastguard Worker RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
527*9880d681SAndroid Build Coastguard Worker }
528