15 #define DEBUG_TYPE "asm-printer"
61 bool Indirect)
const {
67 assert(MLoc.
isReg() && !Indirect &&
68 "This doesn't support offset/indirection - implement it if needed");
70 if (Reg >= ARM::S0 && Reg <= ARM::S31) {
71 assert(ARM::S0 + 31 == ARM::S31 &&
"Unexpected ARM S register numbering");
76 unsigned SReg = Reg - ARM::S0;
77 bool odd = SReg & 0x1;
78 unsigned Rx = 256 + (SReg >> 1);
97 }
else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) {
98 assert(ARM::Q0 + 15 == ARM::Q15 &&
"Unexpected ARM Q register numbering");
103 unsigned QReg = Reg - ARM::Q0;
104 unsigned D1 = 256 + 2 * QReg;
105 unsigned D2 = D1 + 1;
128 InConstantPool =
false;
143 assert(Size &&
"C++ constructor pointer had zero size!");
146 assert(GV &&
"C++ constructor pointer was not a GlobalValue!");
177 assert(!MO.
getSubReg() &&
"Subregs should be eliminated!");
178 if(ARM::GPRPairRegClass.contains(Reg)) {
187 int64_t Imm = MO.
getImm();
189 if ((Modifier &&
strcmp(Modifier,
"lo16") == 0) ||
192 else if ((Modifier &&
strcmp(Modifier,
"hi16") == 0) ||
203 if ((Modifier &&
strcmp(Modifier,
"lo16") == 0) ||
206 else if ((Modifier &&
strcmp(Modifier,
"hi16") == 0) ||
234 GetARMJTIPICJumpTableLabel2(
unsigned uid,
unsigned uid2)
const {
242 MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel()
const {
250 unsigned AsmVariant,
const char *ExtraCode,
253 if (ExtraCode && ExtraCode[0]) {
254 if (ExtraCode[1] != 0)
return true;
256 switch (ExtraCode[0]) {
284 if (!ARM::DPRRegClass.contains(*SR))
306 unsigned RegBegin = MO.
getReg();
311 if (ARM::GPRPairRegClass.contains(RegBegin)) {
313 unsigned Reg0 = TRI->
getSubReg(RegBegin, ARM::gsub_0);
315 RegBegin = TRI->
getSubReg(RegBegin, ARM::gsub_1);
323 unsigned RegOps = OpNum + 1;
339 if (!FlagsOP.
isImm())
348 for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) {
362 if (RC == ARM::GPRPairRegClassID) {
370 ARM::gsub_0 : ARM::gsub_1);
376 unsigned RegOp = ExtraCode[0] ==
'Q' ? OpNum : OpNum + 1;
392 if (!ARM::QPRRegClass.contains(Reg))
395 unsigned SubReg = TRI->
getSubReg(Reg, ExtraCode[0] ==
'e' ?
396 ARM::dsub_0 : ARM::dsub_1);
411 if(!ARM::GPRPairRegClass.contains(Reg))
425 unsigned OpNum,
unsigned AsmVariant,
426 const char *ExtraCode,
429 if (ExtraCode && ExtraCode[0]) {
430 if (ExtraCode[1] != 0)
return true;
432 switch (ExtraCode[0]) {
434 default:
return true;
444 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
470 if (!
F->isDeclaration() && !
F->hasAvailableExternallyLinkage())
477 for (
unsigned i = 0, e = TextSections.
size(); i != e; ++i)
496 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
522 if (!Stubs.empty()) {
526 for (
unsigned i = 0, e = Stubs.size(); i != e; ++i) {
553 if (!Stubs.empty()) {
556 for (
unsigned i = 0, e = Stubs.size(); i != e; ++i) {
561 Create(Stubs[i].second.getPointer(),
613 void ARMAsmPrinter::emitAttributes() {
621 if (CPUString !=
"generic")
653 ATS.
emitFPU(ARM::CRYPTO_NEON_FP_ARMV8);
655 ATS.
emitFPU(ARM::NEON_FP_ARMV8);
669 ATS.
emitFPU(Subtarget->
hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4);
671 ATS.
emitFPU(Subtarget->
hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3);
732 void ARMAsmPrinter::emitARMAttributeSection() {
760 +
"PC" +
Twine(FunctionNumber) +
"_" +
Twine(LabelId));
790 if (StubSym.getPointer() == 0)
810 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
813 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
814 MCSym = GetARMGVSymbol(GV);
819 assert(ACPV->
isExtSymbol() &&
"unrecognized constant pool value");
820 const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->
getSymbol();
856 if (Opcode == ARM::BR_JTadd)
858 else if (Opcode == ARM::BR_JTm)
866 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.
getImm());
874 const std::vector<MachineJumpTableEntry> &JT = MJTI->
getJumpTables();
875 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
877 for (
unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
906 int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
911 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.
getImm());
916 const std::vector<MachineJumpTableEntry> &JT = MJTI->
getJumpTables();
917 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
918 unsigned OffsetWidth = 4;
923 }
else if (MI->
getOpcode() == ARM::t2TBH_JT) {
929 for (
unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
934 if (OffsetWidth == 4) {
936 .addExpr(MBBSymbolExpr)
961 if (OffsetWidth != 4)
965 void ARMAsmPrinter::EmitUnwindingInstruction(
const MachineInstr *
MI) {
967 "Only instruction which are involved into frame setup code are allowed");
977 unsigned SrcReg, DstReg;
979 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
985 SrcReg = DstReg = ARM::SP;
994 assert(DstReg == ARM::SP &&
995 "Only stack pointer as a destination reg is supported");
999 unsigned StartOp = 2 + 2;
1001 unsigned NumOffset = 0;
1009 StartOp = 2; NumOffset = 2;
1010 case ARM::STMDB_UPD:
1011 case ARM::t2STMDB_UPD:
1012 case ARM::VSTMDDB_UPD:
1013 assert(SrcReg == ARM::SP &&
1014 "Only stack pointer as a source reg is supported");
1015 for (
unsigned i = StartOp, NumOps = MI->
getNumOperands() - NumOffset;
1025 case ARM::STR_PRE_IMM:
1026 case ARM::STR_PRE_REG:
1027 case ARM::t2STR_PRE:
1029 "Only stack pointer as a source reg is supported");
1033 ATS.
emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
1036 if (SrcReg == ARM::SP) {
1060 case ARM::tLDRpci: {
1067 assert(CPI != -1U &&
"Invalid constpool index");
1073 Offset = -cast<ConstantInt>(CPE.
Val.
ConstVal)->getSExtValue();
1078 if (DstReg == FramePtr && FramePtr != ARM::SP)
1081 ATS.
emitSetFP(FramePtr, ARM::SP, -Offset);
1082 else if (DstReg == ARM::SP) {
1090 }
else if (DstReg == ARM::SP) {
1106 #include "ARMGenMCPseudoLowering.inc"
1110 if (InConstantPool && MI->
getOpcode() != ARM::CONSTPOOL_ENTRY) {
1112 InConstantPool =
false;
1117 EmitUnwindingInstruction(MI);
1124 "Pseudo flag setting opcode should be expanded early");
1129 case ARM::t2MOVi32imm:
llvm_unreachable(
"Should be lowered by thumb2it pass");
1132 case ARM::tLEApcrel:
1133 case ARM::t2LEApcrel: {
1137 ARM::t2LEApcrel ? ARM::t2ADR
1138 : (MI->
getOpcode() == ARM::tLEApcrel ? ARM::tADR
1147 case ARM::LEApcrelJT:
1148 case ARM::tLEApcrelJT:
1149 case ARM::t2LEApcrelJT: {
1154 ARM::t2LEApcrelJT ? ARM::t2ADR
1155 : (MI->
getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1166 case ARM::BX_CALL: {
1180 case ARM::tBX_CALL: {
1195 case ARM::BMOVPCRX_CALL: {
1215 case ARM::BMOVPCB_CALL: {
1235 case ARM::MOVi16_ga_pcrel:
1236 case ARM::t2MOVi16_ga_pcrel: {
1238 TmpInst.
setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
1244 MCSymbol *GVSym = GetARMGVSymbol(GV);
1251 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
1252 const MCExpr *PCRelExpr =
1271 case ARM::MOVTi16_ga_pcrel:
1272 case ARM::t2MOVTi16_ga_pcrel: {
1274 TmpInst.
setOpcode(Opc == ARM::MOVTi16_ga_pcrel
1275 ? ARM::MOVTi16 : ARM::t2MOVTi16);
1282 MCSymbol *GVSym = GetARMGVSymbol(GV);
1289 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
1290 const MCExpr *PCRelExpr =
1308 case ARM::tPICADD: {
1359 case ARM::PICLDRSH: {
1376 case ARM::PICSTR: Opcode = ARM::STRrs;
break;
1377 case ARM::PICSTRB: Opcode = ARM::STRBrs;
break;
1378 case ARM::PICSTRH: Opcode = ARM::STRH;
break;
1379 case ARM::PICLDR: Opcode = ARM::LDRrs;
break;
1380 case ARM::PICLDRB: Opcode = ARM::LDRBrs;
break;
1381 case ARM::PICLDRH: Opcode = ARM::LDRH;
break;
1382 case ARM::PICLDRSB: Opcode = ARM::LDRSB;
break;
1383 case ARM::PICLDRSH: Opcode = ARM::LDRSH;
break;
1396 case ARM::CONSTPOOL_ENTRY: {
1406 if (!InConstantPool) {
1408 InConstantPool =
true;
1420 case ARM::t2BR_JT: {
1433 case ARM::t2TBB_JT: {
1448 case ARM::t2TBH_JT: {
1466 unsigned Opc = MI->
getOpcode() == ARM::BR_JTr ?
1467 ARM::MOVr : ARM::tMOVr;
1475 if (Opc == ARM::MOVr)
1480 if (Opc == ARM::tMOVr)
1513 case ARM::BR_JTadd: {
1535 uint32_t Val = 0xe7ffdefeUL;
1542 case ARM::TRAPNaCl: {
1544 uint32_t Val = 0xe7fedef0UL;
1554 uint16_t Val = 0xdefe;
1561 case ARM::t2Int_eh_sjlj_setjmp:
1562 case ARM::t2Int_eh_sjlj_setjmp_nofp:
1563 case ARM::tInt_eh_sjlj_setjmp: {
1574 MCSymbol *Label = GetARMSJLJEHLabel();
1613 .addExpr(SymbolExpr)
1630 case ARM::Int_eh_sjlj_setjmp_nofp:
1631 case ARM::Int_eh_sjlj_setjmp: {
1690 case ARM::Int_eh_sjlj_longjmp: {
1728 case ARM::tInt_eh_sjlj_longjmp: {
MachineConstantPoolValue * MachineCPVal
int strcmp(const char *s1, const char *s2);
StubValueTy & getHiddenGVStubEntry(MCSymbol *Sym)
void push_back(const T &Elt)
const MachineFunction * getParent() const
The machine constant pool.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number. Returns -1 if there is no equivalent va...
virtual void AddComment(const Twine &T)
const GlobalValue * getGlobal() const
static ARMBuildAttrs::CPUArch getArchForCPU(StringRef CPU, const ARMSubtarget *Subtarget)
void EmitJump2Table(const MachineInstr *MI)
MCSymbol * getSymbol(const GlobalValue *GV) const
static const MCBinaryExpr * CreateDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Reloc::Model getRelocationModel() const
virtual void switchVendor(StringRef Vendor)=0
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
void EmitJumpTable(const MachineInstr *MI)
static MCOperand CreateReg(unsigned Reg)
const std::string & getCPUString() const
MachineBasicBlock * getMBB() const
static const MCConstantExpr * Create(int64_t Value, MCContext &Ctx)
The main container class for the LLVM Intermediate Representation.
virtual void AddBlankLine()
AddBlankLine - Emit a blank line to a .s file to pretty it up.
void EmitInt8(int Value) const
virtual void EmitFunctionBodyEnd() LLVM_OVERRIDE
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool mayStore(QueryType Type=AnyInBundle) const
const char * getPrivateGlobalPrefix() const
const MachineFunction * MF
The current machine function.
static MCOperand CreateExpr(const MCExpr *Val)
const MCSection * getNonLazySymbolPointerSection() const
virtual bool hasRawTextSupport() const
virtual void EmitInstruction(const MCInst &Inst)=0
virtual void EmitDwarfRegOp(const MachineLocation &MLoc, bool Indirect) const
EmitDwarfRegOp - Emit dwarf register operation.
unsigned getFunctionNumber() const
const char * getSymbolName() const
bool isThumbFunction() const
static const ARMMCExpr * CreateLower16(const MCExpr *Expr, MCContext &Ctx)
virtual const MCSection * getAttributesSection() const
virtual void EmitThumbFunc(MCSymbol *Func)=0
bool isThumb1Only() const
virtual void EmitEndOfAsmFile(Module &M) LLVM_OVERRIDE
std::vector< std::pair< MCSymbol *, StubValueTy > > SymbolListTy
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, const char *Modifier=0)
size_type size() const
Determine the number of elements in the SetVector.
SymbolListTy GetGVStubList() const
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx)
void LLVMInitializeARMAsmPrinter()
virtual void finishAttributeSection()=0
MCSymbol * GetSymbolWithGlobalValueBase(const GlobalValue *GV, StringRef Suffix, bool ForcePrivate=true) const
Address of indexed Jump Table for switch.
bool isGlobalValue() const
const std::vector< MachineJumpTableEntry > & getJumpTables() const
MCSymbol * GetOrCreateSymbol(StringRef Name)
virtual void EmitStartOfAsmFile(Module &M) LLVM_OVERRIDE
MCSymbol * CreateTempSymbol()
bool isTargetDarwin() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
bool hasInternalLinkage() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mustAddCurrentAddress() const
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
GetJTISymbol - Return the symbol for the specified jump table entry.
bool hasMPExtension() const
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) LLVM_OVERRIDE
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) LLVM_OVERRIDE
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
static const MCBinaryExpr * CreateSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
unsigned getNumOperands() const
void SwitchSection(const MCSection *Section, const MCExpr *Subsection=0)
bool insert(const value_type &X)
Insert a new element into the SetVector.
.code16 (X86) / .code 16 (ARM)
static MCSymbol * getPICLabel(const char *Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)
virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset=0)=0
const MachineJumpTableInfo * getJumpTableInfo() const
An entry in a MachineConstantPool.
static MCSymbolRefExpr::VariantKind getModifierVariantKind(ARMCP::ARMCPModifier Modifier)
const MCSection * getTextSection() const
static const char * getRegisterName(unsigned RegNo)
bool isMachineBasicBlock() const
virtual void EmitIntValue(uint64_t Value, unsigned Size)
Address of indexed Constant in Constant Pool.
virtual void EmitInstruction(const MachineInstr *MI) LLVM_OVERRIDE
EmitInstruction - Targets should implement this to emit instructions.
const MCSection * getTextCoalSection() const
void EmitValue(const MCExpr *Value, unsigned Size)
MachineModuleInfo * MMI
MMI - This is a pointer to the current MachineModuleInfo.
bool isMachineConstantPoolEntry() const
const MachineBasicBlock * getParent() const
static const MCSymbolRefExpr * Create(const MCSymbol *Symbol, MCContext &Ctx)
const MCSection * getConstTextCoalSection() const
const Constant * ConstVal
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag)=0
EmitAssemblerFlag - Note in the output the specified Flag.
unsigned getTargetFlags() const
const MCSection * SectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
bool isBlockAddress() const
virtual bool runOnMachineFunction(MachineFunction &MF)
LLVM Constant Representation.
bool hasHiddenVisibility() const
virtual void emitRegSave(const SmallVectorImpl< unsigned > &RegList, bool isVector)=0
const MachineOperand & getOperand(unsigned i) const
bool hasVirtualization() const
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
virtual bool runOnMachineFunction(MachineFunction &F) LLVM_OVERRIDE
static unsigned getNumOperandRegisters(unsigned Flag)
virtual void EmitDwarfRegOp(const MachineLocation &MLoc, bool Indirect) const LLVM_OVERRIDE
EmitDwarfRegOp - Emit dwarf register operation.
virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
EmitSymbolAttribute - Add the given Attribute to Symbol.
bool getFlag(MIFlag Flag) const
getFlag - Return whether an MI flag is set.
void printOffset(int64_t Offset, raw_ostream &OS) const
printOffset - This is just convenient handler for printing offsets.
.subsections_via_symbols (MachO)
TRAP - Trapping instruction.
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
int64_t getOffset() const
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) LLVM_OVERRIDE
MachineConstantPool * getConstantPool()
union llvm::MachineConstantPoolEntry::@29 Val
The constant itself.
unsigned getSubReg() const
MCSymbol * getSymbol() const
StubValueTy & getGVStubEntry(MCSymbol *Sym)
virtual void EmitDataRegion(MCDataRegionType Kind)
EmitDataRegion - Note in the output the specified region Kind.
PointerTy getPointer() const
void setOpcode(unsigned Op)
virtual void emitAttribute(unsigned Attribute, unsigned Value)=0
virtual void emitFPU(unsigned FPU)=0
virtual void EmitLabel(MCSymbol *Symbol)
bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const
GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
uint64_t getTypeAllocSize(Type *Ty) const
void EmitGlobalConstant(const Constant *CV)
Print a general LLVM constant to the .s file.
Value * stripPointerCasts()
Strips off any unneeded pointer casts, all-zero GEPs and aliases from the specified value...
StringRef str() const
Explicit conversion to StringRef.
virtual void EmitFunctionEntryLabel() LLVM_OVERRIDE
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP)
FunctionNumber(functionNumber)
static const ARMMCExpr * CreateUpper16(const MCExpr *Expr, MCContext &Ctx)
static const MCBinaryExpr * CreateAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
MachineOperandType getType() const
static bool isPhysicalRegister(unsigned Reg)
cl::opt< bool > EnableARMEHABI
virtual void emitPad(int64_t Offset)=0
void EmitULEB128(uint64_t Value, const char *Desc=0, unsigned PadTo=0) const
EmitULEB128 - emit the specified unsigned leb128 value.
static MCOperand CreateImm(int64_t Val)
MCTargetStreamer & getTargetStreamer()
virtual const DataLayout * getDataLayout() const
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
void EmitAlignment(unsigned NumBits, const GlobalValue *GV=0) const
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
MCSymbol * GetCPISymbol(unsigned CPID) const
GetCPISymbol - Return the symbol for the specified constant pool entry.
unsigned getReg() const
getReg - Returns the register number.
unsigned getLabelId() const
bool hasTrustZone() const
const TargetLoweringObjectFile & getObjFileLowering() const
getObjFileLowering - Return information about object file lowering.
unsigned char getPCAdjustment() const
A vector that has set insertion semantics.
virtual void emitTextAttribute(unsigned Attribute, StringRef String)=0
virtual void EmitXXStructor(const Constant *CV) LLVM_OVERRIDE
const MCSectionMachO * getMachOSection(StringRef Segment, StringRef Section, unsigned TypeAndAttributes, unsigned Reserved2, SectionKind K)
const std::vector< MachineConstantPoolEntry > & getConstants() const
bool hasDivideInARMMode() const
void addOperand(const MCOperand &Op)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
unsigned getOriginalCPIdx(unsigned CloneIdx) const
ARMCP::ARMCPModifier getModifier() const
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
SymbolListTy GetHiddenGVStubList() const
bool hasThumb2DSP() const
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
MachineBasicBlock reference.
FloatABI::ABIType FloatABIType
Address of a global value.
static SectionKind getText()
Name of external global symbol.