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/Support/Debug.h"
24#include "llvm/Support/MemoryObject.h"
25#include "llvm/Support/TargetRegistry.h"
26#include "llvm/Support/raw_ostream.h"
27
28// #include "MBlazeGenDecoderTables.inc"
29// #include "MBlazeGenRegisterNames.inc"
30#include "MBlazeGenEDInfo.inc"
31
32namespace llvm {
33extern MCInstrDesc MBlazeInsts[];
34}
35
36using namespace llvm;
37
38const unsigned UNSUPPORTED = -1;
39
40static 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
62static unsigned getRD(uint32_t insn) {
63  if (!isMBlazeRegister((insn>>21)&0x1F))
64    return UNSUPPORTED;
65  return getMBlazeRegisterFromNumbering((insn>>21)&0x1F);
66}
67
68static unsigned getRA(uint32_t insn) {
69  if (!getMBlazeRegisterFromNumbering((insn>>16)&0x1F))
70    return UNSUPPORTED;
71  return getMBlazeRegisterFromNumbering((insn>>16)&0x1F);
72}
73
74static unsigned getRB(uint32_t insn) {
75  if (!getMBlazeRegisterFromNumbering((insn>>11)&0x1F))
76    return UNSUPPORTED;
77  return getMBlazeRegisterFromNumbering((insn>>11)&0x1F);
78}
79
80static int64_t getRS(uint32_t insn) {
81  if (!isSpecialMBlazeRegister(insn&0x3FFF))
82    return UNSUPPORTED;
83  return getSpecialMBlazeRegisterFromNumbering(insn&0x3FFF);
84}
85
86static int64_t getIMM(uint32_t insn) {
87    int16_t val = (insn & 0xFFFF);
88    return val;
89}
90
91static int64_t getSHT(uint32_t insn) {
92    int16_t val = (insn & 0x1F);
93    return val;
94}
95
96static unsigned getFLAGS(int32_t insn) {
97    return (insn & 0x7FF);
98}
99
100static int64_t getFSL(uint32_t insn) {
101    int16_t val = (insn & 0xF);
102    return val;
103}
104
105static 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
115static 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
130static 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
148static 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
166static 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
179static 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
192static 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
201static 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
210static 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
219static 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
239static 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
293static 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
347static 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
355static 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
363static 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
371static 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
380static 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
388static 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
396static 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
405static 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
423static 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
431static 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
439static 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
447static 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
457static 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
488EDInstInfo *MBlazeDisassembler::getEDInfo() const {
489  return instInfoMBlaze;
490}
491
492//
493// Public interface for the disassembler
494//
495
496MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr,
497                                        uint64_t &size,
498                                        const MemoryObject &region,
499                                        uint64_t address,
500                                        raw_ostream &vStream,
501                                        raw_ostream &cStream) const {
502  // The machine instruction.
503  uint32_t insn;
504  uint64_t read;
505  uint8_t bytes[4];
506
507  // By default we consume 1 byte on failure
508  size = 1;
509
510  // We want to read exactly 4 bytes of data.
511  if (region.readBytes(address, 4, (uint8_t*)bytes, &read) == -1 || read < 4)
512    return Fail;
513
514  // Encoded as a big-endian 32-bit word in the stream.
515  insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
516
517  // Get the MCInst opcode from the binary instruction and make sure
518  // that it is a valid instruction.
519  unsigned opcode = getOPCODE(insn);
520  if (opcode == UNSUPPORTED)
521    return Fail;
522
523  instr.setOpcode(opcode);
524
525  unsigned RD = getRD(insn);
526  unsigned RA = getRA(insn);
527  unsigned RB = getRB(insn);
528  unsigned RS = getRS(insn);
529
530  uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
531  switch ((tsFlags & MBlazeII::FormMask)) {
532  default:
533    return Fail;
534
535  case MBlazeII::FRRRR:
536    if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
537      return Fail;
538    instr.addOperand(MCOperand::CreateReg(RD));
539    instr.addOperand(MCOperand::CreateReg(RB));
540    instr.addOperand(MCOperand::CreateReg(RA));
541    break;
542
543  case MBlazeII::FRRR:
544    if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
545      return Fail;
546    instr.addOperand(MCOperand::CreateReg(RD));
547    instr.addOperand(MCOperand::CreateReg(RA));
548    instr.addOperand(MCOperand::CreateReg(RB));
549    break;
550
551  case MBlazeII::FRI:
552    switch (opcode) {
553    default:
554      return Fail;
555    case MBlaze::MFS:
556      if (RD == UNSUPPORTED)
557        return Fail;
558      instr.addOperand(MCOperand::CreateReg(RD));
559      instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
560      break;
561    case MBlaze::MTS:
562      if (RA == UNSUPPORTED)
563        return Fail;
564      instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
565      instr.addOperand(MCOperand::CreateReg(RA));
566      break;
567    case MBlaze::MSRSET:
568    case MBlaze::MSRCLR:
569      if (RD == UNSUPPORTED)
570        return Fail;
571      instr.addOperand(MCOperand::CreateReg(RD));
572      instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
573      break;
574    }
575    break;
576
577  case MBlazeII::FRRI:
578    if (RD == UNSUPPORTED || RA == UNSUPPORTED)
579      return Fail;
580    instr.addOperand(MCOperand::CreateReg(RD));
581    instr.addOperand(MCOperand::CreateReg(RA));
582    switch (opcode) {
583    default:
584      instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
585      break;
586    case MBlaze::BSRLI:
587    case MBlaze::BSRAI:
588    case MBlaze::BSLLI:
589      instr.addOperand(MCOperand::CreateImm(insn&0x1F));
590      break;
591    }
592    break;
593
594  case MBlazeII::FCRR:
595    if (RA == UNSUPPORTED || RB == UNSUPPORTED)
596      return Fail;
597    instr.addOperand(MCOperand::CreateReg(RA));
598    instr.addOperand(MCOperand::CreateReg(RB));
599    break;
600
601  case MBlazeII::FCRI:
602    if (RA == UNSUPPORTED)
603      return Fail;
604    instr.addOperand(MCOperand::CreateReg(RA));
605    instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
606    break;
607
608  case MBlazeII::FRCR:
609    if (RD == UNSUPPORTED || RB == UNSUPPORTED)
610      return Fail;
611    instr.addOperand(MCOperand::CreateReg(RD));
612    instr.addOperand(MCOperand::CreateReg(RB));
613    break;
614
615  case MBlazeII::FRCI:
616    if (RD == UNSUPPORTED)
617      return Fail;
618    instr.addOperand(MCOperand::CreateReg(RD));
619    instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
620    break;
621
622  case MBlazeII::FCCR:
623    if (RB == UNSUPPORTED)
624      return Fail;
625    instr.addOperand(MCOperand::CreateReg(RB));
626    break;
627
628  case MBlazeII::FCCI:
629    instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
630    break;
631
632  case MBlazeII::FRRCI:
633    if (RD == UNSUPPORTED || RA == UNSUPPORTED)
634      return Fail;
635    instr.addOperand(MCOperand::CreateReg(RD));
636    instr.addOperand(MCOperand::CreateReg(RA));
637    instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
638    break;
639
640  case MBlazeII::FRRC:
641    if (RD == UNSUPPORTED || RA == UNSUPPORTED)
642      return Fail;
643    instr.addOperand(MCOperand::CreateReg(RD));
644    instr.addOperand(MCOperand::CreateReg(RA));
645    break;
646
647  case MBlazeII::FRCX:
648    if (RD == UNSUPPORTED)
649      return Fail;
650    instr.addOperand(MCOperand::CreateReg(RD));
651    instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
652    break;
653
654  case MBlazeII::FRCS:
655    if (RD == UNSUPPORTED || RS == UNSUPPORTED)
656      return Fail;
657    instr.addOperand(MCOperand::CreateReg(RD));
658    instr.addOperand(MCOperand::CreateReg(RS));
659    break;
660
661  case MBlazeII::FCRCS:
662    if (RS == UNSUPPORTED || RA == UNSUPPORTED)
663      return Fail;
664    instr.addOperand(MCOperand::CreateReg(RS));
665    instr.addOperand(MCOperand::CreateReg(RA));
666    break;
667
668  case MBlazeII::FCRCX:
669    if (RA == UNSUPPORTED)
670      return Fail;
671    instr.addOperand(MCOperand::CreateReg(RA));
672    instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
673    break;
674
675  case MBlazeII::FCX:
676    instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
677    break;
678
679  case MBlazeII::FCR:
680    if (RB == UNSUPPORTED)
681      return Fail;
682    instr.addOperand(MCOperand::CreateReg(RB));
683    break;
684
685  case MBlazeII::FRIR:
686    if (RD == UNSUPPORTED || RA == UNSUPPORTED)
687      return Fail;
688    instr.addOperand(MCOperand::CreateReg(RD));
689    instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
690    instr.addOperand(MCOperand::CreateReg(RA));
691    break;
692  }
693
694  // We always consume 4 bytes of data on success
695  size = 4;
696
697  return Success;
698}
699
700static MCDisassembler *createMBlazeDisassembler(const Target &T,
701                                                const MCSubtargetInfo &STI) {
702  return new MBlazeDisassembler(STI);
703}
704
705extern "C" void LLVMInitializeMBlazeDisassembler() {
706  // Register the disassembler.
707  TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
708                                         createMBlazeDisassembler);
709}
710