Implement ELF object file writing support for the MBlaze backend. Its not perfect yet, but it works for many tests.

llvm-svn: 119952
This commit is contained in:
Wesley Peck 2010-11-21 22:06:28 +00:00
parent f1d3800e65
commit 7699d6cfe9
8 changed files with 279 additions and 121 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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 -------------------------------------------===//

View File

@ -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);

View File

@ -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");

View File

@ -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();

View File

@ -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 ">;
}
//===----------------------------------------------------------------------===//

View File

@ -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