Home | History | Annotate | Download | only in Disassembler
      1 //===-- MBlazeDisassembler.cpp - Disassembler for MicroBlaze  -------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is part of the MBlaze Disassembler. It contains code to translate
     11 // the data produced by the decoder into MCInsts.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "MBlazeDisassembler.h"
     16 #include "MBlaze.h"
     17 #include "llvm/MC/MCDisassembler.h"
     18 #include "llvm/MC/MCInst.h"
     19 #include "llvm/MC/MCInstrDesc.h"
     20 #include "llvm/Support/Debug.h"
     21 #include "llvm/Support/MemoryObject.h"
     22 #include "llvm/Support/TargetRegistry.h"
     23 #include "llvm/Support/raw_ostream.h"
     24 
     25 // #include "MBlazeGenDecoderTables.inc"
     26 // #include "MBlazeGenRegisterNames.inc"
     27 
     28 namespace llvm {
     29 extern const MCInstrDesc MBlazeInsts[];
     30 }
     31 
     32 using namespace llvm;
     33 
     34 const uint16_t UNSUPPORTED = -1;
     35 
     36 static const uint16_t mblazeBinary2Opcode[] = {
     37   MBlaze::ADD,   MBlaze::RSUB,   MBlaze::ADDC,   MBlaze::RSUBC,   //00,01,02,03
     38   MBlaze::ADDK,  MBlaze::RSUBK,  MBlaze::ADDKC,  MBlaze::RSUBKC,  //04,05,06,07
     39   MBlaze::ADDI,  MBlaze::RSUBI,  MBlaze::ADDIC,  MBlaze::RSUBIC,  //08,09,0A,0B
     40   MBlaze::ADDIK, MBlaze::RSUBIK, MBlaze::ADDIKC, MBlaze::RSUBIKC, //0C,0D,0E,0F
     41 
     42   MBlaze::MUL,   MBlaze::BSRL,   MBlaze::IDIV,   MBlaze::GETD,    //10,11,12,13
     43   UNSUPPORTED,   UNSUPPORTED,    MBlaze::FADD,   UNSUPPORTED,     //14,15,16,17
     44   MBlaze::MULI,  MBlaze::BSRLI,  UNSUPPORTED,    MBlaze::GET,     //18,19,1A,1B
     45   UNSUPPORTED,   UNSUPPORTED,    UNSUPPORTED,    UNSUPPORTED,     //1C,1D,1E,1F
     46 
     47   MBlaze::OR,    MBlaze::AND,    MBlaze::XOR,    MBlaze::ANDN,    //20,21,22,23
     48   MBlaze::SEXT8, MBlaze::MFS,    MBlaze::BR,     MBlaze::BEQ,     //24,25,26,27
     49   MBlaze::ORI,   MBlaze::ANDI,   MBlaze::XORI,   MBlaze::ANDNI,   //28,29,2A,2B
     50   MBlaze::IMM,   MBlaze::RTSD,   MBlaze::BRI,    MBlaze::BEQI,    //2C,2D,2E,2F
     51 
     52   MBlaze::LBU,   MBlaze::LHU,    MBlaze::LW,     UNSUPPORTED,     //30,31,32,33
     53   MBlaze::SB,    MBlaze::SH,     MBlaze::SW,     UNSUPPORTED,     //34,35,36,37
     54   MBlaze::LBUI,  MBlaze::LHUI,   MBlaze::LWI,    UNSUPPORTED,     //38,39,3A,3B
     55   MBlaze::SBI,   MBlaze::SHI,    MBlaze::SWI,    UNSUPPORTED,     //3C,3D,3E,3F
     56 };
     57 
     58 static unsigned getRD(uint32_t insn) {
     59   if (!isMBlazeRegister((insn>>21)&0x1F))
     60     return UNSUPPORTED;
     61   return getMBlazeRegisterFromNumbering((insn>>21)&0x1F);
     62 }
     63 
     64 static unsigned getRA(uint32_t insn) {
     65   if (!getMBlazeRegisterFromNumbering((insn>>16)&0x1F))
     66     return UNSUPPORTED;
     67   return getMBlazeRegisterFromNumbering((insn>>16)&0x1F);
     68 }
     69 
     70 static unsigned getRB(uint32_t insn) {
     71   if (!getMBlazeRegisterFromNumbering((insn>>11)&0x1F))
     72     return UNSUPPORTED;
     73   return getMBlazeRegisterFromNumbering((insn>>11)&0x1F);
     74 }
     75 
     76 static int64_t getRS(uint32_t insn) {
     77   if (!isSpecialMBlazeRegister(insn&0x3FFF))
     78     return UNSUPPORTED;
     79   return getSpecialMBlazeRegisterFromNumbering(insn&0x3FFF);
     80 }
     81 
     82 static int64_t getIMM(uint32_t insn) {
     83     int16_t val = (insn & 0xFFFF);
     84     return val;
     85 }
     86 
     87 static int64_t getSHT(uint32_t insn) {
     88     int16_t val = (insn & 0x1F);
     89     return val;
     90 }
     91 
     92 static unsigned getFLAGS(int32_t insn) {
     93     return (insn & 0x7FF);
     94 }
     95 
     96 static int64_t getFSL(uint32_t insn) {
     97     int16_t val = (insn & 0xF);
     98     return val;
     99 }
    100 
    101 static unsigned decodeMUL(uint32_t insn) {
    102     switch (getFLAGS(insn)) {
    103     default: return UNSUPPORTED;
    104     case 0:  return MBlaze::MUL;
    105     case 1:  return MBlaze::MULH;
    106     case 2:  return MBlaze::MULHSU;
    107     case 3:  return MBlaze::MULHU;
    108     }
    109 }
    110 
    111 static unsigned decodeSEXT(uint32_t insn) {
    112     switch (insn&0x7FF) {
    113     default:   return UNSUPPORTED;
    114     case 0x60: return MBlaze::SEXT8;
    115     case 0x68: return MBlaze::WIC;
    116     case 0x64: return MBlaze::WDC;
    117     case 0x66: return MBlaze::WDCC;
    118     case 0x74: return MBlaze::WDCF;
    119     case 0x61: return MBlaze::SEXT16;
    120     case 0x41: return MBlaze::SRL;
    121     case 0x21: return MBlaze::SRC;
    122     case 0x01: return MBlaze::SRA;
    123     case 0xE0: return MBlaze::CLZ;
    124     }
    125 }
    126 
    127 static unsigned decodeBEQ(uint32_t insn) {
    128     switch ((insn>>21)&0x1F) {
    129     default:    return UNSUPPORTED;
    130     case 0x00:  return MBlaze::BEQ;
    131     case 0x10:  return MBlaze::BEQD;
    132     case 0x05:  return MBlaze::BGE;
    133     case 0x15:  return MBlaze::BGED;
    134     case 0x04:  return MBlaze::BGT;
    135     case 0x14:  return MBlaze::BGTD;
    136     case 0x03:  return MBlaze::BLE;
    137     case 0x13:  return MBlaze::BLED;
    138     case 0x02:  return MBlaze::BLT;
    139     case 0x12:  return MBlaze::BLTD;
    140     case 0x01:  return MBlaze::BNE;
    141     case 0x11:  return MBlaze::BNED;
    142     }
    143 }
    144 
    145 static unsigned decodeBEQI(uint32_t insn) {
    146     switch ((insn>>21)&0x1F) {
    147     default:    return UNSUPPORTED;
    148     case 0x00:  return MBlaze::BEQI;
    149     case 0x10:  return MBlaze::BEQID;
    150     case 0x05:  return MBlaze::BGEI;
    151     case 0x15:  return MBlaze::BGEID;
    152     case 0x04:  return MBlaze::BGTI;
    153     case 0x14:  return MBlaze::BGTID;
    154     case 0x03:  return MBlaze::BLEI;
    155     case 0x13:  return MBlaze::BLEID;
    156     case 0x02:  return MBlaze::BLTI;
    157     case 0x12:  return MBlaze::BLTID;
    158     case 0x01:  return MBlaze::BNEI;
    159     case 0x11:  return MBlaze::BNEID;
    160     }
    161 }
    162 
    163 static unsigned decodeBR(uint32_t insn) {
    164     switch ((insn>>16)&0x1F) {
    165     default:   return UNSUPPORTED;
    166     case 0x00: return MBlaze::BR;
    167     case 0x08: return MBlaze::BRA;
    168     case 0x0C: return MBlaze::BRK;
    169     case 0x10: return MBlaze::BRD;
    170     case 0x14: return MBlaze::BRLD;
    171     case 0x18: return MBlaze::BRAD;
    172     case 0x1C: return MBlaze::BRALD;
    173     }
    174 }
    175 
    176 static unsigned decodeBRI(uint32_t insn) {
    177     switch (insn&0x3FFFFFF) {
    178     default:        break;
    179     case 0x0020004: return MBlaze::IDMEMBAR;
    180     case 0x0220004: return MBlaze::DMEMBAR;
    181     case 0x0420004: return MBlaze::IMEMBAR;
    182     }
    183 
    184     switch ((insn>>16)&0x1F) {
    185     default:   return UNSUPPORTED;
    186     case 0x00: return MBlaze::BRI;
    187     case 0x08: return MBlaze::BRAI;
    188     case 0x0C: return MBlaze::BRKI;
    189     case 0x10: return MBlaze::BRID;
    190     case 0x14: return MBlaze::BRLID;
    191     case 0x18: return MBlaze::BRAID;
    192     case 0x1C: return MBlaze::BRALID;
    193     }
    194 }
    195 
    196 static unsigned decodeBSRL(uint32_t insn) {
    197     switch ((insn>>9)&0x3) {
    198     default:  return UNSUPPORTED;
    199     case 0x2: return MBlaze::BSLL;
    200     case 0x1: return MBlaze::BSRA;
    201     case 0x0: return MBlaze::BSRL;
    202     }
    203 }
    204 
    205 static unsigned decodeBSRLI(uint32_t insn) {
    206     switch ((insn>>9)&0x3) {
    207     default:  return UNSUPPORTED;
    208     case 0x2: return MBlaze::BSLLI;
    209     case 0x1: return MBlaze::BSRAI;
    210     case 0x0: return MBlaze::BSRLI;
    211     }
    212 }
    213 
    214 static unsigned decodeRSUBK(uint32_t insn) {
    215     switch (getFLAGS(insn)) {
    216     default:  return UNSUPPORTED;
    217     case 0x0: return MBlaze::RSUBK;
    218     case 0x1: return MBlaze::CMP;
    219     case 0x3: return MBlaze::CMPU;
    220     }
    221 }
    222 
    223 static unsigned decodeFADD(uint32_t insn) {
    224     switch (getFLAGS(insn)) {
    225     default:    return UNSUPPORTED;
    226     case 0x000: return MBlaze::FADD;
    227     case 0x080: return MBlaze::FRSUB;
    228     case 0x100: return MBlaze::FMUL;
    229     case 0x180: return MBlaze::FDIV;
    230     case 0x200: return MBlaze::FCMP_UN;
    231     case 0x210: return MBlaze::FCMP_LT;
    232     case 0x220: return MBlaze::FCMP_EQ;
    233     case 0x230: return MBlaze::FCMP_LE;
    234     case 0x240: return MBlaze::FCMP_GT;
    235     case 0x250: return MBlaze::FCMP_NE;
    236     case 0x260: return MBlaze::FCMP_GE;
    237     case 0x280: return MBlaze::FLT;
    238     case 0x300: return MBlaze::FINT;
    239     case 0x380: return MBlaze::FSQRT;
    240     }
    241 }
    242 
    243 static unsigned decodeGET(uint32_t insn) {
    244     switch ((insn>>10)&0x3F) {
    245     default:   return UNSUPPORTED;
    246     case 0x00: return MBlaze::GET;
    247     case 0x01: return MBlaze::EGET;
    248     case 0x02: return MBlaze::AGET;
    249     case 0x03: return MBlaze::EAGET;
    250     case 0x04: return MBlaze::TGET;
    251     case 0x05: return MBlaze::TEGET;
    252     case 0x06: return MBlaze::TAGET;
    253     case 0x07: return MBlaze::TEAGET;
    254     case 0x08: return MBlaze::CGET;
    255     case 0x09: return MBlaze::ECGET;
    256     case 0x0A: return MBlaze::CAGET;
    257     case 0x0B: return MBlaze::ECAGET;
    258     case 0x0C: return MBlaze::TCGET;
    259     case 0x0D: return MBlaze::TECGET;
    260     case 0x0E: return MBlaze::TCAGET;
    261     case 0x0F: return MBlaze::TECAGET;
    262     case 0x10: return MBlaze::NGET;
    263     case 0x11: return MBlaze::NEGET;
    264     case 0x12: return MBlaze::NAGET;
    265     case 0x13: return MBlaze::NEAGET;
    266     case 0x14: return MBlaze::TNGET;
    267     case 0x15: return MBlaze::TNEGET;
    268     case 0x16: return MBlaze::TNAGET;
    269     case 0x17: return MBlaze::TNEAGET;
    270     case 0x18: return MBlaze::NCGET;
    271     case 0x19: return MBlaze::NECGET;
    272     case 0x1A: return MBlaze::NCAGET;
    273     case 0x1B: return MBlaze::NECAGET;
    274     case 0x1C: return MBlaze::TNCGET;
    275     case 0x1D: return MBlaze::TNECGET;
    276     case 0x1E: return MBlaze::TNCAGET;
    277     case 0x1F: return MBlaze::TNECAGET;
    278     case 0x20: return MBlaze::PUT;
    279     case 0x22: return MBlaze::APUT;
    280     case 0x24: return MBlaze::TPUT;
    281     case 0x26: return MBlaze::TAPUT;
    282     case 0x28: return MBlaze::CPUT;
    283     case 0x2A: return MBlaze::CAPUT;
    284     case 0x2C: return MBlaze::TCPUT;
    285     case 0x2E: return MBlaze::TCAPUT;
    286     case 0x30: return MBlaze::NPUT;
    287     case 0x32: return MBlaze::NAPUT;
    288     case 0x34: return MBlaze::TNPUT;
    289     case 0x36: return MBlaze::TNAPUT;
    290     case 0x38: return MBlaze::NCPUT;
    291     case 0x3A: return MBlaze::NCAPUT;
    292     case 0x3C: return MBlaze::TNCPUT;
    293     case 0x3E: return MBlaze::TNCAPUT;
    294     }
    295 }
    296 
    297 static unsigned decodeGETD(uint32_t insn) {
    298     switch ((insn>>5)&0x3F) {
    299     default:   return UNSUPPORTED;
    300     case 0x00: return MBlaze::GETD;
    301     case 0x01: return MBlaze::EGETD;
    302     case 0x02: return MBlaze::AGETD;
    303     case 0x03: return MBlaze::EAGETD;
    304     case 0x04: return MBlaze::TGETD;
    305     case 0x05: return MBlaze::TEGETD;
    306     case 0x06: return MBlaze::TAGETD;
    307     case 0x07: return MBlaze::TEAGETD;
    308     case 0x08: return MBlaze::CGETD;
    309     case 0x09: return MBlaze::ECGETD;
    310     case 0x0A: return MBlaze::CAGETD;
    311     case 0x0B: return MBlaze::ECAGETD;
    312     case 0x0C: return MBlaze::TCGETD;
    313     case 0x0D: return MBlaze::TECGETD;
    314     case 0x0E: return MBlaze::TCAGETD;
    315     case 0x0F: return MBlaze::TECAGETD;
    316     case 0x10: return MBlaze::NGETD;
    317     case 0x11: return MBlaze::NEGETD;
    318     case 0x12: return MBlaze::NAGETD;
    319     case 0x13: return MBlaze::NEAGETD;
    320     case 0x14: return MBlaze::TNGETD;
    321     case 0x15: return MBlaze::TNEGETD;
    322     case 0x16: return MBlaze::TNAGETD;
    323     case 0x17: return MBlaze::TNEAGETD;
    324     case 0x18: return MBlaze::NCGETD;
    325     case 0x19: return MBlaze::NECGETD;
    326     case 0x1A: return MBlaze::NCAGETD;
    327     case 0x1B: return MBlaze::NECAGETD;
    328     case 0x1C: return MBlaze::TNCGETD;
    329     case 0x1D: return MBlaze::TNECGETD;
    330     case 0x1E: return MBlaze::TNCAGETD;
    331     case 0x1F: return MBlaze::TNECAGETD;
    332     case 0x20: return MBlaze::PUTD;
    333     case 0x22: return MBlaze::APUTD;
    334     case 0x24: return MBlaze::TPUTD;
    335     case 0x26: return MBlaze::TAPUTD;
    336     case 0x28: return MBlaze::CPUTD;
    337     case 0x2A: return MBlaze::CAPUTD;
    338     case 0x2C: return MBlaze::TCPUTD;
    339     case 0x2E: return MBlaze::TCAPUTD;
    340     case 0x30: return MBlaze::NPUTD;
    341     case 0x32: return MBlaze::NAPUTD;
    342     case 0x34: return MBlaze::TNPUTD;
    343     case 0x36: return MBlaze::TNAPUTD;
    344     case 0x38: return MBlaze::NCPUTD;
    345     case 0x3A: return MBlaze::NCAPUTD;
    346     case 0x3C: return MBlaze::TNCPUTD;
    347     case 0x3E: return MBlaze::TNCAPUTD;
    348     }
    349 }
    350 
    351 static unsigned decodeIDIV(uint32_t insn) {
    352     switch (insn&0x3) {
    353     default:  return UNSUPPORTED;
    354     case 0x0: return MBlaze::IDIV;
    355     case 0x2: return MBlaze::IDIVU;
    356     }
    357 }
    358 
    359 static unsigned decodeLBU(uint32_t insn) {
    360     switch ((insn>>9)&0x1) {
    361     default:  return UNSUPPORTED;
    362     case 0x0: return MBlaze::LBU;
    363     case 0x1: return MBlaze::LBUR;
    364     }
    365 }
    366 
    367 static unsigned decodeLHU(uint32_t insn) {
    368     switch ((insn>>9)&0x1) {
    369     default:  return UNSUPPORTED;
    370     case 0x0: return MBlaze::LHU;
    371     case 0x1: return MBlaze::LHUR;
    372     }
    373 }
    374 
    375 static unsigned decodeLW(uint32_t insn) {
    376     switch ((insn>>9)&0x3) {
    377     default:  return UNSUPPORTED;
    378     case 0x0: return MBlaze::LW;
    379     case 0x1: return MBlaze::LWR;
    380     case 0x2: return MBlaze::LWX;
    381     }
    382 }
    383 
    384 static unsigned decodeSB(uint32_t insn) {
    385     switch ((insn>>9)&0x1) {
    386     default:  return UNSUPPORTED;
    387     case 0x0: return MBlaze::SB;
    388     case 0x1: return MBlaze::SBR;
    389     }
    390 }
    391 
    392 static unsigned decodeSH(uint32_t insn) {
    393     switch ((insn>>9)&0x1) {
    394     default:  return UNSUPPORTED;
    395     case 0x0: return MBlaze::SH;
    396     case 0x1: return MBlaze::SHR;
    397     }
    398 }
    399 
    400 static unsigned decodeSW(uint32_t insn) {
    401     switch ((insn>>9)&0x3) {
    402     default:  return UNSUPPORTED;
    403     case 0x0: return MBlaze::SW;
    404     case 0x1: return MBlaze::SWR;
    405     case 0x2: return MBlaze::SWX;
    406     }
    407 }
    408 
    409 static unsigned decodeMFS(uint32_t insn) {
    410     switch ((insn>>15)&0x1) {
    411     default:   return UNSUPPORTED;
    412     case 0x0:
    413       switch ((insn>>16)&0x1) {
    414       default:   return UNSUPPORTED;
    415       case 0x0: return MBlaze::MSRSET;
    416       case 0x1: return MBlaze::MSRCLR;
    417       }
    418     case 0x1:
    419       switch ((insn>>14)&0x1) {
    420       default:   return UNSUPPORTED;
    421       case 0x0: return MBlaze::MFS;
    422       case 0x1: return MBlaze::MTS;
    423       }
    424     }
    425 }
    426 
    427 static unsigned decodeOR(uint32_t insn) {
    428     switch (getFLAGS(insn)) {
    429     default:    return UNSUPPORTED;
    430     case 0x000: return MBlaze::OR;
    431     case 0x400: return MBlaze::PCMPBF;
    432     }
    433 }
    434 
    435 static unsigned decodeXOR(uint32_t insn) {
    436     switch (getFLAGS(insn)) {
    437     default:    return UNSUPPORTED;
    438     case 0x000: return MBlaze::XOR;
    439     case 0x400: return MBlaze::PCMPEQ;
    440     }
    441 }
    442 
    443 static unsigned decodeANDN(uint32_t insn) {
    444     switch (getFLAGS(insn)) {
    445     default:    return UNSUPPORTED;
    446     case 0x000: return MBlaze::ANDN;
    447     case 0x400: return MBlaze::PCMPNE;
    448     }
    449 }
    450 
    451 static unsigned decodeRTSD(uint32_t insn) {
    452     switch ((insn>>21)&0x1F) {
    453     default:   return UNSUPPORTED;
    454     case 0x10: return MBlaze::RTSD;
    455     case 0x11: return MBlaze::RTID;
    456     case 0x12: return MBlaze::RTBD;
    457     case 0x14: return MBlaze::RTED;
    458     }
    459 }
    460 
    461 static unsigned getOPCODE(uint32_t insn) {
    462   unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
    463   switch (opcode) {
    464   case MBlaze::MUL:     return decodeMUL(insn);
    465   case MBlaze::SEXT8:   return decodeSEXT(insn);
    466   case MBlaze::BEQ:     return decodeBEQ(insn);
    467   case MBlaze::BEQI:    return decodeBEQI(insn);
    468   case MBlaze::BR:      return decodeBR(insn);
    469   case MBlaze::BRI:     return decodeBRI(insn);
    470   case MBlaze::BSRL:    return decodeBSRL(insn);
    471   case MBlaze::BSRLI:   return decodeBSRLI(insn);
    472   case MBlaze::RSUBK:   return decodeRSUBK(insn);
    473   case MBlaze::FADD:    return decodeFADD(insn);
    474   case MBlaze::GET:     return decodeGET(insn);
    475   case MBlaze::GETD:    return decodeGETD(insn);
    476   case MBlaze::IDIV:    return decodeIDIV(insn);
    477   case MBlaze::LBU:     return decodeLBU(insn);
    478   case MBlaze::LHU:     return decodeLHU(insn);
    479   case MBlaze::LW:      return decodeLW(insn);
    480   case MBlaze::SB:      return decodeSB(insn);
    481   case MBlaze::SH:      return decodeSH(insn);
    482   case MBlaze::SW:      return decodeSW(insn);
    483   case MBlaze::MFS:     return decodeMFS(insn);
    484   case MBlaze::OR:      return decodeOR(insn);
    485   case MBlaze::XOR:     return decodeXOR(insn);
    486   case MBlaze::ANDN:    return decodeANDN(insn);
    487   case MBlaze::RTSD:    return decodeRTSD(insn);
    488   default:              return opcode;
    489   }
    490 }
    491 
    492 //
    493 // Public interface for the disassembler
    494 //
    495 
    496 MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr,
    497                                         uint64_t &size,
    498                                         const MemoryObject &region,
    499                                         uint64_t address,
    500                                         raw_ostream &vStream,
    501                                         raw_ostream &cStream) const {
    502   // The machine instruction.
    503   uint32_t insn;
    504   uint64_t read;
    505   uint8_t bytes[4];
    506 
    507   // By default we consume 1 byte on failure
    508   size = 1;
    509 
    510   // We want to read exactly 4 bytes of data.
    511   if (region.readBytes(address, 4, (uint8_t*)bytes, &read) == -1 || read < 4)
    512     return Fail;
    513 
    514   // Encoded as a big-endian 32-bit word in the stream.
    515   insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
    516 
    517   // Get the MCInst opcode from the binary instruction and make sure
    518   // that it is a valid instruction.
    519   unsigned opcode = getOPCODE(insn);
    520   if (opcode == UNSUPPORTED)
    521     return Fail;
    522 
    523   instr.setOpcode(opcode);
    524 
    525   unsigned RD = getRD(insn);
    526   unsigned RA = getRA(insn);
    527   unsigned RB = getRB(insn);
    528   unsigned RS = getRS(insn);
    529 
    530   uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
    531   switch ((tsFlags & MBlazeII::FormMask)) {
    532   default:
    533     return Fail;
    534 
    535   case MBlazeII::FC:
    536     break;
    537 
    538   case MBlazeII::FRRRR:
    539     if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
    540       return Fail;
    541     instr.addOperand(MCOperand::CreateReg(RD));
    542     instr.addOperand(MCOperand::CreateReg(RB));
    543     instr.addOperand(MCOperand::CreateReg(RA));
    544     break;
    545 
    546   case MBlazeII::FRRR:
    547     if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
    548       return Fail;
    549     instr.addOperand(MCOperand::CreateReg(RD));
    550     instr.addOperand(MCOperand::CreateReg(RA));
    551     instr.addOperand(MCOperand::CreateReg(RB));
    552     break;
    553 
    554   case MBlazeII::FRR:
    555     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
    556       return Fail;
    557     instr.addOperand(MCOperand::CreateReg(RD));
    558     instr.addOperand(MCOperand::CreateReg(RA));
    559     break;
    560 
    561   case MBlazeII::FRI:
    562     switch (opcode) {
    563     default:
    564       return Fail;
    565     case MBlaze::MFS:
    566       if (RD == UNSUPPORTED)
    567         return Fail;
    568       instr.addOperand(MCOperand::CreateReg(RD));
    569       instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
    570       break;
    571     case MBlaze::MTS:
    572       if (RA == UNSUPPORTED)
    573         return Fail;
    574       instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
    575       instr.addOperand(MCOperand::CreateReg(RA));
    576       break;
    577     case MBlaze::MSRSET:
    578     case MBlaze::MSRCLR:
    579       if (RD == UNSUPPORTED)
    580         return Fail;
    581       instr.addOperand(MCOperand::CreateReg(RD));
    582       instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
    583       break;
    584     }
    585     break;
    586 
    587   case MBlazeII::FRRI:
    588     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
    589       return Fail;
    590     instr.addOperand(MCOperand::CreateReg(RD));
    591     instr.addOperand(MCOperand::CreateReg(RA));
    592     switch (opcode) {
    593     default:
    594       instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
    595       break;
    596     case MBlaze::BSRLI:
    597     case MBlaze::BSRAI:
    598     case MBlaze::BSLLI:
    599       instr.addOperand(MCOperand::CreateImm(insn&0x1F));
    600       break;
    601     }
    602     break;
    603 
    604   case MBlazeII::FCRR:
    605     if (RA == UNSUPPORTED || RB == UNSUPPORTED)
    606       return Fail;
    607     instr.addOperand(MCOperand::CreateReg(RA));
    608     instr.addOperand(MCOperand::CreateReg(RB));
    609     break;
    610 
    611   case MBlazeII::FCRI:
    612     if (RA == UNSUPPORTED)
    613       return Fail;
    614     instr.addOperand(MCOperand::CreateReg(RA));
    615     instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
    616     break;
    617 
    618   case MBlazeII::FRCR:
    619     if (RD == UNSUPPORTED || RB == UNSUPPORTED)
    620       return Fail;
    621     instr.addOperand(MCOperand::CreateReg(RD));
    622     instr.addOperand(MCOperand::CreateReg(RB));
    623     break;
    624 
    625   case MBlazeII::FRCI:
    626     if (RD == UNSUPPORTED)
    627       return Fail;
    628     instr.addOperand(MCOperand::CreateReg(RD));
    629     instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
    630     break;
    631 
    632   case MBlazeII::FCCR:
    633     if (RB == UNSUPPORTED)
    634       return Fail;
    635     instr.addOperand(MCOperand::CreateReg(RB));
    636     break;
    637 
    638   case MBlazeII::FCCI:
    639     instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
    640     break;
    641 
    642   case MBlazeII::FRRCI:
    643     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
    644       return Fail;
    645     instr.addOperand(MCOperand::CreateReg(RD));
    646     instr.addOperand(MCOperand::CreateReg(RA));
    647     instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
    648     break;
    649 
    650   case MBlazeII::FRRC:
    651     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
    652       return Fail;
    653     instr.addOperand(MCOperand::CreateReg(RD));
    654     instr.addOperand(MCOperand::CreateReg(RA));
    655     break;
    656 
    657   case MBlazeII::FRCX:
    658     if (RD == UNSUPPORTED)
    659       return Fail;
    660     instr.addOperand(MCOperand::CreateReg(RD));
    661     instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
    662     break;
    663 
    664   case MBlazeII::FRCS:
    665     if (RD == UNSUPPORTED || RS == UNSUPPORTED)
    666       return Fail;
    667     instr.addOperand(MCOperand::CreateReg(RD));
    668     instr.addOperand(MCOperand::CreateReg(RS));
    669     break;
    670 
    671   case MBlazeII::FCRCS:
    672     if (RS == UNSUPPORTED || RA == UNSUPPORTED)
    673       return Fail;
    674     instr.addOperand(MCOperand::CreateReg(RS));
    675     instr.addOperand(MCOperand::CreateReg(RA));
    676     break;
    677 
    678   case MBlazeII::FCRCX:
    679     if (RA == UNSUPPORTED)
    680       return Fail;
    681     instr.addOperand(MCOperand::CreateReg(RA));
    682     instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
    683     break;
    684 
    685   case MBlazeII::FCX:
    686     instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
    687     break;
    688 
    689   case MBlazeII::FCR:
    690     if (RB == UNSUPPORTED)
    691       return Fail;
    692     instr.addOperand(MCOperand::CreateReg(RB));
    693     break;
    694 
    695   case MBlazeII::FRIR:
    696     if (RD == UNSUPPORTED || RA == UNSUPPORTED)
    697       return Fail;
    698     instr.addOperand(MCOperand::CreateReg(RD));
    699     instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
    700     instr.addOperand(MCOperand::CreateReg(RA));
    701     break;
    702   }
    703 
    704   // We always consume 4 bytes of data on success
    705   size = 4;
    706 
    707   return Success;
    708 }
    709 
    710 static MCDisassembler *createMBlazeDisassembler(const Target &T,
    711                                                 const MCSubtargetInfo &STI) {
    712   return new MBlazeDisassembler(STI);
    713 }
    714 
    715 extern "C" void LLVMInitializeMBlazeDisassembler() {
    716   // Register the disassembler.
    717   TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
    718                                          createMBlazeDisassembler);
    719 }
    720