Fix a FIXME by making GlobalVariable::getInitializer() return a
[oota-llvm.git] / lib / Target / MBlaze / MBlazeMCCodeEmitter.cpp
index fec147decdf5a882238b0e6e38b4f12e2ad6c635..3ece1a8a340dc02a287527d500ea3b3e897886b1 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#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"
@@ -52,25 +51,6 @@ public:
     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.");
@@ -94,7 +74,7 @@ public:
 
   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);
@@ -103,9 +83,9 @@ public:
   }
 
   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;
 
@@ -130,7 +110,7 @@ unsigned MBlazeMCCodeEmitter::getMachineOpValue(const MCInst &MI,
     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
@@ -144,7 +124,7 @@ unsigned MBlazeMCCodeEmitter::getMachineOpValue(const MCInst &MI,
 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);
@@ -153,19 +133,48 @@ EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const {
 }
 
 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 {
@@ -175,54 +184,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::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