Adding disassembler to the MicroBlaze backend.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117420 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
index 399c41e..d7e3047 100644
--- a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
+++ b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
@@ -72,10 +72,6 @@
 
   bool ParseDirectiveWord(unsigned Size, SMLoc L);
 
-  bool ParseDirectiveThumb(SMLoc L);
-
-  bool ParseDirectiveThumbFunc(SMLoc L);
-
   bool ParseDirectiveCode(SMLoc L);
 
   bool ParseDirectiveSyntax(SMLoc L);
@@ -750,10 +746,6 @@
   StringRef IDVal = DirectiveID.getIdentifier();
   if (IDVal == ".word")
     return ParseDirectiveWord(4, DirectiveID.getLoc());
-  else if (IDVal == ".thumb")
-    return ParseDirectiveThumb(DirectiveID.getLoc());
-  else if (IDVal == ".thumb_func")
-    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
   else if (IDVal == ".code")
     return ParseDirectiveCode(DirectiveID.getLoc());
   else if (IDVal == ".syntax")
@@ -786,36 +778,6 @@
   return false;
 }
 
-/// ParseDirectiveThumb
-///  ::= .thumb
-bool MBlazeAsmParser::ParseDirectiveThumb(SMLoc L) {
-  if (getLexer().isNot(AsmToken::EndOfStatement))
-    return Error(L, "unexpected token in directive");
-  Parser.Lex();
-
-  // TODO: set thumb mode
-  // TODO: tell the MC streamer the mode
-  // getParser().getStreamer().Emit???();
-  return false;
-}
-
-/// ParseDirectiveThumbFunc
-///  ::= .thumbfunc symbol_name
-bool MBlazeAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
-  const AsmToken &Tok = Parser.getTok();
-  if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
-    return Error(L, "unexpected token in .syntax directive");
-  Parser.Lex(); // Consume the identifier token.
-
-  if (getLexer().isNot(AsmToken::EndOfStatement))
-    return Error(L, "unexpected token in directive");
-  Parser.Lex();
-
-  // TODO: mark symbol as a thumb symbol
-  // getParser().getStreamer().Emit???();
-  return false;
-}
-
 /// ParseDirectiveSyntax
 ///  ::= .syntax unified | divided
 bool MBlazeAsmParser::ParseDirectiveSyntax(SMLoc L) {
diff --git a/lib/Target/MBlaze/CMakeLists.txt b/lib/Target/MBlaze/CMakeLists.txt
index 40d3f4d..8e832ee 100644
--- a/lib/Target/MBlaze/CMakeLists.txt
+++ b/lib/Target/MBlaze/CMakeLists.txt
@@ -12,6 +12,7 @@
 tablegen(MBlazeGenCallingConv.inc -gen-callingconv)
 tablegen(MBlazeGenSubtarget.inc -gen-subtarget)
 tablegen(MBlazeGenIntrinsics.inc -gen-tgt-intrinsic)
+tablegen(MBlazeGenEDInfo.inc -gen-enhanced-disassembly-info)
 
 add_llvm_target(MBlazeCodeGen
   MBlazeDelaySlotFiller.cpp
diff --git a/lib/Target/MBlaze/Disassembler/CMakeLists.txt b/lib/Target/MBlaze/Disassembler/CMakeLists.txt
new file mode 100644
index 0000000..9376e68
--- /dev/null
+++ b/lib/Target/MBlaze/Disassembler/CMakeLists.txt
@@ -0,0 +1,16 @@
+include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. 
+                     ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+
+add_llvm_library(LLVMMBlazeDisassembler
+  MBlazeDisassembler.cpp
+  )
+
+# workaround for hanging compilation on MSVC9 and 10
+if( MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 )
+set_property(
+  SOURCE MBlazeDisassembler.cpp
+  PROPERTY COMPILE_FLAGS "/Od"
+  )
+endif()
+
+add_dependencies(LLVMMBlazeDisassembler MBlazeCodeGenTable_gen)
diff --git a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp
new file mode 100644
index 0000000..01a48b2
--- /dev/null
+++ b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp
@@ -0,0 +1,578 @@
+//===- MBlazeDisassembler.cpp - Disassembler for MicroBlaze  ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the MBlaze Disassembler. It contains code to translate
+// the data produced by the decoder into MCInsts.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MBlaze.h"
+#include "MBlazeInstrInfo.h"
+#include "MBlazeDisassembler.h"
+
+#include "llvm/MC/EDInstInfo.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/raw_ostream.h"
+
+// #include "MBlazeGenDecoderTables.inc"
+// #include "MBlazeGenRegisterNames.inc"
+#include "MBlazeGenInstrInfo.inc"
+#include "MBlazeGenEDInfo.inc"
+
+using namespace llvm;
+
+const unsigned UNSUPPORTED = -1;
+
+static unsigned mblazeBinary2Opcode[] = {
+  MBlaze::ADD,   MBlaze::RSUB,   MBlaze::ADDC,   MBlaze::RSUBC,   //00,01,02,03
+  MBlaze::ADDK,  MBlaze::RSUBK,  MBlaze::ADDKC,  MBlaze::RSUBKC,  //04,05,06,07
+  MBlaze::ADDI,  MBlaze::RSUBI,  MBlaze::ADDIC,  MBlaze::RSUBIC,  //08,09,0A,0B
+  MBlaze::ADDIK, MBlaze::RSUBIK, MBlaze::ADDIKC, MBlaze::RSUBIKC, //0C,0D,0E,0F
+
+  MBlaze::MUL,   MBlaze::BSRL,   MBlaze::IDIV,   MBlaze::GETD,    //10,11,12,13
+  UNSUPPORTED,   UNSUPPORTED,    MBlaze::FADD,   UNSUPPORTED,     //14,15,16,17
+  MBlaze::MULI,  MBlaze::BSRLI,  UNSUPPORTED,    MBlaze::GET,     //18,19,1A,1B
+  UNSUPPORTED,   UNSUPPORTED,    UNSUPPORTED,    UNSUPPORTED,     //1C,1D,1E,1F
+
+  MBlaze::OR,    MBlaze::AND,    MBlaze::XOR,    MBlaze::ANDN,    //20,21,22,23
+  MBlaze::SEXT8, MBlaze::MFS,    MBlaze::BR,     MBlaze::BEQ,     //24,25,26,27
+  MBlaze::ORI,   MBlaze::ANDI,   MBlaze::XORI,   MBlaze::ANDNI,   //28,29,2A,2B
+  MBlaze::IMM,   MBlaze::RTSD,   MBlaze::BRI,    MBlaze::BEQI,    //2C,2D,2E,2F
+
+  MBlaze::LBU,   MBlaze::LHU,    MBlaze::LW,     UNSUPPORTED,     //30,31,32,33
+  MBlaze::SB,    MBlaze::SH,     MBlaze::SW,     UNSUPPORTED,     //34,35,36,37
+  MBlaze::LBUI,  MBlaze::LHUI,   MBlaze::LWI,    UNSUPPORTED,     //38,39,3A,3B
+  MBlaze::SBI,   MBlaze::SHI,    MBlaze::SWI,    UNSUPPORTED,     //3C,3D,3E,3F
+};
+
+static unsigned getRD( uint32_t insn ) {
+  return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>21)&0x1F );
+}
+
+static unsigned getRA( uint32_t insn ) {
+  return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>16)&0x1F );
+}
+
+static unsigned getRB( uint32_t insn ) {
+  return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>11)&0x1F );
+}
+
+static int64_t getRS( uint32_t insn ) {
+    int16_t val = (insn & 0x3FFF);
+    return val;
+}
+
+static int64_t getIMM( uint32_t insn ) {
+    int16_t val = (insn & 0xFFFF);
+    return val;
+}
+
+static int64_t getSHT( uint32_t insn ) {
+    int16_t val = (insn & 0x1F);
+    return val;
+}
+
+static unsigned getFLAGS( int32_t insn ) {
+    return (insn & 0x7FF);
+}
+
+static int64_t getFSL( uint32_t insn ) {
+    int16_t val = (insn & 0xF);
+    return val;
+}
+
+static unsigned decodeMUL(uint32_t insn) {
+    switch (getFLAGS(insn)) {
+    default: return UNSUPPORTED;
+    case 0:  return MBlaze::MUL;
+    case 1:  return MBlaze::MULH;
+    case 2:  return MBlaze::MULHSU;
+    case 3:  return MBlaze::MULHU;
+    }
+}
+
+static unsigned decodeSEXT(uint32_t insn) {
+    switch (getIMM(insn)) {
+    default:   return UNSUPPORTED;
+    case 0x60: return MBlaze::SEXT8;
+    case 0x68: return MBlaze::WIC;
+    case 0x64: return MBlaze::WDC;
+    case 0x66: return MBlaze::WDCC;
+    case 0x74: return MBlaze::WDCF;
+    case 0x61: return MBlaze::SEXT16;
+    case 0x41: return MBlaze::SRL;
+    case 0x21: return MBlaze::SRC;
+    case 0x01: return MBlaze::SRA;
+    }
+}
+
+static unsigned decodeBEQ(uint32_t insn) {
+    switch (getRD(insn)) {
+    default:    return UNSUPPORTED;
+    case 0x00:  return MBlaze::BEQ;
+    case 0x10:  return MBlaze::BEQD;
+    case 0x05:  return MBlaze::BGE;
+    case 0x15:  return MBlaze::BGED;
+    case 0x04:  return MBlaze::BGT;
+    case 0x14:  return MBlaze::BGTD;
+    case 0x03:  return MBlaze::BLE;
+    case 0x13:  return MBlaze::BLED;
+    case 0x02:  return MBlaze::BLT;
+    case 0x12:  return MBlaze::BLTD;
+    case 0x01:  return MBlaze::BNE;
+    case 0x11:  return MBlaze::BNED;
+    }
+}
+
+static unsigned decodeBEQI(uint32_t insn) {
+    switch (getRD(insn)) {
+    default:    return UNSUPPORTED;
+    case 0x00:  return MBlaze::BEQI;
+    case 0x10:  return MBlaze::BEQID;
+    case 0x05:  return MBlaze::BGEI;
+    case 0x15:  return MBlaze::BGEID;
+    case 0x04:  return MBlaze::BGTI;
+    case 0x14:  return MBlaze::BGTID;
+    case 0x03:  return MBlaze::BLEI;
+    case 0x13:  return MBlaze::BLEID;
+    case 0x02:  return MBlaze::BLTI;
+    case 0x12:  return MBlaze::BLTID;
+    case 0x01:  return MBlaze::BNEI;
+    case 0x11:  return MBlaze::BNEID;
+    }
+}
+
+static unsigned decodeBR(uint32_t insn) {
+    switch ((insn>>16)&0x1F) {
+    default:   return UNSUPPORTED;
+    case 0x00: return MBlaze::BR;
+    case 0x08: return MBlaze::BRA;
+    case 0x0C: return MBlaze::BRK;
+    case 0x10: return MBlaze::BRD;
+    case 0x14: return MBlaze::BRLD;
+    case 0x18: return MBlaze::BRAD;
+    case 0x1C: return MBlaze::BRALD;
+    }
+}
+
+static unsigned decodeBRI(uint32_t insn) {
+    switch ((insn>>16)&0x1F) {
+    default:   return UNSUPPORTED;
+    case 0x00: return MBlaze::BRI;
+    case 0x08: return MBlaze::BRAI;
+    case 0x0C: return MBlaze::BRKI;
+    case 0x10: return MBlaze::BRID;
+    case 0x14: return MBlaze::BRLID;
+    case 0x18: return MBlaze::BRAID;
+    case 0x1C: return MBlaze::BRALID;
+    }
+}
+
+static unsigned decodeBSRL(uint32_t insn) {
+    switch ((insn>>9)&0x3) {
+    default:  return UNSUPPORTED;
+    case 0x2: return MBlaze::BSLL;
+    case 0x1: return MBlaze::BSRA;
+    case 0x0: return MBlaze::BSRL;
+    }
+}
+
+static unsigned decodeBSRLI(uint32_t insn) {
+    switch ((insn>>9)&0x3) {
+    default:  return UNSUPPORTED;
+    case 0x2: return MBlaze::BSLLI;
+    case 0x1: return MBlaze::BSRAI;
+    case 0x0: return MBlaze::BSRLI;
+    }
+}
+
+static unsigned decodeRSUBK(uint32_t insn) {
+    switch (getFLAGS(insn)) {
+    default:  return UNSUPPORTED;
+    case 0x0: return MBlaze::RSUBK;
+    case 0x1: return MBlaze::CMP;
+    case 0x3: return MBlaze::CMPU;
+    }
+}
+
+static unsigned decodeFADD(uint32_t insn) {
+    switch (getFLAGS(insn)) {
+    default:    return UNSUPPORTED;
+    case 0x000: return MBlaze::FADD;
+    case 0x080: return MBlaze::FRSUB;
+    case 0x100: return MBlaze::FMUL;
+    case 0x180: return MBlaze::FDIV;
+    case 0x200: return MBlaze::FCMP_UN;
+    case 0x210: return MBlaze::FCMP_LT;
+    case 0x220: return MBlaze::FCMP_EQ;
+    case 0x230: return MBlaze::FCMP_LE;
+    case 0x240: return MBlaze::FCMP_GT;
+    case 0x250: return MBlaze::FCMP_NE;
+    case 0x260: return MBlaze::FCMP_GE;
+    case 0x280: return MBlaze::FLT;
+    case 0x300: return MBlaze::FINT;
+    case 0x380: return MBlaze::FSQRT;
+    }
+}
+
+static unsigned decodeGET(uint32_t insn) {
+    switch ((insn>>10)&0x3F) {
+    default:   return UNSUPPORTED;
+    case 0x00: return MBlaze::GET;
+    case 0x01: return MBlaze::EGET;
+    case 0x02: return MBlaze::AGET;
+    case 0x03: return MBlaze::EAGET;
+    case 0x04: return MBlaze::TGET;
+    case 0x05: return MBlaze::TEGET;
+    case 0x06: return MBlaze::TAGET;
+    case 0x07: return MBlaze::TEAGET;
+    case 0x08: return MBlaze::CGET;
+    case 0x09: return MBlaze::ECGET;
+    case 0x0A: return MBlaze::CAGET;
+    case 0x0B: return MBlaze::ECAGET;
+    case 0x0C: return MBlaze::TCGET;
+    case 0x0D: return MBlaze::TECGET;
+    case 0x0E: return MBlaze::TCAGET;
+    case 0x0F: return MBlaze::TECAGET;
+    case 0x10: return MBlaze::NGET;
+    case 0x11: return MBlaze::NEGET;
+    case 0x12: return MBlaze::NAGET;
+    case 0x13: return MBlaze::NEAGET;
+    case 0x14: return MBlaze::TNGET;
+    case 0x15: return MBlaze::TNEGET;
+    case 0x16: return MBlaze::TNAGET;
+    case 0x17: return MBlaze::TNEAGET;
+    case 0x18: return MBlaze::NCGET;
+    case 0x19: return MBlaze::NECGET;
+    case 0x1A: return MBlaze::NCAGET;
+    case 0x1B: return MBlaze::NECAGET;
+    case 0x1C: return MBlaze::TNCGET;
+    case 0x1D: return MBlaze::TNECGET;
+    case 0x1E: return MBlaze::TNCAGET;
+    case 0x1F: return MBlaze::TNECAGET;
+    case 0x20: return MBlaze::PUT;
+    case 0x22: return MBlaze::APUT;
+    case 0x24: return MBlaze::TPUT;
+    case 0x26: return MBlaze::TAPUT;
+    case 0x28: return MBlaze::CPUT;
+    case 0x2A: return MBlaze::CAPUT;
+    case 0x2C: return MBlaze::TCPUT;
+    case 0x2E: return MBlaze::TCAPUT;
+    case 0x30: return MBlaze::NPUT;
+    case 0x32: return MBlaze::NAPUT;
+    case 0x34: return MBlaze::TNPUT;
+    case 0x36: return MBlaze::TNAPUT;
+    case 0x38: return MBlaze::NCPUT;
+    case 0x3A: return MBlaze::NCAPUT;
+    case 0x3C: return MBlaze::TNCPUT;
+    case 0x3E: return MBlaze::TNCAPUT;
+    }
+}
+
+static unsigned decodeGETD(uint32_t insn) {
+    switch ((insn>>5)&0x3F) {
+    default:   return UNSUPPORTED;
+    case 0x00: return MBlaze::GETD;
+    case 0x01: return MBlaze::EGETD;
+    case 0x02: return MBlaze::AGETD;
+    case 0x03: return MBlaze::EAGETD;
+    case 0x04: return MBlaze::TGETD;
+    case 0x05: return MBlaze::TEGETD;
+    case 0x06: return MBlaze::TAGETD;
+    case 0x07: return MBlaze::TEAGETD;
+    case 0x08: return MBlaze::CGETD;
+    case 0x09: return MBlaze::ECGETD;
+    case 0x0A: return MBlaze::CAGETD;
+    case 0x0B: return MBlaze::ECAGETD;
+    case 0x0C: return MBlaze::TCGETD;
+    case 0x0D: return MBlaze::TECGETD;
+    case 0x0E: return MBlaze::TCAGETD;
+    case 0x0F: return MBlaze::TECAGETD;
+    case 0x10: return MBlaze::NGETD;
+    case 0x11: return MBlaze::NEGETD;
+    case 0x12: return MBlaze::NAGETD;
+    case 0x13: return MBlaze::NEAGETD;
+    case 0x14: return MBlaze::TNGETD;
+    case 0x15: return MBlaze::TNEGETD;
+    case 0x16: return MBlaze::TNAGETD;
+    case 0x17: return MBlaze::TNEAGETD;
+    case 0x18: return MBlaze::NCGETD;
+    case 0x19: return MBlaze::NECGETD;
+    case 0x1A: return MBlaze::NCAGETD;
+    case 0x1B: return MBlaze::NECAGETD;
+    case 0x1C: return MBlaze::TNCGETD;
+    case 0x1D: return MBlaze::TNECGETD;
+    case 0x1E: return MBlaze::TNCAGETD;
+    case 0x1F: return MBlaze::TNECAGETD;
+    case 0x20: return MBlaze::PUTD;
+    case 0x22: return MBlaze::APUTD;
+    case 0x24: return MBlaze::TPUTD;
+    case 0x26: return MBlaze::TAPUTD;
+    case 0x28: return MBlaze::CPUTD;
+    case 0x2A: return MBlaze::CAPUTD;
+    case 0x2C: return MBlaze::TCPUTD;
+    case 0x2E: return MBlaze::TCAPUTD;
+    case 0x30: return MBlaze::NPUTD;
+    case 0x32: return MBlaze::NAPUTD;
+    case 0x34: return MBlaze::TNPUTD;
+    case 0x36: return MBlaze::TNAPUTD;
+    case 0x38: return MBlaze::NCPUTD;
+    case 0x3A: return MBlaze::NCAPUTD;
+    case 0x3C: return MBlaze::TNCPUTD;
+    case 0x3E: return MBlaze::TNCAPUTD;
+    }
+}
+
+static unsigned decodeIDIV(uint32_t insn) {
+    switch (insn&0x3) {
+    default:  return UNSUPPORTED;
+    case 0x0: return MBlaze::IDIV;
+    case 0x2: return MBlaze::IDIVU;
+    }
+}
+
+static unsigned decodeLW(uint32_t insn) {
+    switch ((insn>>9)&0x3) {
+    default:  return UNSUPPORTED;
+    case 0x0: return MBlaze::LW;
+    case 0x1: return MBlaze::LWR;
+    case 0x2: return MBlaze::LWX;
+    }
+}
+
+static unsigned decodeSW(uint32_t insn) {
+    switch ((insn>>9)&0x3) {
+    default:  return UNSUPPORTED;
+    case 0x0: return MBlaze::SW;
+    case 0x1: return MBlaze::SWR;
+    case 0x2: return MBlaze::SWX;
+    }
+}
+
+static unsigned decodeMFS(uint32_t insn) {
+    switch ((insn>>15)&0x1) {
+    default:   return UNSUPPORTED;
+    case 0x0:
+      switch ((insn>>16)&0x1F) {
+      default:   return UNSUPPORTED;
+      case 0x22: return MBlaze::MSRCLR;
+      case 0x20: return MBlaze::MSRSET;
+      }
+    case 0x1:
+      switch ((insn>>14)&0x1) {
+      default:   return UNSUPPORTED;
+      case 0x0: return MBlaze::MFS;
+      case 0x1: return MBlaze::MTS;
+      }
+    }
+}
+
+static unsigned decodeOR(uint32_t insn) {
+    switch (getFLAGS(insn)) {
+    default:    return UNSUPPORTED;
+    case 0x000: return MBlaze::OR;
+    case 0x400: return MBlaze::PCMPBF;
+    }
+}
+
+static unsigned decodeXOR(uint32_t insn) {
+    switch (getFLAGS(insn)) {
+    default:    return UNSUPPORTED;
+    case 0x000: return MBlaze::OR;
+    case 0x400: return MBlaze::PCMPEQ;
+    }
+}
+
+static unsigned decodeANDN(uint32_t insn) {
+    switch (getFLAGS(insn)) {
+    default:    return UNSUPPORTED;
+    case 0x000: return MBlaze::OR;
+    case 0x400: return MBlaze::PCMPNE;
+    }
+}
+
+static unsigned decodeRTSD(uint32_t insn) {
+    switch ((insn>>21)&0x1F) {
+    default:   return UNSUPPORTED;
+    case 0x10: return MBlaze::RTSD;
+    case 0x11: return MBlaze::RTID;
+    case 0x12: return MBlaze::RTBD;
+    case 0x14: return MBlaze::RTED;
+    }
+}
+
+static unsigned getOPCODE( uint32_t insn ) {
+  unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
+  switch (opcode) {
+  case MBlaze::MUL:     return decodeMUL(insn);
+  case MBlaze::SEXT8:   return decodeSEXT(insn);
+  case MBlaze::BEQ:     return decodeBEQ(insn);
+  case MBlaze::BEQI:    return decodeBEQI(insn);
+  case MBlaze::BR:      return decodeBR(insn);
+  case MBlaze::BRI:     return decodeBRI(insn);
+  case MBlaze::BSRL:    return decodeBSRL(insn);
+  case MBlaze::BSRLI:   return decodeBSRLI(insn);
+  case MBlaze::RSUBK:   return decodeRSUBK(insn);
+  case MBlaze::FADD:    return decodeFADD(insn);
+  case MBlaze::GET:     return decodeGET(insn);
+  case MBlaze::GETD:    return decodeGETD(insn);
+  case MBlaze::IDIV:    return decodeIDIV(insn);
+  case MBlaze::LW:      return decodeLW(insn);
+  case MBlaze::SW:      return decodeSW(insn);
+  case MBlaze::MFS:     return decodeMFS(insn);
+  case MBlaze::OR:      return decodeOR(insn);
+  case MBlaze::XOR:     return decodeXOR(insn);
+  case MBlaze::ANDN:    return decodeANDN(insn);
+  case MBlaze::RTSD:    return decodeRTSD(insn);
+  default:              return opcode;
+  }
+}
+
+EDInstInfo *MBlazeDisassembler::getEDInfo() const {
+  return instInfoMBlaze;
+}
+
+//
+// Public interface for the disassembler
+//
+
+bool MBlazeDisassembler::getInstruction(MCInst &instr,
+                                        uint64_t &size,
+                                        const MemoryObject &region,
+                                        uint64_t address,
+                                        raw_ostream &vStream) const {
+  // The machine instruction.
+  uint32_t insn;
+  uint8_t bytes[4];
+  
+  // We want to read exactly 4 bytes of data.
+  if (region.readBytes(address, 4, (uint8_t*)bytes, NULL) == -1)
+    return false;
+
+  // Encoded as a big-endian 32-bit word in the stream.
+  insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
+
+  // Get the MCInst opcode from the binary instruction and make sure
+  // that it is a valid instruction.
+  unsigned opcode = getOPCODE( insn );
+  if( opcode == UNSUPPORTED )
+    return false;
+
+  instr.setOpcode(opcode);
+
+  uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
+  switch( (tsFlags & MBlazeII::FormMask) ) {
+  default: 
+    errs() << "Opcode:      " << MBlazeInsts[opcode].Name << "\n";
+    errs() << "Flags:       "; errs().write_hex( tsFlags ); errs() << "\n";
+    return false;
+
+  case MBlazeII::FRRR:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
+    break;
+
+  case MBlazeII::FRRI:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
+    break;
+
+  case MBlazeII::FCRR:
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
+    break;
+
+  case MBlazeII::FCRI:
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
+    break;
+
+  case MBlazeII::FRCR:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
+    break;
+
+  case MBlazeII::FRCI:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
+    break;
+
+  case MBlazeII::FCCR:
+    instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
+    break;
+
+  case MBlazeII::FCCI:
+    instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
+    break;
+
+  case MBlazeII::FRRCI:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getSHT(insn) ) );
+    break;
+
+  case MBlazeII::FRRC:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    break;
+
+  case MBlazeII::FRCX:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) );
+    break;
+
+  case MBlazeII::FRCS:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getRS(insn) ) );
+    break;
+
+  case MBlazeII::FCRCS:
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getRS(insn) ) );
+    break;
+
+  case MBlazeII::FCRCX:
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) );
+    break;
+
+  case MBlazeII::FCX:
+    instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) );
+    break;
+
+  case MBlazeII::FCR:
+    instr.addOperand( MCOperand::CreateReg( getRB(insn) ) );
+    break;
+
+  case MBlazeII::FRIR:
+    instr.addOperand( MCOperand::CreateReg( getRD(insn) ) );
+    instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) );
+    instr.addOperand( MCOperand::CreateReg( getRA(insn) ) );
+    break;
+  }
+
+  return true;
+}
+
+static MCDisassembler *createMBlazeDisassembler(const Target &T) {
+  return new MBlazeDisassembler;
+}
+
+extern "C" void LLVMInitializeMBlazeDisassembler() { 
+  // Register the disassembler.
+  TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget, 
+                                         createMBlazeDisassembler);
+}
diff --git a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h
new file mode 100644
index 0000000..d05eced
--- /dev/null
+++ b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h
@@ -0,0 +1,55 @@
+//===- MBlazeDisassembler.h - Disassembler for MicroBlaze  ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is part of the MBlaze Disassembler. It it the header for
+// MBlazeDisassembler, a subclass of MCDisassembler.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MBLAZEDISASSEMBLER_H
+#define MBLAZEDISASSEMBLER_H
+
+#include "llvm/MC/MCDisassembler.h"
+
+struct InternalInstruction;
+
+namespace llvm {
+  
+class MCInst;
+class MemoryObject;
+class raw_ostream;
+
+struct EDInstInfo;
+  
+/// MBlazeDisassembler - Disassembler for all MBlaze platforms.
+class MBlazeDisassembler : public MCDisassembler {
+public:
+  /// Constructor     - Initializes the disassembler.
+  ///
+  MBlazeDisassembler() :
+    MCDisassembler() {
+  }
+
+  ~MBlazeDisassembler() {
+  }
+
+  /// getInstruction - See MCDisassembler.
+  bool getInstruction(MCInst &instr,
+                      uint64_t &size,
+                      const MemoryObject &region,
+                      uint64_t address,
+                      raw_ostream &vStream) const;
+
+  /// getEDInfo - See MCDisassembler.
+  EDInstInfo *getEDInfo() const;
+};
+
+} // namespace llvm
+  
+#endif
diff --git a/lib/Target/MBlaze/Disassembler/Makefile b/lib/Target/MBlaze/Disassembler/Makefile
new file mode 100644
index 0000000..0530b32
--- /dev/null
+++ b/lib/Target/MBlaze/Disassembler/Makefile
@@ -0,0 +1,16 @@
+##===- lib/Target/MBlaze/Disassembler/Makefile -------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME = LLVMMBlazeDisassembler
+
+# Hack: we need to include 'main' MBlaze target directory to grab headers
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp
index be9de6d..8918b48 100644
--- a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp
+++ b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp
@@ -7,7 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Simple pass to fills delay slots with NOPs.
+// A pass that attempts to fill instructions with delay slots. If no
+// instructions can be moved into the delay slot then a NOP is placed there.
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Target/MBlaze/MBlazeInstrFSL.td b/lib/Target/MBlaze/MBlazeInstrFSL.td
index c896be9..0bdd02c 100644
--- a/lib/Target/MBlaze/MBlazeInstrFSL.td
+++ b/lib/Target/MBlaze/MBlazeInstrFSL.td
@@ -11,7 +11,7 @@
 // FSL Instruction Formats
 //===----------------------------------------------------------------------===//
 class FSLGet<bits<6> op, bits<5> flags, string instr_asm, Intrinsic OpNode> :
