1 //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
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
7 //===----------------------------------------------------------------------===//
9 // Streams SystemZ assembly language and associated data, in the form of
10 // MCInsts and MCExprs respectively.
12 //===----------------------------------------------------------------------===//
14 #include "SystemZAsmPrinter.h"
15 #include "MCTargetDesc/SystemZInstPrinter.h"
16 #include "SystemZConstantPoolValue.h"
17 #include "SystemZMCInstLower.h"
18 #include "TargetInfo/SystemZTargetInfo.h"
19 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/Support/TargetRegistry.h"
29 // Return an RI instruction like MI with opcode Opcode, but with the
30 // GR64 register operands turned into GR32s.
31 static MCInst
lowerRILow(const MachineInstr
*MI
, unsigned Opcode
) {
33 return MCInstBuilder(Opcode
)
34 .addReg(SystemZMC::getRegAsGR32(MI
->getOperand(0).getReg()))
35 .addImm(MI
->getOperand(1).getImm());
37 return MCInstBuilder(Opcode
)
38 .addReg(SystemZMC::getRegAsGR32(MI
->getOperand(0).getReg()))
39 .addReg(SystemZMC::getRegAsGR32(MI
->getOperand(1).getReg()))
40 .addImm(MI
->getOperand(2).getImm());
43 // Return an RI instruction like MI with opcode Opcode, but with the
44 // GR64 register operands turned into GRH32s.
45 static MCInst
lowerRIHigh(const MachineInstr
*MI
, unsigned Opcode
) {
47 return MCInstBuilder(Opcode
)
48 .addReg(SystemZMC::getRegAsGRH32(MI
->getOperand(0).getReg()))
49 .addImm(MI
->getOperand(1).getImm());
51 return MCInstBuilder(Opcode
)
52 .addReg(SystemZMC::getRegAsGRH32(MI
->getOperand(0).getReg()))
53 .addReg(SystemZMC::getRegAsGRH32(MI
->getOperand(1).getReg()))
54 .addImm(MI
->getOperand(2).getImm());
57 // Return an RI instruction like MI with opcode Opcode, but with the
58 // R2 register turned into a GR64.
59 static MCInst
lowerRIEfLow(const MachineInstr
*MI
, unsigned Opcode
) {
60 return MCInstBuilder(Opcode
)
61 .addReg(MI
->getOperand(0).getReg())
62 .addReg(MI
->getOperand(1).getReg())
63 .addReg(SystemZMC::getRegAsGR64(MI
->getOperand(2).getReg()))
64 .addImm(MI
->getOperand(3).getImm())
65 .addImm(MI
->getOperand(4).getImm())
66 .addImm(MI
->getOperand(5).getImm());
69 static const MCSymbolRefExpr
*getTLSGetOffset(MCContext
&Context
) {
70 StringRef Name
= "__tls_get_offset";
71 return MCSymbolRefExpr::create(Context
.getOrCreateSymbol(Name
),
72 MCSymbolRefExpr::VK_PLT
,
76 static const MCSymbolRefExpr
*getGlobalOffsetTable(MCContext
&Context
) {
77 StringRef Name
= "_GLOBAL_OFFSET_TABLE_";
78 return MCSymbolRefExpr::create(Context
.getOrCreateSymbol(Name
),
79 MCSymbolRefExpr::VK_None
,
83 // MI is an instruction that accepts an optional alignment hint,
84 // and which was already lowered to LoweredMI. If the alignment
85 // of the original memory operand is known, update LoweredMI to
86 // an instruction with the corresponding hint set.
87 static void lowerAlignmentHint(const MachineInstr
*MI
, MCInst
&LoweredMI
,
89 if (!MI
->hasOneMemOperand())
91 const MachineMemOperand
*MMO
= *MI
->memoperands_begin();
92 unsigned AlignmentHint
= 0;
93 if (MMO
->getAlignment() >= 16)
95 else if (MMO
->getAlignment() >= 8)
97 if (AlignmentHint
== 0)
100 LoweredMI
.setOpcode(Opcode
);
101 LoweredMI
.addOperand(MCOperand::createImm(AlignmentHint
));
104 // MI loads the high part of a vector from memory. Return an instruction
105 // that uses replicating vector load Opcode to do the same thing.
106 static MCInst
lowerSubvectorLoad(const MachineInstr
*MI
, unsigned Opcode
) {
107 return MCInstBuilder(Opcode
)
108 .addReg(SystemZMC::getRegAsVR128(MI
->getOperand(0).getReg()))
109 .addReg(MI
->getOperand(1).getReg())
110 .addImm(MI
->getOperand(2).getImm())
111 .addReg(MI
->getOperand(3).getReg());
114 // MI stores the high part of a vector to memory. Return an instruction
115 // that uses elemental vector store Opcode to do the same thing.
116 static MCInst
lowerSubvectorStore(const MachineInstr
*MI
, unsigned Opcode
) {
117 return MCInstBuilder(Opcode
)
118 .addReg(SystemZMC::getRegAsVR128(MI
->getOperand(0).getReg()))
119 .addReg(MI
->getOperand(1).getReg())
120 .addImm(MI
->getOperand(2).getImm())
121 .addReg(MI
->getOperand(3).getReg())
125 void SystemZAsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
126 SystemZMCInstLower
Lower(MF
->getContext(), *this);
128 switch (MI
->getOpcode()) {
129 case SystemZ::Return
:
130 LoweredMI
= MCInstBuilder(SystemZ::BR
).addReg(SystemZ::R14D
);
133 case SystemZ::CondReturn
:
134 LoweredMI
= MCInstBuilder(SystemZ::BCR
)
135 .addImm(MI
->getOperand(0).getImm())
136 .addImm(MI
->getOperand(1).getImm())
137 .addReg(SystemZ::R14D
);
140 case SystemZ::CRBReturn
:
141 LoweredMI
= MCInstBuilder(SystemZ::CRB
)
142 .addReg(MI
->getOperand(0).getReg())
143 .addReg(MI
->getOperand(1).getReg())
144 .addImm(MI
->getOperand(2).getImm())
145 .addReg(SystemZ::R14D
)
149 case SystemZ::CGRBReturn
:
150 LoweredMI
= MCInstBuilder(SystemZ::CGRB
)
151 .addReg(MI
->getOperand(0).getReg())
152 .addReg(MI
->getOperand(1).getReg())
153 .addImm(MI
->getOperand(2).getImm())
154 .addReg(SystemZ::R14D
)
158 case SystemZ::CIBReturn
:
159 LoweredMI
= MCInstBuilder(SystemZ::CIB
)
160 .addReg(MI
->getOperand(0).getReg())
161 .addImm(MI
->getOperand(1).getImm())
162 .addImm(MI
->getOperand(2).getImm())
163 .addReg(SystemZ::R14D
)
167 case SystemZ::CGIBReturn
:
168 LoweredMI
= MCInstBuilder(SystemZ::CGIB
)
169 .addReg(MI
->getOperand(0).getReg())
170 .addImm(MI
->getOperand(1).getImm())
171 .addImm(MI
->getOperand(2).getImm())
172 .addReg(SystemZ::R14D
)
176 case SystemZ::CLRBReturn
:
177 LoweredMI
= MCInstBuilder(SystemZ::CLRB
)
178 .addReg(MI
->getOperand(0).getReg())
179 .addReg(MI
->getOperand(1).getReg())
180 .addImm(MI
->getOperand(2).getImm())
181 .addReg(SystemZ::R14D
)
185 case SystemZ::CLGRBReturn
:
186 LoweredMI
= MCInstBuilder(SystemZ::CLGRB
)
187 .addReg(MI
->getOperand(0).getReg())
188 .addReg(MI
->getOperand(1).getReg())
189 .addImm(MI
->getOperand(2).getImm())
190 .addReg(SystemZ::R14D
)
194 case SystemZ::CLIBReturn
:
195 LoweredMI
= MCInstBuilder(SystemZ::CLIB
)
196 .addReg(MI
->getOperand(0).getReg())
197 .addImm(MI
->getOperand(1).getImm())
198 .addImm(MI
->getOperand(2).getImm())
199 .addReg(SystemZ::R14D
)
203 case SystemZ::CLGIBReturn
:
204 LoweredMI
= MCInstBuilder(SystemZ::CLGIB
)
205 .addReg(MI
->getOperand(0).getReg())
206 .addImm(MI
->getOperand(1).getImm())
207 .addImm(MI
->getOperand(2).getImm())
208 .addReg(SystemZ::R14D
)
212 case SystemZ::CallBRASL
:
213 LoweredMI
= MCInstBuilder(SystemZ::BRASL
)
214 .addReg(SystemZ::R14D
)
215 .addExpr(Lower
.getExpr(MI
->getOperand(0), MCSymbolRefExpr::VK_PLT
));
218 case SystemZ::CallBASR
:
219 LoweredMI
= MCInstBuilder(SystemZ::BASR
)
220 .addReg(SystemZ::R14D
)
221 .addReg(MI
->getOperand(0).getReg());
224 case SystemZ::CallJG
:
225 LoweredMI
= MCInstBuilder(SystemZ::JG
)
226 .addExpr(Lower
.getExpr(MI
->getOperand(0), MCSymbolRefExpr::VK_PLT
));
229 case SystemZ::CallBRCL
:
230 LoweredMI
= MCInstBuilder(SystemZ::BRCL
)
231 .addImm(MI
->getOperand(0).getImm())
232 .addImm(MI
->getOperand(1).getImm())
233 .addExpr(Lower
.getExpr(MI
->getOperand(2), MCSymbolRefExpr::VK_PLT
));
236 case SystemZ::CallBR
:
237 LoweredMI
= MCInstBuilder(SystemZ::BR
).addReg(SystemZ::R1D
);
240 case SystemZ::CallBCR
:
241 LoweredMI
= MCInstBuilder(SystemZ::BCR
)
242 .addImm(MI
->getOperand(0).getImm())
243 .addImm(MI
->getOperand(1).getImm())
244 .addReg(SystemZ::R1D
);
247 case SystemZ::CRBCall
:
248 LoweredMI
= MCInstBuilder(SystemZ::CRB
)
249 .addReg(MI
->getOperand(0).getReg())
250 .addReg(MI
->getOperand(1).getReg())
251 .addImm(MI
->getOperand(2).getImm())
252 .addReg(SystemZ::R1D
)
256 case SystemZ::CGRBCall
:
257 LoweredMI
= MCInstBuilder(SystemZ::CGRB
)
258 .addReg(MI
->getOperand(0).getReg())
259 .addReg(MI
->getOperand(1).getReg())
260 .addImm(MI
->getOperand(2).getImm())
261 .addReg(SystemZ::R1D
)
265 case SystemZ::CIBCall
:
266 LoweredMI
= MCInstBuilder(SystemZ::CIB
)
267 .addReg(MI
->getOperand(0).getReg())
268 .addImm(MI
->getOperand(1).getImm())
269 .addImm(MI
->getOperand(2).getImm())
270 .addReg(SystemZ::R1D
)
274 case SystemZ::CGIBCall
:
275 LoweredMI
= MCInstBuilder(SystemZ::CGIB
)
276 .addReg(MI
->getOperand(0).getReg())
277 .addImm(MI
->getOperand(1).getImm())
278 .addImm(MI
->getOperand(2).getImm())
279 .addReg(SystemZ::R1D
)
283 case SystemZ::CLRBCall
:
284 LoweredMI
= MCInstBuilder(SystemZ::CLRB
)
285 .addReg(MI
->getOperand(0).getReg())
286 .addReg(MI
->getOperand(1).getReg())
287 .addImm(MI
->getOperand(2).getImm())
288 .addReg(SystemZ::R1D
)
292 case SystemZ::CLGRBCall
:
293 LoweredMI
= MCInstBuilder(SystemZ::CLGRB
)
294 .addReg(MI
->getOperand(0).getReg())
295 .addReg(MI
->getOperand(1).getReg())
296 .addImm(MI
->getOperand(2).getImm())
297 .addReg(SystemZ::R1D
)
301 case SystemZ::CLIBCall
:
302 LoweredMI
= MCInstBuilder(SystemZ::CLIB
)
303 .addReg(MI
->getOperand(0).getReg())
304 .addImm(MI
->getOperand(1).getImm())
305 .addImm(MI
->getOperand(2).getImm())
306 .addReg(SystemZ::R1D
)
310 case SystemZ::CLGIBCall
:
311 LoweredMI
= MCInstBuilder(SystemZ::CLGIB
)
312 .addReg(MI
->getOperand(0).getReg())
313 .addImm(MI
->getOperand(1).getImm())
314 .addImm(MI
->getOperand(2).getImm())
315 .addReg(SystemZ::R1D
)
319 case SystemZ::TLS_GDCALL
:
320 LoweredMI
= MCInstBuilder(SystemZ::BRASL
)
321 .addReg(SystemZ::R14D
)
322 .addExpr(getTLSGetOffset(MF
->getContext()))
323 .addExpr(Lower
.getExpr(MI
->getOperand(0), MCSymbolRefExpr::VK_TLSGD
));
326 case SystemZ::TLS_LDCALL
:
327 LoweredMI
= MCInstBuilder(SystemZ::BRASL
)
328 .addReg(SystemZ::R14D
)
329 .addExpr(getTLSGetOffset(MF
->getContext()))
330 .addExpr(Lower
.getExpr(MI
->getOperand(0), MCSymbolRefExpr::VK_TLSLDM
));
334 LoweredMI
= MCInstBuilder(SystemZ::LARL
)
335 .addReg(MI
->getOperand(0).getReg())
336 .addExpr(getGlobalOffsetTable(MF
->getContext()));
339 case SystemZ::IILF64
:
340 LoweredMI
= MCInstBuilder(SystemZ::IILF
)
341 .addReg(SystemZMC::getRegAsGR32(MI
->getOperand(0).getReg()))
342 .addImm(MI
->getOperand(2).getImm());
345 case SystemZ::IIHF64
:
346 LoweredMI
= MCInstBuilder(SystemZ::IIHF
)
347 .addReg(SystemZMC::getRegAsGRH32(MI
->getOperand(0).getReg()))
348 .addImm(MI
->getOperand(2).getImm());
351 case SystemZ::RISBHH
:
352 case SystemZ::RISBHL
:
353 LoweredMI
= lowerRIEfLow(MI
, SystemZ::RISBHG
);
356 case SystemZ::RISBLH
:
357 case SystemZ::RISBLL
:
358 LoweredMI
= lowerRIEfLow(MI
, SystemZ::RISBLG
);
361 case SystemZ::VLVGP32
:
362 LoweredMI
= MCInstBuilder(SystemZ::VLVGP
)
363 .addReg(MI
->getOperand(0).getReg())
364 .addReg(SystemZMC::getRegAsGR64(MI
->getOperand(1).getReg()))
365 .addReg(SystemZMC::getRegAsGR64(MI
->getOperand(2).getReg()));
370 LoweredMI
= MCInstBuilder(SystemZ::VLR
)
371 .addReg(SystemZMC::getRegAsVR128(MI
->getOperand(0).getReg()))
372 .addReg(SystemZMC::getRegAsVR128(MI
->getOperand(1).getReg()));
376 Lower
.lower(MI
, LoweredMI
);
377 lowerAlignmentHint(MI
, LoweredMI
, SystemZ::VLAlign
);
381 Lower
.lower(MI
, LoweredMI
);
382 lowerAlignmentHint(MI
, LoweredMI
, SystemZ::VSTAlign
);
386 Lower
.lower(MI
, LoweredMI
);
387 lowerAlignmentHint(MI
, LoweredMI
, SystemZ::VLMAlign
);
391 Lower
.lower(MI
, LoweredMI
);
392 lowerAlignmentHint(MI
, LoweredMI
, SystemZ::VSTMAlign
);
396 LoweredMI
= lowerSubvectorLoad(MI
, SystemZ::VLREPF
);
400 LoweredMI
= lowerSubvectorLoad(MI
, SystemZ::VLREPG
);
404 LoweredMI
= lowerSubvectorStore(MI
, SystemZ::VSTEF
);
408 LoweredMI
= lowerSubvectorStore(MI
, SystemZ::VSTEG
);
412 LoweredMI
= MCInstBuilder(SystemZ::VLGVF
)
413 .addReg(SystemZMC::getRegAsGR64(MI
->getOperand(0).getReg()))
414 .addReg(SystemZMC::getRegAsVR128(MI
->getOperand(1).getReg()))
415 .addReg(0).addImm(0);
419 LoweredMI
= MCInstBuilder(SystemZ::VLVGF
)
420 .addReg(SystemZMC::getRegAsVR128(MI
->getOperand(0).getReg()))
421 .addReg(SystemZMC::getRegAsVR128(MI
->getOperand(0).getReg()))
422 .addReg(MI
->getOperand(1).getReg())
423 .addReg(0).addImm(0);
426 #define LOWER_LOW(NAME) \
427 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
443 #define LOWER_HIGH(NAME) \
444 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
460 case SystemZ::Serialize
:
461 if (MF
->getSubtarget
<SystemZSubtarget
>().hasFastSerialization())
462 LoweredMI
= MCInstBuilder(SystemZ::BCRAsm
)
463 .addImm(14).addReg(SystemZ::R0D
);
465 LoweredMI
= MCInstBuilder(SystemZ::BCRAsm
)
466 .addImm(15).addReg(SystemZ::R0D
);
469 // Emit nothing here but a comment if we can.
470 case SystemZ::MemBarrier
:
471 OutStreamer
->emitRawComment("MEMBARRIER");
474 // We want to emit "j .+2" for traps, jumping to the relative immediate field
475 // of the jump instruction, which is an illegal instruction. We cannot emit a
476 // "." symbol, so create and emit a temp label before the instruction and use
478 case SystemZ::Trap
: {
479 MCSymbol
*DotSym
= OutContext
.createTempSymbol();
480 OutStreamer
->EmitLabel(DotSym
);
482 const MCSymbolRefExpr
*Expr
= MCSymbolRefExpr::create(DotSym
, OutContext
);
483 const MCConstantExpr
*ConstExpr
= MCConstantExpr::create(2, OutContext
);
484 LoweredMI
= MCInstBuilder(SystemZ::J
)
485 .addExpr(MCBinaryExpr::createAdd(Expr
, ConstExpr
, OutContext
));
489 // Conditional traps will create a branch on condition instruction that jumps
490 // to the relative immediate field of the jump instruction. (eg. "jo .+2")
491 case SystemZ::CondTrap
: {
492 MCSymbol
*DotSym
= OutContext
.createTempSymbol();
493 OutStreamer
->EmitLabel(DotSym
);
495 const MCSymbolRefExpr
*Expr
= MCSymbolRefExpr::create(DotSym
, OutContext
);
496 const MCConstantExpr
*ConstExpr
= MCConstantExpr::create(2, OutContext
);
497 LoweredMI
= MCInstBuilder(SystemZ::BRC
)
498 .addImm(MI
->getOperand(0).getImm())
499 .addImm(MI
->getOperand(1).getImm())
500 .addExpr(MCBinaryExpr::createAdd(Expr
, ConstExpr
, OutContext
));
504 case TargetOpcode::FENTRY_CALL
:
505 LowerFENTRY_CALL(*MI
, Lower
);
508 case TargetOpcode::STACKMAP
:
512 case TargetOpcode::PATCHPOINT
:
513 LowerPATCHPOINT(*MI
, Lower
);
517 Lower
.lower(MI
, LoweredMI
);
520 EmitToStreamer(*OutStreamer
, LoweredMI
);
524 // Emit the largest nop instruction smaller than or equal to NumBytes
525 // bytes. Return the size of nop emitted.
526 static unsigned EmitNop(MCContext
&OutContext
, MCStreamer
&OutStreamer
,
527 unsigned NumBytes
, const MCSubtargetInfo
&STI
) {
529 llvm_unreachable("Zero nops?");
532 else if (NumBytes
< 4) {
533 OutStreamer
.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm
)
534 .addImm(0).addReg(SystemZ::R0D
), STI
);
537 else if (NumBytes
< 6) {
538 OutStreamer
.EmitInstruction(MCInstBuilder(SystemZ::BCAsm
)
539 .addImm(0).addReg(0).addImm(0).addReg(0),
544 MCSymbol
*DotSym
= OutContext
.createTempSymbol();
545 const MCSymbolRefExpr
*Dot
= MCSymbolRefExpr::create(DotSym
, OutContext
);
546 OutStreamer
.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm
)
547 .addImm(0).addExpr(Dot
), STI
);
548 OutStreamer
.EmitLabel(DotSym
);
553 void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr
&MI
,
554 SystemZMCInstLower
&Lower
) {
555 MCContext
&Ctx
= MF
->getContext();
556 if (MF
->getFunction().getFnAttribute("mnop-mcount")
557 .getValueAsString() == "true") {
558 EmitNop(Ctx
, *OutStreamer
, 6, getSubtargetInfo());
562 MCSymbol
*fentry
= Ctx
.getOrCreateSymbol("__fentry__");
563 const MCSymbolRefExpr
*Op
=
564 MCSymbolRefExpr::create(fentry
, MCSymbolRefExpr::VK_PLT
, Ctx
);
565 OutStreamer
->EmitInstruction(MCInstBuilder(SystemZ::BRASL
)
566 .addReg(SystemZ::R0D
).addExpr(Op
), getSubtargetInfo());
569 void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr
&MI
) {
570 const SystemZInstrInfo
*TII
=
571 static_cast<const SystemZInstrInfo
*>(MF
->getSubtarget().getInstrInfo());
573 unsigned NumNOPBytes
= MI
.getOperand(1).getImm();
575 SM
.recordStackMap(MI
);
576 assert(NumNOPBytes
% 2 == 0 && "Invalid number of NOP bytes requested!");
578 // Scan ahead to trim the shadow.
579 unsigned ShadowBytes
= 0;
580 const MachineBasicBlock
&MBB
= *MI
.getParent();
581 MachineBasicBlock::const_iterator
MII(MI
);
583 while (ShadowBytes
< NumNOPBytes
) {
584 if (MII
== MBB
.end() ||
585 MII
->getOpcode() == TargetOpcode::PATCHPOINT
||
586 MII
->getOpcode() == TargetOpcode::STACKMAP
)
588 ShadowBytes
+= TII
->getInstSizeInBytes(*MII
);
595 while (ShadowBytes
< NumNOPBytes
)
596 ShadowBytes
+= EmitNop(OutContext
, *OutStreamer
, NumNOPBytes
- ShadowBytes
,
600 // Lower a patchpoint of the form:
601 // [<def>], <id>, <numBytes>, <target>, <numArgs>
602 void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr
&MI
,
603 SystemZMCInstLower
&Lower
) {
604 SM
.recordPatchPoint(MI
);
605 PatchPointOpers
Opers(&MI
);
607 unsigned EncodedBytes
= 0;
608 const MachineOperand
&CalleeMO
= Opers
.getCallTarget();
610 if (CalleeMO
.isImm()) {
611 uint64_t CallTarget
= CalleeMO
.getImm();
613 unsigned ScratchIdx
= -1;
614 unsigned ScratchReg
= 0;
616 ScratchIdx
= Opers
.getNextScratchIdx(ScratchIdx
+ 1);
617 ScratchReg
= MI
.getOperand(ScratchIdx
).getReg();
618 } while (ScratchReg
== SystemZ::R0D
);
620 // Materialize the call target address
621 EmitToStreamer(*OutStreamer
, MCInstBuilder(SystemZ::LLILF
)
623 .addImm(CallTarget
& 0xFFFFFFFF));
625 if (CallTarget
>> 32) {
626 EmitToStreamer(*OutStreamer
, MCInstBuilder(SystemZ::IIHF
)
628 .addImm(CallTarget
>> 32));
632 EmitToStreamer(*OutStreamer
, MCInstBuilder(SystemZ::BASR
)
633 .addReg(SystemZ::R14D
)
634 .addReg(ScratchReg
));
637 } else if (CalleeMO
.isGlobal()) {
638 const MCExpr
*Expr
= Lower
.getExpr(CalleeMO
, MCSymbolRefExpr::VK_PLT
);
639 EmitToStreamer(*OutStreamer
, MCInstBuilder(SystemZ::BRASL
)
640 .addReg(SystemZ::R14D
)
646 unsigned NumBytes
= Opers
.getNumPatchBytes();
647 assert(NumBytes
>= EncodedBytes
&&
648 "Patchpoint can't request size less than the length of a call.");
649 assert((NumBytes
- EncodedBytes
) % 2 == 0 &&
650 "Invalid number of NOP bytes requested!");
651 while (EncodedBytes
< NumBytes
)
652 EncodedBytes
+= EmitNop(OutContext
, *OutStreamer
, NumBytes
- EncodedBytes
,
656 // Convert a SystemZ-specific constant pool modifier into the associated
657 // MCSymbolRefExpr variant kind.
658 static MCSymbolRefExpr::VariantKind
659 getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier
) {
661 case SystemZCP::TLSGD
: return MCSymbolRefExpr::VK_TLSGD
;
662 case SystemZCP::TLSLDM
: return MCSymbolRefExpr::VK_TLSLDM
;
663 case SystemZCP::DTPOFF
: return MCSymbolRefExpr::VK_DTPOFF
;
664 case SystemZCP::NTPOFF
: return MCSymbolRefExpr::VK_NTPOFF
;
666 llvm_unreachable("Invalid SystemCPModifier!");
669 void SystemZAsmPrinter::
670 EmitMachineConstantPoolValue(MachineConstantPoolValue
*MCPV
) {
671 auto *ZCPV
= static_cast<SystemZConstantPoolValue
*>(MCPV
);
674 MCSymbolRefExpr::create(getSymbol(ZCPV
->getGlobalValue()),
675 getModifierVariantKind(ZCPV
->getModifier()),
677 uint64_t Size
= getDataLayout().getTypeAllocSize(ZCPV
->getType());
679 OutStreamer
->EmitValue(Expr
, Size
);
682 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
683 const char *ExtraCode
,
686 return AsmPrinter::PrintAsmOperand(MI
, OpNo
, ExtraCode
, OS
);
687 SystemZMCInstLower
Lower(MF
->getContext(), *this);
688 MCOperand
MO(Lower
.lowerOperand(MI
->getOperand(OpNo
)));
689 SystemZInstPrinter::printOperand(MO
, MAI
, OS
);
693 bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
695 const char *ExtraCode
,
697 SystemZInstPrinter::printAddress(MI
->getOperand(OpNo
).getReg(),
698 MI
->getOperand(OpNo
+ 1).getImm(),
699 MI
->getOperand(OpNo
+ 2).getReg(), OS
);
703 void SystemZAsmPrinter::EmitEndOfAsmFile(Module
&M
) {
707 // Force static initialization.
708 extern "C" void LLVMInitializeSystemZAsmPrinter() {
709 RegisterAsmPrinter
<SystemZAsmPrinter
> X(getTheSystemZTarget());