diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-11-21 22:06:28 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-11-21 22:06:28 +0000 |
commit | 4b04713423c6da988db75c7546baa3db7ddfa119 (patch) | |
tree | 6af0a6e0e6c05fa1d2b7ae9acb8bd8f20df59a9d /lib/Target/MBlaze | |
parent | 46a928b864369ba9e1b8fc055d100c2fa0f97d16 (diff) | |
download | external_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
Diffstat (limited to 'lib/Target/MBlaze')
-rw-r--r-- | lib/Target/MBlaze/MBlazeAsmBackend.cpp | 30 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeELFWriterInfo.cpp | 47 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeELFWriterInfo.h | 27 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrInfo.td | 18 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp | 93 |
5 files changed, 104 insertions, 111 deletions
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 |