-             MBlazeInst<op, FFSL, (outs GPR:$dst), (ins fslimm:$b),
+             MBlazeInst<op, FRCX, (outs GPR:$dst), (ins fslimm:$b),
                         !strconcat(instr_asm, " $dst, $b"),
                         [(set GPR:$dst, (OpNode immZExt4:$b))],IIAlu>
 {
@@ -27,7 +27,7 @@
 }
 
 class FSLGetD<bits<6> op, bits<5> flags, string instr_asm, Intrinsic OpNode> :
-              MBlazeInst<op, FFSLD, (outs GPR:$dst), (ins GPR:$b),
+              MBlazeInst<op, FRCR, (outs GPR:$dst), (ins GPR:$b),
                          !strconcat(instr_asm, " $dst, $b"),
                          [(set GPR:$dst, (OpNode GPR:$b))], IIAlu>
 {
@@ -43,7 +43,7 @@
 }
 
 class FSLPut<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> :
-             MBlazeInst<op, FFSL, (outs), (ins GPR:$v, fslimm:$b),
+             MBlazeInst<op, FCRCX, (outs), (ins GPR:$v, fslimm:$b),
                         !strconcat(instr_asm, " $v, $b"),
                         [(OpNode GPR:$v, immZExt4:$b)], IIAlu>
 {
@@ -59,7 +59,7 @@
 }
 
 class FSLPutD<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> :
