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