forked from OSchip/llvm-project
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:
parent
f1d3800e65
commit
7699d6cfe9
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 -------------------------------------------===//
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 ">;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue