aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/MBlaze
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 /lib/Target/MBlaze
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
Diffstat (limited to 'lib/Target/MBlaze')
-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
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