Skip to content

Commit 310dead

Browse files
committedJun 4, 2015
[bpf] add big- and host- endian support
Summary: -march=bpf -> host endian -march=bpf_le -> little endian -match=bpf_be -> big endian Test Plan: v1 was tested by IBM s390 guys and appears to be working there. It bit rots too fast here. Reviewers: chandlerc, tstellarAMD Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10177 llvm-svn: 239071
1 parent 9ac8a6b commit 310dead

25 files changed

+271
-72
lines changed
 

‎llvm/include/llvm/ADT/Triple.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class Triple {
5050
armeb, // ARM (big endian): armeb
5151
aarch64, // AArch64 (little endian): aarch64
5252
aarch64_be, // AArch64 (big endian): aarch64_be
53-
bpf, // eBPF or extended BPF or 64-bit BPF (little endian)
53+
bpf_le, // eBPF or extended BPF or 64-bit BPF (little endian)
54+
bpf_be, // eBPF or extended BPF or 64-bit BPF (big endian)
5455
hexagon, // Hexagon: hexagon
5556
mips, // MIPS: mips, mipsallegrex
5657
mipsel, // MIPSEL: mipsel, mipsallegrexel

‎llvm/lib/Support/Triple.cpp

+30-7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "llvm/ADT/StringSwitch.h"
1414
#include "llvm/Support/ErrorHandling.h"
1515
#include "llvm/Support/TargetParser.h"
16+
#include "llvm/Support/Host.h"
1617
#include <cstring>
1718
using namespace llvm;
1819

@@ -24,7 +25,8 @@ const char *Triple::getArchTypeName(ArchType Kind) {
2425
case aarch64_be: return "aarch64_be";
2526
case arm: return "arm";
2627
case armeb: return "armeb";
27-
case bpf: return "bpf";
28+
case bpf_le: return "bpf_le";
29+
case bpf_be: return "bpf_be";
2830
case hexagon: return "hexagon";
2931
case mips: return "mips";
3032
case mipsel: return "mipsel";
@@ -89,7 +91,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
8991
case amdgcn:
9092
case r600: return "amdgpu";
9193

92-
case bpf: return "bpf";
94+
case bpf_le:
95+
case bpf_be: return "bpf";
9396

9497
case sparcv9:
9598
case sparcel:
@@ -192,14 +195,30 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
192195
llvm_unreachable("Invalid EnvironmentType!");
193196
}
194197

198+
static Triple::ArchType parseBPFArch(StringRef ArchName) {
199+
if (ArchName.equals("bpf")) {
200+
if (sys::IsLittleEndianHost)
201+
return Triple::bpf_le;
202+
else
203+
return Triple::bpf_be;
204+
} else if (ArchName.equals("bpf_be")) {
205+
return Triple::bpf_be;
206+
} else if (ArchName.equals("bpf_le")) {
207+
return Triple::bpf_le;
208+
} else {
209+
return Triple::UnknownArch;
210+
}
211+
}
212+
195213
Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
214+
Triple::ArchType BPFArch(parseBPFArch(Name));
196215
return StringSwitch<Triple::ArchType>(Name)
197216
.Case("aarch64", aarch64)
198217
.Case("aarch64_be", aarch64_be)
199218
.Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
200219
.Case("arm", arm)
201220
.Case("armeb", armeb)
202-
.Case("bpf", bpf)
221+
.StartsWith("bpf", BPFArch)
203222
.Case("mips", mips)
204223
.Case("mipsel", mipsel)
205224
.Case("mips64", mips64)
@@ -296,6 +315,7 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
296315

297316
static Triple::ArchType parseArch(StringRef ArchName) {
298317
Triple::ArchType ARMArch(parseARMArch(ArchName));
318+
Triple::ArchType BPFArch(parseBPFArch(ArchName));
299319

300320
return StringSwitch<Triple::ArchType>(ArchName)
301321
.Cases("i386", "i486", "i586", "i686", Triple::x86)
@@ -317,7 +337,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
317337
.Case("mips64el", Triple::mips64el)
318338
.Case("r600", Triple::r600)
319339
.Case("amdgcn", Triple::amdgcn)
320-
.Case("bpf", Triple::bpf)
340+
.StartsWith("bpf", BPFArch)
321341
.Case("hexagon", Triple::hexagon)
322342
.Case("s390x", Triple::systemz)
323343
.Case("sparc", Triple::sparc)
@@ -989,7 +1009,8 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
9891009
case llvm::Triple::aarch64:
9901010
case llvm::Triple::aarch64_be:
9911011
case llvm::Triple::amdgcn:
992-
case llvm::Triple::bpf:
1012+
case llvm::Triple::bpf_le:
1013+
case llvm::Triple::bpf_be:
9931014
case llvm::Triple::le64:
9941015
case llvm::Triple::mips64:
9951016
case llvm::Triple::mips64el:
@@ -1026,7 +1047,8 @@ Triple Triple::get32BitArchVariant() const {
10261047
case Triple::aarch64:
10271048
case Triple::aarch64_be:
10281049
case Triple::amdgcn:
1029-
case Triple::bpf:
1050+
case Triple::bpf_le:
1051+
case Triple::bpf_be:
10301052
case Triple::msp430:
10311053
case Triple::systemz:
10321054
case Triple::ppc64le:
@@ -1090,7 +1112,8 @@ Triple Triple::get64BitArchVariant() const {
10901112

10911113
case Triple::aarch64:
10921114
case Triple::aarch64_be:
1093-
case Triple::bpf:
1115+
case Triple::bpf_le:
1116+
case Triple::bpf_be:
10941117
case Triple::le64:
10951118
case Triple::amdil64:
10961119
case Triple::amdgcn:

‎llvm/lib/Target/BPF/BPFAsmPrinter.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,7 @@ void BPFAsmPrinter::EmitInstruction(const MachineInstr *MI) {
8383

8484
// Force static initialization.
8585
extern "C" void LLVMInitializeBPFAsmPrinter() {
86-
RegisterAsmPrinter<BPFAsmPrinter> X(TheBPFTarget);
86+
RegisterAsmPrinter<BPFAsmPrinter> X(TheBPFleTarget);
87+
RegisterAsmPrinter<BPFAsmPrinter> Y(TheBPFbeTarget);
88+
RegisterAsmPrinter<BPFAsmPrinter> Z(TheBPFTarget);
8789
}

‎llvm/lib/Target/BPF/BPFTargetMachine.cpp

+12-7
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,24 @@ using namespace llvm;
2323

2424
extern "C" void LLVMInitializeBPFTarget() {
2525
// Register the target.
26-
RegisterTargetMachine<BPFTargetMachine> X(TheBPFTarget);
26+
RegisterTargetMachine<BPFTargetMachine> X(TheBPFleTarget);
27+
RegisterTargetMachine<BPFTargetMachine> Y(TheBPFbeTarget);
28+
RegisterTargetMachine<BPFTargetMachine> Z(TheBPFTarget);
29+
}
30+
31+
// DataLayout: little or big endian
32+
static std::string computeDataLayout(StringRef TT) {
33+
if (Triple(TT).getArch() == Triple::bpf_be)
34+
return "E-m:e-p:64:64-i64:64-n32:64-S128";
35+
else
36+
return "e-m:e-p:64:64-i64:64-n32:64-S128";
2737
}
2838

29-
// DataLayout --> Little-endian, 64-bit pointer/ABI/alignment
30-
// The stack is always 8 byte aligned
31-
// On function prologue, the stack is created by decrementing
32-
// its pointer. Once decremented, all references are done with positive
33-
// offset from the stack/frame pointer.
3439
BPFTargetMachine::BPFTargetMachine(const Target &T, StringRef TT, StringRef CPU,
3540
StringRef FS, const TargetOptions &Options,
3641
Reloc::Model RM, CodeModel::Model CM,
3742
CodeGenOpt::Level OL)
38-
: LLVMTargetMachine(T, "e-m:e-p:64:64-i64:64-n32:64-S128", TT, CPU, FS,
43+
: LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS,
3944
Options, RM, CM, OL),
4045
TLOF(make_unique<TargetLoweringObjectFileELF>()),
4146
Subtarget(TT, CPU, FS, *this) {

‎llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp

+19-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ using namespace llvm;
2525
namespace {
2626
class BPFAsmBackend : public MCAsmBackend {
2727
public:
28-
BPFAsmBackend() : MCAsmBackend() {}
28+
bool IsLittleEndian;
29+
30+
BPFAsmBackend(bool IsLittleEndian)
31+
: MCAsmBackend(), IsLittleEndian(IsLittleEndian) {}
2932
~BPFAsmBackend() override {}
3033

3134
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
@@ -69,17 +72,28 @@ void BPFAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
6972
}
7073
assert(Fixup.getKind() == FK_PCRel_2);
7174
Value = (uint16_t)((Value - 8) / 8);
72-
Data[Fixup.getOffset() + 2] = Value & 0xFF;
73-
Data[Fixup.getOffset() + 3] = Value >> 8;
75+
if (IsLittleEndian) {
76+
Data[Fixup.getOffset() + 2] = Value & 0xFF;
77+
Data[Fixup.getOffset() + 3] = Value >> 8;
78+
} else {
79+
Data[Fixup.getOffset() + 2] = Value >> 8;
80+
Data[Fixup.getOffset() + 3] = Value & 0xFF;
81+
}
7482
}
7583

7684
MCObjectWriter *BPFAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
77-
return createBPFELFObjectWriter(OS, 0);
85+
return createBPFELFObjectWriter(OS, 0, IsLittleEndian);
7886
}
7987
}
8088

8189
MCAsmBackend *llvm::createBPFAsmBackend(const Target &T,
8290
const MCRegisterInfo &MRI, StringRef TT,
8391
StringRef CPU) {
84-
return new BPFAsmBackend();
92+
return new BPFAsmBackend(/*IsLittleEndian=*/true);
93+
}
94+
95+
MCAsmBackend *llvm::createBPFbeAsmBackend(const Target &T,
96+
const MCRegisterInfo &MRI, StringRef TT,
97+
StringRef CPU) {
98+
return new BPFAsmBackend(/*IsLittleEndian=*/false);
8599
}

‎llvm/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ unsigned BPFELFObjectWriter::GetRelocType(const MCValue &Target,
4747
}
4848
}
4949

50-
MCObjectWriter *llvm::createBPFELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI) {
50+
MCObjectWriter *llvm::createBPFELFObjectWriter(raw_pwrite_stream &OS,
51+
uint8_t OSABI, bool IsLittleEndian) {
5152
MCELFObjectTargetWriter *MOTW = new BPFELFObjectWriter(OSABI);
52-
return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true);
53+
return createELFObjectWriter(MOTW, OS, IsLittleEndian);
5354
}

‎llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "llvm/ADT/StringRef.h"
1818
#include "llvm/MC/MCAsmInfo.h"
19+
#include "llvm/ADT/Triple.h"
1920

2021
namespace llvm {
2122
class Target;
@@ -24,6 +25,9 @@ class Triple;
2425
class BPFMCAsmInfo : public MCAsmInfo {
2526
public:
2627
explicit BPFMCAsmInfo(const Triple &TT) {
28+
if (TT.getArch() == Triple::bpf_be)
29+
IsLittleEndian = false;
30+
2731
PrivateGlobalPrefix = ".L";
2832
WeakRefDirective = "\t.weak\t";
2933

‎llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp

+37-8
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ class BPFMCCodeEmitter : public MCCodeEmitter {
3030
BPFMCCodeEmitter(const BPFMCCodeEmitter &) = delete;
3131
void operator=(const BPFMCCodeEmitter &) = delete;
3232
const MCRegisterInfo &MRI;
33+
bool IsLittleEndian;
3334

3435
public:
35-
BPFMCCodeEmitter(const MCRegisterInfo &mri) : MRI(mri) {}
36+
BPFMCCodeEmitter(const MCRegisterInfo &mri, bool IsLittleEndian)
37+
: MRI(mri), IsLittleEndian(IsLittleEndian) {}
3638

3739
~BPFMCCodeEmitter() {}
3840

@@ -61,7 +63,13 @@ class BPFMCCodeEmitter : public MCCodeEmitter {
6163
MCCodeEmitter *llvm::createBPFMCCodeEmitter(const MCInstrInfo &MCII,
6264
const MCRegisterInfo &MRI,
6365
MCContext &Ctx) {
64-
return new BPFMCCodeEmitter(MRI);
66+
return new BPFMCCodeEmitter(MRI, true);
67+
}
68+
69+
MCCodeEmitter *llvm::createBPFbeMCCodeEmitter(const MCInstrInfo &MCII,
70+
const MCRegisterInfo &MRI,
71+
MCContext &Ctx) {
72+
return new BPFMCCodeEmitter(MRI, false);
6573
}
6674

6775
unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI,
@@ -91,32 +99,53 @@ unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI,
9199
return 0;
92100
}
93101

102+
static uint8_t SwapBits(uint8_t Val)
103+
{
104+
return (Val & 0x0F) << 4 | (Val & 0xF0) >> 4;
105+
}
106+
94107
void BPFMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
95108
SmallVectorImpl<MCFixup> &Fixups,
96109
const MCSubtargetInfo &STI) const {
97110
unsigned Opcode = MI.getOpcode();
98111
support::endian::Writer<support::little> LE(OS);
112+
support::endian::Writer<support::big> BE(OS);
99113

100114
if (Opcode == BPF::LD_imm64 || Opcode == BPF::LD_pseudo) {
101115
uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI);
102116
LE.write<uint8_t>(Value >> 56);
103-
LE.write<uint8_t>(((Value >> 48) & 0xff));
117+
if (IsLittleEndian)
118+
LE.write<uint8_t>((Value >> 48) & 0xff);
119+
else
120+
LE.write<uint8_t>(SwapBits((Value >> 48) & 0xff));
104121
LE.write<uint16_t>(0);
105-
LE.write<uint32_t>(Value & 0xffffFFFF);
122+
if (IsLittleEndian)
123+
LE.write<uint32_t>(Value & 0xffffFFFF);
124+
else
125+
BE.write<uint32_t>(Value & 0xffffFFFF);
106126

107127
const MCOperand &MO = MI.getOperand(1);
108128
uint64_t Imm = MO.isImm() ? MO.getImm() : 0;
109129
LE.write<uint8_t>(0);
110130
LE.write<uint8_t>(0);
111131
LE.write<uint16_t>(0);
112-
LE.write<uint32_t>(Imm >> 32);
132+
if (IsLittleEndian)
133+
LE.write<uint32_t>(Imm >> 32);
134+
else
135+
BE.write<uint32_t>(Imm >> 32);
113136
} else {
114137
// Get instruction encoding and emit it
115138
uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI);
116139
LE.write<uint8_t>(Value >> 56);
117-
LE.write<uint8_t>((Value >> 48) & 0xff);
118-
LE.write<uint16_t>((Value >> 32) & 0xffff);
119-
LE.write<uint32_t>(Value & 0xffffFFFF);
140+
if (IsLittleEndian) {
141+
LE.write<uint8_t>((Value >> 48) & 0xff);
142+
LE.write<uint16_t>((Value >> 32) & 0xffff);
143+
LE.write<uint32_t>(Value & 0xffffFFFF);
144+
} else {
145+
LE.write<uint8_t>(SwapBits((Value >> 48) & 0xff));
146+
BE.write<uint16_t>((Value >> 32) & 0xffff);
147+
BE.write<uint32_t>(Value & 0xffffFFFF);
148+
}
120149
}
121150
}
122151

‎llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp

+31-20
Original file line numberDiff line numberDiff line change
@@ -79,32 +79,43 @@ static MCInstPrinter *createBPFMCInstPrinter(const Triple &T,
7979
}
8080

8181
extern "C" void LLVMInitializeBPFTargetMC() {
82-
// Register the MC asm info.
83-
RegisterMCAsmInfo<BPFMCAsmInfo> X(TheBPFTarget);
82+
for (Target *T : {&TheBPFleTarget, &TheBPFbeTarget, &TheBPFTarget}) {
83+
// Register the MC asm info.
84+
RegisterMCAsmInfo<BPFMCAsmInfo> X(*T);
8485

85-
// Register the MC codegen info.
86-
TargetRegistry::RegisterMCCodeGenInfo(TheBPFTarget, createBPFMCCodeGenInfo);
86+
// Register the MC codegen info.
87+
TargetRegistry::RegisterMCCodeGenInfo(*T, createBPFMCCodeGenInfo);
8788

88-
// Register the MC instruction info.
89-
TargetRegistry::RegisterMCInstrInfo(TheBPFTarget, createBPFMCInstrInfo);
89+
// Register the MC instruction info.
90+
TargetRegistry::RegisterMCInstrInfo(*T, createBPFMCInstrInfo);
9091

91-
// Register the MC register info.
92-
TargetRegistry::RegisterMCRegInfo(TheBPFTarget, createBPFMCRegisterInfo);
92+
// Register the MC register info.
93+
TargetRegistry::RegisterMCRegInfo(*T, createBPFMCRegisterInfo);
9394

94-
// Register the MC subtarget info.
95-
TargetRegistry::RegisterMCSubtargetInfo(TheBPFTarget,
96-
createBPFMCSubtargetInfo);
95+
// Register the MC subtarget info.
96+
TargetRegistry::RegisterMCSubtargetInfo(*T,
97+
createBPFMCSubtargetInfo);
9798

98-
// Register the MC code emitter
99-
TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget,
100-
llvm::createBPFMCCodeEmitter);
99+
// Register the object streamer
100+
TargetRegistry::RegisterELFStreamer(*T, createBPFMCStreamer);
101101

102-
// Register the ASM Backend
103-
TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFAsmBackend);
102+
// Register the MCInstPrinter.
103+
TargetRegistry::RegisterMCInstPrinter(*T, createBPFMCInstPrinter);
104+
}
104105

105-
// Register the object streamer
106-
TargetRegistry::RegisterELFStreamer(TheBPFTarget, createBPFMCStreamer);
106+
// Register the MC code emitter
107+
TargetRegistry::RegisterMCCodeEmitter(TheBPFleTarget, createBPFMCCodeEmitter);
108+
TargetRegistry::RegisterMCCodeEmitter(TheBPFbeTarget, createBPFbeMCCodeEmitter);
107109

108-
// Register the MCInstPrinter.
109-
TargetRegistry::RegisterMCInstPrinter(TheBPFTarget, createBPFMCInstPrinter);
110+
// Register the ASM Backend
111+
TargetRegistry::RegisterMCAsmBackend(TheBPFleTarget, createBPFAsmBackend);
112+
TargetRegistry::RegisterMCAsmBackend(TheBPFbeTarget, createBPFbeAsmBackend);
113+
114+
if (sys::IsLittleEndianHost) {
115+
TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget, createBPFMCCodeEmitter);
116+
TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFAsmBackend);
117+
} else {
118+
TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget, createBPFbeMCCodeEmitter);
119+
TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFbeAsmBackend);
120+
}
110121
}

0 commit comments

Comments
 (0)
Please sign in to comment.