blob: e8aeca01ea0a0e134c87fd9f20993ddbcde8512a [file] [log] [blame]
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Ulrich Weigand5f613df2013-05-06 16:15:19 +00006//
7//===----------------------------------------------------------------------===//
8//
9// Streams SystemZ assembly language and associated data, in the form of
10// MCInsts and MCExprs respectively.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SystemZAsmPrinter.h"
15#include "InstPrinter/SystemZInstPrinter.h"
16#include "SystemZConstantPoolValue.h"
17#include "SystemZMCInstLower.h"
18#include "llvm/CodeGen/MachineModuleInfoImpls.h"
19#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
Rafael Espindola894843c2014-01-07 21:19:40 +000020#include "llvm/IR/Mangler.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000021#include "llvm/MC/MCExpr.h"
Richard Sandiford9ab97cd2013-09-25 10:20:08 +000022#include "llvm/MC/MCInstBuilder.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000023#include "llvm/MC/MCStreamer.h"
24#include "llvm/Support/TargetRegistry.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000025
26using namespace llvm;
27
Richard Sandiford652784e2013-09-25 11:11:53 +000028// Return an RI instruction like MI with opcode Opcode, but with the
29// GR64 register operands turned into GR32s.
30static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
Richard Sandifordf03789c2013-11-22 17:28:28 +000031 if (MI->isCompare())
32 return MCInstBuilder(Opcode)
33 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
34 .addImm(MI->getOperand(1).getImm());
35 else
36 return MCInstBuilder(Opcode)
37 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
38 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
39 .addImm(MI->getOperand(2).getImm());
Richard Sandiford652784e2013-09-25 11:11:53 +000040}
41
Richard Sandiford0755c932013-10-01 11:26:28 +000042// Return an RI instruction like MI with opcode Opcode, but with the
Richard Sandiford1a569312013-10-01 13:18:56 +000043// GR64 register operands turned into GRH32s.
44static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
Richard Sandifordf03789c2013-11-22 17:28:28 +000045 if (MI->isCompare())
46 return MCInstBuilder(Opcode)
47 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
48 .addImm(MI->getOperand(1).getImm());
49 else
50 return MCInstBuilder(Opcode)
51 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
52 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
53 .addImm(MI->getOperand(2).getImm());
Richard Sandiford1a569312013-10-01 13:18:56 +000054}
55
56// Return an RI instruction like MI with opcode Opcode, but with the
Richard Sandiford0755c932013-10-01 11:26:28 +000057// R2 register turned into a GR64.
58static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
59 return MCInstBuilder(Opcode)
60 .addReg(MI->getOperand(0).getReg())
61 .addReg(MI->getOperand(1).getReg())
62 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
63 .addImm(MI->getOperand(3).getImm())
64 .addImm(MI->getOperand(4).getImm())
65 .addImm(MI->getOperand(5).getImm());
66}
67
Ulrich Weigand7db69182015-02-18 09:13:27 +000068static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
69 StringRef Name = "__tls_get_offset";
Jim Grosbach13760bd2015-05-30 01:25:56 +000070 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
Ulrich Weigand7db69182015-02-18 09:13:27 +000071 MCSymbolRefExpr::VK_PLT,
72 Context);
73}
74
75static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
76 StringRef Name = "_GLOBAL_OFFSET_TABLE_";
Jim Grosbach13760bd2015-05-30 01:25:56 +000077 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
Ulrich Weigand7db69182015-02-18 09:13:27 +000078 MCSymbolRefExpr::VK_None,
79 Context);
80}
81
Ulrich Weigand49506d72015-05-05 19:28:34 +000082// MI loads the high part of a vector from memory. Return an instruction
83// that uses replicating vector load Opcode to do the same thing.
84static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
85 return MCInstBuilder(Opcode)
86 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
87 .addReg(MI->getOperand(1).getReg())
88 .addImm(MI->getOperand(2).getImm())
89 .addReg(MI->getOperand(3).getReg());
90}
91
92// MI stores the high part of a vector to memory. Return an instruction
93// that uses elemental vector store Opcode to do the same thing.
94static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
95 return MCInstBuilder(Opcode)
96 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
97 .addReg(MI->getOperand(1).getReg())
98 .addImm(MI->getOperand(2).getImm())
99 .addReg(MI->getOperand(3).getReg())
100 .addImm(0);
101}
102
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000103void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
Rafael Espindola69c1d632013-10-29 16:18:15 +0000104 SystemZMCInstLower Lower(MF->getContext(), *this);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000105 MCInst LoweredMI;
Richard Sandiford9ab97cd2013-09-25 10:20:08 +0000106 switch (MI->getOpcode()) {
107 case SystemZ::Return:
108 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
109 break;
110
Ulrich Weigand2eb027d2016-04-07 16:11:44 +0000111 case SystemZ::CondReturn:
112 LoweredMI = MCInstBuilder(SystemZ::BCR)
113 .addImm(MI->getOperand(0).getImm())
114 .addImm(MI->getOperand(1).getImm())
115 .addReg(SystemZ::R14D);
116 break;
117
118 case SystemZ::CRBReturn:
119 LoweredMI = MCInstBuilder(SystemZ::CRB)
120 .addReg(MI->getOperand(0).getReg())
121 .addReg(MI->getOperand(1).getReg())
122 .addImm(MI->getOperand(2).getImm())
123 .addReg(SystemZ::R14D)
124 .addImm(0);
125 break;
126
127 case SystemZ::CGRBReturn:
128 LoweredMI = MCInstBuilder(SystemZ::CGRB)
129 .addReg(MI->getOperand(0).getReg())
130 .addReg(MI->getOperand(1).getReg())
131 .addImm(MI->getOperand(2).getImm())
132 .addReg(SystemZ::R14D)
133 .addImm(0);
134 break;
135
136 case SystemZ::CIBReturn:
137 LoweredMI = MCInstBuilder(SystemZ::CIB)
138 .addReg(MI->getOperand(0).getReg())
139 .addImm(MI->getOperand(1).getImm())
140 .addImm(MI->getOperand(2).getImm())
141 .addReg(SystemZ::R14D)
142 .addImm(0);
143 break;
144
145 case SystemZ::CGIBReturn:
146 LoweredMI = MCInstBuilder(SystemZ::CGIB)
147 .addReg(MI->getOperand(0).getReg())
148 .addImm(MI->getOperand(1).getImm())
149 .addImm(MI->getOperand(2).getImm())
150 .addReg(SystemZ::R14D)
151 .addImm(0);
152 break;
153
154 case SystemZ::CLRBReturn:
155 LoweredMI = MCInstBuilder(SystemZ::CLRB)
156 .addReg(MI->getOperand(0).getReg())
157 .addReg(MI->getOperand(1).getReg())
158 .addImm(MI->getOperand(2).getImm())
159 .addReg(SystemZ::R14D)
160 .addImm(0);
161 break;
162
163 case SystemZ::CLGRBReturn:
164 LoweredMI = MCInstBuilder(SystemZ::CLGRB)
165 .addReg(MI->getOperand(0).getReg())
166 .addReg(MI->getOperand(1).getReg())
167 .addImm(MI->getOperand(2).getImm())
168 .addReg(SystemZ::R14D)
169 .addImm(0);
170 break;
171
172 case SystemZ::CLIBReturn:
173 LoweredMI = MCInstBuilder(SystemZ::CLIB)
174 .addReg(MI->getOperand(0).getReg())
175 .addImm(MI->getOperand(1).getImm())
176 .addImm(MI->getOperand(2).getImm())
177 .addReg(SystemZ::R14D)
178 .addImm(0);
179 break;
180
181 case SystemZ::CLGIBReturn:
182 LoweredMI = MCInstBuilder(SystemZ::CLGIB)
183 .addReg(MI->getOperand(0).getReg())
184 .addImm(MI->getOperand(1).getImm())
185 .addImm(MI->getOperand(2).getImm())
186 .addReg(SystemZ::R14D)
187 .addImm(0);
188 break;
189
Richard Sandifordf348f832013-09-25 10:37:17 +0000190 case SystemZ::CallBRASL:
191 LoweredMI = MCInstBuilder(SystemZ::BRASL)
192 .addReg(SystemZ::R14D)
193 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
194 break;
195
196 case SystemZ::CallBASR:
197 LoweredMI = MCInstBuilder(SystemZ::BASR)
198 .addReg(SystemZ::R14D)
199 .addReg(MI->getOperand(0).getReg());
200 break;
201
202 case SystemZ::CallJG:
203 LoweredMI = MCInstBuilder(SystemZ::JG)
204 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
205 break;
206
Ulrich Weigandfa2dffb2016-04-08 17:22:19 +0000207 case SystemZ::CallBRCL:
208 LoweredMI = MCInstBuilder(SystemZ::BRCL)
209 .addImm(MI->getOperand(0).getImm())
210 .addImm(MI->getOperand(1).getImm())
211 .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
212 break;
213
Richard Sandifordf348f832013-09-25 10:37:17 +0000214 case SystemZ::CallBR:
215 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
216 break;
217
Ulrich Weigand848a5132016-04-11 12:12:32 +0000218 case SystemZ::CallBCR:
219 LoweredMI = MCInstBuilder(SystemZ::BCR)
220 .addImm(MI->getOperand(0).getImm())
221 .addImm(MI->getOperand(1).getImm())
222 .addReg(SystemZ::R1D);
223 break;
224
225 case SystemZ::CRBCall:
226 LoweredMI = MCInstBuilder(SystemZ::CRB)
227 .addReg(MI->getOperand(0).getReg())
228 .addReg(MI->getOperand(1).getReg())
229 .addImm(MI->getOperand(2).getImm())
230 .addReg(SystemZ::R1D)
231 .addImm(0);
232 break;
233
234 case SystemZ::CGRBCall:
235 LoweredMI = MCInstBuilder(SystemZ::CGRB)
236 .addReg(MI->getOperand(0).getReg())
237 .addReg(MI->getOperand(1).getReg())
238 .addImm(MI->getOperand(2).getImm())
239 .addReg(SystemZ::R1D)
240 .addImm(0);
241 break;
242
243 case SystemZ::CIBCall:
244 LoweredMI = MCInstBuilder(SystemZ::CIB)
245 .addReg(MI->getOperand(0).getReg())
246 .addImm(MI->getOperand(1).getImm())
247 .addImm(MI->getOperand(2).getImm())
248 .addReg(SystemZ::R1D)
249 .addImm(0);
250 break;
251
252 case SystemZ::CGIBCall:
253 LoweredMI = MCInstBuilder(SystemZ::CGIB)
254 .addReg(MI->getOperand(0).getReg())
255 .addImm(MI->getOperand(1).getImm())
256 .addImm(MI->getOperand(2).getImm())
257 .addReg(SystemZ::R1D)
258 .addImm(0);
259 break;
260
261 case SystemZ::CLRBCall:
262 LoweredMI = MCInstBuilder(SystemZ::CLRB)
263 .addReg(MI->getOperand(0).getReg())
264 .addReg(MI->getOperand(1).getReg())
265 .addImm(MI->getOperand(2).getImm())
266 .addReg(SystemZ::R1D)
267 .addImm(0);
268 break;
269
270 case SystemZ::CLGRBCall:
271 LoweredMI = MCInstBuilder(SystemZ::CLGRB)
272 .addReg(MI->getOperand(0).getReg())
273 .addReg(MI->getOperand(1).getReg())
274 .addImm(MI->getOperand(2).getImm())
275 .addReg(SystemZ::R1D)
276 .addImm(0);
277 break;
278
279 case SystemZ::CLIBCall:
280 LoweredMI = MCInstBuilder(SystemZ::CLIB)
281 .addReg(MI->getOperand(0).getReg())
282 .addImm(MI->getOperand(1).getImm())
283 .addImm(MI->getOperand(2).getImm())
284 .addReg(SystemZ::R1D)
285 .addImm(0);
286 break;
287
288 case SystemZ::CLGIBCall:
289 LoweredMI = MCInstBuilder(SystemZ::CLGIB)
290 .addReg(MI->getOperand(0).getReg())
291 .addImm(MI->getOperand(1).getImm())
292 .addImm(MI->getOperand(2).getImm())
293 .addReg(SystemZ::R1D)
294 .addImm(0);
295 break;
296
Ulrich Weigand7db69182015-02-18 09:13:27 +0000297 case SystemZ::TLS_GDCALL:
298 LoweredMI = MCInstBuilder(SystemZ::BRASL)
299 .addReg(SystemZ::R14D)
300 .addExpr(getTLSGetOffset(MF->getContext()))
301 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
302 break;
303
304 case SystemZ::TLS_LDCALL:
305 LoweredMI = MCInstBuilder(SystemZ::BRASL)
306 .addReg(SystemZ::R14D)
307 .addExpr(getTLSGetOffset(MF->getContext()))
308 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
309 break;
310
311 case SystemZ::GOT:
312 LoweredMI = MCInstBuilder(SystemZ::LARL)
313 .addReg(MI->getOperand(0).getReg())
314 .addExpr(getGlobalOffsetTable(MF->getContext()));
315 break;
316
Richard Sandiford652784e2013-09-25 11:11:53 +0000317 case SystemZ::IILF64:
318 LoweredMI = MCInstBuilder(SystemZ::IILF)
319 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
320 .addImm(MI->getOperand(2).getImm());
321 break;
322
Richard Sandiford01240232013-10-01 13:02:28 +0000323 case SystemZ::IIHF64:
324 LoweredMI = MCInstBuilder(SystemZ::IIHF)
325 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
326 .addImm(MI->getOperand(2).getImm());
327 break;
328
Richard Sandiford0755c932013-10-01 11:26:28 +0000329 case SystemZ::RISBHH:
330 case SystemZ::RISBHL:
331 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
332 break;
333
334 case SystemZ::RISBLH:
335 case SystemZ::RISBLL:
336 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
337 break;
338
Ulrich Weigandce4c1092015-05-05 19:25:42 +0000339 case SystemZ::VLVGP32:
340 LoweredMI = MCInstBuilder(SystemZ::VLVGP)
341 .addReg(MI->getOperand(0).getReg())
342 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
343 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
344 break;
345
Ulrich Weigand49506d72015-05-05 19:28:34 +0000346 case SystemZ::VLR32:
347 case SystemZ::VLR64:
348 LoweredMI = MCInstBuilder(SystemZ::VLR)
349 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
350 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
351 break;
352
353 case SystemZ::VL32:
354 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
355 break;
356
357 case SystemZ::VL64:
358 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
359 break;
360
361 case SystemZ::VST32:
362 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
363 break;
364
365 case SystemZ::VST64:
366 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
367 break;
368
Ulrich Weigand80b3af72015-05-05 19:27:45 +0000369 case SystemZ::LFER:
370 LoweredMI = MCInstBuilder(SystemZ::VLGVF)
371 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
372 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
373 .addReg(0).addImm(0);
374 break;
375
376 case SystemZ::LEFR:
377 LoweredMI = MCInstBuilder(SystemZ::VLVGF)
378 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
379 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
380 .addReg(MI->getOperand(1).getReg())
381 .addReg(0).addImm(0);
382 break;
383
Richard Sandiford652784e2013-09-25 11:11:53 +0000384#define LOWER_LOW(NAME) \
385 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
386
387 LOWER_LOW(IILL);
388 LOWER_LOW(IILH);
Richard Sandifordf03789c2013-11-22 17:28:28 +0000389 LOWER_LOW(TMLL);
390 LOWER_LOW(TMLH);
Richard Sandiford652784e2013-09-25 11:11:53 +0000391 LOWER_LOW(NILL);
392 LOWER_LOW(NILH);
393 LOWER_LOW(NILF);
394 LOWER_LOW(OILL);
395 LOWER_LOW(OILH);
396 LOWER_LOW(OILF);
397 LOWER_LOW(XILF);
398
399#undef LOWER_LOW
400
Richard Sandiford1a569312013-10-01 13:18:56 +0000401#define LOWER_HIGH(NAME) \
402 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
403
404 LOWER_HIGH(IIHL);
405 LOWER_HIGH(IIHH);
Richard Sandifordf03789c2013-11-22 17:28:28 +0000406 LOWER_HIGH(TMHL);
407 LOWER_HIGH(TMHH);
Richard Sandiford70284282013-10-01 14:20:41 +0000408 LOWER_HIGH(NIHL);
409 LOWER_HIGH(NIHH);
410 LOWER_HIGH(NIHF);
Richard Sandiford6e96ac62013-10-01 13:22:41 +0000411 LOWER_HIGH(OIHL);
412 LOWER_HIGH(OIHH);
413 LOWER_HIGH(OIHF);
Richard Sandiford5718dac2013-10-01 14:08:44 +0000414 LOWER_HIGH(XIHF);
Richard Sandiford1a569312013-10-01 13:18:56 +0000415
416#undef LOWER_HIGH
417
Richard Sandiford9afe6132013-12-10 10:36:34 +0000418 case SystemZ::Serialize:
Eric Christopherd84f5d32015-02-19 01:26:28 +0000419 if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
Ulrich Weigandd2148ca2016-11-08 18:30:50 +0000420 LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
Richard Sandiford9afe6132013-12-10 10:36:34 +0000421 .addImm(14).addReg(SystemZ::R0D);
422 else
Ulrich Weigandd2148ca2016-11-08 18:30:50 +0000423 LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
Richard Sandiford9afe6132013-12-10 10:36:34 +0000424 .addImm(15).addReg(SystemZ::R0D);
425 break;
426
Ulrich Weiganda9ac6d62016-04-04 12:45:44 +0000427 // Emit nothing here but a comment if we can.
428 case SystemZ::MemBarrier:
429 OutStreamer->emitRawComment("MEMBARRIER");
430 return;
431
Zhan Jun Liauab42cbc2016-06-10 19:58:10 +0000432 // We want to emit "j .+2" for traps, jumping to the relative immediate field
433 // of the jump instruction, which is an illegal instruction. We cannot emit a
434 // "." symbol, so create and emit a temp label before the instruction and use
435 // that instead.
436 case SystemZ::Trap: {
437 MCSymbol *DotSym = OutContext.createTempSymbol();
438 OutStreamer->EmitLabel(DotSym);
439
440 const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
441 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
442 LoweredMI = MCInstBuilder(SystemZ::J)
443 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
444 }
445 break;
446
447 // Conditional traps will create a branch on condition instruction that jumps
448 // to the relative immediate field of the jump instruction. (eg. "jo .+2")
449 case SystemZ::CondTrap: {
450 MCSymbol *DotSym = OutContext.createTempSymbol();
451 OutStreamer->EmitLabel(DotSym);
452
453 const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
454 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
455 LoweredMI = MCInstBuilder(SystemZ::BRC)
456 .addImm(MI->getOperand(0).getImm())
457 .addImm(MI->getOperand(1).getImm())
458 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
459 }
460 break;
461
Ulrich Weigand5eb64112018-03-02 20:39:30 +0000462 case TargetOpcode::STACKMAP:
463 LowerSTACKMAP(*MI);
464 return;
465
466 case TargetOpcode::PATCHPOINT:
467 LowerPATCHPOINT(*MI, Lower);
468 return;
469
Richard Sandiford9ab97cd2013-09-25 10:20:08 +0000470 default:
Richard Sandifordf348f832013-09-25 10:37:17 +0000471 Lower.lower(MI, LoweredMI);
Richard Sandiford9ab97cd2013-09-25 10:20:08 +0000472 break;
473 }
Lang Hames9ff69c82015-04-24 19:11:51 +0000474 EmitToStreamer(*OutStreamer, LoweredMI);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000475}
476
Ulrich Weigand5eb64112018-03-02 20:39:30 +0000477
478// Emit the largest nop instruction smaller than or equal to NumBytes
479// bytes. Return the size of nop emitted.
480static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
481 unsigned NumBytes, const MCSubtargetInfo &STI) {
482 if (NumBytes < 2) {
483 llvm_unreachable("Zero nops?");
484 return 0;
485 }
486 else if (NumBytes < 4) {
487 OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm)
488 .addImm(0).addReg(SystemZ::R0D), STI);
489 return 2;
490 }
491 else if (NumBytes < 6) {
492 OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm)
493 .addImm(0).addReg(0).addImm(0).addReg(0),
494 STI);
495 return 4;
496 }
497 else {
498 MCSymbol *DotSym = OutContext.createTempSymbol();
499 const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
500 OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm)
501 .addImm(0).addExpr(Dot), STI);
502 OutStreamer.EmitLabel(DotSym);
503 return 6;
504 }
505}
506
507void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
508 const SystemZInstrInfo *TII =
509 static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
510
511 unsigned NumNOPBytes = MI.getOperand(1).getImm();
512
513 SM.recordStackMap(MI);
514 assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
515
516 // Scan ahead to trim the shadow.
517 unsigned ShadowBytes = 0;
518 const MachineBasicBlock &MBB = *MI.getParent();
519 MachineBasicBlock::const_iterator MII(MI);
520 ++MII;
521 while (ShadowBytes < NumNOPBytes) {
522 if (MII == MBB.end() ||
523 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
524 MII->getOpcode() == TargetOpcode::STACKMAP)
525 break;
526 ShadowBytes += TII->getInstSizeInBytes(*MII);
527 if (MII->isCall())
528 break;
529 ++MII;
530 }
531
532 // Emit nops.
533 while (ShadowBytes < NumNOPBytes)
534 ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
535 getSubtargetInfo());
536}
537
538// Lower a patchpoint of the form:
539// [<def>], <id>, <numBytes>, <target>, <numArgs>
540void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
541 SystemZMCInstLower &Lower) {
542 SM.recordPatchPoint(MI);
543 PatchPointOpers Opers(&MI);
544
545 unsigned EncodedBytes = 0;
546 const MachineOperand &CalleeMO = Opers.getCallTarget();
547
548 if (CalleeMO.isImm()) {
549 uint64_t CallTarget = CalleeMO.getImm();
550 if (CallTarget) {
551 unsigned ScratchIdx = -1;
552 unsigned ScratchReg = 0;
553 do {
554 ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
555 ScratchReg = MI.getOperand(ScratchIdx).getReg();
556 } while (ScratchReg == SystemZ::R0D);
557
558 // Materialize the call target address
559 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
560 .addReg(ScratchReg)
561 .addImm(CallTarget & 0xFFFFFFFF));
562 EncodedBytes += 6;
563 if (CallTarget >> 32) {
564 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
565 .addReg(ScratchReg)
566 .addImm(CallTarget >> 32));
567 EncodedBytes += 6;
568 }
569
570 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
571 .addReg(SystemZ::R14D)
572 .addReg(ScratchReg));
573 EncodedBytes += 2;
574 }
575 } else if (CalleeMO.isGlobal()) {
576 const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
577 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
578 .addReg(SystemZ::R14D)
579 .addExpr(Expr));
580 EncodedBytes += 6;
581 }
582
583 // Emit padding.
584 unsigned NumBytes = Opers.getNumPatchBytes();
585 assert(NumBytes >= EncodedBytes &&
586 "Patchpoint can't request size less than the length of a call.");
587 assert((NumBytes - EncodedBytes) % 2 == 0 &&
588 "Invalid number of NOP bytes requested!");
589 while (EncodedBytes < NumBytes)
590 EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
591 getSubtargetInfo());
592}
593
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000594// Convert a SystemZ-specific constant pool modifier into the associated
595// MCSymbolRefExpr variant kind.
596static MCSymbolRefExpr::VariantKind
597getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
598 switch (Modifier) {
Ulrich Weigand7db69182015-02-18 09:13:27 +0000599 case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
600 case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
601 case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000602 case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
603 }
604 llvm_unreachable("Invalid SystemCPModifier!");
605}
606
607void SystemZAsmPrinter::
608EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
Richard Sandiford21f5d682014-03-06 11:22:58 +0000609 auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000610
611 const MCExpr *Expr =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000612 MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000613 getModifierVariantKind(ZCPV->getModifier()),
614 OutContext);
Mehdi Aminibd7287e2015-07-16 06:11:10 +0000615 uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000616
Lang Hames9ff69c82015-04-24 19:11:51 +0000617 OutStreamer->EmitValue(Expr, Size);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000618}
619
Nick Desaulniers5277b3f2019-04-10 16:38:43 +0000620bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000621 const char *ExtraCode,
622 raw_ostream &OS) {
Nick Desaulniers7ab164c2019-04-26 18:45:04 +0000623 if (ExtraCode)
624 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
625 SystemZMCInstLower Lower(MF->getContext(), *this);
626 MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
627 SystemZInstPrinter::printOperand(MO, MAI, OS);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000628 return false;
629}
630
631bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
632 unsigned OpNo,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000633 const char *ExtraCode,
634 raw_ostream &OS) {
635 SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
636 MI->getOperand(OpNo + 1).getImm(),
637 MI->getOperand(OpNo + 2).getReg(), OS);
638 return false;
639}
640
Ulrich Weigand5eb64112018-03-02 20:39:30 +0000641void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
Than McIntosh30c804b2018-11-26 18:43:48 +0000642 emitStackMaps(SM);
Ulrich Weigand5eb64112018-03-02 20:39:30 +0000643}
644
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000645// Force static initialization.
646extern "C" void LLVMInitializeSystemZAsmPrinter() {
Mehdi Aminif42454b2016-10-09 23:00:34 +0000647 RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000648}