-              MBlazeInst<op, FFSLD, (outs), (ins GPR:$v, GPR:$b),
+              MBlazeInst<op, FCRR, (outs), (ins GPR:$v, GPR:$b),
                          !strconcat(instr_asm, " $v, $b"),
                          [(OpNode GPR:$v, GPR:$b)], IIAlu>
 {
@@ -75,7 +75,7 @@
 }
 
 class FSLPutT<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> :
-              MBlazeInst<op, FFSLT, (outs), (ins fslimm:$b),
+              MBlazeInst<op, FCX, (outs), (ins fslimm:$b),
                          !strconcat(instr_asm, " $b"),
                          [(OpNode immZExt4:$b)], IIAlu>
 {
@@ -90,7 +90,7 @@
 }
 
 class FSLPutTD<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> :
-               MBlazeInst<op, FFSLTD, (outs), (ins GPR:$b),
+               MBlazeInst<op, FCR, (outs), (ins GPR:$b),
                           !strconcat(instr_asm, " $b"),
                           [(OpNode GPR:$b)], IIAlu>
 {
diff --git a/lib/Target/MBlaze/MBlazeInstrFormats.td b/lib/Target/MBlaze/MBlazeInstrFormats.td
index 595ef1d..71e3b12 100644
--- a/lib/Target/MBlaze/MBlazeInstrFormats.td
+++ b/lib/Target/MBlaze/MBlazeInstrFormats.td
@@ -15,17 +15,24 @@
 }
 
 def FPseudo : Format<0>;
