diff options
Diffstat (limited to 'lib/Target/ARM/MCTargetDesc')
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h | 51 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 83 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h | 11 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h | 8 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h | 3 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h | 1 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h | 14 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 19 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 6 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h | 10 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp | 3 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 120 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 16 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMachORelocationInfo.cpp | 2 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp | 9 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/Makefile | 16 |
16 files changed, 241 insertions, 131 deletions
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h b/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h index b03cada9a641d..3959eab966a84 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h @@ -486,7 +486,7 @@ namespace ARM_AM { // addrmode5 := reg +/- imm8*4 // // The first operand is always a Reg. The second operand encodes the - // operation in bit 8 and the immediate in bits 0-7. + // operation (add or subtract) in bit 8 and the immediate in bits 0-7. /// getAM5Opc - This function encodes the addrmode5 opc field. static inline unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset) { @@ -501,6 +501,29 @@ namespace ARM_AM { } //===--------------------------------------------------------------------===// + // Addressing Mode #5 FP16 + //===--------------------------------------------------------------------===// + // + // This is used for coprocessor instructions, such as 16-bit FP load/stores. + // + // addrmode5fp16 := reg +/- imm8*2 + // + // The first operand is always a Reg. The second operand encodes the + // operation (add or subtract) in bit 8 and the immediate in bits 0-7. + + /// getAM5FP16Opc - This function encodes the addrmode5fp16 opc field. + static inline unsigned getAM5FP16Opc(AddrOpc Opc, unsigned char Offset) { + bool isSub = Opc == sub; + return ((int)isSub << 8) | Offset; + } + static inline unsigned char getAM5FP16Offset(unsigned AM5Opc) { + return AM5Opc & 0xFF; + } + static inline AddrOpc getAM5FP16Op(unsigned AM5Opc) { + return ((AM5Opc >> 8) & 1) ? sub : add; + } + + //===--------------------------------------------------------------------===// // Addressing Mode #6 //===--------------------------------------------------------------------===// // @@ -650,6 +673,32 @@ namespace ARM_AM { return FPUnion.F; } + /// getFP16Imm - Return an 8-bit floating-point version of the 16-bit + /// floating-point value. If the value cannot be represented as an 8-bit + /// floating-point value, then return -1. + static inline int getFP16Imm(const APInt &Imm) { + uint32_t Sign = Imm.lshr(15).getZExtValue() & 1; + int32_t Exp = (Imm.lshr(10).getSExtValue() & 0x1f) - 15; // -14 to 15 + int64_t Mantissa = Imm.getZExtValue() & 0x3ff; // 10 bits + + // We can handle 4 bits of mantissa. + // mantissa = (16+UInt(e:f:g:h))/16. + if (Mantissa & 0x3f) + return -1; + Mantissa >>= 6; + + // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 + if (Exp < -3 || Exp > 4) + return -1; + Exp = ((Exp+3) & 0x7) ^ 4; + + return ((int)Sign << 7) | (Exp << 4) | Mantissa; + } + + static inline int getFP16Imm(const APFloat &FPImm) { + return getFP16Imm(FPImm.bitcastToAPInt()); + } + /// getFP32Imm - Return an 8-bit floating-point version of the 32-bit /// floating-point value. If the value cannot be represented as an 8-bit /// floating-point value, then return -1. diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index fa52c9354c171..0fc758201d47b 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -46,6 +46,7 @@ public: : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_ARM, /*HasRelocationAddend*/ false) {} }; +} // end anonymous namespace const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = { @@ -62,6 +63,10 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_pcrel_9", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, {"fixup_thumb_adr_pcrel_10", 0, 8, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, @@ -78,7 +83,9 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, - {"fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_thumb_blx", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_thumb_cp", 0, 8, MCFixupKindInfo::FKF_IsPCRel | @@ -90,6 +97,7 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_arm_movw_lo16", 0, 20, 0}, {"fixup_t2_movt_hi16", 0, 20, 0}, {"fixup_t2_movw_lo16", 0, 20, 0}, + {"fixup_arm_mod_imm", 0, 12, 0}, }; const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = { // This table *must* be in the order that the fixup_* kinds are defined in @@ -105,6 +113,10 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_pcrel_9", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, {"fixup_thumb_adr_pcrel_10", 8, 8, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, @@ -121,7 +133,9 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_arm_condbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_blx", 8, 24, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, - {"fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_thumb_blx", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_thumb_cp", 8, 8, MCFixupKindInfo::FKF_IsPCRel | @@ -133,6 +147,7 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_arm_movw_lo16", 12, 20, 0}, {"fixup_t2_movt_hi16", 12, 20, 0}, {"fixup_t2_movw_lo16", 12, 20, 0}, + {"fixup_arm_mod_imm", 20, 12, 0}, }; if (Kind < FirstTargetFixupKind) @@ -155,10 +170,10 @@ void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) { break; } } -} // end anonymous namespace unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const { bool HasThumb2 = STI->getFeatureBits()[ARM::FeatureThumb2]; + bool HasV8MBaselineOps = STI->getFeatureBits()[ARM::HasV8MBaselineOps]; switch (Op) { default: @@ -170,7 +185,7 @@ unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const { case ARM::tADR: return HasThumb2 ? (unsigned)ARM::t2ADR : Op; case ARM::tB: - return HasThumb2 ? (unsigned)ARM::t2B : Op; + return HasV8MBaselineOps ? (unsigned)ARM::t2B : Op; case ARM::tCBZ: return ARM::tHINT; case ARM::tCBNZ: @@ -243,7 +258,9 @@ bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, return reasonForFixupRelaxation(Fixup, Value); } -void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { +void ARMAsmBackend::relaxInstruction(const MCInst &Inst, + const MCSubtargetInfo &STI, + MCInst &Res) const { unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); // Sanity check w/ diagnostic if we get here w/ a bogus instruction. @@ -449,7 +466,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, // Offset by 8 just as above. if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Fixup.getValue())) - if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL) + if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL) return 0; return 0xffffff & ((Value - 8) >> 2); case ARM::fixup_t2_uncondbranch: { @@ -524,10 +541,15 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, // // Note that the halfwords are stored high first, low second; so we need // to transpose the fixup value here to map properly. - uint32_t offset = (Value - 2) >> 2; + if (Ctx && Value % 4 != 0) { + Ctx->reportError(Fixup.getLoc(), "misaligned ARM call destination"); + return 0; + } + + uint32_t offset = (Value - 4) >> 2; if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Fixup.getValue())) - if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL) + if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL) offset = 0; uint32_t signBit = (offset & 0x400000) >> 22; uint32_t I1Bit = (offset & 0x200000) >> 21; @@ -563,7 +585,8 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, } case ARM::fixup_arm_thumb_br: // Offset by 4 and don't encode the lower bit, which is always 0. - if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2]) { + if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2] && + !STI->getFeatureBits()[ARM::HasV8MBaselineOps]) { const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value); if (FixupDiagnostic) { Ctx->reportError(Fixup.getLoc(), FixupDiagnostic); @@ -624,6 +647,44 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, return Value; } + case ARM::fixup_arm_pcrel_9: + Value = Value - 4; // ARM fixups offset by an additional word and don't + // need to adjust for the half-word ordering. + // Fall through. + case ARM::fixup_t2_pcrel_9: { + // Offset by 4, adjusted by two due to the half-word ordering of thumb. + Value = Value - 4; + bool isAdd = true; + if ((int64_t)Value < 0) { + Value = -Value; + isAdd = false; + } + // These values don't encode the low bit since it's always zero. + if (Ctx && (Value & 1)) { + Ctx->reportError(Fixup.getLoc(), "invalid value for this fixup"); + return 0; + } + Value >>= 1; + if (Ctx && Value >= 256) { + Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value"); + return 0; + } + Value |= isAdd << 23; + + // Same addressing mode as fixup_arm_pcrel_9, but with 16-bit halfwords + // swapped. + if (Kind == ARM::fixup_t2_pcrel_9) + return swapHalfWords(Value, IsLittleEndian); + + return Value; + } + case ARM::fixup_arm_mod_imm: + Value = ARM_AM::getSOImmVal(Value); + if (Ctx && Value >> 12) { + Ctx->reportError(Fixup.getLoc(), "out of range immediate fixup value"); + return 0; + } + return Value; } } @@ -690,11 +751,13 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { case FK_Data_2: case ARM::fixup_arm_thumb_br: case ARM::fixup_arm_thumb_cb: + case ARM::fixup_arm_mod_imm: return 2; case ARM::fixup_arm_pcrel_10_unscaled: case ARM::fixup_arm_ldst_pcrel_12: case ARM::fixup_arm_pcrel_10: + case ARM::fixup_arm_pcrel_9: case ARM::fixup_arm_adr_pcrel_12: case ARM::fixup_arm_uncondbl: case ARM::fixup_arm_condbl: @@ -708,6 +771,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { case ARM::fixup_t2_condbranch: case ARM::fixup_t2_uncondbranch: case ARM::fixup_t2_pcrel_10: + case ARM::fixup_t2_pcrel_9: case ARM::fixup_t2_adr_pcrel_12: case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: @@ -766,6 +830,7 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) { case ARM::fixup_arm_movw_lo16: case ARM::fixup_t2_movt_hi16: case ARM::fixup_t2_movw_lo16: + case ARM::fixup_arm_mod_imm: // Instruction size is 4 bytes. return 4; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h index 28a62132a4199..84caaacc47d3a 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -11,12 +11,12 @@ #define LLVM_LIB_TARGET_ARM_ARMASMBACKEND_H #include "MCTargetDesc/ARMFixupKinds.h" +#include "MCTargetDesc/ARMMCTargetDesc.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/TargetRegistry.h" -using namespace llvm; - -namespace { +namespace llvm { class ARMAsmBackend : public MCAsmBackend { const MCSubtargetInfo *STI; @@ -63,7 +63,8 @@ public: const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; - void relaxInstruction(const MCInst &Inst, MCInst &Res) const override; + void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, + MCInst &Res) const override; bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; @@ -74,6 +75,6 @@ public: void setIsThumb(bool it) { isThumbMode = it; } bool isLittle() const { return IsLittleEndian; } }; -} // end anonymous namespace +} // end namespace llvm #endif diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h index 995dd0fe08ee9..09dc0173ade65 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h @@ -10,11 +10,10 @@ #ifndef LLVM_LIB_TARGET_ARM_ARMASMBACKENDDARWIN_H #define LLVM_LIB_TARGET_ARM_ARMASMBACKENDDARWIN_H +#include "ARMAsmBackend.h" #include "llvm/Support/MachO.h" -using namespace llvm; - -namespace { +namespace llvm { class ARMAsmBackendDarwin : public ARMAsmBackend { const MCRegisterInfo &MRI; public: @@ -22,7 +21,6 @@ public: ARMAsmBackendDarwin(const Target &T, const Triple &TT, const MCRegisterInfo &MRI, MachO::CPUSubTypeARM st) : ARMAsmBackend(T, TT, /* IsLittleEndian */ true), MRI(MRI), Subtype(st) { - HasDataInCodeSupport = true; } MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { @@ -33,6 +31,6 @@ public: uint32_t generateCompactUnwindEncoding( ArrayRef<MCCFIInstruction> Instrs) const override; }; -} +} // end namespace llvm #endif diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h index 68b12edd089e6..748f915be17bb 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h @@ -10,7 +10,10 @@ #ifndef LLVM_LIB_TARGET_ARM_ELFARMASMBACKEND_H #define LLVM_LIB_TARGET_ARM_ELFARMASMBACKEND_H +#include "ARMAsmBackend.h" +#include "MCTargetDesc/ARMMCTargetDesc.h" using namespace llvm; + namespace { class ARMAsmBackendELF : public ARMAsmBackend { public: diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h index 170f59a4c905e..2a375be49a830 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h @@ -10,6 +10,7 @@ #ifndef LLVM_LIB_TARGET_ARM_ARMASMBACKENDWINCOFF_H #define LLVM_LIB_TARGET_ARM_ARMASMBACKENDWINCOFF_H +#include "ARMAsmBackend.h" using namespace llvm; namespace { diff --git a/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h index 4289a73e9d6b1..088b4205ed624 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h +++ b/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h @@ -289,18 +289,20 @@ namespace ARMII { /// higher 16 bit of the address. Used only via movt instruction. MO_HI16 = 0x2, - /// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a - /// call operand. - MO_PLT = 0x3, - /// MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects /// just that part of the flag set. - MO_OPTION_MASK = 0x3f, + MO_OPTION_MASK = 0x1f, /// MO_DLLIMPORT - On a symbol operand, this represents that the reference /// to the symbol is for an import stub. This is used for DLL import /// storage class indication on Windows. - MO_DLLIMPORT = 0x40, + MO_DLLIMPORT = 0x20, + + /// MO_SECREL - On a symbol operand this indicates that the immediate is + /// the offset from beginning of section. + /// + /// This is the TLS offset for the COFF/Windows TLS mechanism. + MO_SECREL = 0x40, /// MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it /// represents a symbol which, if indirect, will get special Darwin mangling diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 52eba8be288fd..4118fe8e8cdbc 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -34,8 +34,8 @@ namespace { ~ARMELFObjectWriter() override; - unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel) const override; + unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsPCRel) const override; bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const override; @@ -67,7 +67,7 @@ bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, // Need to examine the Fixup when determining whether to // emit the relocation as an explicit symbol or as a section relative // offset -unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, +unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { return GetRelocTypeInner(Target, Fixup, IsPCRel); @@ -98,6 +98,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_ARM_GOT_PREL: Type = ELF::R_ARM_GOT_PREL; break; + case MCSymbolRefExpr::VK_ARM_PREL31: + Type = ELF::R_ARM_PREL31; + break; } break; case ARM::fixup_arm_blx: @@ -106,7 +109,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_PLT: Type = ELF::R_ARM_CALL; break; - case MCSymbolRefExpr::VK_ARM_TLSCALL: + case MCSymbolRefExpr::VK_TLSCALL: Type = ELF::R_ARM_TLS_CALL; break; default: @@ -120,6 +123,8 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, Type = ELF::R_ARM_JUMP24; break; case ARM::fixup_t2_condbranch: + Type = ELF::R_ARM_THM_JUMP19; + break; case ARM::fixup_t2_uncondbranch: Type = ELF::R_ARM_THM_JUMP24; break; @@ -138,7 +143,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: switch (Modifier) { - case MCSymbolRefExpr::VK_ARM_TLSCALL: + case MCSymbolRefExpr::VK_TLSCALL: Type = ELF::R_ARM_THM_TLS_CALL; break; default: @@ -210,10 +215,10 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_ARM_TLSLDO: Type = ELF::R_ARM_TLS_LDO32; break; - case MCSymbolRefExpr::VK_ARM_TLSCALL: + case MCSymbolRefExpr::VK_TLSCALL: Type = ELF::R_ARM_TLS_CALL; break; - case MCSymbolRefExpr::VK_ARM_TLSDESC: + case MCSymbolRefExpr::VK_TLSDESC: Type = ELF::R_ARM_TLS_GOTDESC; break; case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ: diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 57577dc834b7f..36cb74765f3b9 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -763,6 +763,12 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() { setAttributeItem(Virtualization_use, AllowTZVirtualization, false); break; + case ARM::AK_ARMV8MBaseline: + case ARM::AK_ARMV8MMainline: + setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false); + setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); + break; + case ARM::AK_IWMMXT: setAttributeItem(ARM_ISA_use, Allowed, false); setAttributeItem(THUMB_ISA_use, Allowed, false); diff --git a/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h b/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h index 46ba57170db5f..3fe2302bdd372 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h +++ b/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h @@ -33,6 +33,13 @@ enum Fixups { // fixup_t2_pcrel_10 - Equivalent to fixup_arm_pcrel_10, accounting for // the short-swapped encoding of Thumb2 instructions. fixup_t2_pcrel_10, + // fixup_arm_pcrel_9 - 9-bit PC relative relocation for symbol addresses + // used in VFP instructions where bit 0 not encoded (so it's encoded as an + // 8-bit immediate). + fixup_arm_pcrel_9, + // fixup_t2_pcrel_9 - Equivalent to fixup_arm_pcrel_9, accounting for + // the short-swapped encoding of Thumb2 instructions. + fixup_t2_pcrel_9, // fixup_thumb_adr_pcrel_10 - 10-bit PC relative relocation for symbol // addresses where the lower 2 bits are not encoded (so it's encoded as an // 8-bit immediate). @@ -100,6 +107,9 @@ enum Fixups { fixup_t2_movt_hi16, // :upper16: fixup_t2_movw_lo16, // :lower16: + // fixup_arm_mod_imm - Fixup for mod_imm + fixup_arm_mod_imm, + // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp index bda37f6616a8d..53cd29a6061e8 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -13,7 +13,6 @@ #include "ARMMCAsmInfo.h" #include "llvm/ADT/Triple.h" -#include "llvm/Support/CommandLine.h" using namespace llvm; @@ -33,7 +32,7 @@ ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin(const Triple &TheTriple) { SupportsDebugInformation = true; // Exceptions handling - ExceptionsType = TheTriple.isOSDarwin() && !TheTriple.isWatchOS() + ExceptionsType = (TheTriple.isOSDarwin() && !TheTriple.isWatchABI()) ? ExceptionHandling::SjLj : ExceptionHandling::DwarfCFI; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index b88578309f08a..9fca13eeea93c 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -120,11 +120,11 @@ public: SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; - /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit + /// getThumbBranchTargetOpValue - Return encoding info for 24-bit /// immediate Thumb2 direct branch target. - uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; + uint32_t getThumbBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate /// branch target. @@ -214,11 +214,6 @@ public: llvm_unreachable("Invalid ShiftOpc!"); } - /// getAddrMode2OpValue - Return encoding for addrmode2 operands. - uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, @@ -255,11 +250,16 @@ public: SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; - /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. + /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand. uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; + /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand. + uint32_t getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + /// getCCOutOpValue - Return encoding of the 's' bit. unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups, @@ -312,12 +312,8 @@ public: // Support for fixups (MCFixup) if (MO.isExpr()) { const MCExpr *Expr = MO.getExpr(); - // In instruction code this value always encoded as lowest 12 bits, - // so we don't have to perform any specific adjustments. - // Due to requirements of relocatable records we have to use FK_Data_4. - // See ARMELFObjectWriter::ExplicitRelSym and - // ARMELFObjectWriter::GetRelocTypeInner for more details. - MCFixupKind Kind = MCFixupKind(FK_Data_4); + // Fixups resolve to plain values that need to be encoded. + MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_mod_imm); Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); return 0; } @@ -345,9 +341,6 @@ public: unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; - unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; /// getSORegOpValue - Return an encoded so_reg shifted register value. unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, @@ -757,10 +750,9 @@ getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit /// immediate branch target. -uint32_t ARMMCCodeEmitter:: -getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { +uint32_t ARMMCCodeEmitter::getThumbBranchTargetOpValue( + const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { unsigned Val = 0; const MCOperand MO = MI.getOperand(OpIdx); @@ -1049,12 +1041,12 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, switch (ARM16Expr->getKind()) { default: llvm_unreachable("Unsupported ARMFixup"); case ARMMCExpr::VK_ARM_HI16: - Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movt_hi16 - : ARM::fixup_arm_movt_hi16); + Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movt_hi16 + : ARM::fixup_arm_movt_hi16); break; case ARMMCExpr::VK_ARM_LO16: - Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16 - : ARM::fixup_arm_movw_lo16); + Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movw_lo16 + : ARM::fixup_arm_movw_lo16); break; } @@ -1105,21 +1097,6 @@ getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, } uint32_t ARMMCCodeEmitter:: -getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - // {17-14} Rn - // {13} 1 == imm12, 0 == Rm - // {12} isAdd - // {11-0} imm12/Rm - const MCOperand &MO = MI.getOperand(OpIdx); - unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); - uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups, STI); - Binary |= Rn << 14; - return Binary; -} - -uint32_t ARMMCCodeEmitter:: getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { @@ -1252,7 +1229,7 @@ getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, return (MO.getImm() >> 2); } -/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. +/// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand. uint32_t ARMMCCodeEmitter:: getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, @@ -1292,6 +1269,46 @@ getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, return Binary; } +/// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand. +uint32_t ARMMCCodeEmitter:: +getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // {12-9} = reg + // {8} = (U)nsigned (add == '1', sub == '0') + // {7-0} = imm8 + unsigned Reg, Imm8; + bool isAdd; + // If The first operand isn't a register, we have a label reference. + const MCOperand &MO = MI.getOperand(OpIdx); + if (!MO.isReg()) { + Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC. + Imm8 = 0; + isAdd = false; // 'U' bit is handled as part of the fixup. + + assert(MO.isExpr() && "Unexpected machine operand type!"); + const MCExpr *Expr = MO.getExpr(); + MCFixupKind Kind; + if (isThumb2(STI)) + Kind = MCFixupKind(ARM::fixup_t2_pcrel_9); + else + Kind = MCFixupKind(ARM::fixup_arm_pcrel_9); + Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); + + ++MCNumCPRelocations; + } else { + EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI); + isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add; + } + + uint32_t Binary = ARM_AM::getAM5Offset(Imm8); + // Immediate is always encoded as positive. The 'U' bit controls add vs sub. + if (isAdd) + Binary |= (1 << 8); + Binary |= (Reg << 9); + return Binary; +} + unsigned ARMMCCodeEmitter:: getSORegRegOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, @@ -1446,23 +1463,6 @@ getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, } unsigned ARMMCCodeEmitter:: -getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO1 = MI.getOperand(OpNum); - - // FIXME: Needs fixup support. - unsigned Value = 0; - int32_t tmp = (int32_t)MO1.getImm(); - if (tmp < 0) - tmp = abs(tmp); - else - Value |= 4096; // Set the ADD bit - Value |= tmp & 4095; - return Value; -} - -unsigned ARMMCCodeEmitter:: getT2SORegOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 8c8c249addb5c..afb089ab0286f 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -16,7 +16,6 @@ #include "ARMMCTargetDesc.h" #include "InstPrinter/ARMInstPrinter.h" #include "llvm/ADT/Triple.h" -#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" @@ -201,18 +200,6 @@ static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, return MAI; } -static MCCodeGenInfo *createARMMCCodeGenInfo(const Triple &TT, Reloc::Model RM, - CodeModel::Model CM, - CodeGenOpt::Level OL) { - MCCodeGenInfo *X = new MCCodeGenInfo(); - if (RM == Reloc::Default) { - // Default relocation model on Darwin is PIC, not DynamicNoPIC. - RM = TT.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; - } - X->initMCCodeGenInfo(RM, CM, OL); - return X; -} - static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx, MCAsmBackend &MAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter, bool RelaxAll) { @@ -291,9 +278,6 @@ extern "C" void LLVMInitializeARMTargetMC() { // Register the MC asm info. RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo); - // Register the MC codegen info. - TargetRegistry::RegisterMCCodeGenInfo(*T, createARMMCCodeGenInfo); - // Register the MC instruction info. TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo); diff --git a/lib/Target/ARM/MCTargetDesc/ARMMachORelocationInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMachORelocationInfo.cpp index 4468132588cf9..482bcf9025186 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMachORelocationInfo.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMachORelocationInfo.cpp @@ -12,7 +12,7 @@ #include "llvm-c/Disassembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCRelocationInfo.h" +#include "llvm/MC/MCDisassembler/MCRelocationInfo.h" using namespace llvm; using namespace object; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp index cfd504e533afa..cfa6ce7da65e2 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -389,7 +389,8 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer, uint32_t Offset = Target.getConstant(); if (IsPCRel && RelocType == MachO::ARM_RELOC_VANILLA) Offset += 1 << Log2Size; - if (Offset && A && !Writer->doesSymbolRequireExternRelocation(*A)) + if (Offset && A && !Writer->doesSymbolRequireExternRelocation(*A) && + RelocType != MachO::ARM_RELOC_HALF) return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, Target, RelocType, Log2Size, FixedValue); @@ -447,8 +448,10 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer, // Even when it's not a scattered relocation, movw/movt always uses // a PAIR relocation. if (Type == MachO::ARM_RELOC_HALF) { - // The other-half value only gets populated for the movt and movw - // relocation entries. + // The entire addend is needed to correctly apply a relocation. One half is + // extracted from the instruction itself, the other comes from this + // PAIR. I.e. it's correct that we insert the high bits of the addend in the + // MOVW case here. relocation entries. uint32_t Value = 0; switch ((unsigned)Fixup.getKind()) { default: break; diff --git a/lib/Target/ARM/MCTargetDesc/Makefile b/lib/Target/ARM/MCTargetDesc/Makefile deleted file mode 100644 index 448ed9df2bff9..0000000000000 --- a/lib/Target/ARM/MCTargetDesc/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -##===- lib/Target/ARM/TargetDesc/Makefile ------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../../.. -LIBRARYNAME = LLVMARMDesc - -# Hack: we need to include 'main' target directory to grab private headers -CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LEVEL)/Makefile.common |
