aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/BPF
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/BPF')
-rw-r--r--lib/Target/BPF/BPFAsmPrinter.cpp4
-rw-r--r--lib/Target/BPF/BPFMCInstLower.cpp4
-rw-r--r--lib/Target/BPF/BPFTargetMachine.cpp19
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp26
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp5
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h7
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp82
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp51
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h10
-rw-r--r--lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp14
10 files changed, 140 insertions, 82 deletions
diff --git a/lib/Target/BPF/BPFAsmPrinter.cpp b/lib/Target/BPF/BPFAsmPrinter.cpp
index 32375968eac1..10ec6587550b 100644
--- a/lib/Target/BPF/BPFAsmPrinter.cpp
+++ b/lib/Target/BPF/BPFAsmPrinter.cpp
@@ -83,5 +83,7 @@ void BPFAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Force static initialization.
extern "C" void LLVMInitializeBPFAsmPrinter() {
- RegisterAsmPrinter<BPFAsmPrinter> X(TheBPFTarget);
+ RegisterAsmPrinter<BPFAsmPrinter> X(TheBPFleTarget);
+ RegisterAsmPrinter<BPFAsmPrinter> Y(TheBPFbeTarget);
+ RegisterAsmPrinter<BPFAsmPrinter> Z(TheBPFTarget);
}
diff --git a/lib/Target/BPF/BPFMCInstLower.cpp b/lib/Target/BPF/BPFMCInstLower.cpp
index d608afb348cb..00bd8d9c090c 100644
--- a/lib/Target/BPF/BPFMCInstLower.cpp
+++ b/lib/Target/BPF/BPFMCInstLower.cpp
@@ -33,7 +33,7 @@ BPFMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
MCOperand BPFMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MCSymbol *Sym) const {
- const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
+ const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
if (!MO.isJTI() && MO.getOffset())
llvm_unreachable("unknown symbol op");
@@ -63,7 +63,7 @@ void BPFMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::createExpr(
- MCSymbolRefExpr::Create(MO.getMBB()->getSymbol(), Ctx));
+ MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
break;
case MachineOperand::MO_RegisterMask:
continue;
diff --git a/lib/Target/BPF/BPFTargetMachine.cpp b/lib/Target/BPF/BPFTargetMachine.cpp
index 9487427fef5e..3329d5f87409 100644
--- a/lib/Target/BPF/BPFTargetMachine.cpp
+++ b/lib/Target/BPF/BPFTargetMachine.cpp
@@ -23,19 +23,24 @@ using namespace llvm;
extern "C" void LLVMInitializeBPFTarget() {
// Register the target.
- RegisterTargetMachine<BPFTargetMachine> X(TheBPFTarget);
+ RegisterTargetMachine<BPFTargetMachine> X(TheBPFleTarget);
+ RegisterTargetMachine<BPFTargetMachine> Y(TheBPFbeTarget);
+ RegisterTargetMachine<BPFTargetMachine> Z(TheBPFTarget);
+}
+
+// DataLayout: little or big endian
+static std::string computeDataLayout(StringRef TT) {
+ if (Triple(TT).getArch() == Triple::bpfeb)
+ return "E-m:e-p:64:64-i64:64-n32:64-S128";
+ else
+ return "e-m:e-p:64:64-i64:64-n32:64-S128";
}
-// DataLayout --> Little-endian, 64-bit pointer/ABI/alignment
-// The stack is always 8 byte aligned
-// On function prologue, the stack is created by decrementing
-// its pointer. Once decremented, all references are done with positive
-// offset from the stack/frame pointer.
BPFTargetMachine::BPFTargetMachine(const Target &T, StringRef TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
- : LLVMTargetMachine(T, "e-m:e-p:64:64-i64:64-n32:64-S128", TT, CPU, FS,
+ : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS,
Options, RM, CM, OL),
TLOF(make_unique<TargetLoweringObjectFileELF>()),
Subtarget(TT, CPU, FS, *this) {
diff --git a/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp b/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
index 48f34e484590..7b1d9259caf9 100644
--- a/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
+++ b/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
@@ -25,7 +25,10 @@ using namespace llvm;
namespace {
class BPFAsmBackend : public MCAsmBackend {
public:
- BPFAsmBackend() : MCAsmBackend() {}
+ bool IsLittleEndian;
+
+ BPFAsmBackend(bool IsLittleEndian)
+ : MCAsmBackend(), IsLittleEndian(IsLittleEndian) {}
~BPFAsmBackend() override {}
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
@@ -54,7 +57,7 @@ bool BPFAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
return false;
for (uint64_t i = 0; i < Count; i += 8)
- OW->Write64(0x15000000);
+ OW->write64(0x15000000);
return true;
}
@@ -69,17 +72,28 @@ void BPFAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
}
assert(Fixup.getKind() == FK_PCRel_2);
Value = (uint16_t)((Value - 8) / 8);
- Data[Fixup.getOffset() + 2] = Value & 0xFF;
- Data[Fixup.getOffset() + 3] = Value >> 8;
+ if (IsLittleEndian) {
+ Data[Fixup.getOffset() + 2] = Value & 0xFF;
+ Data[Fixup.getOffset() + 3] = Value >> 8;
+ } else {
+ Data[Fixup.getOffset() + 2] = Value >> 8;
+ Data[Fixup.getOffset() + 3] = Value & 0xFF;
+ }
}
MCObjectWriter *BPFAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
- return createBPFELFObjectWriter(OS, 0);
+ return createBPFELFObjectWriter(OS, 0, IsLittleEndian);
}
}
MCAsmBackend *llvm::createBPFAsmBackend(const Target &T,
const MCRegisterInfo &MRI, StringRef TT,
StringRef CPU) {
- return new BPFAsmBackend();
+ return new BPFAsmBackend(/*IsLittleEndian=*/true);
+}
+
+MCAsmBackend *llvm::createBPFbeAsmBackend(const Target &T,
+ const MCRegisterInfo &MRI, StringRef TT,
+ StringRef CPU) {
+ return new BPFAsmBackend(/*IsLittleEndian=*/false);
}
diff --git a/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp b/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp
index a5562c1a933e..05ba6183e322 100644
--- a/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp
+++ b/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp
@@ -47,7 +47,8 @@ unsigned BPFELFObjectWriter::GetRelocType(const MCValue &Target,
}
}
-MCObjectWriter *llvm::createBPFELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI) {
+MCObjectWriter *llvm::createBPFELFObjectWriter(raw_pwrite_stream &OS,
+ uint8_t OSABI, bool IsLittleEndian) {
MCELFObjectTargetWriter *MOTW = new BPFELFObjectWriter(OSABI);
- return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true);
+ return createELFObjectWriter(MOTW, OS, IsLittleEndian);
}
diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h b/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h
index ab61ae7ae662..d63bbf49294e 100644
--- a/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h
+++ b/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h
@@ -16,13 +16,18 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/ADT/Triple.h"
namespace llvm {
class Target;
+class Triple;
class BPFMCAsmInfo : public MCAsmInfo {
public:
- explicit BPFMCAsmInfo(StringRef TT) {
+ explicit BPFMCAsmInfo(const Triple &TT) {
+ if (TT.getArch() == Triple::bpfeb)
+ IsLittleEndian = false;
+
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp b/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
index ba8a874e4966..dc4ede30f191 100644
--- a/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
+++ b/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
@@ -30,9 +30,11 @@ class BPFMCCodeEmitter : public MCCodeEmitter {
BPFMCCodeEmitter(const BPFMCCodeEmitter &) = delete;
void operator=(const BPFMCCodeEmitter &) = delete;
const MCRegisterInfo &MRI;
+ bool IsLittleEndian;
public:
- BPFMCCodeEmitter(const MCRegisterInfo &mri) : MRI(mri) {}
+ BPFMCCodeEmitter(const MCRegisterInfo &mri, bool IsLittleEndian)
+ : MRI(mri), IsLittleEndian(IsLittleEndian) {}
~BPFMCCodeEmitter() {}
@@ -61,7 +63,13 @@ public:
MCCodeEmitter *llvm::createBPFMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
MCContext &Ctx) {
- return new BPFMCCodeEmitter(MRI);
+ return new BPFMCCodeEmitter(MRI, true);
+}
+
+MCCodeEmitter *llvm::createBPFbeMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx) {
+ return new BPFMCCodeEmitter(MRI, false);
}
unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI,
@@ -91,59 +99,53 @@ unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI,
return 0;
}
-// Emit one byte through output stream
-void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) {
- OS << (char)C;
- ++CurByte;
-}
-
-// Emit a series of bytes (little endian)
-void EmitLEConstant(uint64_t Val, unsigned Size, unsigned &CurByte,
- raw_ostream &OS) {
- assert(Size <= 8 && "size too big in emit constant");
-
- for (unsigned i = 0; i != Size; ++i) {
- EmitByte(Val & 255, CurByte, OS);
- Val >>= 8;
- }
-}
-
-// Emit a series of bytes (big endian)
-void EmitBEConstant(uint64_t Val, unsigned Size, unsigned &CurByte,
- raw_ostream &OS) {
- assert(Size <= 8 && "size too big in emit constant");
-
- for (int i = (Size - 1) * 8; i >= 0; i -= 8)
- EmitByte((Val >> i) & 255, CurByte, OS);
+static uint8_t SwapBits(uint8_t Val)
+{
+ return (Val & 0x0F) << 4 | (Val & 0xF0) >> 4;
}
void BPFMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
unsigned Opcode = MI.getOpcode();
- // Keep track of the current byte being emitted
- unsigned CurByte = 0;
+ support::endian::Writer<support::little> LE(OS);
+ support::endian::Writer<support::big> BE(OS);
if (Opcode == BPF::LD_imm64 || Opcode == BPF::LD_pseudo) {
uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI);
- EmitByte(Value >> 56, CurByte, OS);
- EmitByte(((Value >> 48) & 0xff), CurByte, OS);
- EmitLEConstant(0, 2, CurByte, OS);
- EmitLEConstant(Value & 0xffffFFFF, 4, CurByte, OS);
+ LE.write<uint8_t>(Value >> 56);
+ if (IsLittleEndian)
+ LE.write<uint8_t>((Value >> 48) & 0xff);
+ else
+ LE.write<uint8_t>(SwapBits((Value >> 48) & 0xff));
+ LE.write<uint16_t>(0);
+ if (IsLittleEndian)
+ LE.write<uint32_t>(Value & 0xffffFFFF);
+ else
+ BE.write<uint32_t>(Value & 0xffffFFFF);
const MCOperand &MO = MI.getOperand(1);
uint64_t Imm = MO.isImm() ? MO.getImm() : 0;
- EmitByte(0, CurByte, OS);
- EmitByte(0, CurByte, OS);
- EmitLEConstant(0, 2, CurByte, OS);
- EmitLEConstant(Imm >> 32, 4, CurByte, OS);
+ LE.write<uint8_t>(0);
+ LE.write<uint8_t>(0);
+ LE.write<uint16_t>(0);
+ if (IsLittleEndian)
+ LE.write<uint32_t>(Imm >> 32);
+ else
+ BE.write<uint32_t>(Imm >> 32);
} else {
// Get instruction encoding and emit it
uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI);
- EmitByte(Value >> 56, CurByte, OS);
- EmitByte((Value >> 48) & 0xff, CurByte, OS);
- EmitLEConstant((Value >> 32) & 0xffff, 2, CurByte, OS);
- EmitLEConstant(Value & 0xffffFFFF, 4, CurByte, OS);
+ LE.write<uint8_t>(Value >> 56);
+ if (IsLittleEndian) {
+ LE.write<uint8_t>((Value >> 48) & 0xff);
+ LE.write<uint16_t>((Value >> 32) & 0xffff);
+ LE.write<uint32_t>(Value & 0xffffFFFF);
+ } else {
+ LE.write<uint8_t>(SwapBits((Value >> 48) & 0xff));
+ BE.write<uint16_t>((Value >> 32) & 0xffff);
+ BE.write<uint32_t>(Value & 0xffffFFFF);
+ }
}
}
diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
index c4cf4b824508..7cedba90a746 100644
--- a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
+++ b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
@@ -79,32 +79,43 @@ static MCInstPrinter *createBPFMCInstPrinter(const Triple &T,
}
extern "C" void LLVMInitializeBPFTargetMC() {
- // Register the MC asm info.
- RegisterMCAsmInfo<BPFMCAsmInfo> X(TheBPFTarget);
+ for (Target *T : {&TheBPFleTarget, &TheBPFbeTarget, &TheBPFTarget}) {
+ // Register the MC asm info.
+ RegisterMCAsmInfo<BPFMCAsmInfo> X(*T);
- // Register the MC codegen info.
- TargetRegistry::RegisterMCCodeGenInfo(TheBPFTarget, createBPFMCCodeGenInfo);
+ // Register the MC codegen info.
+ TargetRegistry::RegisterMCCodeGenInfo(*T, createBPFMCCodeGenInfo);
- // Register the MC instruction info.
- TargetRegistry::RegisterMCInstrInfo(TheBPFTarget, createBPFMCInstrInfo);
+ // Register the MC instruction info.
+ TargetRegistry::RegisterMCInstrInfo(*T, createBPFMCInstrInfo);
- // Register the MC register info.
- TargetRegistry::RegisterMCRegInfo(TheBPFTarget, createBPFMCRegisterInfo);
+ // Register the MC register info.
+ TargetRegistry::RegisterMCRegInfo(*T, createBPFMCRegisterInfo);
- // Register the MC subtarget info.
- TargetRegistry::RegisterMCSubtargetInfo(TheBPFTarget,
- createBPFMCSubtargetInfo);
+ // Register the MC subtarget info.
+ TargetRegistry::RegisterMCSubtargetInfo(*T,
+ createBPFMCSubtargetInfo);
- // Register the MC code emitter
- TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget,
- llvm::createBPFMCCodeEmitter);
+ // Register the object streamer
+ TargetRegistry::RegisterELFStreamer(*T, createBPFMCStreamer);
- // Register the ASM Backend
- TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFAsmBackend);
+ // Register the MCInstPrinter.
+ TargetRegistry::RegisterMCInstPrinter(*T, createBPFMCInstPrinter);
+ }
- // Register the object streamer
- TargetRegistry::RegisterELFStreamer(TheBPFTarget, createBPFMCStreamer);
+ // Register the MC code emitter
+ TargetRegistry::RegisterMCCodeEmitter(TheBPFleTarget, createBPFMCCodeEmitter);
+ TargetRegistry::RegisterMCCodeEmitter(TheBPFbeTarget, createBPFbeMCCodeEmitter);
- // Register the MCInstPrinter.
- TargetRegistry::RegisterMCInstPrinter(TheBPFTarget, createBPFMCInstPrinter);
+ // Register the ASM Backend
+ TargetRegistry::RegisterMCAsmBackend(TheBPFleTarget, createBPFAsmBackend);
+ TargetRegistry::RegisterMCAsmBackend(TheBPFbeTarget, createBPFbeAsmBackend);
+
+ if (sys::IsLittleEndianHost) {
+ TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget, createBPFMCCodeEmitter);
+ TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFAsmBackend);
+ } else {
+ TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget, createBPFbeMCCodeEmitter);
+ TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFbeAsmBackend);
+ }
}
diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h
index ce08b7cf76e6..a9ba7d990e17 100644
--- a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h
+++ b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h
@@ -30,16 +30,24 @@ class StringRef;
class raw_ostream;
class raw_pwrite_stream;
+extern Target TheBPFleTarget;
+extern Target TheBPFbeTarget;
extern Target TheBPFTarget;
MCCodeEmitter *createBPFMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
MCContext &Ctx);
+MCCodeEmitter *createBPFbeMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx);
MCAsmBackend *createBPFAsmBackend(const Target &T, const MCRegisterInfo &MRI,
StringRef TT, StringRef CPU);
+MCAsmBackend *createBPFbeAsmBackend(const Target &T, const MCRegisterInfo &MRI,
+ StringRef TT, StringRef CPU);
-MCObjectWriter *createBPFELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI);
+MCObjectWriter *createBPFELFObjectWriter(raw_pwrite_stream &OS,
+ uint8_t OSABI, bool IsLittleEndian);
}
// Defines symbolic names for BPF registers. This defines a mapping from
diff --git a/lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp b/lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp
index 87716e6775cf..a16dbae867b2 100644
--- a/lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp
+++ b/lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp
@@ -11,8 +11,18 @@
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
-Target llvm::TheBPFTarget;
+namespace llvm {
+Target TheBPFleTarget;
+Target TheBPFbeTarget;
+Target TheBPFTarget;
+}
extern "C" void LLVMInitializeBPFTargetInfo() {
- RegisterTarget<Triple::bpf, /*HasJIT=*/true> X(TheBPFTarget, "bpf", "BPF");
+ TargetRegistry::RegisterTarget(TheBPFTarget, "bpf",
+ "BPF (host endian)",
+ [](Triple::ArchType) { return false; }, true);
+ RegisterTarget<Triple::bpfel, /*HasJIT=*/true> X(
+ TheBPFleTarget, "bpfel", "BPF (little endian)");
+ RegisterTarget<Triple::bpfeb, /*HasJIT=*/true> Y(
+ TheBPFbeTarget, "bpfeb", "BPF (big endian)");
}