-def FRRR    : Format<1>;
-def FRRI    : Format<2>;
-def FRIR    : Format<3>;
-def FFSL    : Format<4>;
-def FFSLD   : Format<5>;
-def FFSLT   : Format<6>;
-def FFSLTD  : Format<7>;
-def FR      : Format<8>;
-def FI      : Format<9>;
-def FRR     : Format<10>;
-def FRI     : Format<11>;
+def FRRR    : Format<1>;  // ADD, RSUB, OR, etc.
+def FRRI    : Format<2>;  // ADDI, RSUBI, ORI, etc.
+def FCRR    : Format<3>;  // PUTD, WDC, WIC, BEQ, BNE, BGE, etc.
+def FCRI    : Format<4>;  // RTID, RTED, RTSD, BEQI, BNEI, BGEI, etc.
+def FRCR    : Format<5>;  // BRLD, BRALD, GETD
+def FRCI    : Format<6>;  // BRLID, BRALID, MSRCLR, MSRSET
+def FCCR    : Format<7>;  // BR, BRA, BRD, etc.
+def FCCI    : Format<8>;  // IMM, BRI, BRAI, BRID, etc.
+def FRRCI   : Format<9>;  // BSRLI, BSRAI, BSLLI
+def FRRC    : Format<10>; // SEXT8, SEXT16, SRA, SRC, SRL, FLT, FINT, FSQRT
+def FRCX    : Format<11>; // GET
+def FRCS    : Format<12>; // MFS
+def FCRCS   : Format<13>; // MTS
+def FCRCX   : Format<14>; // PUT
+def FCX     : Format<15>; // TPUT
+def FCR     : Format<16>; // TPUTD
+def FRIR    : Format<17>; // RSUBI
+def FC      : Format<18>; // NOP
 
 //===----------------------------------------------------------------------===//
 //  Describe MBlaze instructions format
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.h b/lib/Target/MBlaze/MBlazeInstrInfo.h
index eda16cc..d2cc921 100644
--- a/lib/Target/MBlaze/MBlazeInstrInfo.h
+++ b/lib/Target/MBlaze/MBlazeInstrInfo.h
@@ -138,21 +138,26 @@
     // PseudoFrm - This represents an instruction that is a pseudo instruction
     // or one that has not been implemented yet.  It is illegal to code generate
     // it, but tolerated for intermediate implementation stages.
