LLVM API Documentation

MBlazeDisassembler.cpp
Go to the documentation of this file.
00001 //===-- MBlazeDisassembler.cpp - Disassembler for MicroBlaze  -------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file is part of the MBlaze Disassembler. It contains code to translate
00011 // the data produced by the decoder into MCInsts.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "MBlazeDisassembler.h"
00016 #include "MBlaze.h"
00017 #include "llvm/MC/MCDisassembler.h"
00018 #include "llvm/MC/MCInst.h"
00019 #include "llvm/MC/MCInstrDesc.h"
00020 #include "llvm/Support/Debug.h"
00021 #include "llvm/Support/MemoryObject.h"
00022 #include "llvm/Support/TargetRegistry.h"
00023 #include "llvm/Support/raw_ostream.h"
00024 
00025 // #include "MBlazeGenDecoderTables.inc"
00026 // #include "MBlazeGenRegisterNames.inc"
00027 
00028 namespace llvm {
00029 extern const MCInstrDesc MBlazeInsts[];
00030 }
00031 
00032 using namespace llvm;
00033 
00034 const uint16_t UNSUPPORTED = -1;
00035 
00036 static const uint16_t mblazeBinary2Opcode[] = {
00037   MBlaze::ADD,   MBlaze::RSUB,   MBlaze::ADDC,   MBlaze::RSUBC,   //00,01,02,03
00038   MBlaze::ADDK,  MBlaze::RSUBK,  MBlaze::ADDKC,  MBlaze::RSUBKC,  //04,05,06,07
00039   MBlaze::ADDI,  MBlaze::RSUBI,  MBlaze::ADDIC,  MBlaze::RSUBIC,  //08,09,0A,0B
00040   MBlaze::ADDIK, MBlaze::RSUBIK, MBlaze::ADDIKC, MBlaze::RSUBIKC, //0C,0D,0E,0F
00041 
00042   MBlaze::MUL,   MBlaze::BSRL,   MBlaze::IDIV,   MBlaze::GETD,    //10,11,12,13
00043   UNSUPPORTED,   UNSUPPORTED,    MBlaze::FADD,   UNSUPPORTED,     //14,15,16,17
00044   MBlaze::MULI,  MBlaze::BSRLI,  UNSUPPORTED,    MBlaze::GET,     //18,19,1A,1B
00045   UNSUPPORTED,   UNSUPPORTED,    UNSUPPORTED,    UNSUPPORTED,     //1C,1D,1E,1F
00046 
00047   MBlaze::OR,    MBlaze::AND,    MBlaze::XOR,    MBlaze::ANDN,    //20,21,22,23
00048   MBlaze::SEXT8, MBlaze::MFS,    MBlaze::BR,     MBlaze::BEQ,     //24,25,26,27
00049   MBlaze::ORI,   MBlaze::ANDI,   MBlaze::XORI,   MBlaze::ANDNI,   //28,29,2A,2B
00050   MBlaze::IMM,   MBlaze::RTSD,   MBlaze::BRI,    MBlaze::BEQI,    //2C,2D,2E,2F
00051 
00052   MBlaze::LBU,   MBlaze::LHU,    MBlaze::LW,     UNSUPPORTED,     //30,31,32,33
00053   MBlaze::SB,    MBlaze::SH,     MBlaze::SW,     UNSUPPORTED,     //34,35,36,37
00054   MBlaze::LBUI,  MBlaze::LHUI,   MBlaze::LWI,    UNSUPPORTED,     //38,39,3A,3B
00055   MBlaze::SBI,   MBlaze::SHI,    MBlaze::SWI,    UNSUPPORTED,     //3C,3D,3E,3F
00056 };
00057 
00058 static unsigned getRD(uint32_t insn) {
00059   if (!isMBlazeRegister((insn>>21)&0x1F))
00060     return UNSUPPORTED;
00061   return getMBlazeRegisterFromNumbering((insn>>21)&0x1F);
00062 }
00063 
00064 static unsigned getRA(uint32_t insn) {
00065   if (!getMBlazeRegisterFromNumbering((insn>>16)&0x1F))
00066     return UNSUPPORTED;
00067   return getMBlazeRegisterFromNumbering((insn>>16)&0x1F);
00068 }
00069 
00070 static unsigned getRB(uint32_t insn) {
00071   if (!getMBlazeRegisterFromNumbering((insn>>11)&0x1F))
00072     return UNSUPPORTED;
00073   return getMBlazeRegisterFromNumbering((insn>>11)&0x1F);
00074 }
00075 
00076 static int64_t getRS(uint32_t insn) {
00077   if (!isSpecialMBlazeRegister(insn&0x3FFF))
00078     return UNSUPPORTED;
00079   return getSpecialMBlazeRegisterFromNumbering(insn&0x3FFF);
00080 }
00081 
00082 static int64_t getIMM(uint32_t insn) {
00083     int16_t val = (insn & 0xFFFF);
00084     return val;
00085 }
00086 
00087 static int64_t getSHT(uint32_t insn) {
00088     int16_t val = (insn & 0x1F);
00089     return val;
00090 }
00091 
00092 static unsigned getFLAGS(int32_t insn) {
00093     return (insn & 0x7FF);
00094 }
00095 
00096 static int64_t getFSL(uint32_t insn) {
00097     int16_t val = (insn & 0xF);
00098     return val;
00099 }
00100 
00101 static unsigned decodeMUL(uint32_t insn) {
00102     switch (getFLAGS(insn)) {
00103     default: return UNSUPPORTED;
00104     case 0:  return MBlaze::MUL;
00105     case 1:  return MBlaze::MULH;
00106     case 2:  return MBlaze::MULHSU;
00107     case 3:  return MBlaze::MULHU;
00108     }
00109 }
00110 
00111 static unsigned decodeSEXT(uint32_t insn) {
00112     switch (insn&0x7FF) {
00113     default:   return UNSUPPORTED;
00114     case 0x60: return MBlaze::SEXT8;
00115     case 0x68: return MBlaze::WIC;
00116     case 0x64: return MBlaze::WDC;
00117     case 0x66: return MBlaze::WDCC;
00118     case 0x74: return MBlaze::WDCF;
00119     case 0x61: return MBlaze::SEXT16;
00120     case 0x41: return MBlaze::SRL;
00121     case 0x21: return MBlaze::SRC;
00122     case 0x01: return MBlaze::SRA;
00123     case 0xE0: return MBlaze::CLZ;
00124     }
00125 }
00126 
00127 static unsigned decodeBEQ(uint32_t insn) {
00128     switch ((insn>>21)&0x1F) {
00129     default:    return UNSUPPORTED;
00130     case 0x00:  return MBlaze::BEQ;
00131     case 0x10:  return MBlaze::BEQD;
00132     case 0x05:  return MBlaze::BGE;
00133     case 0x15:  return MBlaze::BGED;
00134     case 0x04:  return MBlaze::BGT;
00135     case 0x14:  return MBlaze::BGTD;
00136     case 0x03:  return MBlaze::BLE;
00137     case 0x13:  return MBlaze::BLED;
00138     case 0x02:  return MBlaze::BLT;
00139     case 0x12:  return MBlaze::BLTD;
00140     case 0x01:  return MBlaze::BNE;
00141     case 0x11:  return MBlaze::BNED;
00142     }
00143 }
00144 
00145 static unsigned decodeBEQI(uint32_t insn) {
00146     switch ((insn>>21)&0x1F) {
00147     default:    return UNSUPPORTED;
00148     case 0x00:  return MBlaze::BEQI;
00149     case 0x10:  return MBlaze::BEQID;
00150     case 0x05:  return MBlaze::BGEI;
00151     case 0x15:  return MBlaze::BGEID;
00152     case 0x04:  return MBlaze::BGTI;
00153     case 0x14:  return MBlaze::BGTID;
00154     case 0x03:  return MBlaze::BLEI;
00155     case 0x13:  return MBlaze::BLEID;
00156     case 0x02:  return MBlaze::BLTI;
00157     case 0x12:  return MBlaze::BLTID;
00158     case 0x01:  return MBlaze::BNEI;
00159     case 0x11:  return MBlaze::BNEID;
00160     }
00161 }
00162 
00163 static unsigned decodeBR(uint32_t insn) {
00164     switch ((insn>>16)&0x1F) {
00165     default:   return UNSUPPORTED;
00166     case 0x00: return MBlaze::BR;
00167     case 0x08: return MBlaze::BRA;
00168     case 0x0C: return MBlaze::BRK;
00169     case 0x10: return MBlaze::BRD;
00170     case 0x14: return MBlaze::BRLD;
00171     case 0x18: return MBlaze::BRAD;
00172     case 0x1C: return MBlaze::BRALD;
00173     }
00174 }
00175 
00176 static unsigned decodeBRI(uint32_t insn) {
00177     switch (insn&0x3FFFFFF) {
00178     default:        break;
00179     case 0x0020004: return MBlaze::IDMEMBAR;
00180     case 0x0220004: return MBlaze::DMEMBAR;
00181     case 0x0420004: return MBlaze::IMEMBAR;
00182     }
00183 
00184     switch ((insn>>16)&0x1F) {
00185     default:   return UNSUPPORTED;
00186     case 0x00: return MBlaze::BRI;
00187     case 0x08: return MBlaze::BRAI;
00188     case 0x0C: return MBlaze::BRKI;
00189     case 0x10: return MBlaze::BRID;
00190     case 0x14: return MBlaze::BRLID;
00191     case 0x18: return MBlaze::BRAID;
00192     case 0x1C: return MBlaze::BRALID;
00193     }
00194 }
00195 
00196 static unsigned decodeBSRL(uint32_t insn) {
00197     switch ((insn>>9)&0x3) {
00198     default:  return UNSUPPORTED;
00199     case 0x2: return MBlaze::BSLL;
00200     case 0x1: return MBlaze::BSRA;
00201     case 0x0: return MBlaze::BSRL;
00202     }
00203 }
00204 
00205 static unsigned decodeBSRLI(uint32_t insn) {
00206     switch ((insn>>9)&0x3) {
00207     default:  return UNSUPPORTED;
00208     case 0x2: return MBlaze::BSLLI;
00209     case 0x1: return MBlaze::BSRAI;
00210     case 0x0: return MBlaze::BSRLI;
00211     }
00212 }
00213 
00214 static unsigned decodeRSUBK(uint32_t insn) {
00215     switch (getFLAGS(insn)) {
00216     default:  return UNSUPPORTED;
00217     case 0x0: return MBlaze::RSUBK;
00218     case 0x1: return MBlaze::CMP;
00219     case 0x3: return MBlaze::CMPU;
00220     }
00221 }
00222 
00223 static unsigned decodeFADD(uint32_t insn) {
00224     switch (getFLAGS(insn)) {
00225     default:    return UNSUPPORTED;
00226     case 0x000: return MBlaze::FADD;
00227     case 0x080: return MBlaze::FRSUB;
00228     case 0x100: return MBlaze::FMUL;
00229     case 0x180: return MBlaze::FDIV;
00230     case 0x200: return MBlaze::FCMP_UN;
00231     case 0x210: return MBlaze::FCMP_LT;
00232     case 0x220: return MBlaze::FCMP_EQ;
00233     case 0x230: return MBlaze::FCMP_LE;
00234     case 0x240: return MBlaze::FCMP_GT;
00235     case 0x250: return MBlaze::FCMP_NE;
00236     case 0x260: return MBlaze::FCMP_GE;
00237     case 0x280: return MBlaze::FLT;
00238     case 0x300: return MBlaze::FINT;
00239     case 0x380: return MBlaze::FSQRT;
00240     }
00241 }
00242 
00243 static unsigned decodeGET(uint32_t insn) {
00244     switch ((insn>>10)&0x3F) {
00245     default:   return UNSUPPORTED;
00246     case 0x00: return MBlaze::GET;
00247     case 0x01: return MBlaze::EGET;
00248     case 0x02: return MBlaze::AGET;
00249     case 0x03: return MBlaze::EAGET;
00250     case 0x04: return MBlaze::TGET;
00251     case 0x05: return MBlaze::TEGET;
00252     case 0x06: return MBlaze::TAGET;
00253     case 0x07: return MBlaze::TEAGET;
00254     case 0x08: return MBlaze::CGET;
00255     case 0x09: return MBlaze::ECGET;
00256     case 0x0A: return MBlaze::CAGET;
00257     case 0x0B: return MBlaze::ECAGET;
00258     case 0x0C: return MBlaze::TCGET;
00259     case 0x0D: return MBlaze::TECGET;
00260     case 0x0E: return MBlaze::TCAGET;
00261     case 0x0F: return MBlaze::TECAGET;
00262     case 0x10: return MBlaze::NGET;
00263     case 0x11: return MBlaze::NEGET;
00264     case 0x12: return MBlaze::NAGET;
00265     case 0x13: return MBlaze::NEAGET;
00266     case 0x14: return MBlaze::TNGET;
00267     case 0x15: return MBlaze::TNEGET;
00268     case 0x16: return MBlaze::TNAGET;
00269     case 0x17: return MBlaze::TNEAGET;
00270     case 0x18: return MBlaze::NCGET;
00271     case 0x19: return MBlaze::NECGET;
00272     case 0x1A: return MBlaze::NCAGET;
00273     case 0x1B: return MBlaze::NECAGET;
00274     case 0x1C: return MBlaze::TNCGET;
00275     case 0x1D: return MBlaze::TNECGET;
00276     case 0x1E: return MBlaze::TNCAGET;
00277     case 0x1F: return MBlaze::TNECAGET;
00278     case 0x20: return MBlaze::PUT;
00279     case 0x22: return MBlaze::APUT;
00280     case 0x24: return MBlaze::TPUT;
00281     case 0x26: return MBlaze::TAPUT;
00282     case 0x28: return MBlaze::CPUT;
00283     case 0x2A: return MBlaze::CAPUT;
00284     case 0x2C: return MBlaze::TCPUT;
00285     case 0x2E: return MBlaze::TCAPUT;
00286     case 0x30: return MBlaze::NPUT;
00287     case 0x32: return MBlaze::NAPUT;
00288     case 0x34: return MBlaze::TNPUT;
00289     case 0x36: return MBlaze::TNAPUT;
00290     case 0x38: return MBlaze::NCPUT;
00291     case 0x3A: return MBlaze::NCAPUT;
00292     case 0x3C: return MBlaze::TNCPUT;
00293     case 0x3E: return MBlaze::TNCAPUT;
00294     }
00295 }
00296 
00297 static unsigned decodeGETD(uint32_t insn) {
00298     switch ((insn>>5)&0x3F) {
00299     default:   return UNSUPPORTED;
00300     case 0x00: return MBlaze::GETD;
00301     case 0x01: return MBlaze::EGETD;
00302     case 0x02: return MBlaze::AGETD;
00303     case 0x03: return MBlaze::EAGETD;
00304     case 0x04: return MBlaze::TGETD;
00305     case 0x05: return MBlaze::TEGETD;
00306     case 0x06: return MBlaze::TAGETD;
00307     case 0x07: return MBlaze::TEAGETD;
00308     case 0x08: return MBlaze::CGETD;
00309     case 0x09: return MBlaze::ECGETD;
00310     case 0x0A: return MBlaze::CAGETD;
00311     case 0x0B: return MBlaze::ECAGETD;
00312     case 0x0C: return MBlaze::TCGETD;
00313     case 0x0D: return MBlaze::TECGETD;
00314     case 0x0E: return MBlaze::TCAGETD;
00315     case 0x0F: return MBlaze::TECAGETD;
00316     case 0x10: return MBlaze::NGETD;
00317     case 0x11: return MBlaze::NEGETD;
00318     case 0x12: return MBlaze::NAGETD;
00319     case 0x13: return MBlaze::NEAGETD;
00320     case 0x14: return MBlaze::TNGETD;
00321     case 0x15: return MBlaze::TNEGETD;
00322     case 0x16: return MBlaze::TNAGETD;
00323     case 0x17: return MBlaze::TNEAGETD;
00324     case 0x18: return MBlaze::NCGETD;
00325     case 0x19: return MBlaze::NECGETD;
00326     case 0x1A: return MBlaze::NCAGETD;
00327     case 0x1B: return MBlaze::NECAGETD;
00328     case 0x1C: return MBlaze::TNCGETD;
00329     case 0x1D: return MBlaze::TNECGETD;
00330     case 0x1E: return MBlaze::TNCAGETD;
00331     case 0x1F: return MBlaze::TNECAGETD;
00332     case 0x20: return MBlaze::PUTD;
00333     case 0x22: return MBlaze::APUTD;
00334     case 0x24: return MBlaze::TPUTD;
00335     case 0x26: return MBlaze::TAPUTD;
00336     case 0x28: return MBlaze::CPUTD;
00337     case 0x2A: return MBlaze::CAPUTD;
00338     case 0x2C: return MBlaze::TCPUTD;
00339     case 0x2E: return MBlaze::TCAPUTD;
00340     case 0x30: return MBlaze::NPUTD;
00341     case 0x32: return MBlaze::NAPUTD;
00342     case 0x34: return MBlaze::TNPUTD;
00343     case 0x36: return MBlaze::TNAPUTD;
00344     case 0x38: return MBlaze::NCPUTD;
00345     case 0x3A: return MBlaze::NCAPUTD;
00346     case 0x3C: return MBlaze::TNCPUTD;
00347     case 0x3E: return MBlaze::TNCAPUTD;
00348     }
00349 }
00350 
00351 static unsigned decodeIDIV(uint32_t insn) {
00352     switch (insn&0x3) {
00353     default:  return UNSUPPORTED;
00354     case 0x0: return MBlaze::IDIV;
00355     case 0x2: return MBlaze::IDIVU;
00356     }
00357 }
00358 
00359 static unsigned decodeLBU(uint32_t insn) {
00360     switch ((insn>>9)&0x1) {
00361     default:  return UNSUPPORTED;
00362     case 0x0: return MBlaze::LBU;
00363     case 0x1: return MBlaze::LBUR;
00364     }
00365 }
00366 
00367 static unsigned decodeLHU(uint32_t insn) {
00368     switch ((insn>>9)&0x1) {
00369     default:  return UNSUPPORTED;
00370     case 0x0: return MBlaze::LHU;
00371     case 0x1: return MBlaze::LHUR;
00372     }
00373 }
00374 
00375 static unsigned decodeLW(uint32_t insn) {
00376     switch ((insn>>9)&0x3) {
00377     default:  return UNSUPPORTED;
00378     case 0x0: return MBlaze::LW;
00379     case 0x1: return MBlaze::LWR;
00380     case 0x2: return MBlaze::LWX;
00381     }
00382 }
00383 
00384 static unsigned decodeSB(uint32_t insn) {
00385     switch ((insn>>9)&0x1) {
00386     default:  return UNSUPPORTED;
00387     case 0x0: return MBlaze::SB;
00388     case 0x1: return MBlaze::SBR;
00389     }
00390 }
00391 
00392 static unsigned decodeSH(uint32_t insn) {
00393     switch ((insn>>9)&0x1) {
00394     default:  return UNSUPPORTED;
00395     case 0x0: return MBlaze::SH;
00396     case 0x1: return MBlaze::SHR;
00397     }
00398 }
00399 
00400 static unsigned decodeSW(uint32_t insn) {
00401     switch ((insn>>9)&0x3) {
00402     default:  return UNSUPPORTED;
00403     case 0x0: return MBlaze::SW;
00404     case 0x1: return MBlaze::SWR;
00405     case 0x2: return MBlaze::SWX;
00406     }
00407 }
00408 
00409 static unsigned decodeMFS(uint32_t insn) {
00410     switch ((insn>>15)&0x1) {
00411     default:   return UNSUPPORTED;
00412     case 0x0:
00413       switch ((insn>>16)&0x1) {
00414       default:   return UNSUPPORTED;
00415       case 0x0: return MBlaze::MSRSET;
00416       case 0x1: return MBlaze::MSRCLR;
00417       }
00418     case 0x1:
00419       switch ((insn>>14)&0x1) {
00420       default:   return UNSUPPORTED;
00421       case 0x0: return MBlaze::MFS;
00422       case 0x1: return MBlaze::MTS;
00423       }
00424     }
00425 }
00426 
00427 static unsigned decodeOR(uint32_t insn) {
00428     switch (getFLAGS(insn)) {
00429     default:    return UNSUPPORTED;
00430     case 0x000: return MBlaze::OR;
00431     case 0x400: return MBlaze::PCMPBF;
00432     }
00433 }
00434 
00435 static unsigned decodeXOR(uint32_t insn) {
00436     switch (getFLAGS(insn)) {
00437     default:    return UNSUPPORTED;
00438     case 0x000: return MBlaze::XOR;
00439     case 0x400: return MBlaze::PCMPEQ;
00440     }
00441 }
00442 
00443 static unsigned decodeANDN(uint32_t insn) {
00444     switch (getFLAGS(insn)) {
00445     default:    return UNSUPPORTED;
00446     case 0x000: return MBlaze::ANDN;
00447     case 0x400: return MBlaze::PCMPNE;
00448     }
00449 }
00450 
00451 static unsigned decodeRTSD(uint32_t insn) {
00452     switch ((insn>>21)&0x1F) {
00453     default:   return UNSUPPORTED;
00454     case 0x10: return MBlaze::RTSD;
00455     case 0x11: return MBlaze::RTID;
00456     case 0x12: return MBlaze::RTBD;
00457     case 0x14: return MBlaze::RTED;
00458     }
00459 }
00460 
00461 static unsigned getOPCODE(uint32_t insn) {
00462   unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
00463   switch (opcode) {
00464   case MBlaze::MUL:     return decodeMUL(insn);
00465   case MBlaze::SEXT8:   return decodeSEXT(insn);
00466   case MBlaze::BEQ:     return decodeBEQ(insn);
00467   case MBlaze::BEQI:    return decodeBEQI(insn);
00468   case MBlaze::BR:      return decodeBR(insn);
00469   case MBlaze::BRI:     return decodeBRI(insn);
00470   case MBlaze::BSRL:    return decodeBSRL(insn);
00471   case MBlaze::BSRLI:   return decodeBSRLI(insn);
00472   case MBlaze::RSUBK:   return decodeRSUBK(insn);
00473   case MBlaze::FADD:    return decodeFADD(insn);
00474   case MBlaze::GET:     return decodeGET(insn);
00475   case MBlaze::GETD:    return decodeGETD(insn);
00476   case MBlaze::IDIV:    return decodeIDIV(insn);
00477   case MBlaze::LBU:     return decodeLBU(insn);
00478   case MBlaze::LHU:     return decodeLHU(insn);
00479   case MBlaze::LW:      return decodeLW(insn);
00480   case MBlaze::SB:      return decodeSB(insn);
00481   case MBlaze::SH:      return decodeSH(insn);
00482   case MBlaze::SW:      return decodeSW(insn);
00483   case MBlaze::MFS:     return decodeMFS(insn);
00484   case MBlaze::OR:      return decodeOR(insn);
00485   case MBlaze::XOR:     return decodeXOR(insn);
00486   case MBlaze::ANDN:    return decodeANDN(insn);
00487   case MBlaze::RTSD:    return decodeRTSD(insn);
00488   default:              return opcode;
00489   }
00490 }
00491 
00492 //
00493 // Public interface for the disassembler
00494 //
00495 
00496 MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr,
00497                                         uint64_t &size,
00498                                         const MemoryObject &region,
00499                                         uint64_t address,
00500                                         raw_ostream &vStream,
00501                                         raw_ostream &cStream) const {
00502   // The machine instruction.
00503   uint32_t insn;
00504   uint64_t read;
00505   uint8_t bytes[4];
00506 
00507   // By default we consume 1 byte on failure
00508   size = 1;
00509 
00510   // We want to read exactly 4 bytes of data.
00511   if (region.readBytes(address, 4, (uint8_t*)bytes, &read) == -1 || read < 4)
00512     return Fail;
00513 
00514   // Encoded as a big-endian 32-bit word in the stream.
00515   insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
00516 
00517   // Get the MCInst opcode from the binary instruction and make sure
00518   // that it is a valid instruction.
00519   unsigned opcode = getOPCODE(insn);
00520   if (opcode == UNSUPPORTED)
00521     return Fail;
00522 
00523   instr.setOpcode(opcode);
00524 
00525   unsigned RD = getRD(insn);
00526   unsigned RA = getRA(insn);
00527   unsigned RB = getRB(insn);
00528   unsigned RS = getRS(insn);
00529 
00530   uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
00531   switch ((tsFlags & MBlazeII::FormMask)) {
00532   default: 
00533     return Fail;
00534 
00535   case MBlazeII::FC:
00536     break;
00537 
00538   case MBlazeII::FRRRR:
00539     if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
00540       return Fail;
00541     instr.addOperand(MCOperand::CreateReg(RD));
00542     instr.addOperand(MCOperand::CreateReg(RB));
00543     instr.addOperand(MCOperand::CreateReg(RA));
00544     break;
00545 
00546   case MBlazeII::FRRR:
00547     if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
00548       return Fail;
00549     instr.addOperand(MCOperand::CreateReg(RD));
00550     instr.addOperand(MCOperand::CreateReg(RA));
00551     instr.addOperand(MCOperand::CreateReg(RB));
00552     break;
00553 
00554   case MBlazeII::FRR:
00555     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
00556       return Fail;
00557     instr.addOperand(MCOperand::CreateReg(RD));
00558     instr.addOperand(MCOperand::CreateReg(RA));
00559     break;
00560 
00561   case MBlazeII::FRI:
00562     switch (opcode) {
00563     default: 
00564       return Fail;
00565     case MBlaze::MFS:
00566       if (RD == UNSUPPORTED)
00567         return Fail;
00568       instr.addOperand(MCOperand::CreateReg(RD));
00569       instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
00570       break;
00571     case MBlaze::MTS:
00572       if (RA == UNSUPPORTED)
00573         return Fail;
00574       instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
00575       instr.addOperand(MCOperand::CreateReg(RA));
00576       break;
00577     case MBlaze::MSRSET:
00578     case MBlaze::MSRCLR:
00579       if (RD == UNSUPPORTED)
00580         return Fail;
00581       instr.addOperand(MCOperand::CreateReg(RD));
00582       instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
00583       break;
00584     }
00585     break;
00586 
00587   case MBlazeII::FRRI:
00588     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
00589       return Fail;
00590     instr.addOperand(MCOperand::CreateReg(RD));
00591     instr.addOperand(MCOperand::CreateReg(RA));
00592     switch (opcode) {
00593     default:
00594       instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
00595       break;
00596     case MBlaze::BSRLI:
00597     case MBlaze::BSRAI:
00598     case MBlaze::BSLLI:
00599       instr.addOperand(MCOperand::CreateImm(insn&0x1F));
00600       break;
00601     }
00602     break;
00603 
00604   case MBlazeII::FCRR:
00605     if (RA == UNSUPPORTED || RB == UNSUPPORTED)
00606       return Fail;
00607     instr.addOperand(MCOperand::CreateReg(RA));
00608     instr.addOperand(MCOperand::CreateReg(RB));
00609     break;
00610 
00611   case MBlazeII::FCRI:
00612     if (RA == UNSUPPORTED)
00613       return Fail;
00614     instr.addOperand(MCOperand::CreateReg(RA));
00615     instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
00616     break;
00617 
00618   case MBlazeII::FRCR:
00619     if (RD == UNSUPPORTED || RB == UNSUPPORTED)
00620       return Fail;
00621     instr.addOperand(MCOperand::CreateReg(RD));
00622     instr.addOperand(MCOperand::CreateReg(RB));
00623     break;
00624 
00625   case MBlazeII::FRCI:
00626     if (RD == UNSUPPORTED)
00627       return Fail;
00628     instr.addOperand(MCOperand::CreateReg(RD));
00629     instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
00630     break;
00631 
00632   case MBlazeII::FCCR:
00633     if (RB == UNSUPPORTED)
00634       return Fail;
00635     instr.addOperand(MCOperand::CreateReg(RB));
00636     break;
00637 
00638   case MBlazeII::FCCI:
00639     instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
00640     break;
00641 
00642   case MBlazeII::FRRCI:
00643     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
00644       return Fail;
00645     instr.addOperand(MCOperand::CreateReg(RD));
00646     instr.addOperand(MCOperand::CreateReg(RA));
00647     instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
00648     break;
00649 
00650   case MBlazeII::FRRC:
00651     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
00652       return Fail;
00653     instr.addOperand(MCOperand::CreateReg(RD));
00654     instr.addOperand(MCOperand::CreateReg(RA));
00655     break;
00656 
00657   case MBlazeII::FRCX:
00658     if (RD == UNSUPPORTED)
00659       return Fail;
00660     instr.addOperand(MCOperand::CreateReg(RD));
00661     instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
00662     break;
00663 
00664   case MBlazeII::FRCS:
00665     if (RD == UNSUPPORTED || RS == UNSUPPORTED)
00666       return Fail;
00667     instr.addOperand(MCOperand::CreateReg(RD));
00668     instr.addOperand(MCOperand::CreateReg(RS));
00669     break;
00670 
00671   case MBlazeII::FCRCS:
00672     if (RS == UNSUPPORTED || RA == UNSUPPORTED)
00673       return Fail;
00674     instr.addOperand(MCOperand::CreateReg(RS));
00675     instr.addOperand(MCOperand::CreateReg(RA));
00676     break;
00677 
00678   case MBlazeII::FCRCX:
00679     if (RA == UNSUPPORTED)
00680       return Fail;
00681     instr.addOperand(MCOperand::CreateReg(RA));
00682     instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
00683     break;
00684 
00685   case MBlazeII::FCX:
00686     instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
00687     break;
00688 
00689   case MBlazeII::FCR:
00690     if (RB == UNSUPPORTED)
00691       return Fail;
00692     instr.addOperand(MCOperand::CreateReg(RB));
00693     break;
00694 
00695   case MBlazeII::FRIR:
00696     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
00697       return Fail;
00698     instr.addOperand(MCOperand::CreateReg(RD));
00699     instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
00700     instr.addOperand(MCOperand::CreateReg(RA));
00701     break;
00702   }
00703 
00704   // We always consume 4 bytes of data on success
00705   size = 4;
00706 
00707   return Success;
00708 }
00709 
00710 static MCDisassembler *createMBlazeDisassembler(const Target &T,
00711                                                 const MCSubtargetInfo &STI) {
00712   return new MBlazeDisassembler(STI);
00713 }
00714 
00715 extern "C" void LLVMInitializeMBlazeDisassembler() {
00716   // Register the disassembler.
00717   TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
00718                                          createMBlazeDisassembler);
00719 }