36 }
else if (NumBytes < 4) {
38 MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI);
40 }
else if (NumBytes < 6) {
42 MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0),
67 std::unique_ptr<MCStreamer>
Streamer)
73 switch (
MI->getOpcode()) {
74 case TargetOpcode::FENTRY_CALL:
77 case TargetOpcode::STACKMAP:
80 case TargetOpcode::PATCHPOINT:
83 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
84 LowerPATCHABLE_FUNCTION_ENTER(*
MI,
Lower);
86 case TargetOpcode::PATCHABLE_RET:
89 case SystemZ::CallBASR:
91 .addReg(SystemZ::R14D)
92 .addReg(
MI->getOperand(0).getReg()));
94 case SystemZ::CallBRASL:
96 .addReg(SystemZ::R14D)
97 .addExpr(
Lower.getExpr(
MI->getOperand(0),
100 case SystemZ::CallJG:
102 .addExpr(
Lower.getExpr(
MI->getOperand(0),
105 case SystemZ::CallBRCL:
107 .addImm(
MI->getOperand(0).getImm())
112 case SystemZ::TLS_GDCALL:
114 .addReg(SystemZ::R14D)
119 case SystemZ::TLS_LDCALL:
123 .addReg(SystemZ::R14D)
130 .addReg(
MI->getOperand(0).getReg())
133 case SystemZ::LOAD_TLS_BLOCK_ADDR:
134 lowerLOAD_TLS_BLOCK_ADDR(*
MI,
Lower);
136 case SystemZ::LOAD_GLOBAL_STACKGUARD_ADDR:
137 lowerLOAD_GLOBAL_STACKGUARD_ADDR(*
MI,
Lower);
145void SystemZELFAsmPrinter::LowerFENTRY_CALL(
const MachineInstr &
MI,
164 const MCSymbolRefExpr *
Op =
167 MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(
Op),
172 auto *
TII =
MF->getSubtarget<SystemZSubtarget>().getInstrInfo();
174 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
180 SM.recordStackMap(*MILabel,
MI);
181 assert(NumNOPBytes % 2 == 0 &&
"Invalid number of NOP bytes requested!");
184 unsigned ShadowBytes = 0;
188 while (ShadowBytes < NumNOPBytes) {
189 if (MII ==
MBB.
end() || MII->getOpcode() == TargetOpcode::PATCHPOINT ||
190 MII->getOpcode() == TargetOpcode::STACKMAP)
192 ShadowBytes +=
TII->getInstSizeInBytes(*MII);
199 while (ShadowBytes < NumNOPBytes)
212 SM.recordPatchPoint(*MILabel,
MI);
213 PatchPointOpers Opers(&
MI);
215 unsigned EncodedBytes = 0;
216 const MachineOperand &CalleeMO = Opers.getCallTarget();
218 if (CalleeMO.
isImm()) {
221 unsigned ScratchIdx = -1;
222 unsigned ScratchReg = 0;
224 ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
225 ScratchReg =
MI.getOperand(ScratchIdx).getReg();
226 }
while (ScratchReg == SystemZ::R0D);
231 .addImm(CallTarget & 0xFFFFFFFF));
233 if (CallTarget >> 32) {
236 .addImm(CallTarget >> 32));
241 .addReg(SystemZ::R14D)
242 .addReg(ScratchReg));
249 MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R14D).addExpr(Expr));
254 unsigned NumBytes = Opers.getNumPatchBytes();
255 assert(NumBytes >= EncodedBytes &&
256 "Patchpoint can't request size less than the length of a call.");
257 assert((NumBytes - EncodedBytes) % 2 == 0 &&
258 "Invalid number of NOP bytes requested!");
259 while (EncodedBytes < NumBytes)
264void SystemZELFAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
270 if (
F.hasFnAttribute(
"patchable-function-entry")) {
271 unsigned Num =
F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
272 for (
unsigned I = 0;
I < Num; ++
I)
286 bool HasVectorFeature =
287 TM.getMCSubtargetInfo().hasFeature(SystemZ::FeatureVector) &&
288 !
TM.getMCSubtargetInfo().hasFeature(SystemZ::FeatureSoftFloat);
290 HasVectorFeature ?
"__xray_FunctionEntryVec" :
"__xray_FunctionEntry");
295 MCInstBuilder(SystemZ::J)
299 MCInstBuilder(SystemZ::LLILF).addReg(SystemZ::R2D).addImm(0));
301 .addReg(SystemZ::R14D)
308void SystemZELFAsmPrinter::LowerPATCHABLE_RET(
const MachineInstr &
MI,
310 unsigned OpCode =
MI.getOperand(0).getImm();
311 MCSymbol *FallthroughLabel =
nullptr;
312 if (OpCode == SystemZ::CondReturn) {
313 FallthroughLabel =
OutContext.createTempSymbol();
314 int64_t Cond0 =
MI.getOperand(1).getImm();
315 int64_t Cond1 =
MI.getOperand(2).getImm();
318 .addImm(Cond1 ^ Cond0)
331 bool HasVectorFeature =
332 TM.getMCSubtargetInfo().hasFeature(SystemZ::FeatureVector) &&
333 !
TM.getMCSubtargetInfo().hasFeature(SystemZ::FeatureSoftFloat);
335 HasVectorFeature ?
"__xray_FunctionExitVec" :
"__xray_FunctionExit");
339 MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D));
342 MCInstBuilder(SystemZ::LLILF).addReg(SystemZ::R2D).addImm(0));
346 if (FallthroughLabel)
351void SystemZELFAsmPrinter::lowerLOAD_TLS_BLOCK_ADDR(
const MachineInstr &
MI,
354 const MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
363 MCInstBuilder(SystemZ::EAR).addReg(Reg32).addReg(SystemZ::A0));
374 MCInstBuilder(SystemZ::EAR).addReg(Reg32).addReg(SystemZ::A1));
377void SystemZELFAsmPrinter::lowerLOAD_GLOBAL_STACKGUARD_ADDR(
381 const Module *
M =
MF.getFunction().getParent();
382 const TargetLowering *TLI =
MF.getSubtarget().getTargetLowering();
389 if (
M->hasStackProtectorGuardRecord()) {
406 MCInstBuilder(SystemZ::LGRL)
416void SystemZELFAsmPrinter::emitAttributes(
Module &M) {
417 if (
M.getModuleFlag(
"s390x-visible-vector-ABI")) {
418 bool HasVectorFeature =
419 TM.getMCSubtargetInfo().hasFeature(SystemZ::FeatureVector);
420 OutStreamer->emitGNUAttribute(8, HasVectorFeature ? 2 : 1);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const Function * getParent(const Value *V)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Promote Memory to Register
std::unique_ptr< MCStreamer > && Streamer
static uint8_t getSpecifierFromModifier(SystemZCP::SystemZCPModifier Modifier)
static const MCSymbolRefExpr * getGlobalOffsetTable(MCContext &Context)
static const MCSymbolRefExpr * getTLSGetOffset(MCContext &Context)
static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, unsigned NumBytes, const MCSubtargetInfo &STI)
MCSymbol * getSymbol(const GlobalValue *GV) const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
TargetMachine & TM
Target machine description.
MachineFunction * MF
The current machine function.
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, uint8_t Version=0)
MCContext & OutContext
This is the context for the output file that we are streaming.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
unsigned getPointerSize() const
Return the pointer size from the TargetMachine.
const DataLayout & getDataLayout() const
Return information about data layout.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Context object for machine code objects.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MachineInstrBundleIterator< const MachineInstr > const_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Abstract base class for all machine specific constantpool value subclasses.
MCContext & getContext() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
const TargetRegisterInfo * getTargetRegisterInfo() const
A Module instance is used to store all the information related to an LLVM module.
Represent a constant reference to a string, i.e.
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
A SystemZ-specific constant pool value.
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
SystemZELFAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
const LibcallLoweringInfo & getLibcallLoweringInfo() const
virtual Value * getSDagStackGuard(const Module &M, const LibcallLoweringInfo &Libcalls) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
Primary interface to the complete machine description for the target machine.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Implement std::hash so that hash_code can be used in STL containers.