-    Pseudo         = 0,
-
-    RegRegReg      = 1,
-    RegRegImm      = 2,
-    RegImmReg      = 3,
-    FSL            = 4,
-    FSLD           = 5,
-    FSLT           = 6,
-    FSLTD          = 7,
-    Reg            = 8,
-    Imm            = 9,
-    RegReg         = 10,
-    RegImm         = 11,
-
-    FormMask       = 63
+    FPseudo = 0,
+    FRRR,
+    FRRI,
+    FCRR,
+    FCRI,
+    FRCR,
+    FRCI,
+    FCCR,
+    FCCI,
+    FRRCI,
+    FRRC,
+    FRCX,
+    FRCS,
+    FCRCS,
+    FCRCX,
+    FCX,
+    FCR,
+    FRIR,
+    FC,
+    FormMask = 63
 
     //===------------------------------------------------------------------===//
     // MBlaze Specific MachineOperand flags.
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td
index c10f4a8..277fb6f 100644
--- a/lib/Target/MBlaze/MBlazeInstrInfo.td
+++ b/lib/Target/MBlaze/MBlazeInstrInfo.td
@@ -203,6 +203,11 @@
                 [(set GPR:$dst, (OpNode GPR:$b, immZExt16:$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"),
+                 [], IIAlu>;
+
 //===----------------------------------------------------------------------===//
 // Memory Access Instructions
 //===----------------------------------------------------------------------===//
@@ -211,6 +216,11 @@
                !strconcat(instr_asm, "   $dst, $addr"),
                [(set (i32 GPR:$dst), (OpNode xaddr:$addr))], IILoad>;
 
+class LoadW<bits<6> op, bits<11> flags, string instr_asm> :
+            TA<op, flags, (outs GPR:$dst), (ins memrr:$addr),
+               !strconcat(instr_asm, "   $dst, $addr"),
+               [], IILoad>;
+
 class LoadMI<bits<6> op, string instr_asm, PatFrag OpNode> :
              TBR<op, (outs GPR:$dst), (ins memri:$addr),
                  !strconcat(instr_asm, "   $dst, $addr"),
@@ -221,6 +231,11 @@
                 !strconcat(instr_asm, "   $dst, $addr"),
                 [(OpNode (i32 GPR:$dst), xaddr:$addr)], IIStore>;
 
+class StoreW<bits<6> op, bits<11> flags, string instr_asm> :
+             TA<op, flags, (outs), (ins GPR:$dst, memrr:$addr),
+                !strconcat(instr_asm, "   $dst, $addr"),
+                [], IIStore>;
+
 class StoreMI<bits<6> op, string instr_asm, PatFrag OpNode> :
               TBR<op, (outs), (ins GPR:$dst, memri:$addr),
                   !strconcat(instr_asm, "   $dst, $addr"),
@@ -231,10 +246,11 @@
 //===----------------------------------------------------------------------===//
 class Branch<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> :
              TA<op, flags, (outs), (ins GPR:$target),
-                 !strconcat(instr_asm, "   $target"),
-                 [], IIBranch> {
+                !strconcat(instr_asm, "   $target"),
+                [], IIBranch> {
   let rd = 0x0;
   let ra = br;
+  let Form = FCCR;
 }
 
 class BranchI<bits<6> op, bits<5> br, string instr_asm> :
@@ -243,25 +259,26 @@
                  [], IIBranch> {
   let rd = 0;
   let ra = br;
+  let Form = FCCI;
 }
 
 //===----------------------------------------------------------------------===//
 // Branch and Link Instructions
 //===----------------------------------------------------------------------===//
 class BranchL<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> :
-              TA<op, flags, (outs), (ins GPR:$target),
-                 !strconcat(instr_asm, "   r15, $target"),
+              TA<op, flags, (outs), (ins GPR:$link, GPR:$target),
+                 !strconcat(instr_asm, "   $link, $target"),
                  [], IIBranch> {
-  let rd = 15;
   let ra = br;
+  let Form = FRCR;
 }
 
 class BranchLI<bits<6> op, bits<5> br, string instr_asm> :
-               TB<op, (outs), (ins calltarget:$target),
-                  !strconcat(instr_asm, "   r15, $target"),
+               TB<op, (outs), (ins GPR:$link, calltarget:$target),
+                  !strconcat(instr_asm, "   $link, $target"),
                   [], IIBranch> {
-  let rd = 15;
   let ra = br;
+  let Form = FRCI;
 }
 
 //===----------------------------------------------------------------------===//
@@ -274,6 +291,7 @@
                  !strconcat(instr_asm, "   $a, $b, $offset"),
                  [], IIBranch> {
   let rd = br;
+  let Form = FCRR;
 }
 
 class BranchCI<bits<6> op, bits<5> br, string instr_asm, PatFrag cond_op> :
@@ -281,6 +299,7 @@
                   !strconcat(instr_asm, "   $a, $offset"),
                   [], IIBranch> {
   let rd = br;
+  let Form = FCRI;
 }
 
 //===----------------------------------------------------------------------===//
@@ -295,6 +314,9 @@
   def AND    :  Logic<0x21, 0x000, "and    ", and>;
   def OR     :  Logic<0x20, 0x000, "or     ", or>;
   def XOR    :  Logic<0x22, 0x000, "xor    ", xor>;
+  def PCMPBF : PatCmp<0x20, 0x400, "pcmpbf ">;
+  def PCMPEQ : PatCmp<0x23, 0x400, "pcmpeq ">;
+  def PCMPNE : PatCmp<0x22, 0x400, "pcmpne ">;
 }
 
 let isAsCheapAsAMove = 1 in {
@@ -364,7 +386,10 @@
 let canFoldAsLoad = 1, isReMaterializable = 1 in {
   def LBU  :  LoadM<0x30, "lbu    ", zextloadi8>;
   def LHU  :  LoadM<0x31, "lhu    ", zextloadi16>;
-  def LW   :  LoadM<0x32, "lw     ", load>;
+
+  def LW   :  LoadW<0x32, 0x0, "lw     ">;
+  def LWR  :  LoadW<0x32, 0x2, "lwr    ">;
+  def LWX  :  LoadW<0x32, 0x4, "lwx    ">;
 
   def LBUI : LoadMI<0x38, "lbui   ", zextloadi8>;
   def LHUI : LoadMI<0x39, "lhui   ", zextloadi16>;
@@ -373,7 +398,10 @@
 
   def SB  :  StoreM<0x34, "sb     ", truncstorei8>;
   def SH  :  StoreM<0x35, "sh     ", truncstorei16>;
-  def SW  :  StoreM<0x36, "sw     ", store>;
+
+  def SW  :  StoreW<0x36, 0x0, "sw     ">;
+  def SWR :  StoreW<0x36, 0x2, "swr    ">;
+  def SWX :  StoreW<0x36, 0x4, "swx    ">;
 
   def SBI : StoreMI<0x3C, "sbi    ", truncstorei8>;
   def SHI : StoreMI<0x3D, "shi    ", truncstorei16>;
@@ -383,13 +411,12 @@
 // MBlaze branch instructions
 //===----------------------------------------------------------------------===//
 
-let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1, 
-    Form = FI in {
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
   def BRI    :  BranchI<0x2E, 0x00, "bri    ">;
   def BRAI   :  BranchI<0x2E, 0x08, "brai   ">;
 }
 
-let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, Form = FRI in {
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
   def BEQI   : BranchCI<0x2F, 0x00, "beqi   ", seteq>;
   def BNEI   : BranchCI<0x2F, 0x01, "bnei   ", setne>;
   def BLTI   : BranchCI<0x2F, 0x02, "blti   ", setlt>;
@@ -399,13 +426,12 @@
 }
 
 let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1,
-    isBarrier = 1, Form = FR in {
+    isBarrier = 1 in {
   def BR     :   Branch<0x26, 0x00, 0x000, "br     ">;
   def BRA    :   Branch<0x26, 0x08, 0x000, "bra    ">;
 }
 
-let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1,
-    Form = FRR in {
+let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
   def BEQ    :  BranchC<0x27, 0x00, 0x000, "beq    ", seteq>;
   def BNE    :  BranchC<0x27, 0x01, 0x000, "bne    ", setne>;
   def BLT    :  BranchC<0x27, 0x02, 0x000, "blt    ", setlt>;
@@ -415,13 +441,12 @@
 }
 
 let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1,
-    isBarrier = 1, Form = FI in {
+    isBarrier = 1 in {
   def BRID   :  BranchI<0x2E, 0x10, "brid   ">;
   def BRAID  :  BranchI<0x2E, 0x18, "braid  ">;
 }
 
-let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1,
-    Form = FRI in {
+let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1 in {
   def BEQID  : BranchCI<0x2F, 0x10, "beqid  ", seteq>;
   def BNEID  : BranchCI<0x2F, 0x11, "bneid  ", setne>;
   def BLTID  : BranchCI<0x2F, 0x12, "bltid  ", setlt>;
@@ -430,14 +455,14 @@
   def BGEID  : BranchCI<0x2F, 0x15, "bgeid  ", setge>;
 }
 
-let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, Form = FR,
+let isBranch = 1, isIndirectBranch = 1, isTerminator = 1,
     hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1 in {
   def BRD    :   Branch<0x26, 0x10, 0x000, "brd    ">;
   def BRAD   :   Branch<0x26, 0x18, 0x000, "brad   ">;
 }
 
 let isBranch = 1, isIndirectBranch = 1, isTerminator = 1,
-    hasDelaySlot = 1, hasCtrlDep = 1, Form = FRR in {
+    hasDelaySlot = 1, hasCtrlDep = 1 in {
   def BEQD   :  BranchC<0x27, 0x10, 0x000, "beqd   ", seteq>;
   def BNED   :  BranchC<0x27, 0x11, 0x000, "bned   ", setne>;
   def BLTD   :  BranchC<0x27, 0x12, 0x000, "bltd   ", setlt>;
@@ -446,7 +471,7 @@
   def BGED   :  BranchC<0x27, 0x15, 0x000, "bged   ", setge>;
 }
 
-let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1, Form = FI,
+let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1,
     Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
     Uses = [R1,R5,R6,R7,R8,R9,R10] in {
   def BRLID  : BranchLI<0x2E, 0x14, "brlid  ">;
@@ -454,7 +479,7 @@
 }
 
 let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isIndirectBranch = 1,
-    isBarrier = 1, Form = FR,
+    isBarrier = 1,
     Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
     Uses = [R1,R5,R6,R7,R8,R9,R10] in {
   def BRLD   : BranchL<0x26, 0x14, 0x000, "brld   ">;
@@ -462,10 +487,34 @@
 }
 
 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
-    hasCtrlDep=1, rd=0x10, imm16=0x8, Form=FR in {
-  def RTSD   : TB<0x2D, (outs), (ins GPR:$target),
-                  "rtsd      $target, 8",
-                  [(MBlazeRet GPR:$target)],
+    hasCtrlDep=1, rd=0x10, Form=FCRI in {
+  def RTSD   : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
+                  "rtsd      $target, $imm",
+                  [], 
+                  IIBranch>;
+}
+
+let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
+    hasCtrlDep=1, rd=0x11, Form=FCRI in {
+  def RTID   : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
+                  "rtsd      $target, $imm",
+                  [], 
+                  IIBranch>;
+}
+
+let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
+    hasCtrlDep=1, rd=0x12, Form=FCRI in {
+  def RTBD   : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
+                  "rtsd      $target, $imm",
+                  [], 
+                  IIBranch>;
+}
+
+let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
+    hasCtrlDep=1, rd=0x14, Form=FCRI in {
+  def RTED   : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
+                  "rtsd      $target, $imm",
+                  [], 
                   IIBranch>;
 }
 
@@ -474,7 +523,7 @@
 //===----------------------------------------------------------------------===//
 
 let neverHasSideEffects = 1 in {
-  def NOP :  MBlazeInst< 0x20, FRRR, (outs), (ins), "nop    ", [], IIAlu>;
+  def NOP :  MBlazeInst< 0x20, FC, (outs), (ins), "nop    ", [], IIAlu>;
 }
 
 let usesCustomInserter = 1 in {
@@ -520,6 +569,38 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Misc. instructions
+//===----------------------------------------------------------------------===//
+def MFS : MBlazeInst<0x25, FPseudo, (outs), (ins), "mfs", [], IIAlu> {
+}
+
+def MTS : MBlazeInst<0x25, FPseudo, (outs), (ins), "mts", [], IIAlu> {
+}
+
+def MSRSET : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrset", [], IIAlu> {
+}
+
+def MSRCLR : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrclr", [], IIAlu> {
+}
+
+let rd=0x0, Form=FCRR in {
+  def WDC  : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b), 
+                "wdc       $a, $b", [], IIAlu>;
+  def WDCF : TA<0x24, 0x74, (outs), (ins GPR:$a, GPR:$b),
+                "wdc.flush $a, $b", [], IIAlu>;
+  def WDCC : TA<0x24, 0x66, (outs), (ins GPR:$a, GPR:$b),
+                "wdc.clear $a, $b", [], IIAlu>;
+  def WIC  : TA<0x24, 0x68, (outs), (ins GPR:$a, GPR:$b),
+                "wic       $a, $b", [], IIAlu>;
+}
+
+def BRK  :  Branch<0x26, 0x0C, 0x000, "brk    ">;
+def BRKI : BranchI<0x2E, 0x0C, "brki   ">;
+
+def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm), 
+                     "imm       $imm", [], IIAlu>;
+
+//===----------------------------------------------------------------------===//
 //  Arbitrary patterns that map to one or more instructions
 //===----------------------------------------------------------------------===//
 
@@ -536,9 +617,14 @@
 def : Pat<(sext_inreg GPR:$src, i8),  (SEXT8 GPR:$src)>;
 
 // Call
-def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)), (BRLID tglobaladdr:$dst)>;
-def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),(BRLID texternalsym:$dst)>;
-def : Pat<(MBlazeJmpLink GPR:$dst), (BRLD GPR:$dst)>;
+def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)),
+          (BRLID (i32 R15), tglobaladdr:$dst)>;
+
+def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),
+          (BRLID (i32 R15), texternalsym:$dst)>;
+
+def : Pat<(MBlazeJmpLink GPR:$dst),
+          (BRLD (i32 R15), GPR:$dst)>;
 
 // Shift Instructions
 def : Pat<(shl GPR:$L, GPR:$R), (ShiftL GPR:$L, GPR:$R)>;
@@ -613,6 +699,9 @@
                     (i32 GPR:$T), (i32 GPR:$F), SETULE),
           (Select_CC GPR:$T, GPR:$F, (CMPU GPR:$L, GPR:$R), 6)>;
 
