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