summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWesley Peck <peckw@wesleypeck.com>2010-11-21 22:06:28 +0000
committerWesley Peck <peckw@wesleypeck.com>2010-11-21 22:06:28 +0000
commit4b04713423c6da988db75c7546baa3db7ddfa119 (patch)
tree6af0a6e0e6c05fa1d2b7ae9acb8bd8f20df59a9d
parent46a928b864369ba9e1b8fc055d100c2fa0f97d16 (diff)
downloadexternal_llvm-4b04713423c6da988db75c7546baa3db7ddfa119.zip
external_llvm-4b04713423c6da988db75c7546baa3db7ddfa119.tar.gz
external_llvm-4b04713423c6da988db75c7546baa3db7ddfa119.tar.bz2
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
-rw-r--r--cmake/modules/LLVMLibDeps.cmake16
-rw-r--r--include/llvm/Support/ELF.h27
-rw-r--r--lib/MC/ELFObjectWriter.cpp142
-rw-r--r--lib/Target/MBlaze/MBlazeAsmBackend.cpp30
-rw-r--r--lib/Target/MBlaze/MBlazeELFWriterInfo.cpp47
-rw-r--r--lib/Target/MBlaze/MBlazeELFWriterInfo.h27
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.td18
-rw-r--r--lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp93
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 <vector>
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<bits<6> op, string instr_asm, SDNode OpNode,
!strconcat(instr_asm, " $dst, $b, $c"),
[(set GPR:$dst, (OpNode GPR:$b, imm_type:$c))], IIAlu>;
+class ArithI32<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> :
+ TB<op, (outs GPR:$dst), (ins GPR:$b, Od:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], IIAlu>;
+
class ShiftI<bits<6> op, bits<2> flags, string instr_asm, SDNode OpNode,
Operand Od, PatLeaf imm_type> :
SHT<op, flags, (outs GPR:$dst), (ins GPR:$b, Od:$c),
@@ -224,6 +229,11 @@ class LogicI<bits<6> op, string instr_asm, SDNode OpNode> :
[(set GPR:$dst, (OpNode GPR:$b, immZExt16:$c))],
IIAlu>;
+class LogicI32<bits<6> op, string instr_asm> :
+ TB<op, (outs GPR:$dst), (ins GPR:$b, uimm16:$c),
+ !strconcat(instr_asm, " $dst, $b, $c"),
+ [], IIAlu>;
+
class PatCmp<bits<6> op, bits<11> flags, string instr_asm> :
TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c),
!strconcat(instr_asm, " $dst, $b, $c"),
@@ -578,10 +588,10 @@ let rb = 0 in {
"src $dst, $src", [], IIAlu>;
}
-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<MCFixup> &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<MCFixup> &Fixups) const {
+EmitImmediate(const MCInst &MI, unsigned opNo, bool pcrel, unsigned &CurByte,
+ raw_ostream &OS, SmallVectorImpl<MCFixup> &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