+// Ret instructions
+def : Pat<(MBlazeRet GPR:$target), (RTSD GPR:$target, 0x8)>;
+
 // BR instructions
 def : Pat<(br bb:$T), (BRID bb:$T)>;
 def : Pat<(brind GPR:$T), (BRD GPR:$T)>;
@@ -660,6 +749,10 @@
 def : Pat<(extloadi8  xaddr:$src), (i32 (LBU xaddr:$src))>;
 def : Pat<(extloadi16 xaddr:$src), (i32 (LHU xaddr:$src))>;
 
+// 32-bit load and store
+def : Pat<(store (i32 GPR:$dst), xaddr:$addr), (SW GPR:$dst, xaddr:$addr)>;
+def : Pat<(load xaddr:$addr), (i32 (LW xaddr:$addr))>;
+
 // Peepholes
 def : Pat<(store (i32 0), iaddr:$dst), (SWI (i32 R0), iaddr:$dst)>;
 
diff --git a/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp b/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp
index 4abeb2e..23b8246 100644
--- a/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp
+++ b/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp
@@ -14,7 +14,7 @@
 #include "MBlazeMCAsmInfo.h"
 using namespace llvm;
 
-MBlazeMCAsmInfo::MBlazeMCAsmInfo(const Target &T, StringRef TT) {
+MBlazeMCAsmInfo::MBlazeMCAsmInfo() {
   AlignmentIsInBytes          = false;
   Data16bitsDirective         = "\t.half\t";
   Data32bitsDirective         = "\t.word\t";
diff --git a/lib/Target/MBlaze/MBlazeMCAsmInfo.h b/lib/Target/MBlaze/MBlazeMCAsmInfo.h
index 9d6ff3a..8c3d32b 100644
--- a/lib/Target/MBlaze/MBlazeMCAsmInfo.h
+++ b/lib/Target/MBlaze/MBlazeMCAsmInfo.h
@@ -22,7 +22,7 @@
   
   class MBlazeMCAsmInfo : public MCAsmInfo {
   public:
-    explicit MBlazeMCAsmInfo(const Target &T, StringRef TT);
+    explicit MBlazeMCAsmInfo();
   };
 
 } // namespace llvm
diff --git a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp
index fec147d..9672ebf 100644
--- a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp
+++ b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp
@@ -103,6 +103,8 @@
   }
 
   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 EmitImmediate(const MCInst &MI,
                      unsigned opNo, MCFixupKind FixupKind,
@@ -153,6 +155,18 @@
 }
 
 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);
