blob: 3379ac2169723b53090bf8ae2bbebcd435ec7c74 [file] [log] [blame]
Wesley Pecka0603832010-10-27 00:23:01 +00001//===- 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
33using namespace llvm;
34
35const unsigned UNSUPPORTED = -1;
36
37static 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
Wesley Peck0a67d922010-11-08 19:40:01 +000059static unsigned getRD(uint32_t insn) {
60 return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>21)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000061}
62
Wesley Peck0a67d922010-11-08 19:40:01 +000063static unsigned getRA(uint32_t insn) {
64 return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>16)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000065}
66
Wesley Peck0a67d922010-11-08 19:40:01 +000067static unsigned getRB(uint32_t insn) {
68 return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>11)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000069}
70
Wesley Peck0a67d922010-11-08 19:40:01 +000071static int64_t getRS(uint32_t insn) {
Wesley Peckd66a32c2010-12-20 21:18:04 +000072 return MBlazeRegisterInfo::getSpecialRegisterFromNumbering(insn&0x3FFF);
Wesley Pecka0603832010-10-27 00:23:01 +000073}
74
Wesley Peck0a67d922010-11-08 19:40:01 +000075static int64_t getIMM(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000076 int16_t val = (insn & 0xFFFF);
77 return val;
78}
79
Wesley Peck0a67d922010-11-08 19:40:01 +000080static int64_t getSHT(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000081 int16_t val = (insn & 0x1F);
82 return val;
83}
84
Wesley Peck0a67d922010-11-08 19:40:01 +000085static unsigned getFLAGS(int32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000086 return (insn & 0x7FF);
87}
88
Wesley Peck0a67d922010-11-08 19:40:01 +000089static int64_t getFSL(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000090 int16_t val = (insn & 0xF);
91 return val;
92}
93
94static unsigned decodeMUL(uint32_t insn) {
95 switch (getFLAGS(insn)) {
96 default: return UNSUPPORTED;
97 case 0: return MBlaze::MUL;
98 case 1: return MBlaze::MULH;
99 case 2: return MBlaze::MULHSU;
100 case 3: return MBlaze::MULHU;
101 }
102}
103
104static unsigned decodeSEXT(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000105 switch (insn&0x7FF) {
Wesley Pecka0603832010-10-27 00:23:01 +0000106 default: return UNSUPPORTED;
107 case 0x60: return MBlaze::SEXT8;
108 case 0x68: return MBlaze::WIC;
109 case 0x64: return MBlaze::WDC;
110 case 0x66: return MBlaze::WDCC;
111 case 0x74: return MBlaze::WDCF;
112 case 0x61: return MBlaze::SEXT16;
113 case 0x41: return MBlaze::SRL;
114 case 0x21: return MBlaze::SRC;
115 case 0x01: return MBlaze::SRA;
116 }
117}
118
119static unsigned decodeBEQ(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000120 switch ((insn>>21)&0x1F) {
Wesley Pecka0603832010-10-27 00:23:01 +0000121 default: return UNSUPPORTED;
122 case 0x00: return MBlaze::BEQ;
123 case 0x10: return MBlaze::BEQD;
124 case 0x05: return MBlaze::BGE;
125 case 0x15: return MBlaze::BGED;
126 case 0x04: return MBlaze::BGT;
127 case 0x14: return MBlaze::BGTD;
128 case 0x03: return MBlaze::BLE;
129 case 0x13: return MBlaze::BLED;
130 case 0x02: return MBlaze::BLT;
131 case 0x12: return MBlaze::BLTD;
132 case 0x01: return MBlaze::BNE;
133 case 0x11: return MBlaze::BNED;
134 }
135}
136
137static unsigned decodeBEQI(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000138 switch ((insn>>21)&0x1F) {
Wesley Pecka0603832010-10-27 00:23:01 +0000139 default: return UNSUPPORTED;
140 case 0x00: return MBlaze::BEQI;
141 case 0x10: return MBlaze::BEQID;
142 case 0x05: return MBlaze::BGEI;
143 case 0x15: return MBlaze::BGEID;
144 case 0x04: return MBlaze::BGTI;
145 case 0x14: return MBlaze::BGTID;
146 case 0x03: return MBlaze::BLEI;
147 case 0x13: return MBlaze::BLEID;
148 case 0x02: return MBlaze::BLTI;
149 case 0x12: return MBlaze::BLTID;
150 case 0x01: return MBlaze::BNEI;
151 case 0x11: return MBlaze::BNEID;
152 }
153}
154
155static unsigned decodeBR(uint32_t insn) {
156 switch ((insn>>16)&0x1F) {
157 default: return UNSUPPORTED;
158 case 0x00: return MBlaze::BR;
159 case 0x08: return MBlaze::BRA;
160 case 0x0C: return MBlaze::BRK;
161 case 0x10: return MBlaze::BRD;
162 case 0x14: return MBlaze::BRLD;
163 case 0x18: return MBlaze::BRAD;
164 case 0x1C: return MBlaze::BRALD;
165 }
166}
167
168static unsigned decodeBRI(uint32_t insn) {
169 switch ((insn>>16)&0x1F) {
170 default: return UNSUPPORTED;
171 case 0x00: return MBlaze::BRI;
172 case 0x08: return MBlaze::BRAI;
173 case 0x0C: return MBlaze::BRKI;
174 case 0x10: return MBlaze::BRID;
175 case 0x14: return MBlaze::BRLID;
176 case 0x18: return MBlaze::BRAID;
177 case 0x1C: return MBlaze::BRALID;
178 }
179}
180
181static unsigned decodeBSRL(uint32_t insn) {
182 switch ((insn>>9)&0x3) {
183 default: return UNSUPPORTED;
184 case 0x2: return MBlaze::BSLL;
185 case 0x1: return MBlaze::BSRA;
186 case 0x0: return MBlaze::BSRL;
187 }
188}
189
190static unsigned decodeBSRLI(uint32_t insn) {
191 switch ((insn>>9)&0x3) {
192 default: return UNSUPPORTED;
193 case 0x2: return MBlaze::BSLLI;
194 case 0x1: return MBlaze::BSRAI;
195 case 0x0: return MBlaze::BSRLI;
196 }
197}
198
199static unsigned decodeRSUBK(uint32_t insn) {
200 switch (getFLAGS(insn)) {
201 default: return UNSUPPORTED;
202 case 0x0: return MBlaze::RSUBK;
203 case 0x1: return MBlaze::CMP;
204 case 0x3: return MBlaze::CMPU;
205 }
206}
207
208static unsigned decodeFADD(uint32_t insn) {
209 switch (getFLAGS(insn)) {
210 default: return UNSUPPORTED;
211 case 0x000: return MBlaze::FADD;
212 case 0x080: return MBlaze::FRSUB;
213 case 0x100: return MBlaze::FMUL;
214 case 0x180: return MBlaze::FDIV;
215 case 0x200: return MBlaze::FCMP_UN;
216 case 0x210: return MBlaze::FCMP_LT;
217 case 0x220: return MBlaze::FCMP_EQ;
218 case 0x230: return MBlaze::FCMP_LE;
219 case 0x240: return MBlaze::FCMP_GT;
220 case 0x250: return MBlaze::FCMP_NE;
221 case 0x260: return MBlaze::FCMP_GE;
222 case 0x280: return MBlaze::FLT;
223 case 0x300: return MBlaze::FINT;
224 case 0x380: return MBlaze::FSQRT;
225 }
226}
227
228static unsigned decodeGET(uint32_t insn) {
229 switch ((insn>>10)&0x3F) {
230 default: return UNSUPPORTED;
231 case 0x00: return MBlaze::GET;
232 case 0x01: return MBlaze::EGET;
233 case 0x02: return MBlaze::AGET;
234 case 0x03: return MBlaze::EAGET;
235 case 0x04: return MBlaze::TGET;
236 case 0x05: return MBlaze::TEGET;
237 case 0x06: return MBlaze::TAGET;
238 case 0x07: return MBlaze::TEAGET;
239 case 0x08: return MBlaze::CGET;
240 case 0x09: return MBlaze::ECGET;
241 case 0x0A: return MBlaze::CAGET;
242 case 0x0B: return MBlaze::ECAGET;
243 case 0x0C: return MBlaze::TCGET;
244 case 0x0D: return MBlaze::TECGET;
245 case 0x0E: return MBlaze::TCAGET;
246 case 0x0F: return MBlaze::TECAGET;
247 case 0x10: return MBlaze::NGET;
248 case 0x11: return MBlaze::NEGET;
249 case 0x12: return MBlaze::NAGET;
250 case 0x13: return MBlaze::NEAGET;
251 case 0x14: return MBlaze::TNGET;
252 case 0x15: return MBlaze::TNEGET;
253 case 0x16: return MBlaze::TNAGET;
254 case 0x17: return MBlaze::TNEAGET;
255 case 0x18: return MBlaze::NCGET;
256 case 0x19: return MBlaze::NECGET;
257 case 0x1A: return MBlaze::NCAGET;
258 case 0x1B: return MBlaze::NECAGET;
259 case 0x1C: return MBlaze::TNCGET;
260 case 0x1D: return MBlaze::TNECGET;
261 case 0x1E: return MBlaze::TNCAGET;
262 case 0x1F: return MBlaze::TNECAGET;
263 case 0x20: return MBlaze::PUT;
264 case 0x22: return MBlaze::APUT;
265 case 0x24: return MBlaze::TPUT;
266 case 0x26: return MBlaze::TAPUT;
267 case 0x28: return MBlaze::CPUT;
268 case 0x2A: return MBlaze::CAPUT;
269 case 0x2C: return MBlaze::TCPUT;
270 case 0x2E: return MBlaze::TCAPUT;
271 case 0x30: return MBlaze::NPUT;
272 case 0x32: return MBlaze::NAPUT;
273 case 0x34: return MBlaze::TNPUT;
274 case 0x36: return MBlaze::TNAPUT;
275 case 0x38: return MBlaze::NCPUT;
276 case 0x3A: return MBlaze::NCAPUT;
277 case 0x3C: return MBlaze::TNCPUT;
278 case 0x3E: return MBlaze::TNCAPUT;
279 }
280}
281
282static unsigned decodeGETD(uint32_t insn) {
283 switch ((insn>>5)&0x3F) {
284 default: return UNSUPPORTED;
285 case 0x00: return MBlaze::GETD;
286 case 0x01: return MBlaze::EGETD;
287 case 0x02: return MBlaze::AGETD;
288 case 0x03: return MBlaze::EAGETD;
289 case 0x04: return MBlaze::TGETD;
290 case 0x05: return MBlaze::TEGETD;
291 case 0x06: return MBlaze::TAGETD;
292 case 0x07: return MBlaze::TEAGETD;
293 case 0x08: return MBlaze::CGETD;
294 case 0x09: return MBlaze::ECGETD;
295 case 0x0A: return MBlaze::CAGETD;
296 case 0x0B: return MBlaze::ECAGETD;
297 case 0x0C: return MBlaze::TCGETD;
298 case 0x0D: return MBlaze::TECGETD;
299 case 0x0E: return MBlaze::TCAGETD;
300 case 0x0F: return MBlaze::TECAGETD;
301 case 0x10: return MBlaze::NGETD;
302 case 0x11: return MBlaze::NEGETD;
303 case 0x12: return MBlaze::NAGETD;
304 case 0x13: return MBlaze::NEAGETD;
305 case 0x14: return MBlaze::TNGETD;
306 case 0x15: return MBlaze::TNEGETD;
307 case 0x16: return MBlaze::TNAGETD;
308 case 0x17: return MBlaze::TNEAGETD;
309 case 0x18: return MBlaze::NCGETD;
310 case 0x19: return MBlaze::NECGETD;
311 case 0x1A: return MBlaze::NCAGETD;
312 case 0x1B: return MBlaze::NECAGETD;
313 case 0x1C: return MBlaze::TNCGETD;
314 case 0x1D: return MBlaze::TNECGETD;
315 case 0x1E: return MBlaze::TNCAGETD;
316 case 0x1F: return MBlaze::TNECAGETD;
317 case 0x20: return MBlaze::PUTD;
318 case 0x22: return MBlaze::APUTD;
319 case 0x24: return MBlaze::TPUTD;
320 case 0x26: return MBlaze::TAPUTD;
321 case 0x28: return MBlaze::CPUTD;
322 case 0x2A: return MBlaze::CAPUTD;
323 case 0x2C: return MBlaze::TCPUTD;
324 case 0x2E: return MBlaze::TCAPUTD;
325 case 0x30: return MBlaze::NPUTD;
326 case 0x32: return MBlaze::NAPUTD;
327 case 0x34: return MBlaze::TNPUTD;
328 case 0x36: return MBlaze::TNAPUTD;
329 case 0x38: return MBlaze::NCPUTD;
330 case 0x3A: return MBlaze::NCAPUTD;
331 case 0x3C: return MBlaze::TNCPUTD;
332 case 0x3E: return MBlaze::TNCAPUTD;
333 }
334}
335
336static unsigned decodeIDIV(uint32_t insn) {
337 switch (insn&0x3) {
338 default: return UNSUPPORTED;
339 case 0x0: return MBlaze::IDIV;
340 case 0x2: return MBlaze::IDIVU;
341 }
342}
343
Wesley Peckec57d532010-11-13 02:37:59 +0000344static unsigned decodeLBU(uint32_t insn) {
345 switch ((insn>>9)&0x1) {
346 default: return UNSUPPORTED;
347 case 0x0: return MBlaze::LBU;
348 case 0x1: return MBlaze::LBUR;
349 }
350}
351
352static unsigned decodeLHU(uint32_t insn) {
353 switch ((insn>>9)&0x1) {
354 default: return UNSUPPORTED;
355 case 0x0: return MBlaze::LHU;
356 case 0x1: return MBlaze::LHUR;
357 }
358}
359
Wesley Pecka0603832010-10-27 00:23:01 +0000360static unsigned decodeLW(uint32_t insn) {
361 switch ((insn>>9)&0x3) {
362 default: return UNSUPPORTED;
363 case 0x0: return MBlaze::LW;
364 case 0x1: return MBlaze::LWR;
365 case 0x2: return MBlaze::LWX;
366 }
367}
368
Wesley Peckec57d532010-11-13 02:37:59 +0000369static unsigned decodeSB(uint32_t insn) {
370 switch ((insn>>9)&0x1) {
371 default: return UNSUPPORTED;
372 case 0x0: return MBlaze::SB;
373 case 0x1: return MBlaze::SBR;
374 }
375}
376
377static unsigned decodeSH(uint32_t insn) {
378 switch ((insn>>9)&0x1) {
379 default: return UNSUPPORTED;
380 case 0x0: return MBlaze::SH;
381 case 0x1: return MBlaze::SHR;
382 }
383}
384
Wesley Pecka0603832010-10-27 00:23:01 +0000385static unsigned decodeSW(uint32_t insn) {
386 switch ((insn>>9)&0x3) {
387 default: return UNSUPPORTED;
388 case 0x0: return MBlaze::SW;
389 case 0x1: return MBlaze::SWR;
390 case 0x2: return MBlaze::SWX;
391 }
392}
393
394static unsigned decodeMFS(uint32_t insn) {
395 switch ((insn>>15)&0x1) {
396 default: return UNSUPPORTED;
397 case 0x0:
Wesley Peckec57d532010-11-13 02:37:59 +0000398 switch ((insn>>16)&0x1) {
Wesley Pecka0603832010-10-27 00:23:01 +0000399 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000400 case 0x0: return MBlaze::MSRSET;
401 case 0x1: return MBlaze::MSRCLR;
Wesley Pecka0603832010-10-27 00:23:01 +0000402 }
403 case 0x1:
404 switch ((insn>>14)&0x1) {
405 default: return UNSUPPORTED;
406 case 0x0: return MBlaze::MFS;
407 case 0x1: return MBlaze::MTS;
408 }
409 }
410}
411
412static unsigned decodeOR(uint32_t insn) {
413 switch (getFLAGS(insn)) {
414 default: return UNSUPPORTED;
415 case 0x000: return MBlaze::OR;
416 case 0x400: return MBlaze::PCMPBF;
417 }
418}
419
420static unsigned decodeXOR(uint32_t insn) {
421 switch (getFLAGS(insn)) {
422 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000423 case 0x000: return MBlaze::XOR;
Wesley Pecka0603832010-10-27 00:23:01 +0000424 case 0x400: return MBlaze::PCMPEQ;
425 }
426}
427
428static unsigned decodeANDN(uint32_t insn) {
429 switch (getFLAGS(insn)) {
430 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000431 case 0x000: return MBlaze::ANDN;
Wesley Pecka0603832010-10-27 00:23:01 +0000432 case 0x400: return MBlaze::PCMPNE;
433 }
434}
435
436static unsigned decodeRTSD(uint32_t insn) {
437 switch ((insn>>21)&0x1F) {
438 default: return UNSUPPORTED;
439 case 0x10: return MBlaze::RTSD;
440 case 0x11: return MBlaze::RTID;
441 case 0x12: return MBlaze::RTBD;
442 case 0x14: return MBlaze::RTED;
443 }
444}
445
Wesley Peck0a67d922010-11-08 19:40:01 +0000446static unsigned getOPCODE(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +0000447 unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
448 switch (opcode) {
449 case MBlaze::MUL: return decodeMUL(insn);
450 case MBlaze::SEXT8: return decodeSEXT(insn);
451 case MBlaze::BEQ: return decodeBEQ(insn);
452 case MBlaze::BEQI: return decodeBEQI(insn);
453 case MBlaze::BR: return decodeBR(insn);
454 case MBlaze::BRI: return decodeBRI(insn);
455 case MBlaze::BSRL: return decodeBSRL(insn);
456 case MBlaze::BSRLI: return decodeBSRLI(insn);
457 case MBlaze::RSUBK: return decodeRSUBK(insn);
458 case MBlaze::FADD: return decodeFADD(insn);
459 case MBlaze::GET: return decodeGET(insn);
460 case MBlaze::GETD: return decodeGETD(insn);
461 case MBlaze::IDIV: return decodeIDIV(insn);
Wesley Peckec57d532010-11-13 02:37:59 +0000462 case MBlaze::LBU: return decodeLBU(insn);
463 case MBlaze::LHU: return decodeLHU(insn);
Wesley Pecka0603832010-10-27 00:23:01 +0000464 case MBlaze::LW: return decodeLW(insn);
Wesley Peckec57d532010-11-13 02:37:59 +0000465 case MBlaze::SB: return decodeSB(insn);
466 case MBlaze::SH: return decodeSH(insn);
Wesley Pecka0603832010-10-27 00:23:01 +0000467 case MBlaze::SW: return decodeSW(insn);
468 case MBlaze::MFS: return decodeMFS(insn);
469 case MBlaze::OR: return decodeOR(insn);
470 case MBlaze::XOR: return decodeXOR(insn);
471 case MBlaze::ANDN: return decodeANDN(insn);
472 case MBlaze::RTSD: return decodeRTSD(insn);
473 default: return opcode;
474 }
475}
476
477EDInstInfo *MBlazeDisassembler::getEDInfo() const {
478 return instInfoMBlaze;
479}
480
481//
482// Public interface for the disassembler
483//
484
485bool MBlazeDisassembler::getInstruction(MCInst &instr,
486 uint64_t &size,
487 const MemoryObject &region,
488 uint64_t address,
489 raw_ostream &vStream) const {
490 // The machine instruction.
491 uint32_t insn;
492 uint8_t bytes[4];
Wesley Peckec57d532010-11-13 02:37:59 +0000493
Wesley Peck90eff732010-11-13 05:48:21 +0000494 // We always consume 4 bytes of data
495 size = 4;
496
Wesley Pecka0603832010-10-27 00:23:01 +0000497 // We want to read exactly 4 bytes of data.
498 if (region.readBytes(address, 4, (uint8_t*)bytes, NULL) == -1)
499 return false;
500
501 // Encoded as a big-endian 32-bit word in the stream.
502 insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
503
504 // Get the MCInst opcode from the binary instruction and make sure
505 // that it is a valid instruction.
Wesley Peck0a67d922010-11-08 19:40:01 +0000506 unsigned opcode = getOPCODE(insn);
507 if (opcode == UNSUPPORTED)
Wesley Pecka0603832010-10-27 00:23:01 +0000508 return false;
509
510 instr.setOpcode(opcode);
511
512 uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
Wesley Peck0a67d922010-11-08 19:40:01 +0000513 switch ((tsFlags & MBlazeII::FormMask)) {
514 default: llvm_unreachable("unknown instruction encoding");
Wesley Pecka0603832010-10-27 00:23:01 +0000515
Wesley Peckec57d532010-11-13 02:37:59 +0000516 case MBlazeII::FRRRR:
517 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
518 instr.addOperand(MCOperand::CreateReg(getRB(insn)));
519 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
520 break;
521
Wesley Pecka0603832010-10-27 00:23:01 +0000522 case MBlazeII::FRRR:
Wesley Peck0a67d922010-11-08 19:40:01 +0000523 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
524 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
525 instr.addOperand(MCOperand::CreateReg(getRB(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000526 break;
527
Wesley Peckec57d532010-11-13 02:37:59 +0000528 case MBlazeII::FRI:
529 switch (opcode) {
530 default: llvm_unreachable("unknown instruction encoding");
531 case MBlaze::MFS:
532 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
533 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
534 break;
535 case MBlaze::MTS:
536 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
537 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
538 break;
539 case MBlaze::MSRSET:
540 case MBlaze::MSRCLR:
541 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
542 instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
543 break;
544 }
545 break;
546
Wesley Pecka0603832010-10-27 00:23:01 +0000547 case MBlazeII::FRRI:
Wesley Peck0a67d922010-11-08 19:40:01 +0000548 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
549 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
Wesley Peckec57d532010-11-13 02:37:59 +0000550 switch (opcode) {
551 default:
552 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
553 break;
554 case MBlaze::BSRLI:
555 case MBlaze::BSRAI:
556 case MBlaze::BSLLI:
557 instr.addOperand(MCOperand::CreateImm(insn&0x1F));
558 break;
559 }
Wesley Pecka0603832010-10-27 00:23:01 +0000560 break;
561
562 case MBlazeII::FCRR:
Wesley Peck0a67d922010-11-08 19:40:01 +0000563 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
564 instr.addOperand(MCOperand::CreateReg(getRB(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000565 break;
566
567 case MBlazeII::FCRI:
Wesley Peck0a67d922010-11-08 19:40:01 +0000568 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
569 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000570 break;
571
572 case MBlazeII::FRCR:
Wesley Peck0a67d922010-11-08 19:40:01 +0000573 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
574 instr.addOperand(MCOperand::CreateReg(getRB(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000575 break;
576
577 case MBlazeII::FRCI:
Wesley Peck0a67d922010-11-08 19:40:01 +0000578 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
579 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000580 break;
581
582 case MBlazeII::FCCR:
Wesley Peck0a67d922010-11-08 19:40:01 +0000583 instr.addOperand(MCOperand::CreateReg(getRB(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000584 break;
585
586 case MBlazeII::FCCI:
Wesley Peck0a67d922010-11-08 19:40:01 +0000587 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000588 break;
589
590 case MBlazeII::FRRCI:
Wesley Peck0a67d922010-11-08 19:40:01 +0000591 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
592 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
593 instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000594 break;
595
596 case MBlazeII::FRRC:
Wesley Peck0a67d922010-11-08 19:40:01 +0000597 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
598 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000599 break;
600
601 case MBlazeII::FRCX:
Wesley Peck0a67d922010-11-08 19:40:01 +0000602 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
603 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000604 break;
605
606 case MBlazeII::FRCS:
Wesley Peck0a67d922010-11-08 19:40:01 +0000607 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
Wesley Peckd66a32c2010-12-20 21:18:04 +0000608 instr.addOperand(MCOperand::CreateReg(getRS(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000609 break;
610
611 case MBlazeII::FCRCS:
Wesley Peckd66a32c2010-12-20 21:18:04 +0000612 instr.addOperand(MCOperand::CreateReg(getRS(insn)));
Wesley Peck0a67d922010-11-08 19:40:01 +0000613 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000614 break;
615
616 case MBlazeII::FCRCX:
Wesley Peck0a67d922010-11-08 19:40:01 +0000617 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
618 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000619 break;
620
621 case MBlazeII::FCX:
Wesley Peck0a67d922010-11-08 19:40:01 +0000622 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000623 break;
624
625 case MBlazeII::FCR:
Wesley Peck0a67d922010-11-08 19:40:01 +0000626 instr.addOperand(MCOperand::CreateReg(getRB(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000627 break;
628
629 case MBlazeII::FRIR:
Wesley Peck0a67d922010-11-08 19:40:01 +0000630 instr.addOperand(MCOperand::CreateReg(getRD(insn)));
631 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
632 instr.addOperand(MCOperand::CreateReg(getRA(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000633 break;
634 }
635
636 return true;
637}
638
639static MCDisassembler *createMBlazeDisassembler(const Target &T) {
640 return new MBlazeDisassembler;
641}
642
Wesley Peckec57d532010-11-13 02:37:59 +0000643extern "C" void LLVMInitializeMBlazeDisassembler() {
Wesley Pecka0603832010-10-27 00:23:01 +0000644 // Register the disassembler.
Wesley Peckec57d532010-11-13 02:37:59 +0000645 TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
Wesley Pecka0603832010-10-27 00:23:01 +0000646 createMBlazeDisassembler);
647}