From 57683b8abad0c6144cb5e88172509c3afc9fc97a Mon Sep 17 00:00:00 2001 From: James Molloy Date: Wed, 23 Apr 2014 10:26:40 +0000 Subject: [PATCH] [ARM64] Add a big endian version of the ARM64 target machine, and update all users. This completes the porting of r202024 (cpirker "Add AArch64 big endian Target (aarch64_be)") to ARM64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206965 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM64/ARM64AsmPrinter.cpp | 3 +- lib/Target/ARM64/ARM64Subtarget.cpp | 4 +-- lib/Target/ARM64/ARM64Subtarget.h | 7 +++- lib/Target/ARM64/ARM64TargetMachine.cpp | 35 ++++++++++++++++--- lib/Target/ARM64/ARM64TargetMachine.h | 25 ++++++++++++- lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp | 3 +- .../ARM64/Disassembler/ARM64Disassembler.cpp | 8 +++-- .../ARM64/MCTargetDesc/ARM64AsmBackend.cpp | 24 +++++++++---- .../MCTargetDesc/ARM64ELFObjectWriter.cpp | 11 +++--- .../ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp | 7 +++- .../ARM64/MCTargetDesc/ARM64MCAsmInfo.h | 2 +- .../ARM64/MCTargetDesc/ARM64MCTargetDesc.cpp | 33 +++++++++++------ .../ARM64/MCTargetDesc/ARM64MCTargetDesc.h | 12 ++++--- .../ARM64/TargetInfo/ARM64TargetInfo.cpp | 9 +++-- 14 files changed, 139 insertions(+), 44 deletions(-) diff --git a/lib/Target/ARM64/ARM64AsmPrinter.cpp b/lib/Target/ARM64/ARM64AsmPrinter.cpp index 22ccdf97e3b..6692e662e1c 100644 --- a/lib/Target/ARM64/ARM64AsmPrinter.cpp +++ b/lib/Target/ARM64/ARM64AsmPrinter.cpp @@ -593,5 +593,6 @@ void ARM64AsmPrinter::EmitInstruction(const MachineInstr *MI) { // Force static initialization. extern "C" void LLVMInitializeARM64AsmPrinter() { - RegisterAsmPrinter X(TheARM64Target); + RegisterAsmPrinter X(TheARM64leTarget); + RegisterAsmPrinter Y(TheARM64beTarget); } diff --git a/lib/Target/ARM64/ARM64Subtarget.cpp b/lib/Target/ARM64/ARM64Subtarget.cpp index f30d69bbf34..c37bdbaa9c2 100644 --- a/lib/Target/ARM64/ARM64Subtarget.cpp +++ b/lib/Target/ARM64/ARM64Subtarget.cpp @@ -27,11 +27,11 @@ using namespace llvm; #include "ARM64GenSubtargetInfo.inc" ARM64Subtarget::ARM64Subtarget(const std::string &TT, const std::string &CPU, - const std::string &FS) + const std::string &FS, bool LittleEndian) : ARM64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others), HasFPARMv8(false), HasNEON(false), HasCrypto(false), HasZeroCycleRegMove(false), HasZeroCycleZeroing(false), - CPUString(CPU), TargetTriple(TT) { + CPUString(CPU), TargetTriple(TT), IsLittleEndian(LittleEndian) { // Determine default and user-specified characteristics if (CPUString.empty()) diff --git a/lib/Target/ARM64/ARM64Subtarget.h b/lib/Target/ARM64/ARM64Subtarget.h index 584c41be07c..1977e0bf05a 100644 --- a/lib/Target/ARM64/ARM64Subtarget.h +++ b/lib/Target/ARM64/ARM64Subtarget.h @@ -48,11 +48,14 @@ protected: /// TargetTriple - What processor and OS we're targeting. Triple TargetTriple; + /// IsLittleEndian - Is the target little endian? + bool IsLittleEndian; + public: /// This constructor initializes the data members to match that /// of the specified triple. ARM64Subtarget(const std::string &TT, const std::string &CPU, - const std::string &FS); + const std::string &FS, bool LittleEndian); bool enableMachineScheduler() const override { return true; } @@ -64,6 +67,8 @@ public: bool hasNEON() const { return HasNEON; } bool hasCrypto() const { return HasCrypto; } + bool isLittleEndian() const { return IsLittleEndian; } + bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } diff --git a/lib/Target/ARM64/ARM64TargetMachine.cpp b/lib/Target/ARM64/ARM64TargetMachine.cpp index 8070ce0d8b2..7e3228f0230 100644 --- a/lib/Target/ARM64/ARM64TargetMachine.cpp +++ b/lib/Target/ARM64/ARM64TargetMachine.cpp @@ -49,7 +49,8 @@ EnableDeadRegisterElimination("arm64-dead-def-elimination", cl::Hidden, extern "C" void LLVMInitializeARM64Target() { // Register the target. - RegisterTargetMachine X(TheARM64Target); + RegisterTargetMachine X(TheARM64leTarget); + RegisterTargetMachine Y(TheARM64beTarget); } /// TargetMachine ctor - Create an ARM64 architecture model. @@ -58,16 +59,40 @@ ARM64TargetMachine::ARM64TargetMachine(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 LittleEndian) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), - Subtarget(TT, CPU, FS), - DL(Subtarget.isTargetMachO() ? "e-m:o-i64:64-i128:128-n32:64-S128" - : "e-m:e-i64:64-i128:128-n32:64-S128"), + Subtarget(TT, CPU, FS, LittleEndian), + // This nested ternary is horrible, but DL needs to be properly initialized + // before TLInfo is constructed. + DL(Subtarget.isTargetMachO() ? + "e-m:o-i64:64-i128:128-n32:64-S128" : + (LittleEndian ? + "e-m:e-i64:64-i128:128-n32:64-S128" : + "E-m:e-i64:64-i128:128-n32:64-S128")), InstrInfo(Subtarget), TLInfo(*this), FrameLowering(*this, Subtarget), TSInfo(*this) { initAsmInfo(); } +void ARM64leTargetMachine::anchor() { } + +ARM64leTargetMachine:: +ARM64leTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL) + : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} + +void ARM64beTargetMachine::anchor() { } + +ARM64beTargetMachine:: +ARM64beTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL) + : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} + namespace { /// ARM64 Code Generator Pass Configuration Options. class ARM64PassConfig : public TargetPassConfig { diff --git a/lib/Target/ARM64/ARM64TargetMachine.h b/lib/Target/ARM64/ARM64TargetMachine.h index 8274550d019..730ffcaaf6d 100644 --- a/lib/Target/ARM64/ARM64TargetMachine.h +++ b/lib/Target/ARM64/ARM64TargetMachine.h @@ -39,7 +39,8 @@ private: public: ARM64TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OL); + CodeModel::Model CM, CodeGenOpt::Level OL, + bool IsLittleEndian); const ARM64Subtarget *getSubtargetImpl() const override { return &Subtarget; } const ARM64TargetLowering *getTargetLowering() const override { @@ -64,6 +65,28 @@ public: void addAnalysisPasses(PassManagerBase &PM) override; }; +// ARM64leTargetMachine - ARM64 little endian target machine. +// +class ARM64leTargetMachine : public ARM64TargetMachine { + virtual void anchor(); +public: + ARM64leTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL); +}; + +// ARM64beTargetMachine - ARM64 big endian target machine. +// +class ARM64beTargetMachine : public ARM64TargetMachine { + virtual void anchor(); +public: + ARM64beTargetMachine(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/ARM64/AsmParser/ARM64AsmParser.cpp b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp index d1fee2e7c6a..b377bd1765c 100644 --- a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -4509,7 +4509,8 @@ ARM64AsmParser::classifySymbolRef(const MCExpr *Expr, /// Force static initialization. extern "C" void LLVMInitializeARM64AsmParser() { - RegisterMCAsmParser X(TheARM64Target); + RegisterMCAsmParser X(TheARM64leTarget); + RegisterMCAsmParser Y(TheARM64beTarget); } #define GET_REGISTER_MATCHER diff --git a/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp b/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp index a9b6f059ad4..097594f0340 100644 --- a/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp +++ b/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp @@ -229,9 +229,13 @@ createARM64ExternalSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, } extern "C" void LLVMInitializeARM64Disassembler() { - TargetRegistry::RegisterMCDisassembler(TheARM64Target, + TargetRegistry::RegisterMCDisassembler(TheARM64leTarget, createARM64Disassembler); - TargetRegistry::RegisterMCSymbolizer(TheARM64Target, + TargetRegistry::RegisterMCDisassembler(TheARM64beTarget, + createARM64Disassembler); + TargetRegistry::RegisterMCSymbolizer(TheARM64leTarget, + createARM64ExternalSymbolizer); + TargetRegistry::RegisterMCSymbolizer(TheARM64beTarget, createARM64ExternalSymbolizer); } diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp b/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp index 26813e2ac72..55ba91d7267 100644 --- a/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp +++ b/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp @@ -483,12 +483,13 @@ namespace { class ELFARM64AsmBackend : public ARM64AsmBackend { public: uint8_t OSABI; + bool IsLittleEndian; - ELFARM64AsmBackend(const Target &T, uint8_t OSABI) - : ARM64AsmBackend(T), OSABI(OSABI) {} + ELFARM64AsmBackend(const Target &T, uint8_t OSABI, bool IsLittleEndian) + : ARM64AsmBackend(T), OSABI(OSABI), IsLittleEndian(IsLittleEndian) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createARM64ELFObjectWriter(OS, OSABI); + return createARM64ELFObjectWriter(OS, OSABI, IsLittleEndian); } void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, @@ -520,14 +521,23 @@ void ELFARM64AsmBackend::processFixupValue(const MCAssembler &Asm, } } -MCAsmBackend *llvm::createARM64AsmBackend(const Target &T, - const MCRegisterInfo &MRI, - StringRef TT, StringRef CPU) { +MCAsmBackend *llvm::createARM64leAsmBackend(const Target &T, + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { Triple TheTriple(TT); if (TheTriple.isOSDarwin()) return new DarwinARM64AsmBackend(T, MRI); assert(TheTriple.isOSBinFormatELF() && "Expect either MachO or ELF target"); - return new ELFARM64AsmBackend(T, TheTriple.getOS()); + return new ELFARM64AsmBackend(T, TheTriple.getOS(), /*IsLittleEndian=*/true); +} + +MCAsmBackend *llvm::createARM64beAsmBackend(const Target &T, + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { + Triple TheTriple(TT); + + assert(TheTriple.isOSBinFormatELF() && "Big endian is only supported for ELF targets!"); + return new ELFARM64AsmBackend(T, TheTriple.getOS(), /*IsLittleEndian=*/false); } diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64ELFObjectWriter.cpp b/lib/Target/ARM64/MCTargetDesc/ARM64ELFObjectWriter.cpp index 7779b824e0c..fe3070c019e 100644 --- a/lib/Target/ARM64/MCTargetDesc/ARM64ELFObjectWriter.cpp +++ b/lib/Target/ARM64/MCTargetDesc/ARM64ELFObjectWriter.cpp @@ -24,7 +24,7 @@ using namespace llvm; namespace { class ARM64ELFObjectWriter : public MCELFObjectTargetWriter { public: - ARM64ELFObjectWriter(uint8_t OSABI); + ARM64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian); virtual ~ARM64ELFObjectWriter(); @@ -36,7 +36,7 @@ private: }; } -ARM64ELFObjectWriter::ARM64ELFObjectWriter(uint8_t OSABI) +ARM64ELFObjectWriter::ARM64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian) : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64, /*HasRelocationAddend*/ true) {} @@ -235,7 +235,8 @@ unsigned ARM64ELFObjectWriter::GetRelocType(const MCValue &Target, } MCObjectWriter *llvm::createARM64ELFObjectWriter(raw_ostream &OS, - uint8_t OSABI) { - MCELFObjectTargetWriter *MOTW = new ARM64ELFObjectWriter(OSABI); - return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true); + uint8_t OSABI, + bool IsLittleEndian) { + MCELFObjectTargetWriter *MOTW = new ARM64ELFObjectWriter(OSABI, IsLittleEndian); + return createELFObjectWriter(MOTW, OS, IsLittleEndian); } diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp b/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp index 0575e6f7d4c..137fa880efb 100644 --- a/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp +++ b/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "ARM64MCAsmInfo.h" +#include "llvm/ADT/Triple.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" @@ -63,7 +64,11 @@ const MCExpr *ARM64MCAsmInfoDarwin::getExprForPersonalitySymbol( return MCBinaryExpr::CreateSub(Res, PC, Context); } -ARM64MCAsmInfoELF::ARM64MCAsmInfoELF() { +ARM64MCAsmInfoELF::ARM64MCAsmInfoELF(StringRef TT) { + Triple T(TT); + if (T.getArch() == Triple::aarch64_be) + IsLittleEndian = false; + // We prefer NEON instructions to be printed in the short form. AssemblerDialect = AsmWriterVariant == Default ? 0 : AsmWriterVariant; diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.h b/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.h index f2d33a72db6..2885a66de25 100644 --- a/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.h +++ b/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.h @@ -28,7 +28,7 @@ struct ARM64MCAsmInfoDarwin : public MCAsmInfoDarwin { }; struct ARM64MCAsmInfoELF : public MCAsmInfo { - explicit ARM64MCAsmInfoELF(); + explicit ARM64MCAsmInfoELF(StringRef TT); }; } // namespace llvm diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.cpp b/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.cpp index a7ce09bdeaf..30dcda49ff6 100644 --- a/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.cpp +++ b/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.cpp @@ -66,7 +66,7 @@ static MCAsmInfo *createARM64MCAsmInfo(const MCRegisterInfo &MRI, MAI = new ARM64MCAsmInfoDarwin(); else { assert(TheTriple.isOSBinFormatELF() && "Only expect Darwin or ELF"); - MAI = new ARM64MCAsmInfoELF(); + MAI = new ARM64MCAsmInfoELF(TT); } // Initial state of the frame pointer is SP. @@ -139,33 +139,46 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, // Force static initialization. extern "C" void LLVMInitializeARM64TargetMC() { // Register the MC asm info. - RegisterMCAsmInfoFn X(TheARM64Target, createARM64MCAsmInfo); + RegisterMCAsmInfoFn X(TheARM64leTarget, createARM64MCAsmInfo); + RegisterMCAsmInfoFn Y(TheARM64beTarget, createARM64MCAsmInfo); // Register the MC codegen info. - TargetRegistry::RegisterMCCodeGenInfo(TheARM64Target, + TargetRegistry::RegisterMCCodeGenInfo(TheARM64leTarget, + createARM64MCCodeGenInfo); + TargetRegistry::RegisterMCCodeGenInfo(TheARM64beTarget, createARM64MCCodeGenInfo); // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(TheARM64Target, createARM64MCInstrInfo); + TargetRegistry::RegisterMCInstrInfo(TheARM64leTarget, createARM64MCInstrInfo); + TargetRegistry::RegisterMCInstrInfo(TheARM64beTarget, createARM64MCInstrInfo); // Register the MC register info. - TargetRegistry::RegisterMCRegInfo(TheARM64Target, createARM64MCRegisterInfo); + TargetRegistry::RegisterMCRegInfo(TheARM64leTarget, createARM64MCRegisterInfo); + TargetRegistry::RegisterMCRegInfo(TheARM64beTarget, createARM64MCRegisterInfo); // Register the MC subtarget info. - TargetRegistry::RegisterMCSubtargetInfo(TheARM64Target, + TargetRegistry::RegisterMCSubtargetInfo(TheARM64leTarget, + createARM64MCSubtargetInfo); + TargetRegistry::RegisterMCSubtargetInfo(TheARM64beTarget, createARM64MCSubtargetInfo); // Register the asm backend. - TargetRegistry::RegisterMCAsmBackend(TheARM64Target, createARM64AsmBackend); + TargetRegistry::RegisterMCAsmBackend(TheARM64leTarget, createARM64leAsmBackend); + TargetRegistry::RegisterMCAsmBackend(TheARM64beTarget, createARM64beAsmBackend); // Register the MC Code Emitter - TargetRegistry::RegisterMCCodeEmitter(TheARM64Target, + TargetRegistry::RegisterMCCodeEmitter(TheARM64leTarget, + createARM64MCCodeEmitter); + TargetRegistry::RegisterMCCodeEmitter(TheARM64beTarget, createARM64MCCodeEmitter); // Register the object streamer. - TargetRegistry::RegisterMCObjectStreamer(TheARM64Target, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(TheARM64leTarget, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(TheARM64beTarget, createMCStreamer); // Register the MCInstPrinter. - TargetRegistry::RegisterMCInstPrinter(TheARM64Target, + TargetRegistry::RegisterMCInstPrinter(TheARM64leTarget, + createARM64MCInstPrinter); + TargetRegistry::RegisterMCInstPrinter(TheARM64beTarget, createARM64MCInstPrinter); } diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.h b/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.h index 0db2b224eec..954dcdbb8bc 100644 --- a/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.h +++ b/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.h @@ -29,16 +29,20 @@ class StringRef; class Target; class raw_ostream; -extern Target TheARM64Target; +extern Target TheARM64leTarget; +extern Target TheARM64beTarget; MCCodeEmitter *createARM64MCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx); -MCAsmBackend *createARM64AsmBackend(const Target &T, const MCRegisterInfo &MRI, - StringRef TT, StringRef CPU); +MCAsmBackend *createARM64leAsmBackend(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); +MCAsmBackend *createARM64beAsmBackend(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); -MCObjectWriter *createARM64ELFObjectWriter(raw_ostream &OS, uint8_t OSABI); + MCObjectWriter *createARM64ELFObjectWriter(raw_ostream &OS, uint8_t OSABI, + bool IsLittleEndian); MCObjectWriter *createARM64MachObjectWriter(raw_ostream &OS, uint32_t CPUType, uint32_t CPUSubtype); diff --git a/lib/Target/ARM64/TargetInfo/ARM64TargetInfo.cpp b/lib/Target/ARM64/TargetInfo/ARM64TargetInfo.cpp index dec09ed178c..c2b6f5c7045 100644 --- a/lib/Target/ARM64/TargetInfo/ARM64TargetInfo.cpp +++ b/lib/Target/ARM64/TargetInfo/ARM64TargetInfo.cpp @@ -12,10 +12,13 @@ using namespace llvm; namespace llvm { -Target TheARM64Target; +Target TheARM64leTarget; +Target TheARM64beTarget; } // end namespace llvm extern "C" void LLVMInitializeARM64TargetInfo() { - RegisterTarget X(TheARM64Target, "arm64", - "ARM64"); + RegisterTarget X(TheARM64leTarget, "arm64", + "ARM64 (little endian)"); + RegisterTarget Y(TheARM64beTarget, "arm64_be", + "ARM64 (big endian)"); }