+    }
+}
+
+void MBlazeMCCodeEmitter::
 EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind,
               unsigned &CurByte, raw_ostream &OS,
               SmallVectorImpl<MCFixup> &Fixups) const {
@@ -166,6 +180,8 @@
   }
 }
 
+
+
 void MBlazeMCCodeEmitter::
 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
                   SmallVectorImpl<MCFixup> &Fixups) const {
@@ -177,24 +193,28 @@
 
   switch ((TSFlags & MBlazeII::FormMask)) {
   default: break;
-  case MBlazeII::Pseudo:
+  case MBlazeII::FPseudo:
     // Pseudo instructions don't get encoded.
     return;
 
-  case MBlazeII::RegRegImm:
+  case MBlazeII::FRRI:
     EmitImmediate( MI, 2, FK_Data_4, CurByte, OS, Fixups );
     break;
 
-  case MBlazeII::RegImmReg:
+  case MBlazeII::FRIR:
     EmitImmediate( MI, 1, FK_Data_4, CurByte, OS, Fixups );
     break;
 
-  case MBlazeII::RegImm:
+  case MBlazeII::FCRI:
     EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS,
                    Fixups );
     break;
 
-  case MBlazeII::Imm:
+  case MBlazeII::FRCI:
+    EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS,
+                   Fixups );
+
+  case MBlazeII::FCCI:
     EmitImmediate( MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS,
                    Fixups );
     break;
