diff options
Diffstat (limited to 'lib/Target/ARM/MCTargetDesc')
21 files changed, 522 insertions, 400 deletions
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h b/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h index b6c85c2..f0eed9b 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_ARM_ARMADDRESSINGMODES_H -#define LLVM_TARGET_ARM_ARMADDRESSINGMODES_H +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMADDRESSINGMODES_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMADDRESSINGMODES_H #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" @@ -575,6 +575,53 @@ namespace ARM_AM { return Val; } + // Generic validation for single-byte immediate (0X00, 00X0, etc). + static inline bool isNEONBytesplat(unsigned Value, unsigned Size) { + assert(Size >= 1 && Size <= 4 && "Invalid size"); + unsigned count = 0; + for (unsigned i = 0; i < Size; ++i) { + if (Value & 0xff) count++; + Value >>= 8; + } + return count == 1; + } + + /// Checks if Value is a correct immediate for instructions like VBIC/VORR. + static inline bool isNEONi16splat(unsigned Value) { + if (Value > 0xffff) + return false; + // i16 value with set bits only in one byte X0 or 0X. + return Value == 0 || isNEONBytesplat(Value, 2); + } + + // Encode NEON 16 bits Splat immediate for instructions like VBIC/VORR + static inline unsigned encodeNEONi16splat(unsigned Value) { + assert(isNEONi16splat(Value) && "Invalid NEON splat value"); + if (Value >= 0x100) + Value = (Value >> 8) | 0xa00; + else + Value |= 0x800; + return Value; + } + + /// Checks if Value is a correct immediate for instructions like VBIC/VORR. + static inline bool isNEONi32splat(unsigned Value) { + // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X. + return Value == 0 || isNEONBytesplat(Value, 4); + } + + /// Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR. + static inline unsigned encodeNEONi32splat(unsigned Value) { + assert(isNEONi32splat(Value) && "Invalid NEON splat value"); + if (Value >= 0x100 && Value <= 0xff00) + Value = (Value >> 8) | 0x200; + else if (Value > 0xffff && Value <= 0xff0000) + Value = (Value >> 16) | 0x400; + else if (Value > 0xffffff) + Value = (Value >> 24) | 0x600; + return Value; + } + AMSubMode getLoadStoreMultipleSubMode(int Opcode); //===--------------------------------------------------------------------===// diff --git a/lib/Target/ARM/MCTargetDesc/ARMArchName.h b/lib/Target/ARM/MCTargetDesc/ARMArchName.h index 34b9fc1..bc05673 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMArchName.h +++ b/lib/Target/ARM/MCTargetDesc/ARMArchName.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ARMARCHNAME_H -#define ARMARCHNAME_H +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMARCHNAME_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMARCHNAME_H namespace llvm { namespace ARM { @@ -24,4 +24,4 @@ enum ArchKind { } // namespace ARM } // namespace llvm -#endif // ARMARCHNAME_H +#endif diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 7acd9cc..0b2e3b0 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -9,6 +9,10 @@ #include "MCTargetDesc/ARMMCTargetDesc.h" #include "MCTargetDesc/ARMAddressingModes.h" +#include "MCTargetDesc/ARMAsmBackend.h" +#include "MCTargetDesc/ARMAsmBackendDarwin.h" +#include "MCTargetDesc/ARMAsmBackendELF.h" +#include "MCTargetDesc/ARMAsmBackendWinCOFF.h" #include "MCTargetDesc/ARMBaseInfo.h" #include "MCTargetDesc/ARMFixupKinds.h" #include "llvm/ADT/StringSwitch.h" @@ -35,164 +39,136 @@ namespace { class ARMELFObjectWriter : public MCELFObjectTargetWriter { public: ARMELFObjectWriter(uint8_t OSABI) - : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_ARM, - /*HasRelocationAddend*/ false) {} + : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_ARM, + /*HasRelocationAddend*/ false) {} }; -class ARMAsmBackend : public MCAsmBackend { - const MCSubtargetInfo* STI; - bool isThumbMode; // Currently emitting Thumb code. - bool IsLittleEndian; // Big or little endian. -public: - ARMAsmBackend(const Target &T, const StringRef TT, bool IsLittle) - : MCAsmBackend(), STI(ARM_MC::createARMMCSubtargetInfo(TT, "", "")), - isThumbMode(TT.startswith("thumb")), IsLittleEndian(IsLittle) {} - - ~ARMAsmBackend() { - delete STI; - } - - unsigned getNumFixupKinds() const override { - return ARM::NumTargetFixupKinds; - } - - bool hasNOP() const { - return (STI->getFeatureBits() & ARM::HasV6T2Ops) != 0; - } +const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { + const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = { + // This table *must* be in the order that the fixup_* kinds are defined in + // ARMFixupKinds.h. + // + // Name Offset (bits) Size (bits) Flags + {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_ldst_pcrel_12", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_pcrel_10", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_thumb_adr_pcrel_10", 0, 8, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_adr_pcrel_12", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel}, + {"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_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_thumb_cp", 0, 8, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_thumb_bcc", 0, 8, MCFixupKindInfo::FKF_IsPCRel}, + // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16 + // - 19. + {"fixup_arm_movt_hi16", 0, 20, 0}, + {"fixup_arm_movw_lo16", 0, 20, 0}, + {"fixup_t2_movt_hi16", 0, 20, 0}, + {"fixup_t2_movw_lo16", 0, 20, 0}, + }; + const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = { + // This table *must* be in the order that the fixup_* kinds are defined in + // ARMFixupKinds.h. + // + // Name Offset (bits) Size (bits) Flags + {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_ldst_pcrel_12", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_pcrel_10", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_thumb_adr_pcrel_10", 8, 8, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_adr_pcrel_12", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_condbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_uncondbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_uncondbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel}, + {"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_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_arm_thumb_cp", 8, 8, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + {"fixup_arm_thumb_bcc", 8, 8, MCFixupKindInfo::FKF_IsPCRel}, + // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16 + // - 19. + {"fixup_arm_movt_hi16", 12, 20, 0}, + {"fixup_arm_movw_lo16", 12, 20, 0}, + {"fixup_t2_movt_hi16", 12, 20, 0}, + {"fixup_t2_movw_lo16", 12, 20, 0}, + }; + + if (Kind < FirstTargetFixupKind) + return MCAsmBackend::getFixupKindInfo(Kind); + + assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && + "Invalid kind!"); + return (IsLittleEndian ? InfosLE : InfosBE)[Kind - FirstTargetFixupKind]; +} - const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { - const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = { -// This table *must* be in the order that the fixup_* kinds are defined in -// ARMFixupKinds.h. -// -// Name Offset (bits) Size (bits) Flags -{ "fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_thumb_adr_pcrel_10",0, 8, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, -{ "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_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_thumb_cp", 0, 8, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_arm_thumb_bcc", 0, 8, MCFixupKindInfo::FKF_IsPCRel }, -// movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16 - 19. -{ "fixup_arm_movt_hi16", 0, 20, 0 }, -{ "fixup_arm_movw_lo16", 0, 20, 0 }, -{ "fixup_t2_movt_hi16", 0, 20, 0 }, -{ "fixup_t2_movw_lo16", 0, 20, 0 }, - }; - const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = { -// This table *must* be in the order that the fixup_* kinds are defined in -// ARMFixupKinds.h. -// -// Name Offset (bits) Size (bits) Flags -{ "fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_thumb_adr_pcrel_10",8, 8, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_arm_condbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_uncondbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_uncondbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel }, -{ "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_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_arm_thumb_cp", 8, 8, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, -{ "fixup_arm_thumb_bcc", 8, 8, MCFixupKindInfo::FKF_IsPCRel }, -// movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16 - 19. -{ "fixup_arm_movt_hi16", 12, 20, 0 }, -{ "fixup_arm_movw_lo16", 12, 20, 0 }, -{ "fixup_t2_movt_hi16", 12, 20, 0 }, -{ "fixup_t2_movw_lo16", 12, 20, 0 }, - }; - - if (Kind < FirstTargetFixupKind) - return MCAsmBackend::getFixupKindInfo(Kind); - - assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && - "Invalid kind!"); - return (IsLittleEndian ? InfosLE : InfosBE)[Kind - FirstTargetFixupKind]; - } - - /// processFixupValue - Target hook to process the literal value of a fixup - /// if necessary. - void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFixup &Fixup, const MCFragment *DF, - const MCValue &Target, uint64_t &Value, - bool &IsResolved) override; - - - void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, - uint64_t Value, bool IsPCRel) const override; - - bool mayNeedRelaxation(const MCInst &Inst) const override; - - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, - const MCAsmLayout &Layout) const override; - - void relaxInstruction(const MCInst &Inst, MCInst &Res) const override; - - bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; - - void handleAssemblerFlag(MCAssemblerFlag Flag) override { - switch (Flag) { - default: break; - case MCAF_Code16: - setIsThumb(true); - break; - case MCAF_Code32: - setIsThumb(false); - break; - } +void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) { + switch (Flag) { + default: + break; + case MCAF_Code16: + setIsThumb(true); + break; + case MCAF_Code32: + setIsThumb(false); + break; } - - unsigned getPointerSize() const { return 4; } - bool isThumb() const { return isThumbMode; } - void setIsThumb(bool it) { isThumbMode = it; } - bool isLittle() const { return IsLittleEndian; } -}; +} } // end anonymous namespace static unsigned getRelaxedOpcode(unsigned Op) { switch (Op) { - default: return Op; - case ARM::tBcc: return ARM::t2Bcc; - case ARM::tLDRpci: return ARM::t2LDRpci; - case ARM::tADR: return ARM::t2ADR; - case ARM::tB: return ARM::t2B; - case ARM::tCBZ: return ARM::tHINT; - case ARM::tCBNZ: return ARM::tHINT; + default: + return Op; + case ARM::tBcc: + return ARM::t2Bcc; + case ARM::tLDRpci: + return ARM::t2LDRpci; + case ARM::tADR: + return ARM::t2ADR; + case ARM::tB: + return ARM::t2B; + case ARM::tCBZ: + return ARM::tHINT; + case ARM::tCBNZ: + return ARM::tHINT; } } @@ -202,8 +178,7 @@ bool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst) const { return false; } -bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, - uint64_t Value, +bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const { switch ((unsigned)Fixup.getKind()) { @@ -265,7 +240,7 @@ void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { Res.addOperand(MCOperand::CreateImm(14)); Res.addOperand(MCOperand::CreateReg(0)); return; - } + } // The rest of instructions we're relaxing have the same operands. // We just need to update to the proper opcode. @@ -276,11 +251,11 @@ void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { bool ARMAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8 const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP - const uint32_t ARMv4_NopEncoding = 0xe1a00000; // using MOV r0,r0 + const uint32_t ARMv4_NopEncoding = 0xe1a00000; // using MOV r0,r0 const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP if (isThumb()) { - const uint16_t nopEncoding = hasNOP() ? Thumb2_16bitNopEncoding - : Thumb1_16bitNopEncoding; + const uint16_t nopEncoding = + hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding; uint64_t NumNops = Count / 2; for (uint64_t i = 0; i != NumNops; ++i) OW->Write16(nopEncoding); @@ -289,18 +264,26 @@ bool ARMAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { return true; } // ARM mode - const uint32_t nopEncoding = hasNOP() ? ARMv6T2_NopEncoding - : ARMv4_NopEncoding; + const uint32_t nopEncoding = + hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding; uint64_t NumNops = Count / 4; for (uint64_t i = 0; i != NumNops; ++i) OW->Write32(nopEncoding); // FIXME: should this function return false when unable to write exactly // 'Count' bytes with NOP encodings? switch (Count % 4) { - default: break; // No leftover bytes to write - case 1: OW->Write8(0); break; - case 2: OW->Write16(0); break; - case 3: OW->Write16(0); OW->Write8(0xa0); break; + default: + break; // No leftover bytes to write + case 1: + OW->Write8(0); + break; + case 2: + OW->Write16(0); + break; + case 3: + OW->Write16(0); + OW->Write8(0xa0); + break; } return true; @@ -313,8 +296,7 @@ static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian) { uint32_t Swapped = (Value & 0xFFFF0000) >> 16; Swapped |= (Value & 0x0000FFFF) << 16; return Swapped; - } - else + } else return Value; } @@ -351,7 +333,7 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_arm_movt_hi16: if (!IsPCRel) Value >>= 16; - // Fallthrough + // Fallthrough case ARM::fixup_arm_movw_lo16: { unsigned Hi4 = (Value & 0xF000) >> 12; unsigned Lo12 = Value & 0x0FFF; @@ -363,7 +345,7 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_t2_movt_hi16: if (!IsPCRel) Value >>= 16; - // Fallthrough + // Fallthrough case ARM::fixup_t2_movw_lo16: { unsigned Hi4 = (Value & 0xF000) >> 12; unsigned i = (Value & 0x800) >> 11; @@ -379,7 +361,7 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_arm_ldst_pcrel_12: // ARM PC-relative values are offset by 8. Value -= 4; - // FALLTHROUGH + // FALLTHROUGH case ARM::fixup_t2_ldst_pcrel_12: { // Offset by 4, adjusted by two due to the half-word ordering of thumb. Value -= 4; @@ -438,7 +420,8 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_arm_blx: // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. - if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Fixup.getValue())) + if (const MCSymbolRefExpr *SRE = + dyn_cast<MCSymbolRefExpr>(Fixup.getValue())) if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL) return 0; return 0xffffff & ((Value - 8) >> 2); @@ -447,17 +430,17 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, Value >>= 1; // Low bit is not encoded. uint32_t out = 0; - bool I = Value & 0x800000; + bool I = Value & 0x800000; bool J1 = Value & 0x400000; bool J2 = Value & 0x200000; J1 ^= I; J2 ^= I; - out |= I << 26; // S bit - out |= !J1 << 13; // J1 bit - out |= !J2 << 11; // J2 bit - out |= (Value & 0x1FF800) << 5; // imm6 field - out |= (Value & 0x0007FF); // imm11 field + out |= I << 26; // S bit + out |= !J1 << 13; // J1 bit + out |= !J2 << 11; // J2 bit + out |= (Value & 0x1FF800) << 5; // imm6 field + out |= (Value & 0x0007FF); // imm11 field return swapHalfWords(out, IsLittleEndian); } @@ -498,7 +481,7 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits); uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) | - (uint16_t)imm11Bits); + (uint16_t)imm11Bits); return joinHalfWords(FirstHalf, SecondHalf, IsLittleEndian); } case ARM::fixup_arm_thumb_blx: { @@ -515,7 +498,8 @@ static unsigned 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 (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Fixup.getValue())) + if (const MCSymbolRefExpr *SRE = + dyn_cast<MCSymbolRefExpr>(Fixup.getValue())) if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL) offset = 0; uint32_t signBit = (offset & 0x400000) >> 22; @@ -528,7 +512,7 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits); uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) | - ((uint16_t)imm10LBits) << 1); + ((uint16_t)imm10LBits) << 1); return joinHalfWords(FirstHalf, SecondHalf, IsLittleEndian); } case ARM::fixup_arm_thumb_cp: @@ -564,7 +548,7 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_arm_pcrel_10: Value = Value - 4; // ARM fixups offset by an additional word and don't // need to adjust for the half-word ordering. - // Fall through. + // Fall through. case ARM::fixup_t2_pcrel_10: { // Offset by 4, adjusted by two due to the half-word ordering of thumb. Value = Value - 4; @@ -735,7 +719,8 @@ void ARMAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, bool IsPCRel) const { unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); Value = adjustFixupValue(Fixup, Value, IsPCRel, nullptr, IsLittleEndian); - if (!Value) return; // Doesn't change encoding. + if (!Value) + return; // Doesn't change encoding. unsigned Offset = Fixup.getOffset(); assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!"); @@ -757,80 +742,36 @@ void ARMAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, } } -namespace { -// FIXME: This should be in a separate file. -class ARMWinCOFFAsmBackend : public ARMAsmBackend { -public: - ARMWinCOFFAsmBackend(const Target &T, const StringRef &Triple) - : ARMAsmBackend(T, Triple, true) { } - MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { - return createARMWinCOFFObjectWriter(OS, /*Is64Bit=*/false); - } -}; - -// FIXME: This should be in a separate file. -// ELF is an ELF of course... -class ELFARMAsmBackend : public ARMAsmBackend { -public: - uint8_t OSABI; - ELFARMAsmBackend(const Target &T, const StringRef TT, - uint8_t OSABI, bool IsLittle) - : ARMAsmBackend(T, TT, IsLittle), OSABI(OSABI) { } - - MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { - return createARMELFObjectWriter(OS, OSABI, isLittle()); - } -}; - -// FIXME: This should be in a separate file. -class DarwinARMAsmBackend : public ARMAsmBackend { -public: - const MachO::CPUSubTypeARM Subtype; - DarwinARMAsmBackend(const Target &T, const StringRef TT, - MachO::CPUSubTypeARM st) - : ARMAsmBackend(T, TT, /* IsLittleEndian */ true), Subtype(st) { - HasDataInCodeSupport = true; - } - - MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { - return createARMMachObjectWriter(OS, /*Is64Bit=*/false, - MachO::CPU_TYPE_ARM, - Subtype); - } -}; - -} // end anonymous namespace - MCAsmBackend *llvm::createARMAsmBackend(const Target &T, - const MCRegisterInfo &MRI, - StringRef TT, StringRef CPU, - bool isLittle) { + const MCRegisterInfo &MRI, StringRef TT, + StringRef CPU, bool isLittle) { Triple TheTriple(TT); switch (TheTriple.getObjectFormat()) { - default: llvm_unreachable("unsupported object format"); + default: + llvm_unreachable("unsupported object format"); case Triple::MachO: { MachO::CPUSubTypeARM CS = - StringSwitch<MachO::CPUSubTypeARM>(TheTriple.getArchName()) - .Cases("armv4t", "thumbv4t", MachO::CPU_SUBTYPE_ARM_V4T) - .Cases("armv5e", "thumbv5e", MachO::CPU_SUBTYPE_ARM_V5TEJ) - .Cases("armv6", "thumbv6", MachO::CPU_SUBTYPE_ARM_V6) - .Cases("armv6m", "thumbv6m", MachO::CPU_SUBTYPE_ARM_V6M) - .Cases("armv7em", "thumbv7em", MachO::CPU_SUBTYPE_ARM_V7EM) - .Cases("armv7k", "thumbv7k", MachO::CPU_SUBTYPE_ARM_V7K) - .Cases("armv7m", "thumbv7m", MachO::CPU_SUBTYPE_ARM_V7M) - .Cases("armv7s", "thumbv7s", MachO::CPU_SUBTYPE_ARM_V7S) - .Default(MachO::CPU_SUBTYPE_ARM_V7); - - return new DarwinARMAsmBackend(T, TT, CS); + StringSwitch<MachO::CPUSubTypeARM>(TheTriple.getArchName()) + .Cases("armv4t", "thumbv4t", MachO::CPU_SUBTYPE_ARM_V4T) + .Cases("armv5e", "thumbv5e", MachO::CPU_SUBTYPE_ARM_V5TEJ) + .Cases("armv6", "thumbv6", MachO::CPU_SUBTYPE_ARM_V6) + .Cases("armv6m", "thumbv6m", MachO::CPU_SUBTYPE_ARM_V6M) + .Cases("armv7em", "thumbv7em", MachO::CPU_SUBTYPE_ARM_V7EM) + .Cases("armv7k", "thumbv7k", MachO::CPU_SUBTYPE_ARM_V7K) + .Cases("armv7m", "thumbv7m", MachO::CPU_SUBTYPE_ARM_V7M) + .Cases("armv7s", "thumbv7s", MachO::CPU_SUBTYPE_ARM_V7S) + .Default(MachO::CPU_SUBTYPE_ARM_V7); + + return new ARMAsmBackendDarwin(T, TT, CS); } case Triple::COFF: assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported"); - return new ARMWinCOFFAsmBackend(T, TT); + return new ARMAsmBackendWinCOFF(T, TT); case Triple::ELF: assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target"); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS()); - return new ELFARMAsmBackend(T, TT, OSABI, isLittle); + return new ARMAsmBackendELF(T, TT, OSABI, isLittle); } } @@ -847,14 +788,13 @@ MCAsmBackend *llvm::createARMBEAsmBackend(const Target &T, } MCAsmBackend *llvm::createThumbLEAsmBackend(const Target &T, - const MCRegisterInfo &MRI, - StringRef TT, StringRef CPU) { + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { return createARMAsmBackend(T, MRI, TT, CPU, true); } MCAsmBackend *llvm::createThumbBEAsmBackend(const Target &T, - const MCRegisterInfo &MRI, - StringRef TT, StringRef CPU) { + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { return createARMAsmBackend(T, MRI, TT, CPU, false); } - diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h new file mode 100644 index 0000000..f4f1082 --- /dev/null +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -0,0 +1,69 @@ +//===-- ARMAsmBackend.h - ARM Assembler Backend -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_ARM_ARMASMBACKEND_H +#define LLVM_LIB_TARGET_ARM_ARMASMBACKEND_H + +#include "MCTargetDesc/ARMFixupKinds.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCSubtargetInfo.h" + +using namespace llvm; + +namespace { + +class ARMAsmBackend : public MCAsmBackend { + const MCSubtargetInfo *STI; + bool isThumbMode; // Currently emitting Thumb code. + bool IsLittleEndian; // Big or little endian. +public: + ARMAsmBackend(const Target &T, StringRef TT, bool IsLittle) + : MCAsmBackend(), STI(ARM_MC::createARMMCSubtargetInfo(TT, "", "")), + isThumbMode(TT.startswith("thumb")), IsLittleEndian(IsLittle) {} + + ~ARMAsmBackend() override { delete STI; } + + unsigned getNumFixupKinds() const override { + return ARM::NumTargetFixupKinds; + } + + bool hasNOP() const { return (STI->getFeatureBits() & ARM::HasV6T2Ops) != 0; } + + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; + + /// processFixupValue - Target hook to process the literal value of a fixup + /// if necessary. + void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFixup &Fixup, const MCFragment *DF, + const MCValue &Target, uint64_t &Value, + bool &IsResolved) override; + + void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, + uint64_t Value, bool IsPCRel) const override; + + bool mayNeedRelaxation(const MCInst &Inst) const override; + + bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const override; + + void relaxInstruction(const MCInst &Inst, MCInst &Res) const override; + + bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; + + void handleAssemblerFlag(MCAssemblerFlag Flag) override; + + unsigned getPointerSize() const { return 4; } + bool isThumb() const { return isThumbMode; } + void setIsThumb(bool it) { isThumbMode = it; } + bool isLittle() const { return IsLittleEndian; } +}; +} // end anonymous namespace + +#endif diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h new file mode 100644 index 0000000..3bd7ab7 --- /dev/null +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h @@ -0,0 +1,33 @@ +//===-- ARMAsmBackendDarwin.h ARM Asm Backend Darwin ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_ARM_ARMASMBACKENDDARWIN_H +#define LLVM_LIB_TARGET_ARM_ARMASMBACKENDDARWIN_H + +#include "llvm/Support/MachO.h" + +using namespace llvm; + +namespace { +class ARMAsmBackendDarwin : public ARMAsmBackend { +public: + const MachO::CPUSubTypeARM Subtype; + ARMAsmBackendDarwin(const Target &T, StringRef TT, MachO::CPUSubTypeARM st) + : ARMAsmBackend(T, TT, /* IsLittleEndian */ true), Subtype(st) { + HasDataInCodeSupport = true; + } + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + return createARMMachObjectWriter(OS, /*Is64Bit=*/false, MachO::CPU_TYPE_ARM, + Subtype); + } +}; +} + +#endif diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h new file mode 100644 index 0000000..4efd325 --- /dev/null +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h @@ -0,0 +1,27 @@ +//===-- ARMAsmBackendELF.h ARM Asm Backend ELF -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_ARM_ELFARMASMBACKEND_H +#define LLVM_LIB_TARGET_ARM_ELFARMASMBACKEND_H + +using namespace llvm; +namespace { +class ARMAsmBackendELF : public ARMAsmBackend { +public: + uint8_t OSABI; + ARMAsmBackendELF(const Target &T, StringRef TT, uint8_t OSABI, bool IsLittle) + : ARMAsmBackend(T, TT, IsLittle), OSABI(OSABI) {} + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + return createARMELFObjectWriter(OS, OSABI, isLittle()); + } +}; +} + +#endif diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h new file mode 100644 index 0000000..33be347 --- /dev/null +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h @@ -0,0 +1,26 @@ +//===-- ARMAsmBackendWinCOFF.h - ARM Asm Backend WinCOFF --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_ARM_ARMASMBACKENDWINCOFF_H +#define LLVM_LIB_TARGET_ARM_ARMASMBACKENDWINCOFF_H + +using namespace llvm; + +namespace { +class ARMAsmBackendWinCOFF : public ARMAsmBackend { +public: + ARMAsmBackendWinCOFF(const Target &T, StringRef Triple) + : ARMAsmBackend(T, Triple, true) {} + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + return createARMWinCOFFObjectWriter(OS, /*Is64Bit=*/false); + } +}; +} + +#endif diff --git a/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h index 1686d76..4289a73 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h +++ b/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h @@ -14,8 +14,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ARMBASEINFO_H -#define ARMBASEINFO_H +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMBASEINFO_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMBASEINFO_H #include "ARMMCTargetDesc.h" #include "llvm/Support/ErrorHandling.h" diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 1c84263..f24b419 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -37,7 +37,8 @@ namespace { unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(unsigned Type) const override; + bool needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const override; }; } @@ -48,7 +49,8 @@ ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI) ARMELFObjectWriter::~ARMELFObjectWriter() {} -bool ARMELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const { +bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const { // FIXME: This is extremelly conservative. This really needs to use a // whitelist with a clear explanation for why each realocation needs to // point to the symbol, not to the section. @@ -100,7 +102,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case ARM::fixup_arm_uncondbl: switch (Modifier) { case MCSymbolRefExpr::VK_PLT: - Type = ELF::R_ARM_PLT32; + Type = ELF::R_ARM_CALL; break; case MCSymbolRefExpr::VK_ARM_TLSCALL: Type = ELF::R_ARM_TLS_CALL; diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 7b5d8b0..24ee537 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -848,6 +848,14 @@ void ARMTargetELFStreamer::emitFPUDefaultAttributes() { /* OverwriteExisting= */ false); break; + // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so + // uses the FP_ARMV8_D16 build attribute. + case ARM::FPV5_D16: + setAttributeItem(ARMBuildAttrs::FP_arch, + ARMBuildAttrs::AllowFPARMv8B, + /* OverwriteExisting= */ false); + break; + case ARM::NEON: setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A, @@ -1339,10 +1347,9 @@ MCStreamer *createARMNullStreamer(MCContext &Ctx) { return S; } - MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack, - bool IsThumb) { +MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool IsThumb) { ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); new ARMTargetELFStreamer(*S); // FIXME: This should eventually end up somewhere else where more @@ -1352,8 +1359,6 @@ MCStreamer *createARMNullStreamer(MCContext &Ctx) { if (RelaxAll) S->getAssembler().setRelaxAll(true); - if (NoExecStack) - S->getAssembler().setNoExecStack(true); return S; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h b/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h index bfd9e33..46ba571 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h +++ b/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ARM_ARMFIXUPKINDS_H -#define LLVM_ARM_ARMFIXUPKINDS_H +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMFIXUPKINDS_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMFIXUPKINDS_H #include "llvm/MC/MCFixup.h" diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp index 7a19208..1d82099 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -55,7 +55,6 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo(StringRef TT) { Code16Directive = ".code\t16"; Code32Directive = ".code\t32"; - HasLEB128 = true; SupportsDebugInformation = true; // Exceptions handling @@ -103,7 +102,6 @@ ARMCOFFMCAsmInfoGNU::ARMCOFFMCAsmInfoGNU() { Code32Directive = ".code\t32"; PrivateGlobalPrefix = ".L"; - HasLEB128 = true; SupportsDebugInformation = true; ExceptionsType = ExceptionHandling::None; UseParensForSymbolVariant = true; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h index 51cfa0a..f1fef41 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ARMTARGETASMINFO_H -#define LLVM_ARMTARGETASMINFO_H +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMMCASMINFO_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMMCASMINFO_H #include "llvm/MC/MCAsmInfoCOFF.h" #include "llvm/MC/MCAsmInfoDarwin.h" diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp index e545e3c..68d32b2 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp @@ -35,12 +35,6 @@ void ARMMCExpr::PrintImpl(raw_ostream &OS) const { OS << ')'; } -bool -ARMMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, - const MCAsmLayout *Layout) const { - return false; -} - void ARMMCExpr::visitUsedExpr(MCStreamer &Streamer) const { Streamer.visitUsedExpr(*getSubExpr()); } diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h b/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h index c5c0b10..06bf6c9 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h +++ b/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ARMMCEXPR_H -#define ARMMCEXPR_H +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMMCEXPR_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMMCEXPR_H #include "llvm/MC/MCExpr.h" @@ -58,8 +58,11 @@ public: void PrintImpl(raw_ostream &OS) const override; bool EvaluateAsRelocatableImpl(MCValue &Res, - const MCAsmLayout *Layout) const override; - void visitUsedExpr(MCStreamer &Streamer) const override; + const MCAsmLayout *Layout, + const MCFixup *Fixup) const override { + return false; + } + void visitUsedExpr(MCStreamer &Streamer) const override; const MCSection *FindAssociatedSection() const override { return getSubExpr()->FindAssociatedSection(); } diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 2b3855d..98190ba 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -84,93 +84,89 @@ static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { Triple triple(TT); - // Set the boolean corresponding to the current target triple, or the default - // if one cannot be determined, to true. - unsigned Len = TT.size(); - unsigned Idx = 0; - - // FIXME: Enhance Triple helper class to extract ARM version. bool isThumb = triple.getArch() == Triple::thumb || triple.getArch() == Triple::thumbeb; - if (Len >= 5 && TT.substr(0, 4) == "armv") - Idx = 4; - else if (Len >= 7 && TT.substr(0, 6) == "armebv") - Idx = 6; - else if (Len >= 7 && TT.substr(0, 6) == "thumbv") - Idx = 6; - else if (Len >= 9 && TT.substr(0, 8) == "thumbebv") - Idx = 8; bool NoCPU = CPU == "generic" || CPU.empty(); std::string ARMArchFeature; - if (Idx) { - unsigned SubVer = TT[Idx]; - if (SubVer == '8') { - if (NoCPU) - // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2, - // FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, - // FeatureT2XtPk, FeatureCrypto, FeatureCRC - ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm," - "+trustzone,+t2xtpk,+crypto,+crc"; - else - // Use CPU to figure out the exact features - ARMArchFeature = "+v8"; - } else if (SubVer == '7') { - if (Len >= Idx+2 && TT[Idx+1] == 'm') { - isThumb = true; - if (NoCPU) - // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass - ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass"; - else - // Use CPU to figure out the exact features. - ARMArchFeature = "+v7"; - } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { - if (NoCPU) - // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, - // FeatureT2XtPk, FeatureMClass - ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass"; - else - // Use CPU to figure out the exact features. - ARMArchFeature = "+v7"; - } else if (Len >= Idx+2 && TT[Idx+1] == 's') { - if (NoCPU) - // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS - // Swift - ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+ras"; - else - // Use CPU to figure out the exact features. - ARMArchFeature = "+v7"; - } else { - // v7 CPUs have lots of different feature sets. If no CPU is specified, - // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return - // the "minimum" feature set and use CPU string to figure out the exact - // features. - if (NoCPU) - // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk - ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; - else - // Use CPU to figure out the exact features. - ARMArchFeature = "+v7"; - } - } else if (SubVer == '6') { - if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') - ARMArchFeature = "+v6t2"; - else if (Len >= Idx+2 && TT[Idx+1] == 'm') { - isThumb = true; - if (NoCPU) - // v6m: FeatureNoARM, FeatureMClass - ARMArchFeature = "+v6m,+noarm,+mclass"; - else - ARMArchFeature = "+v6"; - } else - ARMArchFeature = "+v6"; - } else if (SubVer == '5') { - if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') - ARMArchFeature = "+v5te"; - else - ARMArchFeature = "+v5t"; - } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't') - ARMArchFeature = "+v4t"; + switch (triple.getSubArch()) { + default: + llvm_unreachable("invalid sub-architecture for ARM"); + case Triple::ARMSubArch_v8: + if (NoCPU) + // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2, + // FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, + // FeatureT2XtPk, FeatureCrypto, FeatureCRC + ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm," + "+trustzone,+t2xtpk,+crypto,+crc"; + else + // Use CPU to figure out the exact features + ARMArchFeature = "+v8"; + break; + case Triple::ARMSubArch_v7m: + isThumb = true; + if (NoCPU) + // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass + ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass"; + else + // Use CPU to figure out the exact features. + ARMArchFeature = "+v7"; + break; + case Triple::ARMSubArch_v7em: + if (NoCPU) + // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, + // FeatureT2XtPk, FeatureMClass + ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass"; + else + // Use CPU to figure out the exact features. + ARMArchFeature = "+v7"; + break; + case Triple::ARMSubArch_v7s: + if (NoCPU) + // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS + // Swift + ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+ras"; + else + // Use CPU to figure out the exact features. + ARMArchFeature = "+v7"; + break; + case Triple::ARMSubArch_v7: + // v7 CPUs have lots of different feature sets. If no CPU is specified, + // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return + // the "minimum" feature set and use CPU string to figure out the exact + // features. + if (NoCPU) + // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk + ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; + else + // Use CPU to figure out the exact features. + ARMArchFeature = "+v7"; + break; + case Triple::ARMSubArch_v6t2: + ARMArchFeature = "+v6t2"; + break; + case Triple::ARMSubArch_v6m: + isThumb = true; + if (NoCPU) + // v6m: FeatureNoARM, FeatureMClass + ARMArchFeature = "+v6m,+noarm,+mclass"; + else + ARMArchFeature = "+v6"; + break; + case Triple::ARMSubArch_v6: + ARMArchFeature = "+v6"; + break; + case Triple::ARMSubArch_v5te: + ARMArchFeature = "+v5te"; + break; + case Triple::ARMSubArch_v5: + ARMArchFeature = "+v5t"; + break; + case Triple::ARMSubArch_v4t: + ARMArchFeature = "+v4t"; + break; + case Triple::NoSubArch: + break; } if (isThumb) { @@ -221,31 +217,14 @@ static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { Triple TheTriple(TT); MCAsmInfo *MAI; - switch (TheTriple.getOS()) { - case llvm::Triple::Darwin: - case llvm::Triple::IOS: - case llvm::Triple::MacOSX: + if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO()) MAI = new ARMMCAsmInfoDarwin(TT); - break; - case llvm::Triple::Win32: - switch (TheTriple.getEnvironment()) { - case llvm::Triple::Itanium: - MAI = new ARMCOFFMCAsmInfoGNU(); - break; - case llvm::Triple::MSVC: - MAI = new ARMCOFFMCAsmInfoMicrosoft(); - break; - default: - llvm_unreachable("invalid environment"); - } - break; - default: - if (TheTriple.isOSBinFormatMachO()) - MAI = new ARMMCAsmInfoDarwin(TT); - else - MAI = new ARMELFMCAsmInfo(TT); - break; - } + else if (TheTriple.isWindowsItaniumEnvironment()) + MAI = new ARMCOFFMCAsmInfoGNU(); + else if (TheTriple.isWindowsMSVCEnvironment()) + MAI = new ARMCOFFMCAsmInfoMicrosoft(); + else + MAI = new ARMELFMCAsmInfo(TT); unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0)); @@ -269,11 +248,8 @@ static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, // This is duplicated code. Refactor this. static MCStreamer *createMCStreamer(const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &MAB, - raw_ostream &OS, - MCCodeEmitter *Emitter, - const MCSubtargetInfo &STI, - bool RelaxAll, - bool NoExecStack) { + raw_ostream &OS, MCCodeEmitter *Emitter, + const MCSubtargetInfo &STI, bool RelaxAll) { Triple TheTriple(TT); switch (TheTriple.getObjectFormat()) { @@ -287,7 +263,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported"); return createARMWinCOFFStreamer(Ctx, MAB, *Emitter, OS); case Triple::ELF: - return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack, + return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, TheTriple.getArch() == Triple::thumb); } } @@ -362,8 +338,10 @@ extern "C" void LLVMInitializeARMTargetMC() { // Register the MC codegen info. TargetRegistry::RegisterMCCodeGenInfo(TheARMLETarget, createARMMCCodeGenInfo); TargetRegistry::RegisterMCCodeGenInfo(TheARMBETarget, createARMMCCodeGenInfo); - TargetRegistry::RegisterMCCodeGenInfo(TheThumbLETarget, createARMMCCodeGenInfo); - TargetRegistry::RegisterMCCodeGenInfo(TheThumbBETarget, createARMMCCodeGenInfo); + TargetRegistry::RegisterMCCodeGenInfo(TheThumbLETarget, + createARMMCCodeGenInfo); + TargetRegistry::RegisterMCCodeGenInfo(TheThumbBETarget, + createARMMCCodeGenInfo); // Register the MC instruction info. TargetRegistry::RegisterMCInstrInfo(TheARMLETarget, createARMMCInstrInfo); diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h index 5326e56..a6c20d5 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ARMMCTARGETDESC_H -#define ARMMCTARGETDESC_H +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMMCTARGETDESC_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMMCTARGETDESC_H #include "llvm/Support/DataTypes.h" #include <string> diff --git a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp index 186776a..7da5003 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -428,7 +428,7 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer, // For external relocations, make sure to offset the fixup value to // compensate for the addend of the symbol address, if it was // undefined. This occurs with weak definitions, for example. - if (!SD->Symbol->isUndefined()) + if (!SD->getSymbol().isUndefined()) FixedValue -= Layout.getSymbolOffset(SD); } else { // The index is the section ordinal (1-based). diff --git a/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp index ad3f1ca..8acd7af 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp @@ -28,7 +28,7 @@ ARMTargetStreamer::~ARMTargetStreamer() {} // The constant pool handling is shared by all ARMTargetStreamer // implementations. const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr) { - return ConstantPools->addEntry(Streamer, Expr); + return ConstantPools->addEntry(Streamer, Expr, 4); } void ARMTargetStreamer::emitCurrentConstantPool() { diff --git a/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h b/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h index cd58759..e0c113e 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h +++ b/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ARM_UNWIND_OP_ASM_H -#define ARM_UNWIND_OP_ASM_H +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ARMEHABI.h" @@ -90,4 +90,4 @@ private: } // namespace llvm -#endif // ARM_UNWIND_OP_ASM_H +#endif diff --git a/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt b/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt index 2a7fe61..db8fc92 100644 --- a/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt +++ b/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = ARMDesc parent = ARM -required_libraries = ARMAsmPrinter ARMInfo MC Support +required_libraries = ARMAsmPrinter ARMInfo MC MCDisassembler Support add_to_library_groups = ARM |