//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "mblaze-emitter"
+#define DEBUG_TYPE "mccodeemitter"
#include "MBlaze.h"
#include "MBlazeInstrInfo.h"
-#include "MBlazeFixupKinds.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
return getMachineOpValue(MI, MI.getOperand(OpIdx));
}
- unsigned getNumFixupKinds() const {
- return 2;
- }
-
- 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 } };
-
- if (Kind < FirstTargetFixupKind)
- return MCCodeEmitter::getFixupKindInfo(Kind);
-
- if (unsigned(Kind-FirstTargetFixupKind) < getNumFixupKinds())
- return Infos[Kind - FirstTargetFixupKind];
-
- assert(0 && "Invalid fixup kind.");
- return Infos[0];
- }
-
static unsigned GetMBlazeRegNum(const MCOperand &MO) {
// FIXME: getMBlazeRegisterNumbering() is sufficient?
assert(0 && "MBlazeMCCodeEmitter::GetMBlazeRegNum() not yet implemented.");
void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte,
raw_ostream &OS) const {
- assert(Size <= 8 && "size too big in emit constant" );
+ assert(Size <= 8 && "size too big in emit constant");
for (unsigned i = 0; i != Size; ++i) {
EmitByte(Val & 255, CurByte, OS);
}
void EmitIMM(const MCOperand &imm, 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;
return MBlazeRegisterInfo::getRegisterNumbering(MO.getReg());
else if (MO.isImm())
return static_cast<unsigned>(MO.getImm());
- else if (MO.isExpr() )
+ else if (MO.isExpr())
return 0; // The relocation has already been recorded at this point.
else {
#ifndef NDEBUG
void MBlazeMCCodeEmitter::
EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const {
int32_t val = (int32_t)imm.getImm();
- if (val > 32767 || val < -32678 ) {
+ if (val > 32767 || val < -32768) {
EmitByte(0x0D, CurByte, OS);
EmitByte(0x00, CurByte, OS);
EmitRawByte((val >> 24) & 0xFF, CurByte, OS);
}
void MBlazeMCCodeEmitter::
-EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind,
- unsigned &CurByte, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups) const {
- assert( MI.getNumOperands()>opNo && "Not enought operands for instruction" );
+EmitIMM(const MCInst &MI, unsigned &CurByte,raw_ostream &OS) const {
+ switch (MI.getOpcode()) {
+ default: break;
+
+ case MBlaze::ADDIK32:
+ 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, 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 ? FK_PCRel_2 : FK_Data_2;
+ Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind));
+ break;
+ case MBlaze::ORI32:
+ case MBlaze::ADDIK32:
+ case MBlaze::BRLID32:
+ FixupKind = pcrel ? FK_PCRel_4 : FK_Data_4;
Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind));
+ break;
+ }
}
}
+
+
void MBlazeMCCodeEmitter::
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const {
// 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::Pseudo:
+ case MBlazeII::FPseudo:
// Pseudo instructions don't get encoded.
return;
-
- case MBlazeII::RegRegImm:
- EmitImmediate( MI, 2, FK_Data_4, CurByte, OS, Fixups );
+ case MBlazeII::FRRI:
+ EmitImmediate(MI, 2, false, CurByte, OS, Fixups);
break;
-
- case MBlazeII::RegImmReg:
- EmitImmediate( MI, 1, FK_Data_4, CurByte, OS, Fixups );
+ case MBlazeII::FRIR:
+ EmitImmediate(MI, 1, false, CurByte, OS, Fixups);
break;
-
- case MBlazeII::RegImm:
- EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS,
- Fixups );
+ case MBlazeII::FCRI:
+ EmitImmediate(MI, 1, true, CurByte, OS, Fixups);
break;
-
- case MBlazeII::Imm:
- EmitImmediate( MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS,
- Fixups );
+ case MBlazeII::FRCI:
+ EmitImmediate(MI, 1, true, CurByte, OS, Fixups);
+ case MBlazeII::FCCI:
+ 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::BRI:
- case MBlaze::BRAI:
- case MBlaze::BRID:
- case MBlaze::BRAID:
- case MBlaze::BRLID:
- case MBlaze::BRALID:
- MCOperand op = MI.getOperand(0);
- if (op.isExpr()) {
- EmitByte(0x0D, CurByte, OS);
- EmitByte(0x00, CurByte, OS);
- EmitRawByte(0, CurByte, OS);
- EmitRawByte(0, CurByte, OS);
- }
- EmitConstant(Value, 4, CurByte, OS);
- break;
- }
+ EmitConstant(Value, 4, CurByte, OS);
}
// FIXME: These #defines shouldn't be necessary. Instead, tblgen should