Skip to content

Commit 650cb57

Browse files
author
James Molloy
committedApr 23, 2014
[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. llvm-svn: 206965
1 parent 3a9a023 commit 650cb57

14 files changed

+139
-44
lines changed
 

‎llvm/lib/Target/ARM64/ARM64AsmPrinter.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -593,5 +593,6 @@ void ARM64AsmPrinter::EmitInstruction(const MachineInstr *MI) {
593593

594594
// Force static initialization.
595595
extern "C" void LLVMInitializeARM64AsmPrinter() {
596-
RegisterAsmPrinter<ARM64AsmPrinter> X(TheARM64Target);
596+
RegisterAsmPrinter<ARM64AsmPrinter> X(TheARM64leTarget);
597+
RegisterAsmPrinter<ARM64AsmPrinter> Y(TheARM64beTarget);
597598
}

‎llvm/lib/Target/ARM64/ARM64Subtarget.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ using namespace llvm;
2727
#include "ARM64GenSubtargetInfo.inc"
2828

2929
ARM64Subtarget::ARM64Subtarget(const std::string &TT, const std::string &CPU,
30-
const std::string &FS)
30+
const std::string &FS, bool LittleEndian)
3131
: ARM64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others),
3232
HasFPARMv8(false), HasNEON(false), HasCrypto(false),
3333
HasZeroCycleRegMove(false), HasZeroCycleZeroing(false),
34-
CPUString(CPU), TargetTriple(TT) {
34+
CPUString(CPU), TargetTriple(TT), IsLittleEndian(LittleEndian) {
3535
// Determine default and user-specified characteristics
3636

3737
if (CPUString.empty())

‎llvm/lib/Target/ARM64/ARM64Subtarget.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@ class ARM64Subtarget : public ARM64GenSubtargetInfo {
4848
/// TargetTriple - What processor and OS we're targeting.
4949
Triple TargetTriple;
5050

51+
/// IsLittleEndian - Is the target little endian?
52+
bool IsLittleEndian;
53+
5154
public:
5255
/// This constructor initializes the data members to match that
5356
/// of the specified triple.
5457
ARM64Subtarget(const std::string &TT, const std::string &CPU,
55-
const std::string &FS);
58+
const std::string &FS, bool LittleEndian);
5659

5760
bool enableMachineScheduler() const override { return true; }
5861

@@ -64,6 +67,8 @@ class ARM64Subtarget : public ARM64GenSubtargetInfo {
6467
bool hasNEON() const { return HasNEON; }
6568
bool hasCrypto() const { return HasCrypto; }
6669

70+
bool isLittleEndian() const { return IsLittleEndian; }
71+
6772
bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
6873

6974
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }

‎llvm/lib/Target/ARM64/ARM64TargetMachine.cpp

+30-5
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ EnableDeadRegisterElimination("arm64-dead-def-elimination", cl::Hidden,
4949

5050
extern "C" void LLVMInitializeARM64Target() {
5151
// Register the target.
52-
RegisterTargetMachine<ARM64TargetMachine> X(TheARM64Target);
52+
RegisterTargetMachine<ARM64leTargetMachine> X(TheARM64leTarget);
53+
RegisterTargetMachine<ARM64beTargetMachine> Y(TheARM64beTarget);
5354
}
5455

5556
/// TargetMachine ctor - Create an ARM64 architecture model.
@@ -58,16 +59,40 @@ ARM64TargetMachine::ARM64TargetMachine(const Target &T, StringRef TT,
5859
StringRef CPU, StringRef FS,
5960
const TargetOptions &Options,
6061
Reloc::Model RM, CodeModel::Model CM,
61-
CodeGenOpt::Level OL)
62+
CodeGenOpt::Level OL,
63+
bool LittleEndian)
6264
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
63-
Subtarget(TT, CPU, FS),
64-
DL(Subtarget.isTargetMachO() ? "e-m:o-i64:64-i128:128-n32:64-S128"
65-
: "e-m:e-i64:64-i128:128-n32:64-S128"),
65+
Subtarget(TT, CPU, FS, LittleEndian),
66+
// This nested ternary is horrible, but DL needs to be properly initialized
67+
// before TLInfo is constructed.
68+
DL(Subtarget.isTargetMachO() ?
69+
"e-m:o-i64:64-i128:128-n32:64-S128" :
70+
(LittleEndian ?
71+
"e-m:e-i64:64-i128:128-n32:64-S128" :
72+
"E-m:e-i64:64-i128:128-n32:64-S128")),
6673
InstrInfo(Subtarget), TLInfo(*this), FrameLowering(*this, Subtarget),
6774
TSInfo(*this) {
6875
initAsmInfo();
6976
}
7077

78+
void ARM64leTargetMachine::anchor() { }
79+
80+
ARM64leTargetMachine::
81+
ARM64leTargetMachine(const Target &T, StringRef TT,
82+
StringRef CPU, StringRef FS, const TargetOptions &Options,
83+
Reloc::Model RM, CodeModel::Model CM,
84+
CodeGenOpt::Level OL)
85+
: ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
86+
87+
void ARM64beTargetMachine::anchor() { }
88+
89+
ARM64beTargetMachine::
90+
ARM64beTargetMachine(const Target &T, StringRef TT,
91+
StringRef CPU, StringRef FS, const TargetOptions &Options,
92+
Reloc::Model RM, CodeModel::Model CM,
93+
CodeGenOpt::Level OL)
94+
: ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
95+
7196
namespace {
7297
/// ARM64 Code Generator Pass Configuration Options.
7398
class ARM64PassConfig : public TargetPassConfig {

‎llvm/lib/Target/ARM64/ARM64TargetMachine.h

+24-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class ARM64TargetMachine : public LLVMTargetMachine {
3939
public:
4040
ARM64TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS,
4141
const TargetOptions &Options, Reloc::Model RM,
42-
CodeModel::Model CM, CodeGenOpt::Level OL);
42+
CodeModel::Model CM, CodeGenOpt::Level OL,
43+
bool IsLittleEndian);
4344

4445
const ARM64Subtarget *getSubtargetImpl() const override { return &Subtarget; }
4546
const ARM64TargetLowering *getTargetLowering() const override {
@@ -64,6 +65,28 @@ class ARM64TargetMachine : public LLVMTargetMachine {
6465
void addAnalysisPasses(PassManagerBase &PM) override;
6566
};
6667

68+
// ARM64leTargetMachine - ARM64 little endian target machine.
69+
//
70+
class ARM64leTargetMachine : public ARM64TargetMachine {
71+
virtual void anchor();
72+
public:
73+
ARM64leTargetMachine(const Target &T, StringRef TT,
74+
StringRef CPU, StringRef FS, const TargetOptions &Options,
75+
Reloc::Model RM, CodeModel::Model CM,
76+
CodeGenOpt::Level OL);
77+
};
78+
79+
// ARM64beTargetMachine - ARM64 big endian target machine.
80+
//
81+
class ARM64beTargetMachine : public ARM64TargetMachine {
82+
virtual void anchor();
83+
public:
84+
ARM64beTargetMachine(const Target &T, StringRef TT,
85+
StringRef CPU, StringRef FS, const TargetOptions &Options,
86+
Reloc::Model RM, CodeModel::Model CM,
87+
CodeGenOpt::Level OL);
88+
};
89+
6790
} // end namespace llvm
6891

6992
#endif

‎llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -4509,7 +4509,8 @@ ARM64AsmParser::classifySymbolRef(const MCExpr *Expr,
45094509

45104510
/// Force static initialization.
45114511
extern "C" void LLVMInitializeARM64AsmParser() {
4512-
RegisterMCAsmParser<ARM64AsmParser> X(TheARM64Target);
4512+
RegisterMCAsmParser<ARM64AsmParser> X(TheARM64leTarget);
4513+
RegisterMCAsmParser<ARM64AsmParser> Y(TheARM64beTarget);
45134514
}
45144515

45154516
#define GET_REGISTER_MATCHER

‎llvm/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,13 @@ createARM64ExternalSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
229229
}
230230

231231
extern "C" void LLVMInitializeARM64Disassembler() {
232-
TargetRegistry::RegisterMCDisassembler(TheARM64Target,
232+
TargetRegistry::RegisterMCDisassembler(TheARM64leTarget,
233233
createARM64Disassembler);
234-
TargetRegistry::RegisterMCSymbolizer(TheARM64Target,
234+
TargetRegistry::RegisterMCDisassembler(TheARM64beTarget,
235+
createARM64Disassembler);
236+
TargetRegistry::RegisterMCSymbolizer(TheARM64leTarget,
237+
createARM64ExternalSymbolizer);
238+
TargetRegistry::RegisterMCSymbolizer(TheARM64beTarget,
235239
createARM64ExternalSymbolizer);
236240
}
237241

‎llvm/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,13 @@ namespace {
483483
class ELFARM64AsmBackend : public ARM64AsmBackend {
484484
public:
485485
uint8_t OSABI;
486+
bool IsLittleEndian;
486487

487-
ELFARM64AsmBackend(const Target &T, uint8_t OSABI)
488-
: ARM64AsmBackend(T), OSABI(OSABI) {}
488+
ELFARM64AsmBackend(const Target &T, uint8_t OSABI, bool IsLittleEndian)
489+
: ARM64AsmBackend(T), OSABI(OSABI), IsLittleEndian(IsLittleEndian) {}
489490

490491
MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
491-
return createARM64ELFObjectWriter(OS, OSABI);
492+
return createARM64ELFObjectWriter(OS, OSABI, IsLittleEndian);
492493
}
493494

494495
void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout,
@@ -520,14 +521,23 @@ void ELFARM64AsmBackend::processFixupValue(const MCAssembler &Asm,
520521
}
521522
}
522523

523-
MCAsmBackend *llvm::createARM64AsmBackend(const Target &T,
524-
const MCRegisterInfo &MRI,
525-
StringRef TT, StringRef CPU) {
524+
MCAsmBackend *llvm::createARM64leAsmBackend(const Target &T,
525+
const MCRegisterInfo &MRI,
526+
StringRef TT, StringRef CPU) {
526527
Triple TheTriple(TT);
527528

528529
if (TheTriple.isOSDarwin())
529530
return new DarwinARM64AsmBackend(T, MRI);
530531

531532
assert(TheTriple.isOSBinFormatELF() && "Expect either MachO or ELF target");
532-
return new ELFARM64AsmBackend(T, TheTriple.getOS());
533+
return new ELFARM64AsmBackend(T, TheTriple.getOS(), /*IsLittleEndian=*/true);
534+
}
535+
536+
MCAsmBackend *llvm::createARM64beAsmBackend(const Target &T,
537+
const MCRegisterInfo &MRI,
538+
StringRef TT, StringRef CPU) {
539+
Triple TheTriple(TT);
540+
541+
assert(TheTriple.isOSBinFormatELF() && "Big endian is only supported for ELF targets!");
542+
return new ELFARM64AsmBackend(T, TheTriple.getOS(), /*IsLittleEndian=*/false);
533543
}

‎llvm/lib/Target/ARM64/MCTargetDesc/ARM64ELFObjectWriter.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ using namespace llvm;
2424
namespace {
2525
class ARM64ELFObjectWriter : public MCELFObjectTargetWriter {
2626
public:
27-
ARM64ELFObjectWriter(uint8_t OSABI);
27+
ARM64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian);
2828

2929
virtual ~ARM64ELFObjectWriter();
3030

@@ -36,7 +36,7 @@ class ARM64ELFObjectWriter : public MCELFObjectTargetWriter {
3636
};
3737
}
3838

39-
ARM64ELFObjectWriter::ARM64ELFObjectWriter(uint8_t OSABI)
39+
ARM64ELFObjectWriter::ARM64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian)
4040
: MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64,
4141
/*HasRelocationAddend*/ true) {}
4242

@@ -235,7 +235,8 @@ unsigned ARM64ELFObjectWriter::GetRelocType(const MCValue &Target,
235235
}
236236

237237
MCObjectWriter *llvm::createARM64ELFObjectWriter(raw_ostream &OS,
238-
uint8_t OSABI) {
239-
MCELFObjectTargetWriter *MOTW = new ARM64ELFObjectWriter(OSABI);
240-
return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true);
238+
uint8_t OSABI,
239+
bool IsLittleEndian) {
240+
MCELFObjectTargetWriter *MOTW = new ARM64ELFObjectWriter(OSABI, IsLittleEndian);
241+
return createELFObjectWriter(MOTW, OS, IsLittleEndian);
241242
}

‎llvm/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "ARM64MCAsmInfo.h"
15+
#include "llvm/ADT/Triple.h"
1516
#include "llvm/MC/MCExpr.h"
1617
#include "llvm/MC/MCContext.h"
1718
#include "llvm/MC/MCStreamer.h"
@@ -63,7 +64,11 @@ const MCExpr *ARM64MCAsmInfoDarwin::getExprForPersonalitySymbol(
6364
return MCBinaryExpr::CreateSub(Res, PC, Context);
6465
}
6566

66-
ARM64MCAsmInfoELF::ARM64MCAsmInfoELF() {
67+
ARM64MCAsmInfoELF::ARM64MCAsmInfoELF(StringRef TT) {
68+
Triple T(TT);
69+
if (T.getArch() == Triple::aarch64_be)
70+
IsLittleEndian = false;
71+
6772
// We prefer NEON instructions to be printed in the short form.
6873
AssemblerDialect = AsmWriterVariant == Default ? 0 : AsmWriterVariant;
6974

‎llvm/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct ARM64MCAsmInfoDarwin : public MCAsmInfoDarwin {
2828
};
2929

3030
struct ARM64MCAsmInfoELF : public MCAsmInfo {
31-
explicit ARM64MCAsmInfoELF();
31+
explicit ARM64MCAsmInfoELF(StringRef TT);
3232
};
3333

3434
} // namespace llvm

‎llvm/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.cpp

+23-10
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static MCAsmInfo *createARM64MCAsmInfo(const MCRegisterInfo &MRI,
6666
MAI = new ARM64MCAsmInfoDarwin();
6767
else {
6868
assert(TheTriple.isOSBinFormatELF() && "Only expect Darwin or ELF");
69-
MAI = new ARM64MCAsmInfoELF();
69+
MAI = new ARM64MCAsmInfoELF(TT);
7070
}
7171

7272
// Initial state of the frame pointer is SP.
@@ -139,33 +139,46 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
139139
// Force static initialization.
140140
extern "C" void LLVMInitializeARM64TargetMC() {
141141
// Register the MC asm info.
142-
RegisterMCAsmInfoFn X(TheARM64Target, createARM64MCAsmInfo);
142+
RegisterMCAsmInfoFn X(TheARM64leTarget, createARM64MCAsmInfo);
143+
RegisterMCAsmInfoFn Y(TheARM64beTarget, createARM64MCAsmInfo);
143144

144145
// Register the MC codegen info.
145-
TargetRegistry::RegisterMCCodeGenInfo(TheARM64Target,
146+
TargetRegistry::RegisterMCCodeGenInfo(TheARM64leTarget,
147+
createARM64MCCodeGenInfo);
148+
TargetRegistry::RegisterMCCodeGenInfo(TheARM64beTarget,
146149
createARM64MCCodeGenInfo);
147150

148151
// Register the MC instruction info.
149-
TargetRegistry::RegisterMCInstrInfo(TheARM64Target, createARM64MCInstrInfo);
152+
TargetRegistry::RegisterMCInstrInfo(TheARM64leTarget, createARM64MCInstrInfo);
153+
TargetRegistry::RegisterMCInstrInfo(TheARM64beTarget, createARM64MCInstrInfo);
150154

151155
// Register the MC register info.
152-
TargetRegistry::RegisterMCRegInfo(TheARM64Target, createARM64MCRegisterInfo);
156+
TargetRegistry::RegisterMCRegInfo(TheARM64leTarget, createARM64MCRegisterInfo);
157+
TargetRegistry::RegisterMCRegInfo(TheARM64beTarget, createARM64MCRegisterInfo);
153158

154159
// Register the MC subtarget info.
155-
TargetRegistry::RegisterMCSubtargetInfo(TheARM64Target,
160+
TargetRegistry::RegisterMCSubtargetInfo(TheARM64leTarget,
161+
createARM64MCSubtargetInfo);
162+
TargetRegistry::RegisterMCSubtargetInfo(TheARM64beTarget,
156163
createARM64MCSubtargetInfo);
157164

158165
// Register the asm backend.
159-
TargetRegistry::RegisterMCAsmBackend(TheARM64Target, createARM64AsmBackend);
166+
TargetRegistry::RegisterMCAsmBackend(TheARM64leTarget, createARM64leAsmBackend);
167+
TargetRegistry::RegisterMCAsmBackend(TheARM64beTarget, createARM64beAsmBackend);
160168

161169
// Register the MC Code Emitter
162-
TargetRegistry::RegisterMCCodeEmitter(TheARM64Target,
170+
TargetRegistry::RegisterMCCodeEmitter(TheARM64leTarget,
171+
createARM64MCCodeEmitter);
172+
TargetRegistry::RegisterMCCodeEmitter(TheARM64beTarget,
163173
createARM64MCCodeEmitter);
164174

165175
// Register the object streamer.
166-
TargetRegistry::RegisterMCObjectStreamer(TheARM64Target, createMCStreamer);
176+
TargetRegistry::RegisterMCObjectStreamer(TheARM64leTarget, createMCStreamer);
177+
TargetRegistry::RegisterMCObjectStreamer(TheARM64beTarget, createMCStreamer);
167178

168179
// Register the MCInstPrinter.
169-
TargetRegistry::RegisterMCInstPrinter(TheARM64Target,
180+
TargetRegistry::RegisterMCInstPrinter(TheARM64leTarget,
181+
createARM64MCInstPrinter);
182+
TargetRegistry::RegisterMCInstPrinter(TheARM64beTarget,
170183
createARM64MCInstPrinter);
171184
}

‎llvm/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,20 @@ class StringRef;
2929
class Target;
3030
class raw_ostream;
3131

32-
extern Target TheARM64Target;
32+
extern Target TheARM64leTarget;
33+
extern Target TheARM64beTarget;
3334

3435
MCCodeEmitter *createARM64MCCodeEmitter(const MCInstrInfo &MCII,
3536
const MCRegisterInfo &MRI,
3637
const MCSubtargetInfo &STI,
3738
MCContext &Ctx);
38-
MCAsmBackend *createARM64AsmBackend(const Target &T, const MCRegisterInfo &MRI,
39-
StringRef TT, StringRef CPU);
39+
MCAsmBackend *createARM64leAsmBackend(const Target &T, const MCRegisterInfo &MRI,
40+
StringRef TT, StringRef CPU);
41+
MCAsmBackend *createARM64beAsmBackend(const Target &T, const MCRegisterInfo &MRI,
42+
StringRef TT, StringRef CPU);
4043

41-
MCObjectWriter *createARM64ELFObjectWriter(raw_ostream &OS, uint8_t OSABI);
44+
MCObjectWriter *createARM64ELFObjectWriter(raw_ostream &OS, uint8_t OSABI,
45+
bool IsLittleEndian);
4246

4347
MCObjectWriter *createARM64MachObjectWriter(raw_ostream &OS, uint32_t CPUType,
4448
uint32_t CPUSubtype);

‎llvm/lib/Target/ARM64/TargetInfo/ARM64TargetInfo.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
using namespace llvm;
1313

1414
namespace llvm {
15-
Target TheARM64Target;
15+
Target TheARM64leTarget;
16+
Target TheARM64beTarget;
1617
} // end namespace llvm
1718

1819
extern "C" void LLVMInitializeARM64TargetInfo() {
19-
RegisterTarget<Triple::arm64, /*HasJIT=*/true> X(TheARM64Target, "arm64",
20-
"ARM64");
20+
RegisterTarget<Triple::arm64, /*HasJIT=*/true> X(TheARM64leTarget, "arm64",
21+
"ARM64 (little endian)");
22+
RegisterTarget<Triple::arm64_be, /*HasJIT=*/true> Y(TheARM64beTarget, "arm64_be",
23+
"ARM64 (big endian)");
2124
}

0 commit comments

Comments
 (0)
Please sign in to comment.