@@ -207,19 +227,17 @@
     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:
-  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);
-    }
+    EmitIMM(MI,0,CurByte,OS);
     EmitConstant(Value, 4, CurByte, OS);
     break;
   }
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
index a340f12..20e61e8 100644
--- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
@@ -21,6 +21,14 @@
 #include "llvm/Target/TargetRegistry.h"
 using namespace llvm;
 
+static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
+  Triple TheTriple(TT);
+  switch (TheTriple.getOS()) {
+  default:
+    return new MBlazeMCAsmInfo();
+  }
+}
+
 static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
                                     MCContext &Ctx, TargetAsmBackend &TAB,
                                     raw_ostream &_OS,
@@ -46,7 +54,9 @@
 extern "C" void LLVMInitializeMBlazeTarget() {
   // Register the target.
   RegisterTargetMachine<MBlazeTargetMachine> X(TheMBlazeTarget);
-  RegisterAsmInfo<MBlazeMCAsmInfo> A(TheMBlazeTarget);
+
+  // Register the target asm info.
+  RegisterAsmInfoFn A(TheMBlazeTarget, createMCAsmInfo);
 
   // Register the MC code emitter
   TargetRegistry::RegisterCodeEmitter(TheMBlazeTarget,
diff --git a/lib/Target/MBlaze/Makefile b/lib/Target/MBlaze/Makefile
index ae538b4..0150604 100644
--- a/lib/Target/MBlaze/Makefile
+++ b/lib/Target/MBlaze/Makefile
@@ -16,9 +16,10 @@
                 MBlazeGenInstrInfo.inc MBlazeGenAsmWriter.inc \
                 MBlazeGenDAGISel.inc MBlazeGenAsmMatcher.inc \
 		MBlazeGenCodeEmitter.inc MBlazeGenCallingConv.inc \
-                MBlazeGenSubtarget.inc MBlazeGenIntrinsics.inc
+                MBlazeGenSubtarget.inc MBlazeGenIntrinsics.inc \
+		MBlazeGenEDInfo.inc
 
-DIRS = InstPrinter AsmParser TargetInfo
+DIRS = InstPrinter AsmParser Disassembler TargetInfo
 
 include $(LEVEL)/Makefile.common
 
diff --git a/lib/Target/MBlaze/TODO b/lib/Target/MBlaze/TODO
index 67434e9..95047e7 100644
--- a/lib/Target/MBlaze/TODO
+++ b/lib/Target/MBlaze/TODO
@@ -30,3 +30,5 @@
       slots but I'm not sure that is necessary.
     - The processor itineraries are copied from a different backend
       and need to be updated to model the MicroBlaze correctly.
+    - Look at the MBlazeGenFastISel.inc stuff and make use of it
+      if appropriate.