From 4b04713423c6da988db75c7546baa3db7ddfa119 Mon Sep 17 00:00:00 2001 From: Wesley Peck Date: Sun, 21 Nov 2010 22:06:28 +0000 Subject: Implement ELF object file writing support for the MBlaze backend. Its not perfect yet, but it works for many tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119952 91177308-0d34-0410-b5e6-96231b3b80d8 --- cmake/modules/LLVMLibDeps.cmake | 16 ++-- include/llvm/Support/ELF.h | 27 ++++++ lib/MC/ELFObjectWriter.cpp | 142 +++++++++++++++++++++++++++++- lib/Target/MBlaze/MBlazeAsmBackend.cpp | 30 +++++-- lib/Target/MBlaze/MBlazeELFWriterInfo.cpp | 47 +++++----- lib/Target/MBlaze/MBlazeELFWriterInfo.h | 27 ------ lib/Target/MBlaze/MBlazeInstrInfo.td | 18 +++- lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp | 93 +++++++++---------- 8 files changed, 279 insertions(+), 121 deletions(-) diff --git a/cmake/modules/LLVMLibDeps.cmake b/cmake/modules/LLVMLibDeps.cmake index 4fedced..2b698db 100644 --- a/cmake/modules/LLVMLibDeps.cmake +++ b/cmake/modules/LLVMLibDeps.cmake @@ -1,13 +1,13 @@ set(MSVC_LIB_DEPS_LLVMARMAsmParser LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMMCParser LLVMSupport LLVMTarget) set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMARMCodeGen LLVMARMAsmPrinter LLVMARMInfo LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMARMDisassembler LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMARMDisassembler LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMARMInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMAlphaCodeGen LLVMAlphaInfo LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMAlphaInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem) -set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport) +set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMAsmPrinter LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMBitReader LLVMCore LLVMSupport) set(MSVC_LIB_DEPS_LLVMBitWriter LLVMCore LLVMSupport) @@ -19,7 +19,7 @@ set(MSVC_LIB_DEPS_LLVMCellSPUCodeGen LLVMAsmPrinter LLVMCellSPUInfo LLVMCodeGen set(MSVC_LIB_DEPS_LLVMCellSPUInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMCodeGen LLVMAnalysis LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) set(MSVC_LIB_DEPS_LLVMCore LLVMSupport LLVMSystem) -set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMInstCombine LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) @@ -27,8 +27,8 @@ set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMSupport LLVMSyst set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMLinker LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMBlazeAsmPrinter LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget) +set(MSVC_LIB_DEPS_LLVMMBlazeAsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMBlazeAsmPrinter LLVMMBlazeInfo LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC LLVMSupport) @@ -44,7 +44,7 @@ set(MSVC_LIB_DEPS_LLVMMipsInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMObject LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMPTXCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPTXInfo LLVMSelectionDAG LLVMSupport LLVMTarget) set(MSVC_LIB_DEPS_LLVMPTXInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPowerPCAsmPrinter LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMPowerPCAsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMPowerPCCodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCAsmPrinter LLVMPowerPCInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMPowerPCInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMScalarOpts LLVMAnalysis LLVMCore LLVMInstCombine LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) @@ -57,8 +57,8 @@ set(MSVC_LIB_DEPS_LLVMSystemZCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC set(MSVC_LIB_DEPS_LLVMSystemZInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMTransformUtils LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMipa) -set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMMCParser LLVMSupport LLVMTarget LLVMX86Info) -set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget LLVMX86Info) +set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMX86AsmPrinter LLVMX86Info) set(MSVC_LIB_DEPS_LLVMX86Disassembler LLVMMC LLVMSupport LLVMX86Info) set(MSVC_LIB_DEPS_LLVMX86Info LLVMMC LLVMSupport) diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index c6304aa..2a5bf4d 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -263,6 +263,33 @@ enum { R_386_NUM = 43 }; +// MBlaze relocations. +enum { + R_MICROBLAZE_NONE = 0, + R_MICROBLAZE_32 = 1, + R_MICROBLAZE_32_PCREL = 2, + R_MICROBLAZE_64_PCREL = 3, + R_MICROBLAZE_32_PCREL_LO = 4, + R_MICROBLAZE_64 = 5, + R_MICROBLAZE_32_LO = 6, + R_MICROBLAZE_SRO32 = 7, + R_MICROBLAZE_SRW32 = 8, + R_MICROBLAZE_64_NONE = 9, + R_MICROBLAZE_32_SYM_OP_SYM = 10, + R_MICROBLAZE_GNU_VTINHERIT = 11, + R_MICROBLAZE_GNU_VTENTRY = 12, + R_MICROBLAZE_GOTPC_64 = 13, + R_MICROBLAZE_GOT_64 = 14, + R_MICROBLAZE_PLT_64 = 15, + R_MICROBLAZE_REL = 16, + R_MICROBLAZE_JUMP_SLOT = 17, + R_MICROBLAZE_GLOB_DAT = 18, + R_MICROBLAZE_GOTOFF_64 = 19, + R_MICROBLAZE_GOTOFF_32 = 20, + R_MICROBLAZE_COPY = 21 +}; + + // Section header. struct Elf32_Shdr { Elf32_Word sh_name; // Section name (index into string table) diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 4ea6308..b9a0b02 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -30,6 +30,7 @@ #include "llvm/Target/TargetAsmBackend.h" #include "../Target/X86/X86FixupKinds.h" +#include "../Target/MBlaze/MBlazeFixupKinds.h" #include using namespace llvm; @@ -77,6 +78,16 @@ static bool isFixupKindX86PCRel(unsigned Kind) { } } +static bool isFixupKindMBlazePCRel(unsigned Kind) { + switch (Kind) { + default: + return false; + case MBlaze::reloc_pcrel_2byte: + case MBlaze::reloc_pcrel_4byte: + return true; + } +} + static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { switch (Variant) { default: @@ -358,7 +369,7 @@ namespace { X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian, uint16_t _EMachine, bool _HasRelAddend, Triple::OSType _OSType); - + virtual ~X86ELFObjectWriter(); virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, @@ -375,7 +386,7 @@ namespace { ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian, uint16_t _EMachine, bool _HasRelAddend, Triple::OSType _OSType); - + virtual ~ARMELFObjectWriter(); virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, @@ -383,6 +394,22 @@ namespace { const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue); }; + + //===- MBlazeELFObjectWriter -------------------------------------------===// + + class MBlazeELFObjectWriter : public ELFObjectWriter { + public: + MBlazeELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian, + uint16_t _EMachine, bool _HasRelAddend, + Triple::OSType _OSType); + + virtual ~MBlazeELFObjectWriter(); + virtual void RecordRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, MCValue Target, + uint64_t &FixedValue); + }; } ELFObjectWriter::~ELFObjectWriter() @@ -1349,6 +1376,9 @@ MCObjectWriter *llvm::createELFObjectWriter(raw_ostream &OS, case ELF::EM_ARM: return new ARMELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine, HasRelocationAddend, OSType); break; + case ELF::EM_MBLAZE: + return new MBlazeELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine, + HasRelocationAddend, OSType); break; default: llvm_unreachable("Unsupported architecture"); break; } } @@ -1377,7 +1407,115 @@ void ARMELFObjectWriter::RecordRelocation(const MCAssembler &Asm, assert(0 && "ARMELFObjectWriter::RecordRelocation() unimplemented"); } +//===- MBlazeELFObjectWriter -------------------------------------------===// + +MBlazeELFObjectWriter::MBlazeELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, + bool _IsLittleEndian, + uint16_t _EMachine, + bool _HasRelocationAddend, + Triple::OSType _OSType) + : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine, + _HasRelocationAddend, _OSType) { +} + +MBlazeELFObjectWriter::~MBlazeELFObjectWriter() { +} + +void MBlazeELFObjectWriter::RecordRelocation(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, + MCValue Target, + uint64_t &FixedValue) { + int64_t Addend = 0; + int Index = 0; + int64_t Value = Target.getConstant(); + const MCSymbol &Symbol = Target.getSymA()->getSymbol(); + const MCSymbol &ASymbol = Symbol.AliasedSymbol(); + const MCSymbol *RelocSymbol = SymbolToReloc(Asm, Target, *Fragment); + bool IsPCRel = isFixupKindMBlazePCRel(Fixup.getKind()); + if (!Target.isAbsolute()) { + if (const MCSymbolRefExpr *RefB = Target.getSymB()) { + const MCSymbol &SymbolB = RefB->getSymbol(); + MCSymbolData &SDB = Asm.getSymbolData(SymbolB); + IsPCRel = true; + MCSectionData *Sec = Fragment->getParent(); + + // Offset of the symbol in the section + int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec); + + // Ofeset of the relocation in the section + int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + Value += b - a; + } + + if (!RelocSymbol) { + MCSymbolData &SD = Asm.getSymbolData(ASymbol); + MCFragment *F = SD.getFragment(); + + Index = F->getParent()->getOrdinal(); + + MCSectionData *FSD = F->getParent(); + // Offset of the symbol in the section + Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD); + } else { + if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) + WeakrefUsedInReloc.insert(RelocSymbol); + else + UsedInReloc.insert(RelocSymbol); + Index = -1; + } + Addend = Value; + } + + FixedValue = Value; + + // determine the type of the relocation + unsigned Type; + if (IsPCRel) { + switch ((unsigned)Fixup.getKind()) { + default: + llvm_unreachable("Unimplemented"); + case MBlaze::reloc_pcrel_4byte: + Type = ELF::R_MICROBLAZE_64_PCREL; + break; + case MBlaze::reloc_pcrel_2byte: + Type = ELF::R_MICROBLAZE_32_PCREL; + break; + } + } else { + switch ((unsigned)Fixup.getKind()) { + default: llvm_unreachable("invalid fixup kind!"); + case FK_Data_4: + Type = (RelocSymbol || Addend !=0) ? ELF::R_MICROBLAZE_32 + : ELF::R_MICROBLAZE_64; + break; + case FK_Data_2: + Type = ELF::R_MICROBLAZE_32; + break; + } + } + + MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); + if (RelocNeedsGOT(Modifier)) + NeedsGOT = true; + + ELFRelocationEntry ERE; + + ERE.Index = Index; + ERE.Type = Type; + ERE.Symbol = RelocSymbol; + + ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + + if (HasRelocationAddend) + ERE.r_addend = Addend; + else + ERE.r_addend = 0; // Silence compiler warning. + + Relocations[Fragment->getParent()].push_back(ERE); +} //===- X86ELFObjectWriter -------------------------------------------===// diff --git a/lib/Target/MBlaze/MBlazeAsmBackend.cpp b/lib/Target/MBlaze/MBlazeAsmBackend.cpp index 6fc36f7..fcf5de0 100644 --- a/lib/Target/MBlaze/MBlazeAsmBackend.cpp +++ b/lib/Target/MBlaze/MBlazeAsmBackend.cpp @@ -9,14 +9,18 @@ #include "llvm/Target/TargetAsmBackend.h" #include "MBlaze.h" +#include "MBlazeELFWriterInfo.h" #include "MBlazeFixupKinds.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCAsmLayout.h" +#include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectFormat.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -55,13 +59,29 @@ public: } }; +static unsigned getRelaxedOpcode(unsigned Op) { + switch (Op) { + default: return Op; + case MBlaze::ADDI: return MBlaze::ADDI32; + case MBlaze::ORI: return MBlaze::ORI32; + case MBlaze::BRLID: return MBlaze::BRLID32; + } +} + bool MBlazeAsmBackend::MayNeedRelaxation(const MCInst &Inst) const { - return false; + if (getRelaxedOpcode(Inst.getOpcode()) == Inst.getOpcode()) + return false; + + bool hasExprOrImm = false; + for (unsigned i = 0; i < Inst.getNumOperands(); ++i) + hasExprOrImm |= Inst.getOperand(i).isExpr(); + + return hasExprOrImm; } void MBlazeAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const { - assert(0 && "MBlazeAsmBackend::RelaxInstruction() unimplemented"); - return; + Res = Inst; + Res.setOpcode(getRelaxedOpcode(Inst.getOpcode())); } bool MBlazeAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const { @@ -76,8 +96,6 @@ bool MBlazeAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const { } // end anonymous namespace namespace { -// FIXME: This should be in a separate file. -// ELF is an ELF of course... class ELFMBlazeAsmBackend : public MBlazeAsmBackend { MCELFObjectFormat Format; @@ -97,7 +115,7 @@ public: uint64_t Value) const; MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createELFObjectWriter(OS, /*Is64Bit=*/false, + return createELFObjectWriter(OS,/*Is64Bit=*/false, OSType, ELF::EM_MBLAZE, /*IsLittleEndian=*/false, /*HasRelocationAddend=*/true); diff --git a/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp b/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp index cf6312f..3f26ed1 100644 --- a/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp +++ b/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp @@ -14,6 +14,7 @@ #include "MBlazeELFWriterInfo.h" #include "MBlazeRelocations.h" #include "llvm/Function.h" +#include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" @@ -34,9 +35,9 @@ MBlazeELFWriterInfo::~MBlazeELFWriterInfo() {} unsigned MBlazeELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { switch (MachineRelTy) { case MBlaze::reloc_pcrel_word: - return R_MICROBLAZE_64_PCREL; + return ELF::R_MICROBLAZE_64_PCREL; case MBlaze::reloc_absolute_word: - return R_MICROBLAZE_NONE; + return ELF::R_MICROBLAZE_NONE; default: llvm_unreachable("unknown mblaze machine relocation type"); } @@ -46,9 +47,9 @@ unsigned MBlazeELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { long int MBlazeELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, long int Modifier) const { switch (RelTy) { - case R_MICROBLAZE_32_PCREL: + case ELF::R_MICROBLAZE_32_PCREL: return Modifier - 4; - case R_MICROBLAZE_32: + case ELF::R_MICROBLAZE_32: return Modifier; default: llvm_unreachable("unknown mblaze relocation type"); @@ -59,22 +60,22 @@ long int MBlazeELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, unsigned MBlazeELFWriterInfo::getRelocationTySize(unsigned RelTy) const { // FIXME: Most of these sizes are guesses based on the name switch (RelTy) { - case R_MICROBLAZE_32: - case R_MICROBLAZE_32_PCREL: - case R_MICROBLAZE_32_PCREL_LO: - case R_MICROBLAZE_32_LO: - case R_MICROBLAZE_SRO32: - case R_MICROBLAZE_SRW32: - case R_MICROBLAZE_32_SYM_OP_SYM: - case R_MICROBLAZE_GOTOFF_32: + case ELF::R_MICROBLAZE_32: + case ELF::R_MICROBLAZE_32_PCREL: + case ELF::R_MICROBLAZE_32_PCREL_LO: + case ELF::R_MICROBLAZE_32_LO: + case ELF::R_MICROBLAZE_SRO32: + case ELF::R_MICROBLAZE_SRW32: + case ELF::R_MICROBLAZE_32_SYM_OP_SYM: + case ELF::R_MICROBLAZE_GOTOFF_32: return 32; - case R_MICROBLAZE_64_PCREL: - case R_MICROBLAZE_64: - case R_MICROBLAZE_GOTPC_64: - case R_MICROBLAZE_GOT_64: - case R_MICROBLAZE_PLT_64: - case R_MICROBLAZE_GOTOFF_64: + case ELF::R_MICROBLAZE_64_PCREL: + case ELF::R_MICROBLAZE_64: + case ELF::R_MICROBLAZE_GOTPC_64: + case ELF::R_MICROBLAZE_GOT_64: + case ELF::R_MICROBLAZE_PLT_64: + case ELF::R_MICROBLAZE_GOTOFF_64: return 64; } @@ -84,10 +85,10 @@ unsigned MBlazeELFWriterInfo::getRelocationTySize(unsigned RelTy) const { bool MBlazeELFWriterInfo::isPCRelativeRel(unsigned RelTy) const { // FIXME: Most of these are guesses based on the name switch (RelTy) { - case R_MICROBLAZE_32_PCREL: - case R_MICROBLAZE_64_PCREL: - case R_MICROBLAZE_32_PCREL_LO: - case R_MICROBLAZE_GOTPC_64: + case ELF::R_MICROBLAZE_32_PCREL: + case ELF::R_MICROBLAZE_64_PCREL: + case ELF::R_MICROBLAZE_32_PCREL_LO: + case ELF::R_MICROBLAZE_GOTPC_64: return true; } @@ -101,7 +102,7 @@ unsigned MBlazeELFWriterInfo::getAbsoluteLabelMachineRelTy() const { long int MBlazeELFWriterInfo::computeRelocation(unsigned SymOffset, unsigned RelOffset, unsigned RelTy) const { - if (RelTy == R_MICROBLAZE_32_PCREL || R_MICROBLAZE_64_PCREL) + if (RelTy == ELF::R_MICROBLAZE_32_PCREL || ELF::R_MICROBLAZE_64_PCREL) return SymOffset - (RelOffset + 4); else assert("computeRelocation unknown for this relocation type"); diff --git a/lib/Target/MBlaze/MBlazeELFWriterInfo.h b/lib/Target/MBlaze/MBlazeELFWriterInfo.h index abea992..63bfc0d 100644 --- a/lib/Target/MBlaze/MBlazeELFWriterInfo.h +++ b/lib/Target/MBlaze/MBlazeELFWriterInfo.h @@ -19,33 +19,6 @@ namespace llvm { class MBlazeELFWriterInfo : public TargetELFWriterInfo { - - // ELF Relocation types for MBlaze - enum MBlazeRelocationType { - R_MICROBLAZE_NONE = 0, - R_MICROBLAZE_32 = 1, - R_MICROBLAZE_32_PCREL = 2, - R_MICROBLAZE_64_PCREL = 3, - R_MICROBLAZE_32_PCREL_LO = 4, - R_MICROBLAZE_64 = 5, - R_MICROBLAZE_32_LO = 6, - R_MICROBLAZE_SRO32 = 7, - R_MICROBLAZE_SRW32 = 8, - R_MICROBLAZE_64_NONE = 9, - R_MICROBLAZE_32_SYM_OP_SYM = 10, - R_MICROBLAZE_GNU_VTINHERIT = 11, - R_MICROBLAZE_GNU_VTENTRY = 12, - R_MICROBLAZE_GOTPC_64 = 13, - R_MICROBLAZE_GOT_64 = 14, - R_MICROBLAZE_PLT_64 = 15, - R_MICROBLAZE_REL = 16, - R_MICROBLAZE_JUMP_SLOT = 17, - R_MICROBLAZE_GLOB_DAT = 18, - R_MICROBLAZE_GOTOFF_64 = 19, - R_MICROBLAZE_GOTOFF_32 = 20, - R_MICROBLAZE_COPY = 21 - }; - public: MBlazeELFWriterInfo(TargetMachine &TM); virtual ~MBlazeELFWriterInfo(); diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index 7c6c9aa..e1f68d2 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -169,6 +169,11 @@ class ArithI op, string instr_asm, SDNode OpNode, !strconcat(instr_asm, " $dst, $b, $c"), [(set GPR:$dst, (OpNode GPR:$b, imm_type:$c))], IIAlu>; +class ArithI32 op, string instr_asm,Operand Od, PatLeaf imm_type> : + TB; + class ShiftI op, bits<2> flags, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type> : SHT op, string instr_asm, SDNode OpNode> : [(set GPR:$dst, (OpNode GPR:$b, immZExt16:$c))], IIAlu>; +class LogicI32 op, string instr_asm> : + TB; + class PatCmp op, bits<11> flags, string instr_asm> : TA; } -let opcode=0x08, isCodeGenOnly=1 in { - def LEA_ADDI : TB<0x08, (outs GPR:$dst), (ins memri:$addr), - "addi $dst, ${addr:stackloc}", - [(set GPR:$dst, iaddr:$addr)], IIAlu>; +let isCodeGenOnly=1 in { + def ADDI32 : ArithI32<0x08, "addi ", simm16, immSExt16>; + def ORI32 : LogicI32<0x28, "ori ">; + def BRLID32 : BranchLI<0x2E, 0x14, "brlid ">; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp index 19dc89b..625c73f 100644 --- a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp +++ b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp @@ -58,8 +58,9 @@ public: const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[] = { - { "reloc_pcrel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, - { "reloc_pcrel_2byte", 0, 2 * 8, MCFixupKindInfo::FKF_IsPCRel } }; + // name offset bits flags + { "reloc_pcrel_4byte", 2, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, + { "reloc_pcrel_2byte", 2, 2 * 8, MCFixupKindInfo::FKF_IsPCRel } }; if (Kind < FirstTargetFixupKind) return MCCodeEmitter::getFixupKindInfo(Kind); @@ -103,11 +104,9 @@ public: } void EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const; - void EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte, - raw_ostream &OS) const; + void EmitIMM(const MCInst &MI, unsigned &CurByte, raw_ostream &OS) const; - void EmitImmediate(const MCInst &MI, - unsigned opNo, MCFixupKind FixupKind, + void EmitImmediate(const MCInst &MI, unsigned opNo, bool pcrel, unsigned &CurByte, raw_ostream &OS, SmallVectorImpl &Fixups) const; @@ -155,28 +154,43 @@ EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const { } void MBlazeMCCodeEmitter:: -EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte, - raw_ostream &OS) const { - MCOperand mcop = MI.getOperand(op); - if (mcop.isExpr()) { - EmitByte(0x0D, CurByte, OS); - EmitByte(0x00, CurByte, OS); - EmitRawByte(0, CurByte, OS); - EmitRawByte(0, CurByte, OS); - } +EmitIMM(const MCInst &MI, unsigned &CurByte,raw_ostream &OS) const { + switch (MI.getOpcode()) { + default: break; + + case MBlaze::ADDI32: + case MBlaze::ORI32: + case MBlaze::BRLID32: + EmitByte(0x0D, CurByte, OS); + EmitByte(0x00, CurByte, OS); + EmitRawByte(0, CurByte, OS); + EmitRawByte(0, CurByte, OS); + } } void MBlazeMCCodeEmitter:: -EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind, - unsigned &CurByte, raw_ostream &OS, - SmallVectorImpl &Fixups) const { +EmitImmediate(const MCInst &MI, unsigned opNo, bool pcrel, unsigned &CurByte, + raw_ostream &OS, SmallVectorImpl &Fixups) const { assert(MI.getNumOperands()>opNo && "Not enought operands for instruction"); MCOperand oper = MI.getOperand(opNo); + if (oper.isImm()) { - EmitIMM(oper, CurByte, OS); + EmitIMM(oper, CurByte, OS); } else if (oper.isExpr()) { + MCFixupKind FixupKind; + switch (MI.getOpcode()) { + default: + FixupKind = pcrel ? MCFixupKind(MBlaze::reloc_pcrel_2byte) : FK_Data_2; + Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind)); + break; + case MBlaze::ORI32: + case MBlaze::ADDI32: + case MBlaze::BRLID32: + FixupKind = pcrel ? MCFixupKind(MBlaze::reloc_pcrel_4byte) : FK_Data_4; Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind)); + break; + } } } @@ -191,56 +205,33 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, // Keep track of the current byte being emitted. unsigned CurByte = 0; + // Emit an IMM instruction if the instruction we are encoding requires it + EmitIMM(MI,CurByte,OS); + switch ((TSFlags & MBlazeII::FormMask)) { default: break; case MBlazeII::FPseudo: // Pseudo instructions don't get encoded. return; - case MBlazeII::FRRI: - EmitImmediate(MI, 2, FK_Data_4, CurByte, OS, Fixups); + EmitImmediate(MI, 2, false, CurByte, OS, Fixups); break; - case MBlazeII::FRIR: - EmitImmediate(MI, 1, FK_Data_4, CurByte, OS, Fixups); + EmitImmediate(MI, 1, false, CurByte, OS, Fixups); break; - case MBlazeII::FCRI: - EmitImmediate(MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS, - Fixups); + EmitImmediate(MI, 1, true, CurByte, OS, Fixups); break; - case MBlazeII::FRCI: - EmitImmediate(MI, 1, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, - Fixups); - + EmitImmediate(MI, 1, true, CurByte, OS, Fixups); case MBlazeII::FCCI: - EmitImmediate(MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, - Fixups); + EmitImmediate(MI, 0, true, CurByte, OS, Fixups); break; } ++MCNumEmitted; // Keep track of the # of mi's emitted unsigned Value = getBinaryCodeForInstr(MI); - switch (Opcode) { - default: - EmitConstant(Value, 4, CurByte, OS); - break; - - case MBlaze::BRLID: - case MBlaze::BRALID: - EmitIMM(MI,1,CurByte,OS); - EmitConstant(Value, 4, CurByte, OS); - break; - - case MBlaze::BRI: - case MBlaze::BRAI: - case MBlaze::BRID: - case MBlaze::BRAID: - EmitIMM(MI,0,CurByte,OS); - EmitConstant(Value, 4, CurByte, OS); - break; - } + EmitConstant(Value, 4, CurByte, OS); } // FIXME: These #defines shouldn't be necessary. Instead, tblgen should -- cgit v1.1