91 if (
MI->memoperands_empty())
96 EE =
MI->memoperands_end(); MMOI != EE; ++MMOI)
97 if ((*MMOI)->getAlign() < Alignment)
98 Alignment = (*MMOI)->getAlign();
100 unsigned AlignmentHint = 0;
101 if (Alignment >=
Align(16))
103 else if (Alignment >=
Align(8))
105 if (AlignmentHint == 0)
119 .
addReg(
MI->getOperand(3).getReg());
138void SystemZAsmPrinter::emitCallInformation(CallType CT) {
146 SystemZ_MC::verifyInstructionPredicates(
MI->getOpcode(),
151 switch (
MI->getOpcode()) {
152 case SystemZ::Return:
157 case SystemZ::Return_XPLINK:
164 case SystemZ::CondReturn:
171 case SystemZ::CondReturn_XPLINK:
180 case SystemZ::CRBReturn:
189 case SystemZ::CGRBReturn:
198 case SystemZ::CIBReturn:
207 case SystemZ::CGIBReturn:
216 case SystemZ::CLRBReturn:
225 case SystemZ::CLGRBReturn:
234 case SystemZ::CLIBReturn:
243 case SystemZ::CLGIBReturn:
252 case SystemZ::CallBRASL_XPLINK64:
255 .addReg(SystemZ::R7D)
256 .addExpr(
Lower.getExpr(
MI->getOperand(0),
258 emitCallInformation(CallType::BRASL7);
261 case SystemZ::CallBASR_XPLINK64:
263 .addReg(SystemZ::R7D)
264 .addReg(
MI->getOperand(0).getReg()));
265 emitCallInformation(CallType::BASR76);
268 case SystemZ::CallBASR_STACKEXT:
270 .addReg(SystemZ::R3D)
271 .addReg(
MI->getOperand(0).getReg()));
272 emitCallInformation(CallType::BASR33);
275 case SystemZ::CallBRASL:
281 case SystemZ::CallBASR:
284 .
addReg(
MI->getOperand(0).getReg());
287 case SystemZ::CallJG:
292 case SystemZ::CallBRCL:
299 case SystemZ::CallBR:
301 .
addReg(
MI->getOperand(0).getReg());
304 case SystemZ::CallBCR:
308 .
addReg(
MI->getOperand(2).getReg());
311 case SystemZ::CRBCall:
320 case SystemZ::CGRBCall:
329 case SystemZ::CIBCall:
338 case SystemZ::CGIBCall:
347 case SystemZ::CLRBCall:
356 case SystemZ::CLGRBCall:
365 case SystemZ::CLIBCall:
374 case SystemZ::CLGIBCall:
383 case SystemZ::TLS_GDCALL:
390 case SystemZ::TLS_LDCALL:
403 case SystemZ::IILF64:
406 .
addImm(
MI->getOperand(2).getImm());
409 case SystemZ::IIHF64:
412 .
addImm(
MI->getOperand(2).getImm());
415 case SystemZ::RISBHH:
416 case SystemZ::RISBHL:
420 case SystemZ::RISBLH:
421 case SystemZ::RISBLL:
425 case SystemZ::VLVGP32:
490#define LOWER_LOW(NAME) \
491 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
507#define LOWER_HIGH(NAME) \
508 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
524 case SystemZ::Serialize:
537 case SystemZ::Trap: {
550 case SystemZ::CondTrap: {
563 case TargetOpcode::FENTRY_CALL:
567 case TargetOpcode::STACKMAP:
571 case TargetOpcode::PATCHPOINT:
575 case SystemZ::EXRL_Pseudo: {
576 unsigned TargetInsOpc =
MI->getOperand(0).getImm();
577 Register LenMinus1Reg =
MI->getOperand(1).getReg();
578 Register DestReg =
MI->getOperand(2).getReg();
579 int64_t DestDisp =
MI->getOperand(3).getImm();
581 int64_t SrcDisp =
MI->getOperand(5).getImm();
588 SystemZTargetStreamer::EXRLT2SymMap::iterator
I =
597 MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot));
616 else if (NumBytes < 4) {
618 MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI);
621 else if (NumBytes < 6) {
623 MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0),
632 MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI);
659 MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op),
666 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
673 assert(NumNOPBytes % 2 == 0 &&
"Invalid number of NOP bytes requested!");
676 unsigned ShadowBytes = 0;
680 while (ShadowBytes < NumNOPBytes) {
682 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
683 MII->getOpcode() == TargetOpcode::STACKMAP)
685 ShadowBytes +=
TII->getInstSizeInBytes(*MII);
692 while (ShadowBytes < NumNOPBytes)
708 unsigned EncodedBytes = 0;
711 if (CalleeMO.
isImm()) {
714 unsigned ScratchIdx = -1;
715 unsigned ScratchReg = 0;
717 ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
718 ScratchReg =
MI.getOperand(ScratchIdx).getReg();
719 }
while (ScratchReg == SystemZ::R0D);
724 .addImm(CallTarget & 0xFFFFFFFF));
726 if (CallTarget >> 32) {
729 .addImm(CallTarget >> 32));
734 .addReg(SystemZ::R14D)
735 .addReg(ScratchReg));
741 .addReg(SystemZ::R14D)
747 unsigned NumBytes = Opers.getNumPatchBytes();
748 assert(NumBytes >= EncodedBytes &&
749 "Patchpoint can't request size less than the length of a call.");
750 assert((NumBytes - EncodedBytes) % 2 == 0 &&
751 "Invalid number of NOP bytes requested!");
752 while (EncodedBytes < NumBytes)
760void SystemZAsmPrinter::emitAttributes(
Module &M) {
761 if (
M.getModuleFlag(
"s390x-visible-vector-ABI")) {
762 bool HasVectorFeature =
764 OutStreamer->emitGNUAttribute(8, HasVectorFeature ? 2 : 1);
812 }
else if (MCOp.
isImm())
838 const char *ExtraCode,
844 if (ExtraCode[0] ==
'N' && !ExtraCode[1] && MO.
isReg() &&
845 SystemZ::GR128BitRegClass.contains(MO.
getReg()))
852 MCOp =
Lower.lowerOperand(MO);
860 const char *ExtraCode,
864 MI->getOperand(OpNo + 2).getReg(),
OS);
884 CurrentFnPPA1Sym =
nullptr;
885 CurrentFnEPMarkerSym =
nullptr;
889static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer,
bool VarArg,
891 enum class PPA1Flag1 : uint8_t {
892 DSA64Bit = (0x80 >> 0),
893 VarArg = (0x80 >> 7),
896 enum class PPA1Flag2 : uint8_t {
897 ExternalProcedure = (0x80 >> 0),
898 STACKPROTECTOR = (0x80 >> 3),
901 enum class PPA1Flag3 : uint8_t {
902 FPRMask = (0x80 >> 2),
905 enum class PPA1Flag4 : uint8_t {
906 EPMOffsetPresent = (0x80 >> 0),
907 VRMask = (0x80 >> 2),
908 ProcedureNamePresent = (0x80 >> 7),
913 auto Flags1 = PPA1Flag1(0);
914 auto Flags2 = PPA1Flag2::ExternalProcedure;
915 auto Flags3 = PPA1Flag3(0);
916 auto Flags4 = PPA1Flag4::EPMOffsetPresent | PPA1Flag4::ProcedureNamePresent;
918 Flags1 |= PPA1Flag1::DSA64Bit;
921 Flags1 |= PPA1Flag1::VarArg;
924 Flags2 |= PPA1Flag2::STACKPROTECTOR;
928 Flags3 |= PPA1Flag3::FPRMask;
931 Flags4 |= PPA1Flag4::VRMask;
933 OutStreamer->AddComment(
"PPA1 Flags 1");
934 if ((Flags1 & PPA1Flag1::DSA64Bit) == PPA1Flag1::DSA64Bit)
935 OutStreamer->AddComment(
" Bit 0: 1 = 64-bit DSA");
937 OutStreamer->AddComment(
" Bit 0: 0 = 32-bit DSA");
938 if ((Flags1 & PPA1Flag1::VarArg) == PPA1Flag1::VarArg)
939 OutStreamer->AddComment(
" Bit 7: 1 = Vararg function");
940 OutStreamer->emitInt8(
static_cast<uint8_t
>(Flags1));
942 OutStreamer->AddComment(
"PPA1 Flags 2");
943 if ((Flags2 & PPA1Flag2::ExternalProcedure) == PPA1Flag2::ExternalProcedure)
944 OutStreamer->AddComment(
" Bit 0: 1 = External procedure");
945 if ((Flags2 & PPA1Flag2::STACKPROTECTOR) == PPA1Flag2::STACKPROTECTOR)
946 OutStreamer->AddComment(
" Bit 3: 1 = STACKPROTECT is enabled");
948 OutStreamer->AddComment(
" Bit 3: 0 = STACKPROTECT is not enabled");
949 OutStreamer->emitInt8(
static_cast<uint8_t
>(Flags2));
951 OutStreamer->AddComment(
"PPA1 Flags 3");
952 if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask)
953 OutStreamer->AddComment(
" Bit 2: 1 = FP Reg Mask is in optional area");
954 OutStreamer->emitInt8(
955 static_cast<uint8_t
>(Flags3));
957 OutStreamer->AddComment(
"PPA1 Flags 4");
958 if ((Flags4 & PPA1Flag4::VRMask) == PPA1Flag4::VRMask)
959 OutStreamer->AddComment(
" Bit 2: 1 = Vector Reg Mask is in optional area");
960 OutStreamer->emitInt8(
static_cast<uint8_t
>(
964void SystemZAsmPrinter::emitPPA1(
MCSymbol *FnEndSym) {
967 const auto TargetHasVector = Subtarget.hasVector();
979 uint8_t SavedVRMask = 0;
980 int64_t OffsetFPR = 0;
981 int64_t OffsetVR = 0;
982 const int64_t TopOfStack =
989 I &&
E &&
I <=
E; ++
I) {
991 assert(V < 16 &&
"GPR index out of range");
992 SavedGPRMask |= 1 << (15 -
V);
995 for (
auto &CS : CSI) {
996 unsigned Reg = CS.getReg();
997 unsigned I =
TRI->getEncodingValue(Reg);
999 if (SystemZ::FP64BitRegClass.
contains(Reg)) {
1000 assert(
I < 16 &&
"FPR index out of range");
1001 SavedFPRMask |= 1 << (15 -
I);
1003 if (Temp < OffsetFPR)
1005 }
else if (SystemZ::VR128BitRegClass.
contains(Reg)) {
1006 assert(
I >= 16 &&
I <= 23 &&
"VPR index out of range");
1007 unsigned BitNum =
I - 16;
1008 SavedVRMask |= 1 << (7 - BitNum);
1010 if (Temp < OffsetVR)
1016 OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0;
1017 OffsetVR += (OffsetVR < 0) ? TopOfStack : 0;
1020 uint8_t FrameReg =
TRI->getEncodingValue(
TRI->getFrameRegister(*
MF));
1021 uint8_t AllocaReg = ZFL->hasFP(*
MF) ? FrameReg : 0;
1022 assert(AllocaReg < 16 &&
"Can't have alloca register larger than 15");
1028 uint64_t FPRSaveAreaOffset = OffsetFPR;
1029 assert(FPRSaveAreaOffset < 0x10000000 &&
"Offset out of range");
1031 FrameAndFPROffset = FPRSaveAreaOffset & 0x0FFFFFFF;
1032 FrameAndFPROffset |= FrameReg << 28;
1037 if (TargetHasVector && SavedVRMask) {
1038 uint64_t VRSaveAreaOffset = OffsetVR;
1039 assert(VRSaveAreaOffset < 0x10000000 &&
"Offset out of range");
1041 FrameAndVROffset = VRSaveAreaOffset & 0x0FFFFFFF;
1042 FrameAndVROffset |= FrameReg << 28;
1057 TargetHasVector && SavedVRMask != 0);
1063 OutStreamer->emitAbsoluteSymbolDiff(FnEndSym, CurrentFnEPMarkerSym, 4);
1073 .
concat(utostr(FrameAndFPROffset >> 28))
1076 .
concat(utostr(FrameAndFPROffset & 0x0FFFFFFF))
1084 if (TargetHasVector && SavedVRMask) {
1091 .
concat(utostr(FrameAndVROffset >> 28))
1094 .
concat(utostr(FrameAndVROffset & 0x0FFFFFFF))
1100 OutStreamer->emitAbsoluteSymbolDiff(CurrentFnEPMarkerSym, CurrentFnPPA1Sym,
1107 if (Subtarget.getTargetTriple().isOSzOS()) {
1115 CurrentFnEPMarkerSym =
1132 uint32_t DSAAndFlags = DSASize & 0xFFFFFFE0;
1133 DSAAndFlags |=
Flags;
1136 OutStreamer->AddComment(
"XPLINK Routine Layout Entry");
1138 OutStreamer->AddComment(
"Eyecatcher 0x00C300C500C500");
1139 OutStreamer->emitIntValueInHex(0x00C300C500C500, 7);
1143 OutStreamer->emitAbsoluteSymbolDiff(CurrentFnPPA1Sym, CurrentFnEPMarkerSym,
1149 OutStreamer->AddComment(
" Bit 2: 1 = Uses alloca");
1151 OutStreamer->AddComment(
" Bit 2: 0 = Does not use alloca");
unsigned const MachineRegisterInfo * MRI
static MCSymbolRefExpr::VariantKind getModifierVariantKind(ARMCP::ARMCPModifier Modifier)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, unsigned Opcode)
static const MCSymbolRefExpr * getGlobalOffsetTable(MCContext &Context)
static void printFormattedRegName(const MCAsmInfo *MAI, unsigned RegNo, raw_ostream &OS)
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode)
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter()
static void printAddress(const MCAsmInfo *MAI, unsigned Base, const MCOperand &DispMO, unsigned Index, raw_ostream &OS)
static const MCSymbolRefExpr * getTLSGetOffset(MCContext &Context)
static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode)
static void emitPPA1Flags(std::unique_ptr< MCStreamer > &OutStreamer, bool VarArg, bool StackProtector, bool FPRMask, bool VRMask)
static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, unsigned NumBytes, const MCSubtargetInfo &STI)
static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode)
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbol(const GlobalValue *GV) const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
TargetMachine & TM
Target machine description.
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSymbol * createTempSymbol(const Twine &Name) const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
const DataLayout & getDataLayout() const
Return information about data layout.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
This class is intended to be used as a base class for asm properties and features specific to the tar...
unsigned getAssemblerDialect() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
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.
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
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.
bool hasFeature(unsigned Feature) const
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Abstract base class for all machine specific constantpool value subclasses.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
int getOffsetAdjustment() const
Return the correction for frame offsets.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
bool hasStackProtectorIndex() const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
const TargetRegisterInfo * getTargetRegisterInfo() const
A Module instance is used to store all the information related to an LLVM module.
MI-level patchpoint operands.
Wrapper class representing virtual and physical registers.
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
StringRef - Represent a constant reference to a string, i.e.
void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override
void emitFunctionBodyEnd() override
Targets can override this to emit stuff after the last basic block in the function.
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
A SystemZ-specific constant pool value.
static const char * getRegisterName(MCRegister Reg)
SystemZ::GPRRegs getSpillGPRRegs() const
const TargetFrameLowering * getFrameLowering() const override
std::pair< MCInst, const MCSubtargetInfo * > MCInstSTIPair
EXRLT2SymMap EXRLTargets2Sym
const Triple & getTargetTriple() const
const MCSubtargetInfo * getMCSubtargetInfo() const
const MCRegisterInfo * getMCRegisterInfo() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::string str() const
Return the twine contents as a std::string.
Twine concat(const Twine &Suffix) const
static Twine utohexstr(const uint64_t &Val)
StringRef getName() const
Return a constant reference to the value's name.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getRegAsGR32(unsigned Reg)
const unsigned GR64Regs[16]
unsigned getRegAsGRH32(unsigned Reg)
unsigned getRegAsVR128(unsigned Reg)
unsigned getRegAsGR64(unsigned Reg)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSystemZTarget()
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
@ LLVM_MARK_AS_BITMASK_ENUM
This struct is a compact representation of a valid (non-zero power of two) alignment.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...