diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 343eb00fe26..2be26a0e67c 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -46,7 +46,8 @@ public: enum ArchType { UnknownArch, - arm, // ARM: arm, armv.*, xscale + arm, // ARM (little endian): arm, armv.*, xscale + armeb, // ARM (big endian): armeb aarch64, // AArch64 (little endian): aarch64 aarch64_be, // AArch64 (big endian): aarch64_be hexagon, // Hexagon: hexagon @@ -63,7 +64,8 @@ public: sparcv9, // Sparcv9: Sparcv9 systemz, // SystemZ: s390x tce, // TCE (http://tce.cs.tut.fi/): tce - thumb, // Thumb: thumb, thumbv.* + thumb, // Thumb (little endian): thumb, thumbv.* + thumbeb, // Thumb (big endian): thumbeb x86, // X86: i[3-9]86 x86_64, // X86-64: amd64, x86_64 xcore, // XCore: xcore diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 12cd81931ff..986d3a0a354 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -508,7 +508,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) { *StubAddr = 0xd61f0200; // br ip0 return Addr; - } else if (Arch == Triple::arm) { + } else if (Arch == Triple::arm || Arch == Triple::armeb) { // TODO: There is only ARM far stub now. We should add the Thumb stub, // and stubs for branches Thumb - ARM and ARM - Thumb. uint32_t *StubAddr = (uint32_t *)Addr; diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 3b400690eb7..3204b81df2b 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -848,7 +848,9 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, resolveAArch64Relocation(Section, Offset, Value, Type, Addend); break; case Triple::arm: // Fall through. + case Triple::armeb: case Triple::thumb: + case Triple::thumbeb: resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type, (uint32_t)(Addend & 0xffffffffL)); break; diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 85a3422bb7c..904bd29cd6f 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -22,6 +22,7 @@ const char *Triple::getArchTypeName(ArchType Kind) { case aarch64: return "aarch64"; case aarch64_be: return "aarch64_be"; case arm: return "arm"; + case armeb: return "armeb"; case hexagon: return "hexagon"; case mips: return "mips"; case mipsel: return "mipsel"; @@ -37,6 +38,7 @@ const char *Triple::getArchTypeName(ArchType Kind) { case systemz: return "s390x"; case tce: return "tce"; case thumb: return "thumb"; + case thumbeb: return "thumbeb"; case x86: return "i386"; case x86_64: return "x86_64"; case xcore: return "xcore"; @@ -60,7 +62,9 @@ const char *Triple::getArchTypePrefix(ArchType Kind) { case aarch64_be: return "aarch64"; case arm: - case thumb: return "arm"; + case armeb: + case thumb: + case thumbeb: return "arm"; case ppc64: case ppc64le: @@ -168,6 +172,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("aarch64", aarch64) .Case("aarch64_be", aarch64_be) .Case("arm", arm) + .Case("armeb", armeb) .Case("mips", mips) .Case("mipsel", mipsel) .Case("mips64", mips64) @@ -184,6 +189,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("systemz", systemz) .Case("tce", tce) .Case("thumb", thumb) + .Case("thumbeb", thumbeb) .Case("x86", x86) .Case("x86-64", x86_64) .Case("xcore", xcore) @@ -212,6 +218,7 @@ const char *Triple::getArchNameForAssembler() { .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5") .Cases("armv6", "thumbv6", "armv6") .Cases("armv7", "thumbv7", "armv7") + .Case("armeb", "armeb") .Case("r600", "r600") .Case("nvptx", "nvptx") .Case("nvptx64", "nvptx64") @@ -237,8 +244,12 @@ static Triple::ArchType parseArch(StringRef ArchName) { // FIXME: It would be good to replace these with explicit names for all the // various suffixes supported. .StartsWith("armv", Triple::arm) + .Case("armeb", Triple::armeb) + .StartsWith("armebv", Triple::armeb) .Case("thumb", Triple::thumb) .StartsWith("thumbv", Triple::thumb) + .Case("thumbeb", Triple::thumbeb) + .StartsWith("thumbebv", Triple::thumbeb) .Case("msp430", Triple::msp430) .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) .Cases("mipsel", "mipsallegrexel", Triple::mipsel) @@ -743,6 +754,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::amdil: case llvm::Triple::arm: + case llvm::Triple::armeb: case llvm::Triple::hexagon: case llvm::Triple::le32: case llvm::Triple::mips: @@ -753,6 +765,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::sparc: case llvm::Triple::tce: case llvm::Triple::thumb: + case llvm::Triple::thumbeb: case llvm::Triple::x86: case llvm::Triple::xcore: case llvm::Triple::spir: @@ -801,6 +814,7 @@ Triple Triple::get32BitArchVariant() const { case Triple::amdil: case Triple::spir: case Triple::arm: + case Triple::armeb: case Triple::hexagon: case Triple::le32: case Triple::mips: @@ -811,6 +825,7 @@ Triple Triple::get32BitArchVariant() const { case Triple::sparc: case Triple::tce: case Triple::thumb: + case Triple::thumbeb: case Triple::x86: case Triple::xcore: // Already 32-bit. @@ -833,12 +848,14 @@ Triple Triple::get64BitArchVariant() const { case Triple::UnknownArch: case Triple::amdil: case Triple::arm: + case Triple::armeb: case Triple::hexagon: case Triple::le32: case Triple::msp430: case Triple::r600: case Triple::tce: case Triple::thumb: + case Triple::thumbeb: case Triple::xcore: T.setArch(UnknownArch); break; diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index c2526bec9e5..eecfb0dd54c 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1719,6 +1719,8 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { // Force static initialization. extern "C" void LLVMInitializeARMAsmPrinter() { - RegisterAsmPrinter X(TheARMTarget); - RegisterAsmPrinter Y(TheThumbTarget); + RegisterAsmPrinter X(TheARMleTarget); + RegisterAsmPrinter Y(TheARMbeTarget); + RegisterAsmPrinter A(TheThumbleTarget); + RegisterAsmPrinter B(TheThumbbeTarget); } diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index 69b496f386e..a290136f6bd 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -75,12 +75,14 @@ IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), clEnumValEnd)); ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU, - const std::string &FS, const TargetOptions &Options) + const std::string &FS, bool IsLittle, + const TargetOptions &Options) : ARMGenSubtargetInfo(TT, CPU, FS) , ARMProcFamily(Others) , ARMProcClass(None) , stackAlignment(4) , CPUString(CPU) + , IsLittle(IsLittle) , TargetTriple(TT) , Options(Options) , TargetABI(ARM_ABI_UNKNOWN) { diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index 1472bd146b2..2ce99c890f7 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -203,6 +203,9 @@ protected: /// CPUString - String name of used CPU. std::string CPUString; + /// IsLittle - The target is Little Endian + bool IsLittle; + /// TargetTriple - What processor and OS we're targeting. Triple TargetTriple; @@ -226,7 +229,8 @@ protected: /// of the specified triple. /// ARMSubtarget(const std::string &TT, const std::string &CPU, - const std::string &FS, const TargetOptions &Options); + const std::string &FS, bool IsLittle, + const TargetOptions &Options); /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size /// that still makes it profitable to inline the call. @@ -375,6 +379,8 @@ public: const std::string & getCPUString() const { return CPUString; } + bool isLittle() const { return IsLittle; } + unsigned getMispredictionPenalty() const; /// This function returns true if the target has sincos() routine in its diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index 64e00f46a1b..c20672dcec2 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -30,8 +30,10 @@ DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden, extern "C" void LLVMInitializeARMTarget() { // Register the target. - RegisterTargetMachine X(TheARMTarget); - RegisterTargetMachine Y(TheThumbTarget); + RegisterTargetMachine X(TheARMleTarget); + RegisterTargetMachine Y(TheARMbeTarget); + RegisterTargetMachine A(TheThumbleTarget); + RegisterTargetMachine B(TheThumbbeTarget); } @@ -41,9 +43,10 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) + CodeGenOpt::Level OL, + bool isLittle) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), - Subtarget(TT, CPU, FS, Options), + Subtarget(TT, CPU, FS, isLittle, Options), JITInfo(), InstrItins(Subtarget.getInstrItineraryData()) { @@ -65,8 +68,14 @@ void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) { void ARMTargetMachine::anchor() { } static std::string computeDataLayout(ARMSubtarget &ST) { - // Little endian. - std::string Ret = "e"; + std::string Ret = ""; + + if (ST.isLittle()) + // Little endian. + Ret += "e"; + else + // Big endian. + Ret += "E"; Ret += DataLayout::getManglingComponent(ST.getTargetTriple()); @@ -118,8 +127,9 @@ ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + bool isLittle) + : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, isLittle), InstrInfo(Subtarget), DL(computeDataLayout(Subtarget)), TLInfo(*this), @@ -131,14 +141,33 @@ ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT, "support ARM mode execution!"); } +void ARMleTargetMachine::anchor() { } + +ARMleTargetMachine:: +ARMleTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL) + : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} + +void ARMbeTargetMachine::anchor() { } + +ARMbeTargetMachine:: +ARMbeTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL) + : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} + void ThumbTargetMachine::anchor() { } ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + CodeGenOpt::Level OL, + bool isLittle) + : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, isLittle), InstrInfo(Subtarget.hasThumb2() ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget)) : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))), @@ -151,6 +180,24 @@ ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT, initAsmInfo(); } +void ThumbleTargetMachine::anchor() { } + +ThumbleTargetMachine:: +ThumbleTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL) + : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} + +void ThumbbeTargetMachine::anchor() { } + +ThumbbeTargetMachine:: +ThumbbeTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL) + : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} + namespace { /// ARM Code Generator Pass Configuration Options. class ARMPassConfig : public TargetPassConfig { diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h index b762cdddc68..8af3a6f0eb2 100644 --- a/lib/Target/ARM/ARMTargetMachine.h +++ b/lib/Target/ARM/ARMTargetMachine.h @@ -42,7 +42,8 @@ public: StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + bool isLittle); ARMJITInfo *getJITInfo() override { return &JITInfo; } const ARMSubtarget *getSubtargetImpl() const override { return &Subtarget; } @@ -77,7 +78,8 @@ class ARMTargetMachine : public ARMBaseTargetMachine { StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + bool isLittle); const ARMRegisterInfo *getRegisterInfo() const override { return &InstrInfo.getRegisterInfo(); @@ -97,6 +99,28 @@ class ARMTargetMachine : public ARMBaseTargetMachine { const DataLayout *getDataLayout() const override { return &DL; } }; +/// ARMleTargetMachine - ARM little endian target machine. +/// +class ARMleTargetMachine : public ARMTargetMachine { + virtual void anchor(); +public: + ARMleTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL); +}; + +/// ARMbeTargetMachine - ARM big endian target machine. +/// +class ARMbeTargetMachine : public ARMTargetMachine { + virtual void anchor(); +public: + ARMbeTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL); +}; + /// ThumbTargetMachine - Thumb target machine. /// Due to the way architectures are handled, this represents both /// Thumb-1 and Thumb-2. @@ -115,7 +139,8 @@ public: StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL); + CodeGenOpt::Level OL, + bool isLittle); /// returns either Thumb1RegisterInfo or Thumb2RegisterInfo const ARMBaseRegisterInfo *getRegisterInfo() const override { @@ -141,6 +166,28 @@ public: const DataLayout *getDataLayout() const override { return &DL; } }; +/// ThumbleTargetMachine - Thumb little endian target machine. +/// +class ThumbleTargetMachine : public ThumbTargetMachine { + virtual void anchor(); +public: + ThumbleTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL); +}; + +/// ThumbbeTargetMachine - Thumb big endian target machine. +/// +class ThumbbeTargetMachine : public ThumbTargetMachine { + virtual void anchor(); +public: + ThumbbeTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL); +}; + } // end namespace llvm #endif diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 83fedb70ebd..2997c615a85 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -9251,8 +9251,10 @@ bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) { /// Force static initialization. extern "C" void LLVMInitializeARMAsmParser() { - RegisterMCAsmParser X(TheARMTarget); - RegisterMCAsmParser Y(TheThumbTarget); + RegisterMCAsmParser X(TheARMleTarget); + RegisterMCAsmParser Y(TheARMbeTarget); + RegisterMCAsmParser A(TheThumbleTarget); + RegisterMCAsmParser B(TheThumbbeTarget); } #define GET_REGISTER_MATCHER diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 0a5e87aa15c..cf15586da6a 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -856,9 +856,13 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, extern "C" void LLVMInitializeARMDisassembler() { - TargetRegistry::RegisterMCDisassembler(TheARMTarget, + TargetRegistry::RegisterMCDisassembler(TheARMleTarget, createARMDisassembler); - TargetRegistry::RegisterMCDisassembler(TheThumbTarget, + TargetRegistry::RegisterMCDisassembler(TheARMbeTarget, + createARMDisassembler); + TargetRegistry::RegisterMCDisassembler(TheThumbleTarget, + createThumbDisassembler); + TargetRegistry::RegisterMCDisassembler(TheThumbbeTarget, createThumbDisassembler); } diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index aaa8f362e20..8b7b7eadc77 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -41,11 +41,12 @@ public: class ARMAsmBackend : public MCAsmBackend { const MCSubtargetInfo* STI; - bool isThumbMode; // Currently emitting Thumb code. + bool isThumbMode; // Currently emitting Thumb code. + bool IsLittleEndian; // Big or little endian. public: - ARMAsmBackend(const Target &T, const StringRef TT) + ARMAsmBackend(const Target &T, const StringRef TT, bool IsLittle) : MCAsmBackend(), STI(ARM_MC::createARMMCSubtargetInfo(TT, "", "")), - isThumbMode(TT.startswith("thumb")) {} + isThumbMode(TT.startswith("thumb")), IsLittleEndian(IsLittle) {} ~ARMAsmBackend() { delete STI; @@ -60,7 +61,7 @@ public: } const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { - const static MCFixupKindInfo Infos[ARM::NumTargetFixupKinds] = { + const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = { // This table *must* be in the order that the fixup_* kinds are defined in // ARMFixupKinds.h. // @@ -101,13 +102,54 @@ public: { "fixup_t2_movt_hi16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_movw_lo16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel }, }; + 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 }, +{ "fixup_arm_movt_hi16_pcrel", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_movw_lo16_pcrel", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_movt_hi16_pcrel", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_movw_lo16_pcrel", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, + }; if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!"); - return Infos[Kind - FirstTargetFixupKind]; + return (IsLittleEndian ? InfosLE : InfosBE)[Kind - FirstTargetFixupKind]; } /// processFixupValue - Target hook to process the literal value of a fixup @@ -146,6 +188,7 @@ public: unsigned getPointerSize() const { return 4; } bool isThumb() const { return isThumbMode; } void setIsThumb(bool it) { isThumbMode = it; } + bool isLittle() const { return IsLittleEndian; } }; } // end anonymous namespace @@ -637,6 +680,57 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { } } +/// getFixupKindContainerSizeBytes - The number of bytes of the +/// container involved in big endian. +static unsigned getFixupKindContainerSizeBytes(unsigned Kind) { + switch (Kind) { + default: + llvm_unreachable("Unknown fixup kind!"); + + case FK_Data_1: + return 1; + case FK_Data_2: + return 2; + case FK_Data_4: + return 4; + + case ARM::fixup_arm_thumb_bcc: + case ARM::fixup_arm_thumb_cp: + case ARM::fixup_thumb_adr_pcrel_10: + case ARM::fixup_arm_thumb_br: + case ARM::fixup_arm_thumb_cb: + // Instruction size is 2 bytes. + 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_adr_pcrel_12: + case ARM::fixup_arm_uncondbl: + case ARM::fixup_arm_condbl: + case ARM::fixup_arm_blx: + case ARM::fixup_arm_condbranch: + case ARM::fixup_arm_uncondbranch: + case ARM::fixup_t2_ldst_pcrel_12: + case ARM::fixup_t2_condbranch: + case ARM::fixup_t2_uncondbranch: + case ARM::fixup_t2_pcrel_10: + case ARM::fixup_t2_adr_pcrel_12: + case ARM::fixup_arm_thumb_bl: + case ARM::fixup_arm_thumb_blx: + case ARM::fixup_arm_movt_hi16: + case ARM::fixup_arm_movw_lo16: + case ARM::fixup_arm_movt_hi16_pcrel: + case ARM::fixup_arm_movw_lo16_pcrel: + case ARM::fixup_t2_movt_hi16: + case ARM::fixup_t2_movw_lo16: + case ARM::fixup_t2_movt_hi16_pcrel: + case ARM::fixup_t2_movw_lo16_pcrel: + // Instruction size is 4 bytes. + return 4; + } +} + void ARMAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value) const { unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); @@ -646,11 +740,18 @@ void ARMAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, unsigned Offset = Fixup.getOffset(); assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!"); + // Used to point to big endian bytes. + unsigned FullSizeBytes; + if (!IsLittleEndian) + FullSizeBytes = getFixupKindContainerSizeBytes(Fixup.getKind()); + // For each byte of the fragment that the fixup touches, mask in the bits from // the fixup value. The Value has been "split up" into the appropriate // bitfields above. - for (unsigned i = 0; i != NumBytes; ++i) - Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff); + for (unsigned i = 0; i != NumBytes; ++i) { + unsigned Idx = IsLittleEndian ? i : (FullSizeBytes - 1 - i); + Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff); + } } namespace { @@ -661,11 +762,11 @@ class ELFARMAsmBackend : public ARMAsmBackend { public: uint8_t OSABI; ELFARMAsmBackend(const Target &T, const StringRef TT, - uint8_t _OSABI) - : ARMAsmBackend(T, TT), OSABI(_OSABI) { } + uint8_t _OSABI, bool _IsLittle) + : ARMAsmBackend(T, TT, _IsLittle), OSABI(_OSABI) { } MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { - return createARMELFObjectWriter(OS, OSABI); + return createARMELFObjectWriter(OS, OSABI, isLittle()); } }; @@ -675,7 +776,7 @@ public: const MachO::CPUSubTypeARM Subtype; DarwinARMAsmBackend(const Target &T, const StringRef TT, MachO::CPUSubTypeARM st) - : ARMAsmBackend(T, TT), Subtype(st) { + : ARMAsmBackend(T, TT, /* IsLittleEndian */ true), Subtype(st) { HasDataInCodeSupport = true; } @@ -690,7 +791,8 @@ public: MCAsmBackend *llvm::createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI, - StringRef TT, StringRef CPU) { + StringRef TT, StringRef CPU, + bool isLittle) { Triple TheTriple(TT); if (TheTriple.isOSBinFormatMachO()) { @@ -716,5 +818,30 @@ MCAsmBackend *llvm::createARMAsmBackend(const Target &T, #endif uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS()); - return new ELFARMAsmBackend(T, TT, OSABI); + return new ELFARMAsmBackend(T, TT, OSABI, isLittle); } + +MCAsmBackend *llvm::createARMleAsmBackend(const Target &T, + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { + return createARMAsmBackend(T, MRI, TT, CPU, true); +} + +MCAsmBackend *llvm::createARMbeAsmBackend(const Target &T, + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { + return createARMAsmBackend(T, MRI, TT, CPU, false); +} + +MCAsmBackend *llvm::createThumbleAsmBackend(const Target &T, + 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) { + return createARMAsmBackend(T, MRI, TT, CPU, false); +} + diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index fb1380f8726..44c57312829 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -299,7 +299,8 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, } MCObjectWriter *llvm::createARMELFObjectWriter(raw_ostream &OS, - uint8_t OSABI) { + uint8_t OSABI, + bool IsLittleEndian) { MCELFObjectTargetWriter *MOTW = new ARMELFObjectWriter(OSABI); - return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true); + return createELFObjectWriter(MOTW, OS, IsLittleEndian); } diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp index 3b33a9901c6..52e1fb9dd53 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -13,12 +13,18 @@ #include "ARMMCAsmInfo.h" #include "llvm/Support/CommandLine.h" +#include "llvm/ADT/Triple.h" using namespace llvm; void ARMMCAsmInfoDarwin::anchor() { } -ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin() { +ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin(StringRef TT) { + Triple TheTriple(TT); + if ((TheTriple.getArch() == Triple::armeb) || + (TheTriple.getArch() == Triple::thumbeb)) + IsLittleEndian = false; + Data64bitsDirective = 0; CommentString = "@"; Code16Directive = ".code\t16"; @@ -35,7 +41,12 @@ ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin() { void ARMELFMCAsmInfo::anchor() { } -ARMELFMCAsmInfo::ARMELFMCAsmInfo() { +ARMELFMCAsmInfo::ARMELFMCAsmInfo(StringRef TT) { + Triple TheTriple(TT); + if ((TheTriple.getArch() == Triple::armeb) || + (TheTriple.getArch() == Triple::thumbeb)) + IsLittleEndian = false; + // ".comm align is in bytes but .align is pow-2." AlignmentIsInBytes = false; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h index 08efa8e4f24..be0295279c0 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h @@ -22,13 +22,13 @@ namespace llvm { class ARMMCAsmInfoDarwin : public MCAsmInfoDarwin { void anchor() override; public: - explicit ARMMCAsmInfoDarwin(); + explicit ARMMCAsmInfoDarwin(StringRef TT); }; class ARMELFMCAsmInfo : public MCAsmInfoELF { void anchor() override; public: - explicit ARMELFMCAsmInfo(); + explicit ARMELFMCAsmInfo(StringRef TT); void setUseIntegratedAssembler(bool Value) override; }; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 3b2ca73aecd..260201cbcb0 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -40,10 +40,11 @@ class ARMMCCodeEmitter : public MCCodeEmitter { void operator=(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION; const MCInstrInfo &MCII; const MCContext &CTX; + bool IsLittleEndian; public: - ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) - : MCII(mcii), CTX(ctx) { + ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle) + : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) { } ~ARMMCCodeEmitter() {} @@ -385,8 +386,8 @@ public: void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const { // Output the constant in little endian byte order. for (unsigned i = 0; i != Size; ++i) { - EmitByte(Val & 255, OS); - Val >>= 8; + unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; + EmitByte((Val >> Shift) & 0xff, OS); } } @@ -397,11 +398,18 @@ public: } // end anonymous namespace -MCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII, - const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, - MCContext &Ctx) { - return new ARMMCCodeEmitter(MCII, Ctx); +MCCodeEmitter *llvm::createARMleMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI, + MCContext &Ctx) { + return new ARMMCCodeEmitter(MCII, Ctx, true); +} + +MCCodeEmitter *llvm::createARMbeMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI, + MCContext &Ctx) { + return new ARMMCCodeEmitter(MCII, Ctx, false); } /// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 000fc738bdd..23bb85a7463 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -89,11 +89,16 @@ std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { unsigned Idx = 0; // FIXME: Enhance Triple helper class to extract ARM version. - bool isThumb = triple.getArch() == Triple::thumb; + 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; @@ -214,9 +219,9 @@ static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { MCAsmInfo *MAI; if (TheTriple.isOSBinFormatMachO()) - MAI = new ARMMCAsmInfoDarwin(); + MAI = new ARMMCAsmInfoDarwin(TT); else - MAI = new ARMELFMCAsmInfo(); + MAI = new ARMELFMCAsmInfo(TT); unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true); MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(0, Reg, 0)); @@ -323,56 +328,94 @@ static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { // Force static initialization. extern "C" void LLVMInitializeARMTargetMC() { // Register the MC asm info. - RegisterMCAsmInfoFn A(TheARMTarget, createARMMCAsmInfo); - RegisterMCAsmInfoFn B(TheThumbTarget, createARMMCAsmInfo); + RegisterMCAsmInfoFn X(TheARMleTarget, createARMMCAsmInfo); + RegisterMCAsmInfoFn Y(TheARMbeTarget, createARMMCAsmInfo); + RegisterMCAsmInfoFn A(TheThumbleTarget, createARMMCAsmInfo); + RegisterMCAsmInfoFn B(TheThumbbeTarget, createARMMCAsmInfo); // Register the MC codegen info. - TargetRegistry::RegisterMCCodeGenInfo(TheARMTarget, createARMMCCodeGenInfo); - TargetRegistry::RegisterMCCodeGenInfo(TheThumbTarget, createARMMCCodeGenInfo); + TargetRegistry::RegisterMCCodeGenInfo(TheARMleTarget, createARMMCCodeGenInfo); + TargetRegistry::RegisterMCCodeGenInfo(TheARMbeTarget, createARMMCCodeGenInfo); + TargetRegistry::RegisterMCCodeGenInfo(TheThumbleTarget, createARMMCCodeGenInfo); + TargetRegistry::RegisterMCCodeGenInfo(TheThumbbeTarget, createARMMCCodeGenInfo); // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(TheARMTarget, createARMMCInstrInfo); - TargetRegistry::RegisterMCInstrInfo(TheThumbTarget, createARMMCInstrInfo); + TargetRegistry::RegisterMCInstrInfo(TheARMleTarget, createARMMCInstrInfo); + TargetRegistry::RegisterMCInstrInfo(TheARMbeTarget, createARMMCInstrInfo); + TargetRegistry::RegisterMCInstrInfo(TheThumbleTarget, createARMMCInstrInfo); + TargetRegistry::RegisterMCInstrInfo(TheThumbbeTarget, createARMMCInstrInfo); // Register the MC register info. - TargetRegistry::RegisterMCRegInfo(TheARMTarget, createARMMCRegisterInfo); - TargetRegistry::RegisterMCRegInfo(TheThumbTarget, createARMMCRegisterInfo); + TargetRegistry::RegisterMCRegInfo(TheARMleTarget, createARMMCRegisterInfo); + TargetRegistry::RegisterMCRegInfo(TheARMbeTarget, createARMMCRegisterInfo); + TargetRegistry::RegisterMCRegInfo(TheThumbleTarget, createARMMCRegisterInfo); + TargetRegistry::RegisterMCRegInfo(TheThumbbeTarget, createARMMCRegisterInfo); // Register the MC subtarget info. - TargetRegistry::RegisterMCSubtargetInfo(TheARMTarget, + TargetRegistry::RegisterMCSubtargetInfo(TheARMleTarget, ARM_MC::createARMMCSubtargetInfo); - TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, + TargetRegistry::RegisterMCSubtargetInfo(TheARMbeTarget, + ARM_MC::createARMMCSubtargetInfo); + TargetRegistry::RegisterMCSubtargetInfo(TheThumbleTarget, + ARM_MC::createARMMCSubtargetInfo); + TargetRegistry::RegisterMCSubtargetInfo(TheThumbbeTarget, ARM_MC::createARMMCSubtargetInfo); // Register the MC instruction analyzer. - TargetRegistry::RegisterMCInstrAnalysis(TheARMTarget, + TargetRegistry::RegisterMCInstrAnalysis(TheARMleTarget, createARMMCInstrAnalysis); - TargetRegistry::RegisterMCInstrAnalysis(TheThumbTarget, + TargetRegistry::RegisterMCInstrAnalysis(TheARMbeTarget, + createARMMCInstrAnalysis); + TargetRegistry::RegisterMCInstrAnalysis(TheThumbleTarget, + createARMMCInstrAnalysis); + TargetRegistry::RegisterMCInstrAnalysis(TheThumbbeTarget, createARMMCInstrAnalysis); // Register the MC Code Emitter - TargetRegistry::RegisterMCCodeEmitter(TheARMTarget, createARMMCCodeEmitter); - TargetRegistry::RegisterMCCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); + TargetRegistry::RegisterMCCodeEmitter(TheARMleTarget, + createARMleMCCodeEmitter); + TargetRegistry::RegisterMCCodeEmitter(TheARMbeTarget, + createARMbeMCCodeEmitter); + TargetRegistry::RegisterMCCodeEmitter(TheThumbleTarget, + createARMleMCCodeEmitter); + TargetRegistry::RegisterMCCodeEmitter(TheThumbbeTarget, + createARMbeMCCodeEmitter); // Register the asm backend. - TargetRegistry::RegisterMCAsmBackend(TheARMTarget, createARMAsmBackend); - TargetRegistry::RegisterMCAsmBackend(TheThumbTarget, createARMAsmBackend); + TargetRegistry::RegisterMCAsmBackend(TheARMleTarget, createARMleAsmBackend); + TargetRegistry::RegisterMCAsmBackend(TheARMbeTarget, createARMbeAsmBackend); + TargetRegistry::RegisterMCAsmBackend(TheThumbleTarget, + createThumbleAsmBackend); + TargetRegistry::RegisterMCAsmBackend(TheThumbbeTarget, + createThumbbeAsmBackend); // Register the object streamer. - TargetRegistry::RegisterMCObjectStreamer(TheARMTarget, createMCStreamer); - TargetRegistry::RegisterMCObjectStreamer(TheThumbTarget, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(TheARMleTarget, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(TheARMbeTarget, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(TheThumbleTarget, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(TheThumbbeTarget, createMCStreamer); // Register the asm streamer. - TargetRegistry::RegisterAsmStreamer(TheARMTarget, createMCAsmStreamer); - TargetRegistry::RegisterAsmStreamer(TheThumbTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheARMleTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheARMbeTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheThumbleTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheThumbbeTarget, createMCAsmStreamer); // Register the MCInstPrinter. - TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); - TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); + TargetRegistry::RegisterMCInstPrinter(TheARMleTarget, createARMMCInstPrinter); + TargetRegistry::RegisterMCInstPrinter(TheARMbeTarget, createARMMCInstPrinter); + TargetRegistry::RegisterMCInstPrinter(TheThumbleTarget, + createARMMCInstPrinter); + TargetRegistry::RegisterMCInstPrinter(TheThumbbeTarget, + createARMMCInstPrinter); // Register the MC relocation info. - TargetRegistry::RegisterMCRelocationInfo(TheARMTarget, + TargetRegistry::RegisterMCRelocationInfo(TheARMleTarget, createARMMCRelocationInfo); - TargetRegistry::RegisterMCRelocationInfo(TheThumbTarget, + TargetRegistry::RegisterMCRelocationInfo(TheARMbeTarget, + createARMMCRelocationInfo); + TargetRegistry::RegisterMCRelocationInfo(TheThumbleTarget, + createARMMCRelocationInfo); + TargetRegistry::RegisterMCRelocationInfo(TheThumbbeTarget, createARMMCRelocationInfo); } diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h index d7ef101690b..c1f9d041d60 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h @@ -33,7 +33,8 @@ class StringRef; class Target; class raw_ostream; -extern Target TheARMTarget, TheThumbTarget; +extern Target TheARMleTarget, TheThumbleTarget; +extern Target TheARMbeTarget, TheThumbbeTarget; namespace ARM_MC { std::string ParseARMTriple(StringRef TT, StringRef CPU); @@ -51,17 +52,36 @@ MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst); -MCCodeEmitter *createARMMCCodeEmitter(const MCInstrInfo &MCII, - const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, - MCContext &Ctx); +MCCodeEmitter *createARMleMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI, + MCContext &Ctx); + +MCCodeEmitter *createARMbeMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI, + MCContext &Ctx); MCAsmBackend *createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU, + bool IsLittleEndian); + +MCAsmBackend *createARMleAsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef TT, StringRef CPU); +MCAsmBackend *createARMbeAsmBackend(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); + +MCAsmBackend *createThumbleAsmBackend(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); + +MCAsmBackend *createThumbbeAsmBackend(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); + /// createARMELFObjectWriter - Construct an ELF Mach-O object writer. MCObjectWriter *createARMELFObjectWriter(raw_ostream &OS, - uint8_t OSABI); + uint8_t OSABI, + bool IsLittleEndian); /// createARMMachObjectWriter - Construct an ARM Mach-O object writer. MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS, diff --git a/lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp b/lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp index f1d294c733f..b735ad11e56 100644 --- a/lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp +++ b/lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp @@ -12,12 +12,17 @@ #include "llvm/Support/TargetRegistry.h" using namespace llvm; -Target llvm::TheARMTarget, llvm::TheThumbTarget; +Target llvm::TheARMleTarget, llvm::TheARMbeTarget; +Target llvm::TheThumbleTarget, llvm::TheThumbbeTarget; extern "C" void LLVMInitializeARMTargetInfo() { RegisterTarget - X(TheARMTarget, "arm", "ARM"); + X(TheARMleTarget, "arm", "ARM"); + RegisterTarget + Y(TheARMbeTarget, "armeb", "ARM (big endian)"); RegisterTarget - Y(TheThumbTarget, "thumb", "Thumb"); + A(TheThumbleTarget, "thumb", "Thumb"); + RegisterTarget + B(TheThumbbeTarget, "thumbeb", "Thumb (big endian)"); } diff --git a/test/MC/ARM/arm_fixups.s b/test/MC/ARM/arm_fixups.s index 99eb3c53941..bd6906bae77 100644 --- a/test/MC/ARM/arm_fixups.s +++ b/test/MC/ARM/arm_fixups.s @@ -1,9 +1,13 @@ @ RUN: llvm-mc -triple armv7-unknown-unknown %s --show-encoding > %t @ RUN: FileCheck < %t %s +@ RUN: llvm-mc -triple armebv7-unknown-unknown %s --show-encoding > %t +@ RUN: FileCheck --check-prefix=CHECK-BE < %t %s bl _printf @ CHECK: bl _printf @ encoding: [A,A,A,0xeb] @ CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_uncondbl +@ CHECK-BE: bl _printf @ encoding: [0xeb,A,A,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_uncondbl mov r9, :lower16:(_foo) movw r9, :lower16:(_foo) @@ -11,12 +15,20 @@ @ CHECK: movw r9, :lower16:_foo @ encoding: [A,0x90'A',0b0000AAAA,0xe3] @ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movw_lo16 +@ CHECK-BE: movw r9, :lower16:_foo @ encoding: [0xe3,0b0000AAAA,0x90'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movw_lo16 @ CHECK: movw r9, :lower16:_foo @ encoding: [A,0x90'A',0b0000AAAA,0xe3] @ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movw_lo16 +@ CHECK-BE: movw r9, :lower16:_foo @ encoding: [0xe3,0b0000AAAA,0x90'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movw_lo16 @ CHECK: movt r9, :upper16:_foo @ encoding: [A,0x90'A',0b0100AAAA,0xe3] @ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movt_hi16 +@ CHECK-BE: movt r9, :upper16:_foo @ encoding: [0xe3,0b0100AAAA,0x90'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movt_hi16 mov r2, fred @ CHECK: movw r2, fred @ encoding: [A,0x20'A',0b0000AAAA,0xe3] @ CHECK: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16 +@ CHECK-BE: movw r2, fred @ encoding: [0xe3,0b0000AAAA,0x20'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16 diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 29bc6c07cc6..e5e96170a77 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -1,4 +1,5 @@ @ RUN: llvm-mc -triple=armv7-apple-darwin -mcpu=cortex-a8 -show-encoding < %s | FileCheck %s +@ RUN: llvm-mc -triple=armebv7-unknown-unknown -mcpu=cortex-a8 -show-encoding < %s | FileCheck --check-prefix=CHECK-BE %s .syntax unified .globl _func @@ -135,8 +136,12 @@ Lforward: @ CHECK: Lback: @ CHECK: adr r2, Lback @ encoding: [A,0x20'A',0x0f'A',0xe2'A'] @ CHECK: @ fixup A - offset: 0, value: Lback, kind: fixup_arm_adr_pcrel_12 +@ CHECK-BE: adr r2, Lback @ encoding: [0xe2'A',0x0f'A',0x20'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: Lback, kind: fixup_arm_adr_pcrel_12 @ CHECK: adr r3, Lforward @ encoding: [A,0x30'A',0x0f'A',0xe2'A'] @ CHECK: @ fixup A - offset: 0, value: Lforward, kind: fixup_arm_adr_pcrel_12 +@ CHECK-BE: adr r3, Lforward @ encoding: [0xe2'A',0x0f'A',0x30'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: Lforward, kind: fixup_arm_adr_pcrel_12 @ CHECK: Lforward: @ CHECK: adr r2, #3 @ encoding: [0x03,0x20,0x8f,0xe2] @ CHECK: adr r2, #-3 @ encoding: [0x03,0x20,0x4f,0xe2] @@ -310,9 +315,13 @@ Lforward: beq _baz @ CHECK: b _bar @ encoding: [A,A,A,0xea] - @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch +@ CHECK-BE: b _bar @ encoding: [0xea,A,A,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch @ CHECK: beq _baz @ encoding: [A,A,A,0x0a] - @ fixup A - offset: 0, value: _baz, kind: fixup_arm_condbranch +@ CHECK: @ fixup A - offset: 0, value: _baz, kind: fixup_arm_condbranch +@ CHECK-BE: beq _baz @ encoding: [0x0a,A,A,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _baz, kind: fixup_arm_condbranch @------------------------------------------------------------------------------ @@ -420,10 +429,16 @@ Lforward: @ CHECK: bl _bar @ encoding: [A,A,A,0xeb] @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbl +@ CHECK-BE: bl _bar @ encoding: [0xeb,A,A,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbl @ CHECK: bleq _bar @ encoding: [A,A,A,0x0b] @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_condbl +@ CHECK-BE: bleq _bar @ encoding: [0x0b,A,A,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_condbl @ CHECK: blx _bar @ encoding: [A,A,A,0xfa] - @ fixup A - offset: 0, value: _bar, kind: fixup_arm_blx +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_blx +@ CHECK-BE: blx _bar @ encoding: [0xfa,A,A,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_blx @ CHECK: blls #28634268 @ encoding: [0x27,0x3b,0x6d,0x9b] @ CHECK: blx #32424576 @ encoding: [0xa0,0xb0,0x7b,0xfa] @ CHECK: blx #16212288 @ encoding: [0x50,0xd8,0x3d,0xfa] diff --git a/test/MC/ARM/basic-thumb-instructions.s b/test/MC/ARM/basic-thumb-instructions.s index dec7f5b1333..30ab733375b 100644 --- a/test/MC/ARM/basic-thumb-instructions.s +++ b/test/MC/ARM/basic-thumb-instructions.s @@ -4,6 +4,7 @@ @--- @ RUN: llvm-mc -triple=thumbv6-apple-darwin -show-encoding < %s | FileCheck %s @ RUN: llvm-mc -triple=thumbv7-apple-darwin -show-encoding < %s | FileCheck %s +@ RUN: llvm-mc -triple=thumbebv7-unknown-unknown -show-encoding < %s | FileCheck --check-prefix=CHECK-BE %s .syntax unified .globl _func @@ -90,7 +91,9 @@ _func: adr r3, #1020 @ CHECK: adr r2, _baz @ encoding: [A,0xa2] - @ fixup A - offset: 0, value: _baz, kind: fixup_thumb_adr_pcrel_10 +@ CHECK: @ fixup A - offset: 0, value: _baz, kind: fixup_thumb_adr_pcrel_10 +@ CHECK-BE: adr r2, _baz @ encoding: [0xa2,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _baz, kind: fixup_thumb_adr_pcrel_10 @ CHECK: adr r5, #0 @ encoding: [0x00,0xa5] @ CHECK: adr r2, #4 @ encoding: [0x01,0xa2] @ CHECK: adr r3, #1020 @ encoding: [0xff,0xa3] @@ -132,9 +135,13 @@ _func: beq #160 @ CHECK: b _baz @ encoding: [A,0xe0'A'] - @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_br +@ CHECK: @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_br +@ CHECK-BE: b _baz @ encoding: [0xe0'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_br @ CHECK: beq _bar @ encoding: [A,0xd0] - @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bcc +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bcc +@ CHECK-BE: beq _bar @ encoding: [0xd0,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bcc @ CHECK: b #1838 @ encoding: [0x97,0xe3] @ CHECK: b #-420 @ encoding: [0x2e,0xe7] @ CHECK: beq #-256 @ encoding: [0x80,0xd0] @@ -174,9 +181,13 @@ _func: blx _baz @ CHECK: bl _bar @ encoding: [A,0xf0'A',A,0xd0'A'] - @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bl +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bl +@ CHECK-BE: bl _bar @ encoding: [0xf0'A',A,0xd0'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bl @ CHECK: blx _baz @ encoding: [A,0xf0'A',A,0xc0'A'] - @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_blx +@ CHECK: @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_blx +@ CHECK-BE: blx _baz @ encoding: [0xf0'A',A,0xc0'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_blx @------------------------------------------------------------------------------ @@ -272,7 +283,9 @@ _func: ldr r3, #368 @ CHECK: ldr r1, _foo @ encoding: [A,0x49] - @ fixup A - offset: 0, value: _foo, kind: fixup_arm_thumb_cp +@ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_thumb_cp +@ CHECK-BE: ldr r1, _foo @ encoding: [0x49,A] +@ CHECK-BE: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_thumb_cp @ CHECK: ldr r3, [pc, #604] @ encoding: [0x97,0x4b] @ CHECK: ldr r3, [pc, #368] @ encoding: [0x5c,0x4b] diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index 6dacbee8e4c..a8c9cdc610f 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -1,4 +1,5 @@ @ RUN: llvm-mc -triple=thumbv7-apple-darwin -mcpu=cortex-a8 -show-encoding < %s | FileCheck %s +@ RUN: llvm-mc -triple=thumbebv7-unknown-unknown -mcpu=cortex-a8 -show-encoding < %s | FileCheck --check-prefix=CHECK-BE %s .syntax unified .globl _func @@ -227,12 +228,18 @@ _func: bmi.w #-183396 @ CHECK: b.w _bar @ encoding: [A,0xf0'A',A,0x90'A'] - @ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch +@ CHECK-BE: b.w _bar @ encoding: [0xf0'A',A,0x90'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch @ CHECK: beq.w _bar @ encoding: [A,0xf0'A',A,0x80'A'] - @ fixup A - offset: 0, value: _bar, kind: fixup_t2_condbranch +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_condbranch +@ CHECK-BE: beq.w _bar @ encoding: [0xf0'A',A,0x80'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_condbranch @ CHECK: it eq @ encoding: [0x08,0xbf] @ CHECK: beq.w _bar @ encoding: [A,0xf0'A',A,0x90'A'] - @ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch +@ CHECK-BE: beq.w _bar @ encoding: [0xf0'A',A,0x90'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch @ CHECK: bmi.w #-183396 @ encoding: [0x13,0xf5,0xce,0xa9] @@ -332,9 +339,13 @@ _func: @ CHECK: cbnz r7, #6 @ encoding: [0x1f,0xb9] @ CHECK: cbnz r7, #12 @ encoding: [0x37,0xb9] @ CHECK: cbz r6, _bar @ encoding: [0x06'A',0xb1'A'] - @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_cb +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_cb +@ CHECK-BE: cbz r6, _bar @ encoding: [0xb1'A',0x06'A'] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_cb @ CHECK: cbnz r6, _bar @ encoding: [0x06'A',0xb9'A'] - @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_cb +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_cb +@ CHECK-BE: cbnz r6, _bar @ encoding: [0xb9'A',0x06'A'] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_cb @------------------------------------------------------------------------------ @@ -804,10 +815,16 @@ _func: @ CHECK: ldr.w r5, _foo @ encoding: [0x5f'A',0xf8'A',A,0x50'A'] @ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_t2_ldst_pcrel_12 +@ CHECK-BE: ldr.w r5, _foo @ encoding: [0xf8'A',0x5f'A',0x50'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _foo, kind: fixup_t2_ldst_pcrel_12 @ CHECK: ldr.w lr, _strcmp-4 @ encoding: [0x5f'A',0xf8'A',A,0xe0'A'] @ CHECK: @ fixup A - offset: 0, value: _strcmp-4, kind: fixup_t2_ldst_pcrel_12 +@ CHECK-BE: ldr.w lr, _strcmp-4 @ encoding: [0xf8'A',0x5f'A',0xe0'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _strcmp-4, kind: fixup_t2_ldst_pcrel_12 @ CHECK: ldr.w sp, _foo @ encoding: [0x5f'A',0xf8'A',A,0xd0'A'] @ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_t2_ldst_pcrel_12 +@ CHECK-BE: ldr.w sp, _foo @ encoding: [0xf8'A',0x5f'A',0xd0'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _foo, kind: fixup_t2_ldst_pcrel_12 ldr r7, [pc, #8] ldr.n r7, [pc, #8] @@ -1027,6 +1044,8 @@ _func: @ CHECK: ldrh.w r5, _bar @ encoding: [0x3f'A',0xf8'A',A,0x50'A'] @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 +@ CHECK-BE: ldrh.w r5, _bar @ encoding: [0xf8'A',0x3f'A',0x50'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 @------------------------------------------------------------------------------ @@ -1096,6 +1115,8 @@ _func: @ CHECK: ldrsb.w r5, _bar @ encoding: [0x1f'A',0xf9'A',A,0x50'A'] @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 +@ CHECK-BE: ldrsb.w r5, _bar @ encoding: [0xf9'A',0x1f'A',0x50'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 @------------------------------------------------------------------------------ @@ -1165,6 +1186,8 @@ _func: @ CHECK: ldrsh.w r5, _bar @ encoding: [0x3f'A',0xf9'A',A,0x50'A'] @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 +@ CHECK-BE: ldrsh.w r5, _bar @ encoding: [0xf9'A',0x3f'A',0x50'A',A] +@ CHECK-BE: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 @ TEMPORARILY DISABLED: @ ldrsh.w r4, [pc, #1435]