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