diff options
Diffstat (limited to 'lib/Target/BPF')
-rw-r--r-- | lib/Target/BPF/BPFAsmPrinter.cpp | 4 | ||||
-rw-r--r-- | lib/Target/BPF/BPFMCInstLower.cpp | 4 | ||||
-rw-r--r-- | lib/Target/BPF/BPFTargetMachine.cpp | 19 | ||||
-rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp | 26 | ||||
-rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp | 5 | ||||
-rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h | 7 | ||||
-rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp | 82 | ||||
-rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp | 51 | ||||
-rw-r--r-- | lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.h | 10 | ||||
-rw-r--r-- | lib/Target/BPF/TargetInfo/BPFTargetInfo.cpp | 14 |
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)"); } |