[DAGCombiner] Eliminate dead stores to stack.
[llvm-complete.git] / lib / Target / SystemZ / SystemZAsmPrinter.cpp
blob162d30f819816dd53522777847a0f6f248826a27
1 //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Streams SystemZ assembly language and associated data, in the form of
10 // MCInsts and MCExprs respectively.
12 //===----------------------------------------------------------------------===//
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"
20 #include "llvm/IR/Mangler.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/Support/TargetRegistry.h"
26 using namespace llvm;
28 // Return an RI instruction like MI with opcode Opcode, but with the
29 // GR64 register operands turned into GR32s.
30 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
31 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());
42 // Return an RI instruction like MI with opcode Opcode, but with the
43 // GR64 register operands turned into GRH32s.
44 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
45 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());
56 // Return an RI instruction like MI with opcode Opcode, but with the
57 // R2 register turned into a GR64.
58 static 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());
68 static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
69 StringRef Name = "__tls_get_offset";
70 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
71 MCSymbolRefExpr::VK_PLT,
72 Context);
75 static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
76 StringRef Name = "_GLOBAL_OFFSET_TABLE_";
77 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
78 MCSymbolRefExpr::VK_None,
79 Context);
82 // 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.
84 static 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());
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.
94 static 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);
103 void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
104 SystemZMCInstLower Lower(MF->getContext(), *this);
105 MCInst LoweredMI;
106 switch (MI->getOpcode()) {
107 case SystemZ::Return:
108 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
109 break;
111 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;
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;
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;
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;
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;
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;
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;
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;
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;
190 case SystemZ::CallBRASL:
191 LoweredMI = MCInstBuilder(SystemZ::BRASL)
192 .addReg(SystemZ::R14D)
193 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
194 break;
196 case SystemZ::CallBASR:
197 LoweredMI = MCInstBuilder(SystemZ::BASR)
198 .addReg(SystemZ::R14D)
199 .addReg(MI->getOperand(0).getReg());
200 break;
202 case SystemZ::CallJG:
203 LoweredMI = MCInstBuilder(SystemZ::JG)
204 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
205 break;
207 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;
214 case SystemZ::CallBR:
215 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
216 break;
218 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;
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;
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;
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;
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;
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;
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;
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;
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;
297 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;
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;
311 case SystemZ::GOT:
312 LoweredMI = MCInstBuilder(SystemZ::LARL)
313 .addReg(MI->getOperand(0).getReg())
314 .addExpr(getGlobalOffsetTable(MF->getContext()));
315 break;
317 case SystemZ::IILF64:
318 LoweredMI = MCInstBuilder(SystemZ::IILF)
319 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
320 .addImm(MI->getOperand(2).getImm());
321 break;
323 case SystemZ::IIHF64:
324 LoweredMI = MCInstBuilder(SystemZ::IIHF)
325 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
326 .addImm(MI->getOperand(2).getImm());
327 break;
329 case SystemZ::RISBHH:
330 case SystemZ::RISBHL:
331 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
332 break;
334 case SystemZ::RISBLH:
335 case SystemZ::RISBLL:
336 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
337 break;
339 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;
346 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;
353 case SystemZ::VL32:
354 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
355 break;
357 case SystemZ::VL64:
358 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
359 break;
361 case SystemZ::VST32:
362 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
363 break;
365 case SystemZ::VST64:
366 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
367 break;
369 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;
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;
384 #define LOWER_LOW(NAME) \
385 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
387 LOWER_LOW(IILL);
388 LOWER_LOW(IILH);
389 LOWER_LOW(TMLL);
390 LOWER_LOW(TMLH);
391 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);
399 #undef LOWER_LOW
401 #define LOWER_HIGH(NAME) \
402 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
404 LOWER_HIGH(IIHL);
405 LOWER_HIGH(IIHH);
406 LOWER_HIGH(TMHL);
407 LOWER_HIGH(TMHH);
408 LOWER_HIGH(NIHL);
409 LOWER_HIGH(NIHH);
410 LOWER_HIGH(NIHF);
411 LOWER_HIGH(OIHL);
412 LOWER_HIGH(OIHH);
413 LOWER_HIGH(OIHF);
414 LOWER_HIGH(XIHF);
416 #undef LOWER_HIGH
418 case SystemZ::Serialize:
419 if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
420 LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
421 .addImm(14).addReg(SystemZ::R0D);
422 else
423 LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
424 .addImm(15).addReg(SystemZ::R0D);
425 break;
427 // Emit nothing here but a comment if we can.
428 case SystemZ::MemBarrier:
429 OutStreamer->emitRawComment("MEMBARRIER");
430 return;
432 // 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);
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));
445 break;
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);
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));
460 break;
462 case TargetOpcode::STACKMAP:
463 LowerSTACKMAP(*MI);
464 return;
466 case TargetOpcode::PATCHPOINT:
467 LowerPATCHPOINT(*MI, Lower);
468 return;
470 default:
471 Lower.lower(MI, LoweredMI);
472 break;
474 EmitToStreamer(*OutStreamer, LoweredMI);
478 // Emit the largest nop instruction smaller than or equal to NumBytes
479 // bytes. Return the size of nop emitted.
480 static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
481 unsigned NumBytes, const MCSubtargetInfo &STI) {
482 if (NumBytes < 2) {
483 llvm_unreachable("Zero nops?");
484 return 0;
486 else if (NumBytes < 4) {
487 OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm)
488 .addImm(0).addReg(SystemZ::R0D), STI);
489 return 2;
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;
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;
507 void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
508 const SystemZInstrInfo *TII =
509 static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
511 unsigned NumNOPBytes = MI.getOperand(1).getImm();
513 SM.recordStackMap(MI);
514 assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
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;
532 // Emit nops.
533 while (ShadowBytes < NumNOPBytes)
534 ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
535 getSubtargetInfo());
538 // Lower a patchpoint of the form:
539 // [<def>], <id>, <numBytes>, <target>, <numArgs>
540 void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
541 SystemZMCInstLower &Lower) {
542 SM.recordPatchPoint(MI);
543 PatchPointOpers Opers(&MI);
545 unsigned EncodedBytes = 0;
546 const MachineOperand &CalleeMO = Opers.getCallTarget();
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);
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;
570 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
571 .addReg(SystemZ::R14D)
572 .addReg(ScratchReg));
573 EncodedBytes += 2;
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;
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());
594 // Convert a SystemZ-specific constant pool modifier into the associated
595 // MCSymbolRefExpr variant kind.
596 static MCSymbolRefExpr::VariantKind
597 getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
598 switch (Modifier) {
599 case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
600 case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
601 case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
602 case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
604 llvm_unreachable("Invalid SystemCPModifier!");
607 void SystemZAsmPrinter::
608 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
609 auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
611 const MCExpr *Expr =
612 MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
613 getModifierVariantKind(ZCPV->getModifier()),
614 OutContext);
615 uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
617 OutStreamer->EmitValue(Expr, Size);
620 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
621 unsigned OpNo,
622 unsigned AsmVariant,
623 const char *ExtraCode,
624 raw_ostream &OS) {
625 if (ExtraCode && *ExtraCode == 'n') {
626 if (!MI->getOperand(OpNo).isImm())
627 return true;
628 OS << -int64_t(MI->getOperand(OpNo).getImm());
629 } else {
630 SystemZMCInstLower Lower(MF->getContext(), *this);
631 MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
632 SystemZInstPrinter::printOperand(MO, MAI, OS);
634 return false;
637 bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
638 unsigned OpNo,
639 unsigned AsmVariant,
640 const char *ExtraCode,
641 raw_ostream &OS) {
642 SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
643 MI->getOperand(OpNo + 1).getImm(),
644 MI->getOperand(OpNo + 2).getReg(), OS);
645 return false;
648 void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
649 emitStackMaps(SM);
652 // Force static initialization.
653 extern "C" void LLVMInitializeSystemZAsmPrinter() {
654 RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());