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