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
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
getRD(uint32_t insn)62 static unsigned getRD(uint32_t insn) {
63 if (!isMBlazeRegister((insn>>21)&0x1F))
64 return UNSUPPORTED;
65 return getMBlazeRegisterFromNumbering((insn>>21)&0x1F);
66 }
67
getRA(uint32_t insn)68 static unsigned getRA(uint32_t insn) {
69 if (!getMBlazeRegisterFromNumbering((insn>>16)&0x1F))
70 return UNSUPPORTED;
71 return getMBlazeRegisterFromNumbering((insn>>16)&0x1F);
72 }
73
getRB(uint32_t insn)74 static unsigned getRB(uint32_t insn) {
75 if (!getMBlazeRegisterFromNumbering((insn>>11)&0x1F))
76 return UNSUPPORTED;
77 return getMBlazeRegisterFromNumbering((insn>>11)&0x1F);
78 }
79
getRS(uint32_t insn)80 static int64_t getRS(uint32_t insn) {
81 if (!isSpecialMBlazeRegister(insn&0x3FFF))
82 return UNSUPPORTED;
83 return getSpecialMBlazeRegisterFromNumbering(insn&0x3FFF);
84 }
85
getIMM(uint32_t insn)86 static int64_t getIMM(uint32_t insn) {
87 int16_t val = (insn & 0xFFFF);
88 return val;
89 }
90
getSHT(uint32_t insn)91 static int64_t getSHT(uint32_t insn) {
92 int16_t val = (insn & 0x1F);
93 return val;
94 }
95
getFLAGS(int32_t insn)96 static unsigned getFLAGS(int32_t insn) {
97 return (insn & 0x7FF);
98 }
99
getFSL(uint32_t insn)100 static int64_t getFSL(uint32_t insn) {
101 int16_t val = (insn & 0xF);
102 return val;
103 }
104
decodeMUL(uint32_t insn)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
decodeSEXT(uint32_t insn)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
decodeBEQ(uint32_t insn)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
decodeBEQI(uint32_t insn)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
decodeBR(uint32_t insn)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
decodeBRI(uint32_t insn)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
decodeBSRL(uint32_t insn)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
decodeBSRLI(uint32_t insn)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
decodeRSUBK(uint32_t insn)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
decodeFADD(uint32_t insn)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
decodeGET(uint32_t insn)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
decodeGETD(uint32_t insn)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
decodeIDIV(uint32_t insn)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
decodeLBU(uint32_t insn)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
decodeLHU(uint32_t insn)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
decodeLW(uint32_t insn)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
decodeSB(uint32_t insn)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
decodeSH(uint32_t insn)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
decodeSW(uint32_t insn)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
decodeMFS(uint32_t insn)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
decodeOR(uint32_t insn)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
decodeXOR(uint32_t insn)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
decodeANDN(uint32_t insn)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
decodeRTSD(uint32_t insn)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
getOPCODE(uint32_t insn)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
getEDInfo() const488 EDInstInfo *MBlazeDisassembler::getEDInfo() const {
489 return instInfoMBlaze;
490 }
491
492 //
493 // Public interface for the disassembler
494 //
495
getInstruction(MCInst & instr,uint64_t & size,const MemoryObject & region,uint64_t address,raw_ostream & vStream,raw_ostream & cStream) const496 MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr,
497 uint64_t &size,
498 const MemoryObject ®ion,
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
createMBlazeDisassembler(const Target & T,const MCSubtargetInfo & STI)700 static MCDisassembler *createMBlazeDisassembler(const Target &T,
701 const MCSubtargetInfo &STI) {
702 return new MBlazeDisassembler(STI);
703 }
704
LLVMInitializeMBlazeDisassembler()705 extern "C" void LLVMInitializeMBlazeDisassembler() {
706 // Register the disassembler.
707 TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
708 createMBlazeDisassembler);
709 }
710