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