summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChristian Pirker <cpirker@a-bix.com>2014-03-28 14:35:30 +0000
committerChristian Pirker <cpirker@a-bix.com>2014-03-28 14:35:30 +0000
commit1f072c36d0e248d69932a830b698458f032c644d (patch)
tree977adba973520658bf09e9ab8b1e1ae76c1f2369 /lib
parentbd2cca79b753e9491765a5b930ecd38e7fe76d72 (diff)
downloadllvm-1f072c36d0e248d69932a830b698458f032c644d.tar.gz
llvm-1f072c36d0e248d69932a830b698458f032c644d.tar.bz2
llvm-1f072c36d0e248d69932a830b698458f032c644d.tar.xz
Add ARM big endian Target (armeb, thumbeb)
Reviewed at http://llvm-reviews.chandlerc.com/D3095 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205007 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp2
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp2
-rw-r--r--lib/Support/Triple.cpp19
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp6
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp4
-rw-r--r--lib/Target/ARM/ARMSubtarget.h8
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp67
-rw-r--r--lib/Target/ARM/ARMTargetMachine.h53
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp6
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp8
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp153
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp5
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp15
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h4
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp26
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp97
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h32
-rw-r--r--lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp11
18 files changed, 431 insertions, 87 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 12cd81931f..986d3a0a35 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 3b400690eb..3204b81df2 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 85a3422bb7..904bd29cd6 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 c2526bec9e..eecfb0dd54 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<ARMAsmPrinter> X(TheARMTarget);
- RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
+ RegisterAsmPrinter<ARMAsmPrinter> X(TheARMleTarget);
+ RegisterAsmPrinter<ARMAsmPrinter> Y(TheARMbeTarget);
+ RegisterAsmPrinter<ARMAsmPrinter> A(TheThumbleTarget);
+ RegisterAsmPrinter<ARMAsmPrinter> B(TheThumbbeTarget);
}
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index 69b496f386..a290136f6b 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 1472bd146b..2ce99c890f 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 64e00f46a1..c20672dcec 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<ARMTargetMachine> X(TheARMTarget);
- RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
+ RegisterTargetMachine<ARMleTargetMachine> X(TheARMleTarget);
+ RegisterTargetMachine<ARMbeTargetMachine> Y(TheARMbeTarget);
+ RegisterTargetMachine<ThumbleTargetMachine> A(TheThumbleTarget);
+ RegisterTargetMachine<ThumbbeTargetMachine> 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 b762cdddc6..8af3a6f0eb 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 83fedb70eb..2997c615a8 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<ARMAsmParser> X(TheARMTarget);
- RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
+ RegisterMCAsmParser<ARMAsmParser> X(TheARMleTarget);
+ RegisterMCAsmParser<ARMAsmParser> Y(TheARMbeTarget);
+ RegisterMCAsmParser<ARMAsmParser> A(TheThumbleTarget);
+ RegisterMCAsmParser<ARMAsmParser> B(TheThumbbeTarget);
}
#define GET_REGISTER_MATCHER
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 0a5e87aa15..cf15586da6 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 aaa8f362e2..8b7b7eadc7 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 fb1380f872..44c5731282 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 3b33a9901c..52e1fb9dd5 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 08efa8e4f2..be0295279c 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 3b2ca73aec..260201cbcb 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 000fc738bd..23bb85a746 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(TheARMbeTarget,
ARM_MC::createARMMCSubtargetInfo);
- TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget,
+ 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(TheARMbeTarget,
createARMMCInstrAnalysis);
- TargetRegistry::RegisterMCInstrAnalysis(TheThumbTarget,
+ 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(TheARMbeTarget,
+ createARMMCRelocationInfo);
+ TargetRegistry::RegisterMCRelocationInfo(TheThumbleTarget,
createARMMCRelocationInfo);
- TargetRegistry::RegisterMCRelocationInfo(TheThumbTarget,
+ TargetRegistry::RegisterMCRelocationInfo(TheThumbbeTarget,
createARMMCRelocationInfo);
}
diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
index d7ef101690..c1f9d041d6 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 f1d294c733..b735ad11e5 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<Triple::arm, /*HasJIT=*/true>
- X(TheARMTarget, "arm", "ARM");
+ X(TheARMleTarget, "arm", "ARM");
+ RegisterTarget<Triple::armeb, /*HasJIT=*/true>
+ Y(TheARMbeTarget, "armeb", "ARM (big endian)");
RegisterTarget<Triple::thumb, /*HasJIT=*/true>
- Y(TheThumbTarget, "thumb", "Thumb");
+ A(TheThumbleTarget, "thumb", "Thumb");
+ RegisterTarget<Triple::thumbeb, /*HasJIT=*/true>
+ B(TheThumbbeTarget, "thumbeb", "Thumb (big endian)");
}