xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // Streams SystemZ assembly language and associated data, in the form of
10*0b57cec5SDimitry Andric // MCInsts and MCExprs respectively.
11*0b57cec5SDimitry Andric //
12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13*0b57cec5SDimitry Andric 
14*0b57cec5SDimitry Andric #include "SystemZAsmPrinter.h"
15*0b57cec5SDimitry Andric #include "MCTargetDesc/SystemZInstPrinter.h"
16*0b57cec5SDimitry Andric #include "SystemZConstantPoolValue.h"
17*0b57cec5SDimitry Andric #include "SystemZMCInstLower.h"
18*0b57cec5SDimitry Andric #include "TargetInfo/SystemZTargetInfo.h"
19*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
21*0b57cec5SDimitry Andric #include "llvm/IR/Mangler.h"
22*0b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
23*0b57cec5SDimitry Andric #include "llvm/MC/MCInstBuilder.h"
24*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
25*0b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h"
26*0b57cec5SDimitry Andric 
27*0b57cec5SDimitry Andric using namespace llvm;
28*0b57cec5SDimitry Andric 
29*0b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
30*0b57cec5SDimitry Andric // GR64 register operands turned into GR32s.
31*0b57cec5SDimitry Andric static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
32*0b57cec5SDimitry Andric   if (MI->isCompare())
33*0b57cec5SDimitry Andric     return MCInstBuilder(Opcode)
34*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
35*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm());
36*0b57cec5SDimitry Andric   else
37*0b57cec5SDimitry Andric     return MCInstBuilder(Opcode)
38*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
40*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm());
41*0b57cec5SDimitry Andric }
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
44*0b57cec5SDimitry Andric // GR64 register operands turned into GRH32s.
45*0b57cec5SDimitry Andric static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
46*0b57cec5SDimitry Andric   if (MI->isCompare())
47*0b57cec5SDimitry Andric     return MCInstBuilder(Opcode)
48*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
49*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm());
50*0b57cec5SDimitry Andric   else
51*0b57cec5SDimitry Andric     return MCInstBuilder(Opcode)
52*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
53*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
54*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm());
55*0b57cec5SDimitry Andric }
56*0b57cec5SDimitry Andric 
57*0b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
58*0b57cec5SDimitry Andric // R2 register turned into a GR64.
59*0b57cec5SDimitry Andric static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
60*0b57cec5SDimitry Andric   return MCInstBuilder(Opcode)
61*0b57cec5SDimitry Andric     .addReg(MI->getOperand(0).getReg())
62*0b57cec5SDimitry Andric     .addReg(MI->getOperand(1).getReg())
63*0b57cec5SDimitry Andric     .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
64*0b57cec5SDimitry Andric     .addImm(MI->getOperand(3).getImm())
65*0b57cec5SDimitry Andric     .addImm(MI->getOperand(4).getImm())
66*0b57cec5SDimitry Andric     .addImm(MI->getOperand(5).getImm());
67*0b57cec5SDimitry Andric }
68*0b57cec5SDimitry Andric 
69*0b57cec5SDimitry Andric static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
70*0b57cec5SDimitry Andric   StringRef Name = "__tls_get_offset";
71*0b57cec5SDimitry Andric   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
72*0b57cec5SDimitry Andric                                  MCSymbolRefExpr::VK_PLT,
73*0b57cec5SDimitry Andric                                  Context);
74*0b57cec5SDimitry Andric }
75*0b57cec5SDimitry Andric 
76*0b57cec5SDimitry Andric static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
77*0b57cec5SDimitry Andric   StringRef Name = "_GLOBAL_OFFSET_TABLE_";
78*0b57cec5SDimitry Andric   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
79*0b57cec5SDimitry Andric                                  MCSymbolRefExpr::VK_None,
80*0b57cec5SDimitry Andric                                  Context);
81*0b57cec5SDimitry Andric }
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric // MI is an instruction that accepts an optional alignment hint,
84*0b57cec5SDimitry Andric // and which was already lowered to LoweredMI.  If the alignment
85*0b57cec5SDimitry Andric // of the original memory operand is known, update LoweredMI to
86*0b57cec5SDimitry Andric // an instruction with the corresponding hint set.
87*0b57cec5SDimitry Andric static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI,
88*0b57cec5SDimitry Andric                                unsigned Opcode) {
89*0b57cec5SDimitry Andric   if (!MI->hasOneMemOperand())
90*0b57cec5SDimitry Andric     return;
91*0b57cec5SDimitry Andric   const MachineMemOperand *MMO = *MI->memoperands_begin();
92*0b57cec5SDimitry Andric   unsigned AlignmentHint = 0;
93*0b57cec5SDimitry Andric   if (MMO->getAlignment() >= 16)
94*0b57cec5SDimitry Andric     AlignmentHint = 4;
95*0b57cec5SDimitry Andric   else if (MMO->getAlignment() >= 8)
96*0b57cec5SDimitry Andric     AlignmentHint = 3;
97*0b57cec5SDimitry Andric   if (AlignmentHint == 0)
98*0b57cec5SDimitry Andric     return;
99*0b57cec5SDimitry Andric 
100*0b57cec5SDimitry Andric   LoweredMI.setOpcode(Opcode);
101*0b57cec5SDimitry Andric   LoweredMI.addOperand(MCOperand::createImm(AlignmentHint));
102*0b57cec5SDimitry Andric }
103*0b57cec5SDimitry Andric 
104*0b57cec5SDimitry Andric // MI loads the high part of a vector from memory.  Return an instruction
105*0b57cec5SDimitry Andric // that uses replicating vector load Opcode to do the same thing.
106*0b57cec5SDimitry Andric static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
107*0b57cec5SDimitry Andric   return MCInstBuilder(Opcode)
108*0b57cec5SDimitry Andric     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
109*0b57cec5SDimitry Andric     .addReg(MI->getOperand(1).getReg())
110*0b57cec5SDimitry Andric     .addImm(MI->getOperand(2).getImm())
111*0b57cec5SDimitry Andric     .addReg(MI->getOperand(3).getReg());
112*0b57cec5SDimitry Andric }
113*0b57cec5SDimitry Andric 
114*0b57cec5SDimitry Andric // MI stores the high part of a vector to memory.  Return an instruction
115*0b57cec5SDimitry Andric // that uses elemental vector store Opcode to do the same thing.
116*0b57cec5SDimitry Andric static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
117*0b57cec5SDimitry Andric   return MCInstBuilder(Opcode)
118*0b57cec5SDimitry Andric     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
119*0b57cec5SDimitry Andric     .addReg(MI->getOperand(1).getReg())
120*0b57cec5SDimitry Andric     .addImm(MI->getOperand(2).getImm())
121*0b57cec5SDimitry Andric     .addReg(MI->getOperand(3).getReg())
122*0b57cec5SDimitry Andric     .addImm(0);
123*0b57cec5SDimitry Andric }
124*0b57cec5SDimitry Andric 
125*0b57cec5SDimitry Andric void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
126*0b57cec5SDimitry Andric   SystemZMCInstLower Lower(MF->getContext(), *this);
127*0b57cec5SDimitry Andric   MCInst LoweredMI;
128*0b57cec5SDimitry Andric   switch (MI->getOpcode()) {
129*0b57cec5SDimitry Andric   case SystemZ::Return:
130*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
131*0b57cec5SDimitry Andric     break;
132*0b57cec5SDimitry Andric 
133*0b57cec5SDimitry Andric   case SystemZ::CondReturn:
134*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BCR)
135*0b57cec5SDimitry Andric       .addImm(MI->getOperand(0).getImm())
136*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
137*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D);
138*0b57cec5SDimitry Andric     break;
139*0b57cec5SDimitry Andric 
140*0b57cec5SDimitry Andric   case SystemZ::CRBReturn:
141*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CRB)
142*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
143*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
144*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
145*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
146*0b57cec5SDimitry Andric       .addImm(0);
147*0b57cec5SDimitry Andric     break;
148*0b57cec5SDimitry Andric 
149*0b57cec5SDimitry Andric   case SystemZ::CGRBReturn:
150*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CGRB)
151*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
152*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
153*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
154*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
155*0b57cec5SDimitry Andric       .addImm(0);
156*0b57cec5SDimitry Andric     break;
157*0b57cec5SDimitry Andric 
158*0b57cec5SDimitry Andric   case SystemZ::CIBReturn:
159*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CIB)
160*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
161*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
162*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
163*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
164*0b57cec5SDimitry Andric       .addImm(0);
165*0b57cec5SDimitry Andric     break;
166*0b57cec5SDimitry Andric 
167*0b57cec5SDimitry Andric   case SystemZ::CGIBReturn:
168*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CGIB)
169*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
170*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
171*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
172*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
173*0b57cec5SDimitry Andric       .addImm(0);
174*0b57cec5SDimitry Andric     break;
175*0b57cec5SDimitry Andric 
176*0b57cec5SDimitry Andric   case SystemZ::CLRBReturn:
177*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLRB)
178*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
179*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
180*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
181*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
182*0b57cec5SDimitry Andric       .addImm(0);
183*0b57cec5SDimitry Andric     break;
184*0b57cec5SDimitry Andric 
185*0b57cec5SDimitry Andric   case SystemZ::CLGRBReturn:
186*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
187*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
188*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
189*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
190*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
191*0b57cec5SDimitry Andric       .addImm(0);
192*0b57cec5SDimitry Andric     break;
193*0b57cec5SDimitry Andric 
194*0b57cec5SDimitry Andric   case SystemZ::CLIBReturn:
195*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLIB)
196*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
197*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
198*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
199*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
200*0b57cec5SDimitry Andric       .addImm(0);
201*0b57cec5SDimitry Andric     break;
202*0b57cec5SDimitry Andric 
203*0b57cec5SDimitry Andric   case SystemZ::CLGIBReturn:
204*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
205*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
206*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
207*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
208*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
209*0b57cec5SDimitry Andric       .addImm(0);
210*0b57cec5SDimitry Andric     break;
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric   case SystemZ::CallBRASL:
213*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRASL)
214*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
215*0b57cec5SDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
216*0b57cec5SDimitry Andric     break;
217*0b57cec5SDimitry Andric 
218*0b57cec5SDimitry Andric   case SystemZ::CallBASR:
219*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BASR)
220*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
221*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg());
222*0b57cec5SDimitry Andric     break;
223*0b57cec5SDimitry Andric 
224*0b57cec5SDimitry Andric   case SystemZ::CallJG:
225*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::JG)
226*0b57cec5SDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
227*0b57cec5SDimitry Andric     break;
228*0b57cec5SDimitry Andric 
229*0b57cec5SDimitry Andric   case SystemZ::CallBRCL:
230*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRCL)
231*0b57cec5SDimitry Andric       .addImm(MI->getOperand(0).getImm())
232*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
233*0b57cec5SDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
234*0b57cec5SDimitry Andric     break;
235*0b57cec5SDimitry Andric 
236*0b57cec5SDimitry Andric   case SystemZ::CallBR:
237*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
238*0b57cec5SDimitry Andric     break;
239*0b57cec5SDimitry Andric 
240*0b57cec5SDimitry Andric   case SystemZ::CallBCR:
241*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BCR)
242*0b57cec5SDimitry Andric       .addImm(MI->getOperand(0).getImm())
243*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
244*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D);
245*0b57cec5SDimitry Andric     break;
246*0b57cec5SDimitry Andric 
247*0b57cec5SDimitry Andric   case SystemZ::CRBCall:
248*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CRB)
249*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
250*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
251*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
252*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D)
253*0b57cec5SDimitry Andric       .addImm(0);
254*0b57cec5SDimitry Andric     break;
255*0b57cec5SDimitry Andric 
256*0b57cec5SDimitry Andric   case SystemZ::CGRBCall:
257*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CGRB)
258*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
259*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
260*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
261*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D)
262*0b57cec5SDimitry Andric       .addImm(0);
263*0b57cec5SDimitry Andric     break;
264*0b57cec5SDimitry Andric 
265*0b57cec5SDimitry Andric   case SystemZ::CIBCall:
266*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CIB)
267*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
268*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
269*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
270*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D)
271*0b57cec5SDimitry Andric       .addImm(0);
272*0b57cec5SDimitry Andric     break;
273*0b57cec5SDimitry Andric 
274*0b57cec5SDimitry Andric   case SystemZ::CGIBCall:
275*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CGIB)
276*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
277*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
278*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
279*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D)
280*0b57cec5SDimitry Andric       .addImm(0);
281*0b57cec5SDimitry Andric     break;
282*0b57cec5SDimitry Andric 
283*0b57cec5SDimitry Andric   case SystemZ::CLRBCall:
284*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLRB)
285*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
286*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
287*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
288*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D)
289*0b57cec5SDimitry Andric       .addImm(0);
290*0b57cec5SDimitry Andric     break;
291*0b57cec5SDimitry Andric 
292*0b57cec5SDimitry Andric   case SystemZ::CLGRBCall:
293*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
294*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
295*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
296*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
297*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D)
298*0b57cec5SDimitry Andric       .addImm(0);
299*0b57cec5SDimitry Andric     break;
300*0b57cec5SDimitry Andric 
301*0b57cec5SDimitry Andric   case SystemZ::CLIBCall:
302*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLIB)
303*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
304*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
305*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
306*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D)
307*0b57cec5SDimitry Andric       .addImm(0);
308*0b57cec5SDimitry Andric     break;
309*0b57cec5SDimitry Andric 
310*0b57cec5SDimitry Andric   case SystemZ::CLGIBCall:
311*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
312*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
313*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
314*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm())
315*0b57cec5SDimitry Andric       .addReg(SystemZ::R1D)
316*0b57cec5SDimitry Andric       .addImm(0);
317*0b57cec5SDimitry Andric     break;
318*0b57cec5SDimitry Andric 
319*0b57cec5SDimitry Andric   case SystemZ::TLS_GDCALL:
320*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRASL)
321*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
322*0b57cec5SDimitry Andric       .addExpr(getTLSGetOffset(MF->getContext()))
323*0b57cec5SDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
324*0b57cec5SDimitry Andric     break;
325*0b57cec5SDimitry Andric 
326*0b57cec5SDimitry Andric   case SystemZ::TLS_LDCALL:
327*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRASL)
328*0b57cec5SDimitry Andric       .addReg(SystemZ::R14D)
329*0b57cec5SDimitry Andric       .addExpr(getTLSGetOffset(MF->getContext()))
330*0b57cec5SDimitry Andric       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
331*0b57cec5SDimitry Andric     break;
332*0b57cec5SDimitry Andric 
333*0b57cec5SDimitry Andric   case SystemZ::GOT:
334*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::LARL)
335*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
336*0b57cec5SDimitry Andric       .addExpr(getGlobalOffsetTable(MF->getContext()));
337*0b57cec5SDimitry Andric     break;
338*0b57cec5SDimitry Andric 
339*0b57cec5SDimitry Andric   case SystemZ::IILF64:
340*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::IILF)
341*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
342*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm());
343*0b57cec5SDimitry Andric     break;
344*0b57cec5SDimitry Andric 
345*0b57cec5SDimitry Andric   case SystemZ::IIHF64:
346*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::IIHF)
347*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
348*0b57cec5SDimitry Andric       .addImm(MI->getOperand(2).getImm());
349*0b57cec5SDimitry Andric     break;
350*0b57cec5SDimitry Andric 
351*0b57cec5SDimitry Andric   case SystemZ::RISBHH:
352*0b57cec5SDimitry Andric   case SystemZ::RISBHL:
353*0b57cec5SDimitry Andric     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
354*0b57cec5SDimitry Andric     break;
355*0b57cec5SDimitry Andric 
356*0b57cec5SDimitry Andric   case SystemZ::RISBLH:
357*0b57cec5SDimitry Andric   case SystemZ::RISBLL:
358*0b57cec5SDimitry Andric     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
359*0b57cec5SDimitry Andric     break;
360*0b57cec5SDimitry Andric 
361*0b57cec5SDimitry Andric   case SystemZ::VLVGP32:
362*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::VLVGP)
363*0b57cec5SDimitry Andric       .addReg(MI->getOperand(0).getReg())
364*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
365*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
366*0b57cec5SDimitry Andric     break;
367*0b57cec5SDimitry Andric 
368*0b57cec5SDimitry Andric   case SystemZ::VLR32:
369*0b57cec5SDimitry Andric   case SystemZ::VLR64:
370*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::VLR)
371*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
372*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
373*0b57cec5SDimitry Andric     break;
374*0b57cec5SDimitry Andric 
375*0b57cec5SDimitry Andric   case SystemZ::VL:
376*0b57cec5SDimitry Andric     Lower.lower(MI, LoweredMI);
377*0b57cec5SDimitry Andric     lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign);
378*0b57cec5SDimitry Andric     break;
379*0b57cec5SDimitry Andric 
380*0b57cec5SDimitry Andric   case SystemZ::VST:
381*0b57cec5SDimitry Andric     Lower.lower(MI, LoweredMI);
382*0b57cec5SDimitry Andric     lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign);
383*0b57cec5SDimitry Andric     break;
384*0b57cec5SDimitry Andric 
385*0b57cec5SDimitry Andric   case SystemZ::VLM:
386*0b57cec5SDimitry Andric     Lower.lower(MI, LoweredMI);
387*0b57cec5SDimitry Andric     lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign);
388*0b57cec5SDimitry Andric     break;
389*0b57cec5SDimitry Andric 
390*0b57cec5SDimitry Andric   case SystemZ::VSTM:
391*0b57cec5SDimitry Andric     Lower.lower(MI, LoweredMI);
392*0b57cec5SDimitry Andric     lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign);
393*0b57cec5SDimitry Andric     break;
394*0b57cec5SDimitry Andric 
395*0b57cec5SDimitry Andric   case SystemZ::VL32:
396*0b57cec5SDimitry Andric     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
397*0b57cec5SDimitry Andric     break;
398*0b57cec5SDimitry Andric 
399*0b57cec5SDimitry Andric   case SystemZ::VL64:
400*0b57cec5SDimitry Andric     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
401*0b57cec5SDimitry Andric     break;
402*0b57cec5SDimitry Andric 
403*0b57cec5SDimitry Andric   case SystemZ::VST32:
404*0b57cec5SDimitry Andric     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
405*0b57cec5SDimitry Andric     break;
406*0b57cec5SDimitry Andric 
407*0b57cec5SDimitry Andric   case SystemZ::VST64:
408*0b57cec5SDimitry Andric     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
409*0b57cec5SDimitry Andric     break;
410*0b57cec5SDimitry Andric 
411*0b57cec5SDimitry Andric   case SystemZ::LFER:
412*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::VLGVF)
413*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
414*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
415*0b57cec5SDimitry Andric       .addReg(0).addImm(0);
416*0b57cec5SDimitry Andric     break;
417*0b57cec5SDimitry Andric 
418*0b57cec5SDimitry Andric   case SystemZ::LEFR:
419*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::VLVGF)
420*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
421*0b57cec5SDimitry Andric       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
422*0b57cec5SDimitry Andric       .addReg(MI->getOperand(1).getReg())
423*0b57cec5SDimitry Andric       .addReg(0).addImm(0);
424*0b57cec5SDimitry Andric     break;
425*0b57cec5SDimitry Andric 
426*0b57cec5SDimitry Andric #define LOWER_LOW(NAME)                                                 \
427*0b57cec5SDimitry Andric   case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
428*0b57cec5SDimitry Andric 
429*0b57cec5SDimitry Andric   LOWER_LOW(IILL);
430*0b57cec5SDimitry Andric   LOWER_LOW(IILH);
431*0b57cec5SDimitry Andric   LOWER_LOW(TMLL);
432*0b57cec5SDimitry Andric   LOWER_LOW(TMLH);
433*0b57cec5SDimitry Andric   LOWER_LOW(NILL);
434*0b57cec5SDimitry Andric   LOWER_LOW(NILH);
435*0b57cec5SDimitry Andric   LOWER_LOW(NILF);
436*0b57cec5SDimitry Andric   LOWER_LOW(OILL);
437*0b57cec5SDimitry Andric   LOWER_LOW(OILH);
438*0b57cec5SDimitry Andric   LOWER_LOW(OILF);
439*0b57cec5SDimitry Andric   LOWER_LOW(XILF);
440*0b57cec5SDimitry Andric 
441*0b57cec5SDimitry Andric #undef LOWER_LOW
442*0b57cec5SDimitry Andric 
443*0b57cec5SDimitry Andric #define LOWER_HIGH(NAME) \
444*0b57cec5SDimitry Andric   case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
445*0b57cec5SDimitry Andric 
446*0b57cec5SDimitry Andric   LOWER_HIGH(IIHL);
447*0b57cec5SDimitry Andric   LOWER_HIGH(IIHH);
448*0b57cec5SDimitry Andric   LOWER_HIGH(TMHL);
449*0b57cec5SDimitry Andric   LOWER_HIGH(TMHH);
450*0b57cec5SDimitry Andric   LOWER_HIGH(NIHL);
451*0b57cec5SDimitry Andric   LOWER_HIGH(NIHH);
452*0b57cec5SDimitry Andric   LOWER_HIGH(NIHF);
453*0b57cec5SDimitry Andric   LOWER_HIGH(OIHL);
454*0b57cec5SDimitry Andric   LOWER_HIGH(OIHH);
455*0b57cec5SDimitry Andric   LOWER_HIGH(OIHF);
456*0b57cec5SDimitry Andric   LOWER_HIGH(XIHF);
457*0b57cec5SDimitry Andric 
458*0b57cec5SDimitry Andric #undef LOWER_HIGH
459*0b57cec5SDimitry Andric 
460*0b57cec5SDimitry Andric   case SystemZ::Serialize:
461*0b57cec5SDimitry Andric     if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
462*0b57cec5SDimitry Andric       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
463*0b57cec5SDimitry Andric         .addImm(14).addReg(SystemZ::R0D);
464*0b57cec5SDimitry Andric     else
465*0b57cec5SDimitry Andric       LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
466*0b57cec5SDimitry Andric         .addImm(15).addReg(SystemZ::R0D);
467*0b57cec5SDimitry Andric     break;
468*0b57cec5SDimitry Andric 
469*0b57cec5SDimitry Andric   // Emit nothing here but a comment if we can.
470*0b57cec5SDimitry Andric   case SystemZ::MemBarrier:
471*0b57cec5SDimitry Andric     OutStreamer->emitRawComment("MEMBARRIER");
472*0b57cec5SDimitry Andric     return;
473*0b57cec5SDimitry Andric 
474*0b57cec5SDimitry Andric   // We want to emit "j .+2" for traps, jumping to the relative immediate field
475*0b57cec5SDimitry Andric   // of the jump instruction, which is an illegal instruction. We cannot emit a
476*0b57cec5SDimitry Andric   // "." symbol, so create and emit a temp label before the instruction and use
477*0b57cec5SDimitry Andric   // that instead.
478*0b57cec5SDimitry Andric   case SystemZ::Trap: {
479*0b57cec5SDimitry Andric     MCSymbol *DotSym = OutContext.createTempSymbol();
480*0b57cec5SDimitry Andric     OutStreamer->EmitLabel(DotSym);
481*0b57cec5SDimitry Andric 
482*0b57cec5SDimitry Andric     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
483*0b57cec5SDimitry Andric     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
484*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::J)
485*0b57cec5SDimitry Andric       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
486*0b57cec5SDimitry Andric     }
487*0b57cec5SDimitry Andric     break;
488*0b57cec5SDimitry Andric 
489*0b57cec5SDimitry Andric   // Conditional traps will create a branch on condition instruction that jumps
490*0b57cec5SDimitry Andric   // to the relative immediate field of the jump instruction. (eg. "jo .+2")
491*0b57cec5SDimitry Andric   case SystemZ::CondTrap: {
492*0b57cec5SDimitry Andric     MCSymbol *DotSym = OutContext.createTempSymbol();
493*0b57cec5SDimitry Andric     OutStreamer->EmitLabel(DotSym);
494*0b57cec5SDimitry Andric 
495*0b57cec5SDimitry Andric     const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
496*0b57cec5SDimitry Andric     const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
497*0b57cec5SDimitry Andric     LoweredMI = MCInstBuilder(SystemZ::BRC)
498*0b57cec5SDimitry Andric       .addImm(MI->getOperand(0).getImm())
499*0b57cec5SDimitry Andric       .addImm(MI->getOperand(1).getImm())
500*0b57cec5SDimitry Andric       .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
501*0b57cec5SDimitry Andric     }
502*0b57cec5SDimitry Andric     break;
503*0b57cec5SDimitry Andric 
504*0b57cec5SDimitry Andric   case TargetOpcode::STACKMAP:
505*0b57cec5SDimitry Andric     LowerSTACKMAP(*MI);
506*0b57cec5SDimitry Andric     return;
507*0b57cec5SDimitry Andric 
508*0b57cec5SDimitry Andric   case TargetOpcode::PATCHPOINT:
509*0b57cec5SDimitry Andric     LowerPATCHPOINT(*MI, Lower);
510*0b57cec5SDimitry Andric     return;
511*0b57cec5SDimitry Andric 
512*0b57cec5SDimitry Andric   default:
513*0b57cec5SDimitry Andric     Lower.lower(MI, LoweredMI);
514*0b57cec5SDimitry Andric     break;
515*0b57cec5SDimitry Andric   }
516*0b57cec5SDimitry Andric   EmitToStreamer(*OutStreamer, LoweredMI);
517*0b57cec5SDimitry Andric }
518*0b57cec5SDimitry Andric 
519*0b57cec5SDimitry Andric 
520*0b57cec5SDimitry Andric // Emit the largest nop instruction smaller than or equal to NumBytes
521*0b57cec5SDimitry Andric // bytes.  Return the size of nop emitted.
522*0b57cec5SDimitry Andric static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
523*0b57cec5SDimitry Andric                         unsigned NumBytes, const MCSubtargetInfo &STI) {
524*0b57cec5SDimitry Andric   if (NumBytes < 2) {
525*0b57cec5SDimitry Andric     llvm_unreachable("Zero nops?");
526*0b57cec5SDimitry Andric     return 0;
527*0b57cec5SDimitry Andric   }
528*0b57cec5SDimitry Andric   else if (NumBytes < 4) {
529*0b57cec5SDimitry Andric     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm)
530*0b57cec5SDimitry Andric                                   .addImm(0).addReg(SystemZ::R0D), STI);
531*0b57cec5SDimitry Andric     return 2;
532*0b57cec5SDimitry Andric   }
533*0b57cec5SDimitry Andric   else if (NumBytes < 6) {
534*0b57cec5SDimitry Andric     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm)
535*0b57cec5SDimitry Andric                                   .addImm(0).addReg(0).addImm(0).addReg(0),
536*0b57cec5SDimitry Andric                                 STI);
537*0b57cec5SDimitry Andric     return 4;
538*0b57cec5SDimitry Andric   }
539*0b57cec5SDimitry Andric   else {
540*0b57cec5SDimitry Andric     MCSymbol *DotSym = OutContext.createTempSymbol();
541*0b57cec5SDimitry Andric     const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
542*0b57cec5SDimitry Andric     OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm)
543*0b57cec5SDimitry Andric                                   .addImm(0).addExpr(Dot), STI);
544*0b57cec5SDimitry Andric     OutStreamer.EmitLabel(DotSym);
545*0b57cec5SDimitry Andric     return 6;
546*0b57cec5SDimitry Andric   }
547*0b57cec5SDimitry Andric }
548*0b57cec5SDimitry Andric 
549*0b57cec5SDimitry Andric void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
550*0b57cec5SDimitry Andric   const SystemZInstrInfo *TII =
551*0b57cec5SDimitry Andric     static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
552*0b57cec5SDimitry Andric 
553*0b57cec5SDimitry Andric   unsigned NumNOPBytes = MI.getOperand(1).getImm();
554*0b57cec5SDimitry Andric 
555*0b57cec5SDimitry Andric   SM.recordStackMap(MI);
556*0b57cec5SDimitry Andric   assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
557*0b57cec5SDimitry Andric 
558*0b57cec5SDimitry Andric   // Scan ahead to trim the shadow.
559*0b57cec5SDimitry Andric   unsigned ShadowBytes = 0;
560*0b57cec5SDimitry Andric   const MachineBasicBlock &MBB = *MI.getParent();
561*0b57cec5SDimitry Andric   MachineBasicBlock::const_iterator MII(MI);
562*0b57cec5SDimitry Andric   ++MII;
563*0b57cec5SDimitry Andric   while (ShadowBytes < NumNOPBytes) {
564*0b57cec5SDimitry Andric     if (MII == MBB.end() ||
565*0b57cec5SDimitry Andric         MII->getOpcode() == TargetOpcode::PATCHPOINT ||
566*0b57cec5SDimitry Andric         MII->getOpcode() == TargetOpcode::STACKMAP)
567*0b57cec5SDimitry Andric       break;
568*0b57cec5SDimitry Andric     ShadowBytes += TII->getInstSizeInBytes(*MII);
569*0b57cec5SDimitry Andric     if (MII->isCall())
570*0b57cec5SDimitry Andric       break;
571*0b57cec5SDimitry Andric     ++MII;
572*0b57cec5SDimitry Andric   }
573*0b57cec5SDimitry Andric 
574*0b57cec5SDimitry Andric   // Emit nops.
575*0b57cec5SDimitry Andric   while (ShadowBytes < NumNOPBytes)
576*0b57cec5SDimitry Andric     ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
577*0b57cec5SDimitry Andric                            getSubtargetInfo());
578*0b57cec5SDimitry Andric }
579*0b57cec5SDimitry Andric 
580*0b57cec5SDimitry Andric // Lower a patchpoint of the form:
581*0b57cec5SDimitry Andric // [<def>], <id>, <numBytes>, <target>, <numArgs>
582*0b57cec5SDimitry Andric void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
583*0b57cec5SDimitry Andric                                         SystemZMCInstLower &Lower) {
584*0b57cec5SDimitry Andric   SM.recordPatchPoint(MI);
585*0b57cec5SDimitry Andric   PatchPointOpers Opers(&MI);
586*0b57cec5SDimitry Andric 
587*0b57cec5SDimitry Andric   unsigned EncodedBytes = 0;
588*0b57cec5SDimitry Andric   const MachineOperand &CalleeMO = Opers.getCallTarget();
589*0b57cec5SDimitry Andric 
590*0b57cec5SDimitry Andric   if (CalleeMO.isImm()) {
591*0b57cec5SDimitry Andric     uint64_t CallTarget = CalleeMO.getImm();
592*0b57cec5SDimitry Andric     if (CallTarget) {
593*0b57cec5SDimitry Andric       unsigned ScratchIdx = -1;
594*0b57cec5SDimitry Andric       unsigned ScratchReg = 0;
595*0b57cec5SDimitry Andric       do {
596*0b57cec5SDimitry Andric         ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
597*0b57cec5SDimitry Andric         ScratchReg = MI.getOperand(ScratchIdx).getReg();
598*0b57cec5SDimitry Andric       } while (ScratchReg == SystemZ::R0D);
599*0b57cec5SDimitry Andric 
600*0b57cec5SDimitry Andric       // Materialize the call target address
601*0b57cec5SDimitry Andric       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
602*0b57cec5SDimitry Andric                                       .addReg(ScratchReg)
603*0b57cec5SDimitry Andric                                       .addImm(CallTarget & 0xFFFFFFFF));
604*0b57cec5SDimitry Andric       EncodedBytes += 6;
605*0b57cec5SDimitry Andric       if (CallTarget >> 32) {
606*0b57cec5SDimitry Andric         EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
607*0b57cec5SDimitry Andric                                         .addReg(ScratchReg)
608*0b57cec5SDimitry Andric                                         .addImm(CallTarget >> 32));
609*0b57cec5SDimitry Andric         EncodedBytes += 6;
610*0b57cec5SDimitry Andric       }
611*0b57cec5SDimitry Andric 
612*0b57cec5SDimitry Andric       EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
613*0b57cec5SDimitry Andric                                      .addReg(SystemZ::R14D)
614*0b57cec5SDimitry Andric                                      .addReg(ScratchReg));
615*0b57cec5SDimitry Andric       EncodedBytes += 2;
616*0b57cec5SDimitry Andric     }
617*0b57cec5SDimitry Andric   } else if (CalleeMO.isGlobal()) {
618*0b57cec5SDimitry Andric     const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
619*0b57cec5SDimitry Andric     EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
620*0b57cec5SDimitry Andric                                    .addReg(SystemZ::R14D)
621*0b57cec5SDimitry Andric                                    .addExpr(Expr));
622*0b57cec5SDimitry Andric     EncodedBytes += 6;
623*0b57cec5SDimitry Andric   }
624*0b57cec5SDimitry Andric 
625*0b57cec5SDimitry Andric   // Emit padding.
626*0b57cec5SDimitry Andric   unsigned NumBytes = Opers.getNumPatchBytes();
627*0b57cec5SDimitry Andric   assert(NumBytes >= EncodedBytes &&
628*0b57cec5SDimitry Andric          "Patchpoint can't request size less than the length of a call.");
629*0b57cec5SDimitry Andric   assert((NumBytes - EncodedBytes) % 2 == 0 &&
630*0b57cec5SDimitry Andric          "Invalid number of NOP bytes requested!");
631*0b57cec5SDimitry Andric   while (EncodedBytes < NumBytes)
632*0b57cec5SDimitry Andric     EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
633*0b57cec5SDimitry Andric                             getSubtargetInfo());
634*0b57cec5SDimitry Andric }
635*0b57cec5SDimitry Andric 
636*0b57cec5SDimitry Andric // Convert a SystemZ-specific constant pool modifier into the associated
637*0b57cec5SDimitry Andric // MCSymbolRefExpr variant kind.
638*0b57cec5SDimitry Andric static MCSymbolRefExpr::VariantKind
639*0b57cec5SDimitry Andric getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
640*0b57cec5SDimitry Andric   switch (Modifier) {
641*0b57cec5SDimitry Andric   case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
642*0b57cec5SDimitry Andric   case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
643*0b57cec5SDimitry Andric   case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
644*0b57cec5SDimitry Andric   case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
645*0b57cec5SDimitry Andric   }
646*0b57cec5SDimitry Andric   llvm_unreachable("Invalid SystemCPModifier!");
647*0b57cec5SDimitry Andric }
648*0b57cec5SDimitry Andric 
649*0b57cec5SDimitry Andric void SystemZAsmPrinter::
650*0b57cec5SDimitry Andric EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
651*0b57cec5SDimitry Andric   auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
652*0b57cec5SDimitry Andric 
653*0b57cec5SDimitry Andric   const MCExpr *Expr =
654*0b57cec5SDimitry Andric     MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
655*0b57cec5SDimitry Andric                             getModifierVariantKind(ZCPV->getModifier()),
656*0b57cec5SDimitry Andric                             OutContext);
657*0b57cec5SDimitry Andric   uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
658*0b57cec5SDimitry Andric 
659*0b57cec5SDimitry Andric   OutStreamer->EmitValue(Expr, Size);
660*0b57cec5SDimitry Andric }
661*0b57cec5SDimitry Andric 
662*0b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
663*0b57cec5SDimitry Andric                                         const char *ExtraCode,
664*0b57cec5SDimitry Andric                                         raw_ostream &OS) {
665*0b57cec5SDimitry Andric   if (ExtraCode)
666*0b57cec5SDimitry Andric     return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
667*0b57cec5SDimitry Andric   SystemZMCInstLower Lower(MF->getContext(), *this);
668*0b57cec5SDimitry Andric   MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
669*0b57cec5SDimitry Andric   SystemZInstPrinter::printOperand(MO, MAI, OS);
670*0b57cec5SDimitry Andric   return false;
671*0b57cec5SDimitry Andric }
672*0b57cec5SDimitry Andric 
673*0b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
674*0b57cec5SDimitry Andric                                               unsigned OpNo,
675*0b57cec5SDimitry Andric                                               const char *ExtraCode,
676*0b57cec5SDimitry Andric                                               raw_ostream &OS) {
677*0b57cec5SDimitry Andric   SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
678*0b57cec5SDimitry Andric                                    MI->getOperand(OpNo + 1).getImm(),
679*0b57cec5SDimitry Andric                                    MI->getOperand(OpNo + 2).getReg(), OS);
680*0b57cec5SDimitry Andric   return false;
681*0b57cec5SDimitry Andric }
682*0b57cec5SDimitry Andric 
683*0b57cec5SDimitry Andric void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
684*0b57cec5SDimitry Andric   emitStackMaps(SM);
685*0b57cec5SDimitry Andric }
686*0b57cec5SDimitry Andric 
687*0b57cec5SDimitry Andric // Force static initialization.
688*0b57cec5SDimitry Andric extern "C" void LLVMInitializeSystemZAsmPrinter() {
689*0b57cec5SDimitry Andric   RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
690*0b57cec5SDimitry Andric }
691