mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-12 11:03:24 +00:00
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239071 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c07ee0c4ff
commit
ac73683b10
@ -50,7 +50,8 @@ public:
|
|||||||
armeb, // ARM (big endian): armeb
|
armeb, // ARM (big endian): armeb
|
||||||
aarch64, // AArch64 (little endian): aarch64
|
aarch64, // AArch64 (little endian): aarch64
|
||||||
aarch64_be, // AArch64 (big endian): aarch64_be
|
aarch64_be, // AArch64 (big endian): aarch64_be
|
||||||
bpf, // eBPF or extended BPF or 64-bit BPF (little endian)
|
bpf_le, // eBPF or extended BPF or 64-bit BPF (little endian)
|
||||||
|
bpf_be, // eBPF or extended BPF or 64-bit BPF (big endian)
|
||||||
hexagon, // Hexagon: hexagon
|
hexagon, // Hexagon: hexagon
|
||||||
mips, // MIPS: mips, mipsallegrex
|
mips, // MIPS: mips, mipsallegrex
|
||||||
mipsel, // MIPSEL: mipsel, mipsallegrexel
|
mipsel, // MIPSEL: mipsel, mipsallegrexel
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/TargetParser.h"
|
#include "llvm/Support/TargetParser.h"
|
||||||
|
#include "llvm/Support/Host.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -24,7 +25,8 @@ const char *Triple::getArchTypeName(ArchType Kind) {
|
|||||||
case aarch64_be: return "aarch64_be";
|
case aarch64_be: return "aarch64_be";
|
||||||
case arm: return "arm";
|
case arm: return "arm";
|
||||||
case armeb: return "armeb";
|
case armeb: return "armeb";
|
||||||
case bpf: return "bpf";
|
case bpf_le: return "bpf_le";
|
||||||
|
case bpf_be: return "bpf_be";
|
||||||
case hexagon: return "hexagon";
|
case hexagon: return "hexagon";
|
||||||
case mips: return "mips";
|
case mips: return "mips";
|
||||||
case mipsel: return "mipsel";
|
case mipsel: return "mipsel";
|
||||||
@ -89,7 +91,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
|
|||||||
case amdgcn:
|
case amdgcn:
|
||||||
case r600: return "amdgpu";
|
case r600: return "amdgpu";
|
||||||
|
|
||||||
case bpf: return "bpf";
|
case bpf_le:
|
||||||
|
case bpf_be: return "bpf";
|
||||||
|
|
||||||
case sparcv9:
|
case sparcv9:
|
||||||
case sparcel:
|
case sparcel:
|
||||||
@ -192,14 +195,30 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
|
|||||||
llvm_unreachable("Invalid EnvironmentType!");
|
llvm_unreachable("Invalid EnvironmentType!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Triple::ArchType parseBPFArch(StringRef ArchName) {
|
||||||
|
if (ArchName.equals("bpf")) {
|
||||||
|
if (sys::IsLittleEndianHost)
|
||||||
|
return Triple::bpf_le;
|
||||||
|
else
|
||||||
|
return Triple::bpf_be;
|
||||||
|
} else if (ArchName.equals("bpf_be")) {
|
||||||
|
return Triple::bpf_be;
|
||||||
|
} else if (ArchName.equals("bpf_le")) {
|
||||||
|
return Triple::bpf_le;
|
||||||
|
} else {
|
||||||
|
return Triple::UnknownArch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
|
Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
|
||||||
|
Triple::ArchType BPFArch(parseBPFArch(Name));
|
||||||
return StringSwitch<Triple::ArchType>(Name)
|
return StringSwitch<Triple::ArchType>(Name)
|
||||||
.Case("aarch64", aarch64)
|
.Case("aarch64", aarch64)
|
||||||
.Case("aarch64_be", aarch64_be)
|
.Case("aarch64_be", aarch64_be)
|
||||||
.Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
|
.Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
|
||||||
.Case("arm", arm)
|
.Case("arm", arm)
|
||||||
.Case("armeb", armeb)
|
.Case("armeb", armeb)
|
||||||
.Case("bpf", bpf)
|
.StartsWith("bpf", BPFArch)
|
||||||
.Case("mips", mips)
|
.Case("mips", mips)
|
||||||
.Case("mipsel", mipsel)
|
.Case("mipsel", mipsel)
|
||||||
.Case("mips64", mips64)
|
.Case("mips64", mips64)
|
||||||
@ -296,6 +315,7 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
|
|||||||
|
|
||||||
static Triple::ArchType parseArch(StringRef ArchName) {
|
static Triple::ArchType parseArch(StringRef ArchName) {
|
||||||
Triple::ArchType ARMArch(parseARMArch(ArchName));
|
Triple::ArchType ARMArch(parseARMArch(ArchName));
|
||||||
|
Triple::ArchType BPFArch(parseBPFArch(ArchName));
|
||||||
|
|
||||||
return StringSwitch<Triple::ArchType>(ArchName)
|
return StringSwitch<Triple::ArchType>(ArchName)
|
||||||
.Cases("i386", "i486", "i586", "i686", Triple::x86)
|
.Cases("i386", "i486", "i586", "i686", Triple::x86)
|
||||||
@ -317,7 +337,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
|
|||||||
.Case("mips64el", Triple::mips64el)
|
.Case("mips64el", Triple::mips64el)
|
||||||
.Case("r600", Triple::r600)
|
.Case("r600", Triple::r600)
|
||||||
.Case("amdgcn", Triple::amdgcn)
|
.Case("amdgcn", Triple::amdgcn)
|
||||||
.Case("bpf", Triple::bpf)
|
.StartsWith("bpf", BPFArch)
|
||||||
.Case("hexagon", Triple::hexagon)
|
.Case("hexagon", Triple::hexagon)
|
||||||
.Case("s390x", Triple::systemz)
|
.Case("s390x", Triple::systemz)
|
||||||
.Case("sparc", Triple::sparc)
|
.Case("sparc", Triple::sparc)
|
||||||
@ -989,7 +1009,8 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
|
|||||||
case llvm::Triple::aarch64:
|
case llvm::Triple::aarch64:
|
||||||
case llvm::Triple::aarch64_be:
|
case llvm::Triple::aarch64_be:
|
||||||
case llvm::Triple::amdgcn:
|
case llvm::Triple::amdgcn:
|
||||||
case llvm::Triple::bpf:
|
case llvm::Triple::bpf_le:
|
||||||
|
case llvm::Triple::bpf_be:
|
||||||
case llvm::Triple::le64:
|
case llvm::Triple::le64:
|
||||||
case llvm::Triple::mips64:
|
case llvm::Triple::mips64:
|
||||||
case llvm::Triple::mips64el:
|
case llvm::Triple::mips64el:
|
||||||
@ -1026,7 +1047,8 @@ Triple Triple::get32BitArchVariant() const {
|
|||||||
case Triple::aarch64:
|
case Triple::aarch64:
|
||||||
case Triple::aarch64_be:
|
case Triple::aarch64_be:
|
||||||
case Triple::amdgcn:
|
case Triple::amdgcn:
|
||||||
case Triple::bpf:
|
case Triple::bpf_le:
|
||||||
|
case Triple::bpf_be:
|
||||||
case Triple::msp430:
|
case Triple::msp430:
|
||||||
case Triple::systemz:
|
case Triple::systemz:
|
||||||
case Triple::ppc64le:
|
case Triple::ppc64le:
|
||||||
@ -1090,7 +1112,8 @@ Triple Triple::get64BitArchVariant() const {
|
|||||||
|
|
||||||
case Triple::aarch64:
|
case Triple::aarch64:
|
||||||
case Triple::aarch64_be:
|
case Triple::aarch64_be:
|
||||||
case Triple::bpf:
|
case Triple::bpf_le:
|
||||||
|
case Triple::bpf_be:
|
||||||
case Triple::le64:
|
case Triple::le64:
|
||||||
case Triple::amdil64:
|
case Triple::amdil64:
|
||||||
case Triple::amdgcn:
|
case Triple::amdgcn:
|
||||||
|
@ -83,5 +83,7 @@ void BPFAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
|
|
||||||
// Force static initialization.
|
// Force static initialization.
|
||||||
extern "C" void LLVMInitializeBPFAsmPrinter() {
|
extern "C" void LLVMInitializeBPFAsmPrinter() {
|
||||||
RegisterAsmPrinter<BPFAsmPrinter> X(TheBPFTarget);
|
RegisterAsmPrinter<BPFAsmPrinter> X(TheBPFleTarget);
|
||||||
|
RegisterAsmPrinter<BPFAsmPrinter> Y(TheBPFbeTarget);
|
||||||
|
RegisterAsmPrinter<BPFAsmPrinter> Z(TheBPFTarget);
|
||||||
}
|
}
|
||||||
|
@ -23,19 +23,24 @@ using namespace llvm;
|
|||||||
|
|
||||||
extern "C" void LLVMInitializeBPFTarget() {
|
extern "C" void LLVMInitializeBPFTarget() {
|
||||||
// Register the target.
|
// 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::bpf_be)
|
||||||
|
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,
|
BPFTargetMachine::BPFTargetMachine(const Target &T, StringRef TT, StringRef CPU,
|
||||||
StringRef FS, const TargetOptions &Options,
|
StringRef FS, const TargetOptions &Options,
|
||||||
Reloc::Model RM, CodeModel::Model CM,
|
Reloc::Model RM, CodeModel::Model CM,
|
||||||
CodeGenOpt::Level OL)
|
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),
|
Options, RM, CM, OL),
|
||||||
TLOF(make_unique<TargetLoweringObjectFileELF>()),
|
TLOF(make_unique<TargetLoweringObjectFileELF>()),
|
||||||
Subtarget(TT, CPU, FS, *this) {
|
Subtarget(TT, CPU, FS, *this) {
|
||||||
|
@ -25,7 +25,10 @@ using namespace llvm;
|
|||||||
namespace {
|
namespace {
|
||||||
class BPFAsmBackend : public MCAsmBackend {
|
class BPFAsmBackend : public MCAsmBackend {
|
||||||
public:
|
public:
|
||||||
BPFAsmBackend() : MCAsmBackend() {}
|
bool IsLittleEndian;
|
||||||
|
|
||||||
|
BPFAsmBackend(bool IsLittleEndian)
|
||||||
|
: MCAsmBackend(), IsLittleEndian(IsLittleEndian) {}
|
||||||
~BPFAsmBackend() override {}
|
~BPFAsmBackend() override {}
|
||||||
|
|
||||||
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
|
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
|
||||||
@ -69,17 +72,28 @@ void BPFAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
|
|||||||
}
|
}
|
||||||
assert(Fixup.getKind() == FK_PCRel_2);
|
assert(Fixup.getKind() == FK_PCRel_2);
|
||||||
Value = (uint16_t)((Value - 8) / 8);
|
Value = (uint16_t)((Value - 8) / 8);
|
||||||
Data[Fixup.getOffset() + 2] = Value & 0xFF;
|
if (IsLittleEndian) {
|
||||||
Data[Fixup.getOffset() + 3] = Value >> 8;
|
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 {
|
MCObjectWriter *BPFAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
|
||||||
return createBPFELFObjectWriter(OS, 0);
|
return createBPFELFObjectWriter(OS, 0, IsLittleEndian);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MCAsmBackend *llvm::createBPFAsmBackend(const Target &T,
|
MCAsmBackend *llvm::createBPFAsmBackend(const Target &T,
|
||||||
const MCRegisterInfo &MRI, StringRef TT,
|
const MCRegisterInfo &MRI, StringRef TT,
|
||||||
StringRef CPU) {
|
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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
MCELFObjectTargetWriter *MOTW = new BPFELFObjectWriter(OSABI);
|
||||||
return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true);
|
return createELFObjectWriter(MOTW, OS, IsLittleEndian);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
|
#include "llvm/ADT/Triple.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class Target;
|
class Target;
|
||||||
@ -24,6 +25,9 @@ class Triple;
|
|||||||
class BPFMCAsmInfo : public MCAsmInfo {
|
class BPFMCAsmInfo : public MCAsmInfo {
|
||||||
public:
|
public:
|
||||||
explicit BPFMCAsmInfo(const Triple &TT) {
|
explicit BPFMCAsmInfo(const Triple &TT) {
|
||||||
|
if (TT.getArch() == Triple::bpf_be)
|
||||||
|
IsLittleEndian = false;
|
||||||
|
|
||||||
PrivateGlobalPrefix = ".L";
|
PrivateGlobalPrefix = ".L";
|
||||||
WeakRefDirective = "\t.weak\t";
|
WeakRefDirective = "\t.weak\t";
|
||||||
|
|
||||||
|
@ -30,9 +30,11 @@ class BPFMCCodeEmitter : public MCCodeEmitter {
|
|||||||
BPFMCCodeEmitter(const BPFMCCodeEmitter &) = delete;
|
BPFMCCodeEmitter(const BPFMCCodeEmitter &) = delete;
|
||||||
void operator=(const BPFMCCodeEmitter &) = delete;
|
void operator=(const BPFMCCodeEmitter &) = delete;
|
||||||
const MCRegisterInfo &MRI;
|
const MCRegisterInfo &MRI;
|
||||||
|
bool IsLittleEndian;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BPFMCCodeEmitter(const MCRegisterInfo &mri) : MRI(mri) {}
|
BPFMCCodeEmitter(const MCRegisterInfo &mri, bool IsLittleEndian)
|
||||||
|
: MRI(mri), IsLittleEndian(IsLittleEndian) {}
|
||||||
|
|
||||||
~BPFMCCodeEmitter() {}
|
~BPFMCCodeEmitter() {}
|
||||||
|
|
||||||
@ -61,7 +63,13 @@ public:
|
|||||||
MCCodeEmitter *llvm::createBPFMCCodeEmitter(const MCInstrInfo &MCII,
|
MCCodeEmitter *llvm::createBPFMCCodeEmitter(const MCInstrInfo &MCII,
|
||||||
const MCRegisterInfo &MRI,
|
const MCRegisterInfo &MRI,
|
||||||
MCContext &Ctx) {
|
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,
|
unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI,
|
||||||
@ -91,32 +99,53 @@ unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t SwapBits(uint8_t Val)
|
||||||
|
{
|
||||||
|
return (Val & 0x0F) << 4 | (Val & 0xF0) >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
void BPFMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
void BPFMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||||
SmallVectorImpl<MCFixup> &Fixups,
|
SmallVectorImpl<MCFixup> &Fixups,
|
||||||
const MCSubtargetInfo &STI) const {
|
const MCSubtargetInfo &STI) const {
|
||||||
unsigned Opcode = MI.getOpcode();
|
unsigned Opcode = MI.getOpcode();
|
||||||
support::endian::Writer<support::little> LE(OS);
|
support::endian::Writer<support::little> LE(OS);
|
||||||
|
support::endian::Writer<support::big> BE(OS);
|
||||||
|
|
||||||
if (Opcode == BPF::LD_imm64 || Opcode == BPF::LD_pseudo) {
|
if (Opcode == BPF::LD_imm64 || Opcode == BPF::LD_pseudo) {
|
||||||
uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI);
|
uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI);
|
||||||
LE.write<uint8_t>(Value >> 56);
|
LE.write<uint8_t>(Value >> 56);
|
||||||
LE.write<uint8_t>(((Value >> 48) & 0xff));
|
if (IsLittleEndian)
|
||||||
|
LE.write<uint8_t>((Value >> 48) & 0xff);
|
||||||
|
else
|
||||||
|
LE.write<uint8_t>(SwapBits((Value >> 48) & 0xff));
|
||||||
LE.write<uint16_t>(0);
|
LE.write<uint16_t>(0);
|
||||||
LE.write<uint32_t>(Value & 0xffffFFFF);
|
if (IsLittleEndian)
|
||||||
|
LE.write<uint32_t>(Value & 0xffffFFFF);
|
||||||
|
else
|
||||||
|
BE.write<uint32_t>(Value & 0xffffFFFF);
|
||||||
|
|
||||||
const MCOperand &MO = MI.getOperand(1);
|
const MCOperand &MO = MI.getOperand(1);
|
||||||
uint64_t Imm = MO.isImm() ? MO.getImm() : 0;
|
uint64_t Imm = MO.isImm() ? MO.getImm() : 0;
|
||||||
LE.write<uint8_t>(0);
|
LE.write<uint8_t>(0);
|
||||||
LE.write<uint8_t>(0);
|
LE.write<uint8_t>(0);
|
||||||
LE.write<uint16_t>(0);
|
LE.write<uint16_t>(0);
|
||||||
LE.write<uint32_t>(Imm >> 32);
|
if (IsLittleEndian)
|
||||||
|
LE.write<uint32_t>(Imm >> 32);
|
||||||
|
else
|
||||||
|
BE.write<uint32_t>(Imm >> 32);
|
||||||
} else {
|
} else {
|
||||||
// Get instruction encoding and emit it
|
// Get instruction encoding and emit it
|
||||||
uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI);
|
uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI);
|
||||||
LE.write<uint8_t>(Value >> 56);
|
LE.write<uint8_t>(Value >> 56);
|
||||||
LE.write<uint8_t>((Value >> 48) & 0xff);
|
if (IsLittleEndian) {
|
||||||
LE.write<uint16_t>((Value >> 32) & 0xffff);
|
LE.write<uint8_t>((Value >> 48) & 0xff);
|
||||||
LE.write<uint32_t>(Value & 0xffffFFFF);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,32 +79,43 @@ static MCInstPrinter *createBPFMCInstPrinter(const Triple &T,
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void LLVMInitializeBPFTargetMC() {
|
extern "C" void LLVMInitializeBPFTargetMC() {
|
||||||
// Register the MC asm info.
|
for (Target *T : {&TheBPFleTarget, &TheBPFbeTarget, &TheBPFTarget}) {
|
||||||
RegisterMCAsmInfo<BPFMCAsmInfo> X(TheBPFTarget);
|
// Register the MC asm info.
|
||||||
|
RegisterMCAsmInfo<BPFMCAsmInfo> X(*T);
|
||||||
|
|
||||||
// Register the MC codegen info.
|
// Register the MC codegen info.
|
||||||
TargetRegistry::RegisterMCCodeGenInfo(TheBPFTarget, createBPFMCCodeGenInfo);
|
TargetRegistry::RegisterMCCodeGenInfo(*T, createBPFMCCodeGenInfo);
|
||||||
|
|
||||||
// Register the MC instruction info.
|
// Register the MC instruction info.
|
||||||
TargetRegistry::RegisterMCInstrInfo(TheBPFTarget, createBPFMCInstrInfo);
|
TargetRegistry::RegisterMCInstrInfo(*T, createBPFMCInstrInfo);
|
||||||
|
|
||||||
// Register the MC register info.
|
// Register the MC register info.
|
||||||
TargetRegistry::RegisterMCRegInfo(TheBPFTarget, createBPFMCRegisterInfo);
|
TargetRegistry::RegisterMCRegInfo(*T, createBPFMCRegisterInfo);
|
||||||
|
|
||||||
// Register the MC subtarget info.
|
// Register the MC subtarget info.
|
||||||
TargetRegistry::RegisterMCSubtargetInfo(TheBPFTarget,
|
TargetRegistry::RegisterMCSubtargetInfo(*T,
|
||||||
createBPFMCSubtargetInfo);
|
createBPFMCSubtargetInfo);
|
||||||
|
|
||||||
|
// Register the object streamer
|
||||||
|
TargetRegistry::RegisterELFStreamer(*T, createBPFMCStreamer);
|
||||||
|
|
||||||
|
// Register the MCInstPrinter.
|
||||||
|
TargetRegistry::RegisterMCInstPrinter(*T, createBPFMCInstPrinter);
|
||||||
|
}
|
||||||
|
|
||||||
// Register the MC code emitter
|
// Register the MC code emitter
|
||||||
TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget,
|
TargetRegistry::RegisterMCCodeEmitter(TheBPFleTarget, createBPFMCCodeEmitter);
|
||||||
llvm::createBPFMCCodeEmitter);
|
TargetRegistry::RegisterMCCodeEmitter(TheBPFbeTarget, createBPFbeMCCodeEmitter);
|
||||||
|
|
||||||
// Register the ASM Backend
|
// Register the ASM Backend
|
||||||
TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFAsmBackend);
|
TargetRegistry::RegisterMCAsmBackend(TheBPFleTarget, createBPFAsmBackend);
|
||||||
|
TargetRegistry::RegisterMCAsmBackend(TheBPFbeTarget, createBPFbeAsmBackend);
|
||||||
|
|
||||||
// Register the object streamer
|
if (sys::IsLittleEndianHost) {
|
||||||
TargetRegistry::RegisterELFStreamer(TheBPFTarget, createBPFMCStreamer);
|
TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget, createBPFMCCodeEmitter);
|
||||||
|
TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFAsmBackend);
|
||||||
// Register the MCInstPrinter.
|
} else {
|
||||||
TargetRegistry::RegisterMCInstPrinter(TheBPFTarget, createBPFMCInstPrinter);
|
TargetRegistry::RegisterMCCodeEmitter(TheBPFTarget, createBPFbeMCCodeEmitter);
|
||||||
|
TargetRegistry::RegisterMCAsmBackend(TheBPFTarget, createBPFbeAsmBackend);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,16 +30,24 @@ class StringRef;
|
|||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
class raw_pwrite_stream;
|
class raw_pwrite_stream;
|
||||||
|
|
||||||
|
extern Target TheBPFleTarget;
|
||||||
|
extern Target TheBPFbeTarget;
|
||||||
extern Target TheBPFTarget;
|
extern Target TheBPFTarget;
|
||||||
|
|
||||||
MCCodeEmitter *createBPFMCCodeEmitter(const MCInstrInfo &MCII,
|
MCCodeEmitter *createBPFMCCodeEmitter(const MCInstrInfo &MCII,
|
||||||
const MCRegisterInfo &MRI,
|
const MCRegisterInfo &MRI,
|
||||||
MCContext &Ctx);
|
MCContext &Ctx);
|
||||||
|
MCCodeEmitter *createBPFbeMCCodeEmitter(const MCInstrInfo &MCII,
|
||||||
|
const MCRegisterInfo &MRI,
|
||||||
|
MCContext &Ctx);
|
||||||
|
|
||||||
MCAsmBackend *createBPFAsmBackend(const Target &T, const MCRegisterInfo &MRI,
|
MCAsmBackend *createBPFAsmBackend(const Target &T, const MCRegisterInfo &MRI,
|
||||||
StringRef TT, StringRef CPU);
|
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
|
// Defines symbolic names for BPF registers. This defines a mapping from
|
||||||
|
@ -11,8 +11,18 @@
|
|||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
Target llvm::TheBPFTarget;
|
namespace llvm {
|
||||||
|
Target TheBPFleTarget;
|
||||||
|
Target TheBPFbeTarget;
|
||||||
|
Target TheBPFTarget;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void LLVMInitializeBPFTargetInfo() {
|
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::bpf_le, /*HasJIT=*/true> X(
|
||||||
|
TheBPFleTarget, "bpf_le", "BPF (little endian)");
|
||||||
|
RegisterTarget<Triple::bpf_be, /*HasJIT=*/true> Y(
|
||||||
|
TheBPFbeTarget, "bpf_be", "BPF (big endian)");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
; RUN: llc -march=bpf -show-mc-encoding < %s | FileCheck %s
|
; RUN: llc -march=bpf_le -show-mc-encoding < %s | FileCheck %s
|
||||||
; test little endian only for now
|
|
||||||
|
|
||||||
define i8 @mov(i8 %a, i8 %b) nounwind {
|
define i8 @mov(i8 %a, i8 %b) nounwind {
|
||||||
; CHECK-LABEL: mov:
|
; CHECK-LABEL: mov:
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf -verify-machineinstrs -show-mc-encoding | FileCheck %s
|
; RUN: llc < %s -march=bpf_le -verify-machineinstrs -show-mc-encoding | FileCheck %s
|
||||||
; test little endian only for now
|
|
||||||
|
|
||||||
; CHECK-LABEL: test_load_add_32
|
; CHECK-LABEL: test_load_add_32
|
||||||
; CHECK: xadd32
|
; CHECK: xadd32
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf | FileCheck %s
|
; RUN: llc < %s -march=bpf_le | FileCheck %s
|
||||||
|
|
||||||
define i32 @test0(i32 %X) {
|
define i32 @test0(i32 %X) {
|
||||||
%tmp.1 = add i32 %X, 1
|
%tmp.1 = add i32 %X, 1
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf -show-mc-encoding | FileCheck %s
|
; RUN: llc < %s -march=bpf_le -show-mc-encoding | FileCheck %s
|
||||||
; test little endian only for now
|
|
||||||
|
|
||||||
define void @test() #0 {
|
define void @test() #0 {
|
||||||
entry:
|
entry:
|
||||||
|
96
test/CodeGen/BPF/cc_args_be.ll
Normal file
96
test/CodeGen/BPF/cc_args_be.ll
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
; RUN: llc < %s -march=bpf_be -show-mc-encoding | FileCheck %s
|
||||||
|
; test big endian
|
||||||
|
|
||||||
|
define void @test() #0 {
|
||||||
|
entry:
|
||||||
|
; CHECK: test:
|
||||||
|
|
||||||
|
; CHECK: mov r1, 123 # encoding: [0xb7,0x10,0x00,0x00,0x00,0x00,0x00,0x7b]
|
||||||
|
; CHECK: call f_i16
|
||||||
|
call void @f_i16(i16 123)
|
||||||
|
|
||||||
|
; CHECK: mov r1, 12345678 # encoding: [0xb7,0x10,0x00,0x00,0x00,0xbc,0x61,0x4e]
|
||||||
|
; CHECK: call f_i32
|
||||||
|
call void @f_i32(i32 12345678)
|
||||||
|
|
||||||
|
; CHECK: ld_64 r1, 72623859790382856 # encoding: [0x18,0x10,0x00,0x00,0x05,0x06,0x07,0x08,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04]
|
||||||
|
; CHECK: call f_i64
|
||||||
|
call void @f_i64(i64 72623859790382856)
|
||||||
|
|
||||||
|
; CHECK: mov r1, 1234
|
||||||
|
; CHECK: mov r2, 5678
|
||||||
|
; CHECK: call f_i32_i32
|
||||||
|
call void @f_i32_i32(i32 1234, i32 5678)
|
||||||
|
|
||||||
|
; CHECK: mov r1, 2
|
||||||
|
; CHECK: mov r2, 3
|
||||||
|
; CHECK: mov r3, 4
|
||||||
|
; CHECK: call f_i16_i32_i16
|
||||||
|
call void @f_i16_i32_i16(i16 2, i32 3, i16 4)
|
||||||
|
|
||||||
|
; CHECK: mov r1, 5
|
||||||
|
; CHECK: ld_64 r2, 7262385979038285
|
||||||
|
; CHECK: mov r3, 6
|
||||||
|
; CHECK: call f_i16_i64_i16
|
||||||
|
call void @f_i16_i64_i16(i16 5, i64 7262385979038285, i16 6)
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
@g_i16 = common global i16 0, align 2
|
||||||
|
@g_i32 = common global i32 0, align 2
|
||||||
|
@g_i64 = common global i64 0, align 4
|
||||||
|
|
||||||
|
define void @f_i16(i16 %a) #0 {
|
||||||
|
; CHECK: f_i16:
|
||||||
|
; CHECK: sth 0(r2), r1 # encoding: [0x6b,0x21,0x00,0x00,0x00,0x00,0x00,0x00]
|
||||||
|
store volatile i16 %a, i16* @g_i16, align 2
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @f_i32(i32 %a) #0 {
|
||||||
|
; CHECK: f_i32:
|
||||||
|
; CHECK: sth 2(r2), r1 # encoding: [0x6b,0x21,0x00,0x02,0x00,0x00,0x00,0x00]
|
||||||
|
; CHECK: sth 0(r2), r1 # encoding: [0x6b,0x21,0x00,0x00,0x00,0x00,0x00,0x00]
|
||||||
|
store volatile i32 %a, i32* @g_i32, align 2
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @f_i64(i64 %a) #0 {
|
||||||
|
; CHECK: f_i64:
|
||||||
|
; CHECK: stw 4(r2), r1 # encoding: [0x63,0x21,0x00,0x04,0x00,0x00,0x00,0x00]
|
||||||
|
; CHECK: stw 0(r2), r1
|
||||||
|
store volatile i64 %a, i64* @g_i64, align 2
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @f_i32_i32(i32 %a, i32 %b) #0 {
|
||||||
|
; CHECK: f_i32_i32:
|
||||||
|
; CHECK: stw 0(r3), r1
|
||||||
|
store volatile i32 %a, i32* @g_i32, align 4
|
||||||
|
; CHECK: stw 0(r3), r2
|
||||||
|
store volatile i32 %b, i32* @g_i32, align 4
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @f_i16_i32_i16(i16 %a, i32 %b, i16 %c) #0 {
|
||||||
|
; CHECK: f_i16_i32_i16:
|
||||||
|
; CHECK: sth 0(r4), r1
|
||||||
|
store volatile i16 %a, i16* @g_i16, align 2
|
||||||
|
; CHECK: stw 0(r1), r2
|
||||||
|
store volatile i32 %b, i32* @g_i32, align 4
|
||||||
|
; CHECK: sth 0(r4), r3
|
||||||
|
store volatile i16 %c, i16* @g_i16, align 2
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @f_i16_i64_i16(i16 %a, i64 %b, i16 %c) #0 {
|
||||||
|
; CHECK: f_i16_i64_i16:
|
||||||
|
; CHECK: sth 0(r4), r1
|
||||||
|
store volatile i16 %a, i16* @g_i16, align 2
|
||||||
|
; CHECK: std 0(r1), r2 # encoding: [0x7b,0x12,0x00,0x00,0x00,0x00,0x00,0x00]
|
||||||
|
store volatile i64 %b, i64* @g_i64, align 8
|
||||||
|
; CHECK: sth 0(r4), r3
|
||||||
|
store volatile i16 %c, i16* @g_i16, align 2
|
||||||
|
ret void
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf | FileCheck %s
|
; RUN: llc < %s -march=bpf_le | FileCheck %s
|
||||||
|
|
||||||
define void @test() #0 {
|
define void @test() #0 {
|
||||||
entry:
|
entry:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf | FileCheck %s
|
; RUN: llc < %s -march=bpf_le | FileCheck %s
|
||||||
|
|
||||||
%struct.bpf_context = type { i64, i64, i64, i64, i64, i64, i64 }
|
%struct.bpf_context = type { i64, i64, i64, i64, i64, i64, i64 }
|
||||||
%struct.sk_buff = type { i64, i64, i64, i64, i64, i64, i64 }
|
%struct.sk_buff = type { i64, i64, i64, i64, i64, i64, i64 }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf -show-mc-encoding | FileCheck %s
|
; RUN: llc < %s -march=bpf_le -show-mc-encoding | FileCheck %s
|
||||||
|
|
||||||
; Function Attrs: nounwind uwtable
|
; Function Attrs: nounwind uwtable
|
||||||
define i32 @ld_b(i64 %foo, i64* nocapture %bar, i8* %ctx, i8* %ctx2) #0 {
|
define i32 @ld_b(i64 %foo, i64* nocapture %bar, i8* %ctx, i8* %ctx2) #0 {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf | FileCheck %s
|
; RUN: llc < %s -march=bpf_le | FileCheck %s
|
||||||
|
|
||||||
define i16 @am1(i16* %a) nounwind {
|
define i16 @am1(i16* %a) nounwind {
|
||||||
%1 = load i16, i16* %a
|
%1 = load i16, i16* %a
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf | FileCheck %s
|
; RUN: llc < %s -march=bpf_le | FileCheck %s
|
||||||
|
|
||||||
define zeroext i16 @add(i16* nocapture %a, i16 zeroext %n) nounwind readonly {
|
define zeroext i16 @add(i16* nocapture %a, i16 zeroext %n) nounwind readonly {
|
||||||
entry:
|
entry:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf | FileCheck %s
|
; RUN: llc < %s -march=bpf_le | FileCheck %s
|
||||||
|
|
||||||
@foo_printf.fmt = private unnamed_addr constant [9 x i8] c"hello \0A\00", align 1
|
@foo_printf.fmt = private unnamed_addr constant [9 x i8] c"hello \0A\00", align 1
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc -march=bpf < %s | FileCheck %s
|
; RUN: llc -march=bpf_le < %s | FileCheck %s
|
||||||
|
|
||||||
define i16 @sccweqand(i16 %a, i16 %b) nounwind {
|
define i16 @sccweqand(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = and i16 %a, %b
|
%t1 = and i16 %a, %b
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf -show-mc-encoding | FileCheck %s
|
; RUN: llc < %s -march=bpf_le -show-mc-encoding | FileCheck %s
|
||||||
; test little endian only for now
|
|
||||||
|
|
||||||
define zeroext i8 @lshr8(i8 zeroext %a, i8 zeroext %cnt) nounwind readnone {
|
define zeroext i8 @lshr8(i8 zeroext %a, i8 zeroext %cnt) nounwind readnone {
|
||||||
entry:
|
entry:
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
; RUN: llc < %s -march=bpf -show-mc-encoding | FileCheck %s
|
; RUN: llc < %s -march=bpf_le -show-mc-encoding | FileCheck %s
|
||||||
; test little endian only for now
|
|
||||||
|
|
||||||
%struct.bpf_map_def = type { i32, i32, i32, i32 }
|
%struct.bpf_map_def = type { i32, i32, i32, i32 }
|
||||||
%struct.sk_buff = type opaque
|
%struct.sk_buff = type opaque
|
||||||
|
Loading…
x
Reference in New Issue
Block a user