blob: 14642742e349c8ac1f3f991b672195c35139db02 [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"
Evan Cheng22fee2d2011-06-28 20:07:07 +000030#define GET_INSTRINFO_MC_DESC
Wesley Pecka0603832010-10-27 00:23:01 +000031#include "MBlazeGenInstrInfo.inc"
32#include "MBlazeGenEDInfo.inc"
33
34using namespace llvm;
35
36const unsigned UNSUPPORTED = -1;
37
38static unsigned mblazeBinary2Opcode[] = {
39 MBlaze::ADD, MBlaze::RSUB, MBlaze::ADDC, MBlaze::RSUBC, //00,01,02,03
40 MBlaze::ADDK, MBlaze::RSUBK, MBlaze::ADDKC, MBlaze::RSUBKC, //04,05,06,07
41 MBlaze::ADDI, MBlaze::RSUBI, MBlaze::ADDIC, MBlaze::RSUBIC, //08,09,0A,0B
42 MBlaze::ADDIK, MBlaze::RSUBIK, MBlaze::ADDIKC, MBlaze::RSUBIKC, //0C,0D,0E,0F
43
44 MBlaze::MUL, MBlaze::BSRL, MBlaze::IDIV, MBlaze::GETD, //10,11,12,13
45 UNSUPPORTED, UNSUPPORTED, MBlaze::FADD, UNSUPPORTED, //14,15,16,17
46 MBlaze::MULI, MBlaze::BSRLI, UNSUPPORTED, MBlaze::GET, //18,19,1A,1B
47 UNSUPPORTED, UNSUPPORTED, UNSUPPORTED, UNSUPPORTED, //1C,1D,1E,1F
48
49 MBlaze::OR, MBlaze::AND, MBlaze::XOR, MBlaze::ANDN, //20,21,22,23
50 MBlaze::SEXT8, MBlaze::MFS, MBlaze::BR, MBlaze::BEQ, //24,25,26,27
51 MBlaze::ORI, MBlaze::ANDI, MBlaze::XORI, MBlaze::ANDNI, //28,29,2A,2B
52 MBlaze::IMM, MBlaze::RTSD, MBlaze::BRI, MBlaze::BEQI, //2C,2D,2E,2F
53
54 MBlaze::LBU, MBlaze::LHU, MBlaze::LW, UNSUPPORTED, //30,31,32,33
55 MBlaze::SB, MBlaze::SH, MBlaze::SW, UNSUPPORTED, //34,35,36,37
56 MBlaze::LBUI, MBlaze::LHUI, MBlaze::LWI, UNSUPPORTED, //38,39,3A,3B
57 MBlaze::SBI, MBlaze::SHI, MBlaze::SWI, UNSUPPORTED, //3C,3D,3E,3F
58};
59
Wesley Peck0a67d922010-11-08 19:40:01 +000060static unsigned getRD(uint32_t insn) {
Wesley Pecke53060f2011-04-11 21:35:21 +000061 if (!MBlazeRegisterInfo::isRegister((insn>>21)&0x1F))
62 return UNSUPPORTED;
Wesley Peck0a67d922010-11-08 19:40:01 +000063 return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>21)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000064}
65
Wesley Peck0a67d922010-11-08 19:40:01 +000066static unsigned getRA(uint32_t insn) {
Wesley Pecke53060f2011-04-11 21:35:21 +000067 if (!MBlazeRegisterInfo::getRegisterFromNumbering((insn>>16)&0x1F))
68 return UNSUPPORTED;
Wesley Peck0a67d922010-11-08 19:40:01 +000069 return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>16)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000070}
71
Wesley Peck0a67d922010-11-08 19:40:01 +000072static unsigned getRB(uint32_t insn) {
Wesley Pecke53060f2011-04-11 21:35:21 +000073 if (!MBlazeRegisterInfo::getRegisterFromNumbering((insn>>11)&0x1F))
74 return UNSUPPORTED;
Wesley Peck0a67d922010-11-08 19:40:01 +000075 return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>11)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000076}
77
Wesley Peck0a67d922010-11-08 19:40:01 +000078static int64_t getRS(uint32_t insn) {
Wesley Pecke53060f2011-04-11 21:35:21 +000079 if (!MBlazeRegisterInfo::isSpecialRegister(insn&0x3FFF))
80 return UNSUPPORTED;
Wesley Peckd66a32c2010-12-20 21:18:04 +000081 return MBlazeRegisterInfo::getSpecialRegisterFromNumbering(insn&0x3FFF);
Wesley Pecka0603832010-10-27 00:23:01 +000082}
83
Wesley Peck0a67d922010-11-08 19:40:01 +000084static int64_t getIMM(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000085 int16_t val = (insn & 0xFFFF);
86 return val;
87}
88
Wesley Peck0a67d922010-11-08 19:40:01 +000089static int64_t getSHT(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000090 int16_t val = (insn & 0x1F);
91 return val;
92}
93
Wesley Peck0a67d922010-11-08 19:40:01 +000094static unsigned getFLAGS(int32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000095 return (insn & 0x7FF);
96}
97
Wesley Peck0a67d922010-11-08 19:40:01 +000098static int64_t getFSL(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000099 int16_t val = (insn & 0xF);
100 return val;
101}
102
103static unsigned decodeMUL(uint32_t insn) {
104 switch (getFLAGS(insn)) {
105 default: return UNSUPPORTED;
106 case 0: return MBlaze::MUL;
107 case 1: return MBlaze::MULH;
108 case 2: return MBlaze::MULHSU;
109 case 3: return MBlaze::MULHU;
110 }
111}
112
113static unsigned decodeSEXT(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000114 switch (insn&0x7FF) {
Wesley Pecka0603832010-10-27 00:23:01 +0000115 default: return UNSUPPORTED;
116 case 0x60: return MBlaze::SEXT8;
117 case 0x68: return MBlaze::WIC;
118 case 0x64: return MBlaze::WDC;
119 case 0x66: return MBlaze::WDCC;
120 case 0x74: return MBlaze::WDCF;
121 case 0x61: return MBlaze::SEXT16;
122 case 0x41: return MBlaze::SRL;
123 case 0x21: return MBlaze::SRC;
124 case 0x01: return MBlaze::SRA;
125 }
126}
127
128static unsigned decodeBEQ(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000129 switch ((insn>>21)&0x1F) {
Wesley Pecka0603832010-10-27 00:23:01 +0000130 default: return UNSUPPORTED;
131 case 0x00: return MBlaze::BEQ;
132 case 0x10: return MBlaze::BEQD;
133 case 0x05: return MBlaze::BGE;
134 case 0x15: return MBlaze::BGED;
135 case 0x04: return MBlaze::BGT;
136 case 0x14: return MBlaze::BGTD;
137 case 0x03: return MBlaze::BLE;
138 case 0x13: return MBlaze::BLED;
139 case 0x02: return MBlaze::BLT;
140 case 0x12: return MBlaze::BLTD;
141 case 0x01: return MBlaze::BNE;
142 case 0x11: return MBlaze::BNED;
143 }
144}
145
146static unsigned decodeBEQI(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000147 switch ((insn>>21)&0x1F) {
Wesley Pecka0603832010-10-27 00:23:01 +0000148 default: return UNSUPPORTED;
149 case 0x00: return MBlaze::BEQI;
150 case 0x10: return MBlaze::BEQID;
151 case 0x05: return MBlaze::BGEI;
152 case 0x15: return MBlaze::BGEID;
153 case 0x04: return MBlaze::BGTI;
154 case 0x14: return MBlaze::BGTID;
155 case 0x03: return MBlaze::BLEI;
156 case 0x13: return MBlaze::BLEID;
157 case 0x02: return MBlaze::BLTI;
158 case 0x12: return MBlaze::BLTID;
159 case 0x01: return MBlaze::BNEI;
160 case 0x11: return MBlaze::BNEID;
161 }
162}
163
164static unsigned decodeBR(uint32_t insn) {
165 switch ((insn>>16)&0x1F) {
166 default: return UNSUPPORTED;
167 case 0x00: return MBlaze::BR;
168 case 0x08: return MBlaze::BRA;
169 case 0x0C: return MBlaze::BRK;
170 case 0x10: return MBlaze::BRD;
171 case 0x14: return MBlaze::BRLD;
172 case 0x18: return MBlaze::BRAD;
173 case 0x1C: return MBlaze::BRALD;
174 }
175}
176
177static unsigned decodeBRI(uint32_t insn) {
178 switch ((insn>>16)&0x1F) {
179 default: return UNSUPPORTED;
180 case 0x00: return MBlaze::BRI;
181 case 0x08: return MBlaze::BRAI;
182 case 0x0C: return MBlaze::BRKI;
183 case 0x10: return MBlaze::BRID;
184 case 0x14: return MBlaze::BRLID;
185 case 0x18: return MBlaze::BRAID;
186 case 0x1C: return MBlaze::BRALID;
187 }
188}
189
190static unsigned decodeBSRL(uint32_t insn) {
191 switch ((insn>>9)&0x3) {
192 default: return UNSUPPORTED;
193 case 0x2: return MBlaze::BSLL;
194 case 0x1: return MBlaze::BSRA;
195 case 0x0: return MBlaze::BSRL;
196 }
197}
198
199static unsigned decodeBSRLI(uint32_t insn) {
200 switch ((insn>>9)&0x3) {
201 default: return UNSUPPORTED;
202 case 0x2: return MBlaze::BSLLI;
203 case 0x1: return MBlaze::BSRAI;
204 case 0x0: return MBlaze::BSRLI;
205 }
206}
207
208static unsigned decodeRSUBK(uint32_t insn) {
209 switch (getFLAGS(insn)) {
210 default: return UNSUPPORTED;
211 case 0x0: return MBlaze::RSUBK;
212 case 0x1: return MBlaze::CMP;
213 case 0x3: return MBlaze::CMPU;
214 }
215}
216
217static unsigned decodeFADD(uint32_t insn) {
218 switch (getFLAGS(insn)) {
219 default: return UNSUPPORTED;
220 case 0x000: return MBlaze::FADD;
221 case 0x080: return MBlaze::FRSUB;
222 case 0x100: return MBlaze::FMUL;
223 case 0x180: return MBlaze::FDIV;
224 case 0x200: return MBlaze::FCMP_UN;
225 case 0x210: return MBlaze::FCMP_LT;
226 case 0x220: return MBlaze::FCMP_EQ;
227 case 0x230: return MBlaze::FCMP_LE;
228 case 0x240: return MBlaze::FCMP_GT;
229 case 0x250: return MBlaze::FCMP_NE;
230 case 0x260: return MBlaze::FCMP_GE;
231 case 0x280: return MBlaze::FLT;
232 case 0x300: return MBlaze::FINT;
233 case 0x380: return MBlaze::FSQRT;
234 }
235}
236
237static unsigned decodeGET(uint32_t insn) {
238 switch ((insn>>10)&0x3F) {
239 default: return UNSUPPORTED;
240 case 0x00: return MBlaze::GET;
241 case 0x01: return MBlaze::EGET;
242 case 0x02: return MBlaze::AGET;
243 case 0x03: return MBlaze::EAGET;
244 case 0x04: return MBlaze::TGET;
245 case 0x05: return MBlaze::TEGET;
246 case 0x06: return MBlaze::TAGET;
247 case 0x07: return MBlaze::TEAGET;
248 case 0x08: return MBlaze::CGET;
249 case 0x09: return MBlaze::ECGET;
250 case 0x0A: return MBlaze::CAGET;
251 case 0x0B: return MBlaze::ECAGET;
252 case 0x0C: return MBlaze::TCGET;
253 case 0x0D: return MBlaze::TECGET;
254 case 0x0E: return MBlaze::TCAGET;
255 case 0x0F: return MBlaze::TECAGET;
256 case 0x10: return MBlaze::NGET;
257 case 0x11: return MBlaze::NEGET;
258 case 0x12: return MBlaze::NAGET;
259 case 0x13: return MBlaze::NEAGET;
260 case 0x14: return MBlaze::TNGET;
261 case 0x15: return MBlaze::TNEGET;
262 case 0x16: return MBlaze::TNAGET;
263 case 0x17: return MBlaze::TNEAGET;
264 case 0x18: return MBlaze::NCGET;
265 case 0x19: return MBlaze::NECGET;
266 case 0x1A: return MBlaze::NCAGET;
267 case 0x1B: return MBlaze::NECAGET;
268 case 0x1C: return MBlaze::TNCGET;
269 case 0x1D: return MBlaze::TNECGET;
270 case 0x1E: return MBlaze::TNCAGET;
271 case 0x1F: return MBlaze::TNECAGET;
272 case 0x20: return MBlaze::PUT;
273 case 0x22: return MBlaze::APUT;
274 case 0x24: return MBlaze::TPUT;
275 case 0x26: return MBlaze::TAPUT;
276 case 0x28: return MBlaze::CPUT;
277 case 0x2A: return MBlaze::CAPUT;
278 case 0x2C: return MBlaze::TCPUT;
279 case 0x2E: return MBlaze::TCAPUT;
280 case 0x30: return MBlaze::NPUT;
281 case 0x32: return MBlaze::NAPUT;
282 case 0x34: return MBlaze::TNPUT;
283 case 0x36: return MBlaze::TNAPUT;
284 case 0x38: return MBlaze::NCPUT;
285 case 0x3A: return MBlaze::NCAPUT;
286 case 0x3C: return MBlaze::TNCPUT;
287 case 0x3E: return MBlaze::TNCAPUT;
288 }
289}
290
291static unsigned decodeGETD(uint32_t insn) {
292 switch ((insn>>5)&0x3F) {
293 default: return UNSUPPORTED;
294 case 0x00: return MBlaze::GETD;
295 case 0x01: return MBlaze::EGETD;
296 case 0x02: return MBlaze::AGETD;
297 case 0x03: return MBlaze::EAGETD;
298 case 0x04: return MBlaze::TGETD;
299 case 0x05: return MBlaze::TEGETD;
300 case 0x06: return MBlaze::TAGETD;
301 case 0x07: return MBlaze::TEAGETD;
302 case 0x08: return MBlaze::CGETD;
303 case 0x09: return MBlaze::ECGETD;
304 case 0x0A: return MBlaze::CAGETD;
305 case 0x0B: return MBlaze::ECAGETD;
306 case 0x0C: return MBlaze::TCGETD;
307 case 0x0D: return MBlaze::TECGETD;
308 case 0x0E: return MBlaze::TCAGETD;
309 case 0x0F: return MBlaze::TECAGETD;
310 case 0x10: return MBlaze::NGETD;
311 case 0x11: return MBlaze::NEGETD;
312 case 0x12: return MBlaze::NAGETD;
313 case 0x13: return MBlaze::NEAGETD;
314 case 0x14: return MBlaze::TNGETD;
315 case 0x15: return MBlaze::TNEGETD;
316 case 0x16: return MBlaze::TNAGETD;
317 case 0x17: return MBlaze::TNEAGETD;
318 case 0x18: return MBlaze::NCGETD;
319 case 0x19: return MBlaze::NECGETD;
320 case 0x1A: return MBlaze::NCAGETD;
321 case 0x1B: return MBlaze::NECAGETD;
322 case 0x1C: return MBlaze::TNCGETD;
323 case 0x1D: return MBlaze::TNECGETD;
324 case 0x1E: return MBlaze::TNCAGETD;
325 case 0x1F: return MBlaze::TNECAGETD;
326 case 0x20: return MBlaze::PUTD;
327 case 0x22: return MBlaze::APUTD;
328 case 0x24: return MBlaze::TPUTD;
329 case 0x26: return MBlaze::TAPUTD;
330 case 0x28: return MBlaze::CPUTD;
331 case 0x2A: return MBlaze::CAPUTD;
332 case 0x2C: return MBlaze::TCPUTD;
333 case 0x2E: return MBlaze::TCAPUTD;
334 case 0x30: return MBlaze::NPUTD;
335 case 0x32: return MBlaze::NAPUTD;
336 case 0x34: return MBlaze::TNPUTD;
337 case 0x36: return MBlaze::TNAPUTD;
338 case 0x38: return MBlaze::NCPUTD;
339 case 0x3A: return MBlaze::NCAPUTD;
340 case 0x3C: return MBlaze::TNCPUTD;
341 case 0x3E: return MBlaze::TNCAPUTD;
342 }
343}
344
345static unsigned decodeIDIV(uint32_t insn) {
346 switch (insn&0x3) {
347 default: return UNSUPPORTED;
348 case 0x0: return MBlaze::IDIV;
349 case 0x2: return MBlaze::IDIVU;
350 }
351}
352
Wesley Peckec57d532010-11-13 02:37:59 +0000353static unsigned decodeLBU(uint32_t insn) {
354 switch ((insn>>9)&0x1) {
355 default: return UNSUPPORTED;
356 case 0x0: return MBlaze::LBU;
357 case 0x1: return MBlaze::LBUR;
358 }
359}
360
361static unsigned decodeLHU(uint32_t insn) {
362 switch ((insn>>9)&0x1) {
363 default: return UNSUPPORTED;
364 case 0x0: return MBlaze::LHU;
365 case 0x1: return MBlaze::LHUR;
366 }
367}
368
Wesley Pecka0603832010-10-27 00:23:01 +0000369static unsigned decodeLW(uint32_t insn) {
370 switch ((insn>>9)&0x3) {
371 default: return UNSUPPORTED;
372 case 0x0: return MBlaze::LW;
373 case 0x1: return MBlaze::LWR;
374 case 0x2: return MBlaze::LWX;
375 }
376}
377
Wesley Peckec57d532010-11-13 02:37:59 +0000378static unsigned decodeSB(uint32_t insn) {
379 switch ((insn>>9)&0x1) {
380 default: return UNSUPPORTED;
381 case 0x0: return MBlaze::SB;
382 case 0x1: return MBlaze::SBR;
383 }
384}
385
386static unsigned decodeSH(uint32_t insn) {
387 switch ((insn>>9)&0x1) {
388 default: return UNSUPPORTED;
389 case 0x0: return MBlaze::SH;
390 case 0x1: return MBlaze::SHR;
391 }
392}
393
Wesley Pecka0603832010-10-27 00:23:01 +0000394static unsigned decodeSW(uint32_t insn) {
395 switch ((insn>>9)&0x3) {
396 default: return UNSUPPORTED;
397 case 0x0: return MBlaze::SW;
398 case 0x1: return MBlaze::SWR;
399 case 0x2: return MBlaze::SWX;
400 }
401}
402
403static unsigned decodeMFS(uint32_t insn) {
404 switch ((insn>>15)&0x1) {
405 default: return UNSUPPORTED;
406 case 0x0:
Wesley Peckec57d532010-11-13 02:37:59 +0000407 switch ((insn>>16)&0x1) {
Wesley Pecka0603832010-10-27 00:23:01 +0000408 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000409 case 0x0: return MBlaze::MSRSET;
410 case 0x1: return MBlaze::MSRCLR;
Wesley Pecka0603832010-10-27 00:23:01 +0000411 }
412 case 0x1:
413 switch ((insn>>14)&0x1) {
414 default: return UNSUPPORTED;
415 case 0x0: return MBlaze::MFS;
416 case 0x1: return MBlaze::MTS;
417 }
418 }
419}
420
421static unsigned decodeOR(uint32_t insn) {
422 switch (getFLAGS(insn)) {
423 default: return UNSUPPORTED;
424 case 0x000: return MBlaze::OR;
425 case 0x400: return MBlaze::PCMPBF;
426 }
427}
428
429static unsigned decodeXOR(uint32_t insn) {
430 switch (getFLAGS(insn)) {
431 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000432 case 0x000: return MBlaze::XOR;
Wesley Pecka0603832010-10-27 00:23:01 +0000433 case 0x400: return MBlaze::PCMPEQ;
434 }
435}
436
437static unsigned decodeANDN(uint32_t insn) {
438 switch (getFLAGS(insn)) {
439 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000440 case 0x000: return MBlaze::ANDN;
Wesley Pecka0603832010-10-27 00:23:01 +0000441 case 0x400: return MBlaze::PCMPNE;
442 }
443}
444
445static unsigned decodeRTSD(uint32_t insn) {
446 switch ((insn>>21)&0x1F) {
447 default: return UNSUPPORTED;
448 case 0x10: return MBlaze::RTSD;
449 case 0x11: return MBlaze::RTID;
450 case 0x12: return MBlaze::RTBD;
451 case 0x14: return MBlaze::RTED;
452 }
453}
454
Wesley Peck0a67d922010-11-08 19:40:01 +0000455static unsigned getOPCODE(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +0000456 unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
457 switch (opcode) {
458 case MBlaze::MUL: return decodeMUL(insn);
459 case MBlaze::SEXT8: return decodeSEXT(insn);
460 case MBlaze::BEQ: return decodeBEQ(insn);
461 case MBlaze::BEQI: return decodeBEQI(insn);
462 case MBlaze::BR: return decodeBR(insn);
463 case MBlaze::BRI: return decodeBRI(insn);
464 case MBlaze::BSRL: return decodeBSRL(insn);
465 case MBlaze::BSRLI: return decodeBSRLI(insn);
466 case MBlaze::RSUBK: return decodeRSUBK(insn);
467 case MBlaze::FADD: return decodeFADD(insn);
468 case MBlaze::GET: return decodeGET(insn);
469 case MBlaze::GETD: return decodeGETD(insn);
470 case MBlaze::IDIV: return decodeIDIV(insn);
Wesley Peckec57d532010-11-13 02:37:59 +0000471 case MBlaze::LBU: return decodeLBU(insn);
472 case MBlaze::LHU: return decodeLHU(insn);
Wesley Pecka0603832010-10-27 00:23:01 +0000473 case MBlaze::LW: return decodeLW(insn);
Wesley Peckec57d532010-11-13 02:37:59 +0000474 case MBlaze::SB: return decodeSB(insn);
475 case MBlaze::SH: return decodeSH(insn);
Wesley Pecka0603832010-10-27 00:23:01 +0000476 case MBlaze::SW: return decodeSW(insn);
477 case MBlaze::MFS: return decodeMFS(insn);
478 case MBlaze::OR: return decodeOR(insn);
479 case MBlaze::XOR: return decodeXOR(insn);
480 case MBlaze::ANDN: return decodeANDN(insn);
481 case MBlaze::RTSD: return decodeRTSD(insn);
482 default: return opcode;
483 }
484}
485
486EDInstInfo *MBlazeDisassembler::getEDInfo() const {
487 return instInfoMBlaze;
488}
489
490//
491// Public interface for the disassembler
492//
493
494bool MBlazeDisassembler::getInstruction(MCInst &instr,
495 uint64_t &size,
496 const MemoryObject &region,
497 uint64_t address,
498 raw_ostream &vStream) const {
499 // The machine instruction.
500 uint32_t insn;
Wesley Pecke53060f2011-04-11 21:35:21 +0000501 uint64_t read;
Wesley Pecka0603832010-10-27 00:23:01 +0000502 uint8_t bytes[4];
Wesley Peckec57d532010-11-13 02:37:59 +0000503
Wesley Pecke53060f2011-04-11 21:35:21 +0000504 // By default we consume 1 byte on failure
505 size = 1;
Wesley Peck90eff732010-11-13 05:48:21 +0000506
Wesley Pecka0603832010-10-27 00:23:01 +0000507 // We want to read exactly 4 bytes of data.
Wesley Pecke53060f2011-04-11 21:35:21 +0000508 if (region.readBytes(address, 4, (uint8_t*)bytes, &read) == -1 || read < 4)
Wesley Pecka0603832010-10-27 00:23:01 +0000509 return false;
510
511 // Encoded as a big-endian 32-bit word in the stream.
512 insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
513
514 // Get the MCInst opcode from the binary instruction and make sure
515 // that it is a valid instruction.
Wesley Peck0a67d922010-11-08 19:40:01 +0000516 unsigned opcode = getOPCODE(insn);
517 if (opcode == UNSUPPORTED)
Wesley Pecka0603832010-10-27 00:23:01 +0000518 return false;
519
520 instr.setOpcode(opcode);
521
Wesley Pecke53060f2011-04-11 21:35:21 +0000522 unsigned RD = getRD(insn);
523 unsigned RA = getRA(insn);
524 unsigned RB = getRB(insn);
525 unsigned RS = getRS(insn);
526
Wesley Pecka0603832010-10-27 00:23:01 +0000527 uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
Wesley Peck0a67d922010-11-08 19:40:01 +0000528 switch ((tsFlags & MBlazeII::FormMask)) {
Wesley Pecke53060f2011-04-11 21:35:21 +0000529 default:
530 return false;
Wesley Pecka0603832010-10-27 00:23:01 +0000531
Wesley Peckec57d532010-11-13 02:37:59 +0000532 case MBlazeII::FRRRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000533 if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
534 return false;
535 instr.addOperand(MCOperand::CreateReg(RD));
536 instr.addOperand(MCOperand::CreateReg(RB));
537 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000538 break;
539
Wesley Pecka0603832010-10-27 00:23:01 +0000540 case MBlazeII::FRRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000541 if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
542 return false;
543 instr.addOperand(MCOperand::CreateReg(RD));
544 instr.addOperand(MCOperand::CreateReg(RA));
545 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000546 break;
547
Wesley Peckec57d532010-11-13 02:37:59 +0000548 case MBlazeII::FRI:
549 switch (opcode) {
Wesley Pecke53060f2011-04-11 21:35:21 +0000550 default:
551 return false;
Wesley Peckec57d532010-11-13 02:37:59 +0000552 case MBlaze::MFS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000553 if (RD == UNSUPPORTED)
554 return false;
555 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peckec57d532010-11-13 02:37:59 +0000556 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
557 break;
558 case MBlaze::MTS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000559 if (RA == UNSUPPORTED)
560 return false;
Wesley Peckec57d532010-11-13 02:37:59 +0000561 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
Wesley Pecke53060f2011-04-11 21:35:21 +0000562 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000563 break;
564 case MBlaze::MSRSET:
565 case MBlaze::MSRCLR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000566 if (RD == UNSUPPORTED)
567 return false;
568 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peckec57d532010-11-13 02:37:59 +0000569 instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
570 break;
571 }
572 break;
573
Wesley Pecka0603832010-10-27 00:23:01 +0000574 case MBlazeII::FRRI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000575 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
576 return false;
577 instr.addOperand(MCOperand::CreateReg(RD));
578 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000579 switch (opcode) {
580 default:
581 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
582 break;
583 case MBlaze::BSRLI:
584 case MBlaze::BSRAI:
585 case MBlaze::BSLLI:
586 instr.addOperand(MCOperand::CreateImm(insn&0x1F));
587 break;
588 }
Wesley Pecka0603832010-10-27 00:23:01 +0000589 break;
590
591 case MBlazeII::FCRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000592 if (RA == UNSUPPORTED || RB == UNSUPPORTED)
593 return false;
594 instr.addOperand(MCOperand::CreateReg(RA));
595 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000596 break;
597
598 case MBlazeII::FCRI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000599 if (RA == UNSUPPORTED)
600 return false;
601 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000602 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000603 break;
604
605 case MBlazeII::FRCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000606 if (RD == UNSUPPORTED || RB == UNSUPPORTED)
607 return false;
608 instr.addOperand(MCOperand::CreateReg(RD));
609 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000610 break;
611
612 case MBlazeII::FRCI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000613 if (RD == UNSUPPORTED)
614 return false;
615 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000616 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000617 break;
618
619 case MBlazeII::FCCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000620 if (RB == UNSUPPORTED)
621 return false;
622 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000623 break;
624
625 case MBlazeII::FCCI:
Wesley Peck0a67d922010-11-08 19:40:01 +0000626 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000627 break;
628
629 case MBlazeII::FRRCI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000630 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
631 return false;
632 instr.addOperand(MCOperand::CreateReg(RD));
633 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000634 instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000635 break;
636
637 case MBlazeII::FRRC:
Wesley Pecke53060f2011-04-11 21:35:21 +0000638 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
639 return false;
640 instr.addOperand(MCOperand::CreateReg(RD));
641 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000642 break;
643
644 case MBlazeII::FRCX:
Wesley Pecke53060f2011-04-11 21:35:21 +0000645 if (RD == UNSUPPORTED)
646 return false;
647 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000648 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000649 break;
650
651 case MBlazeII::FRCS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000652 if (RD == UNSUPPORTED || RS == UNSUPPORTED)
653 return false;
654 instr.addOperand(MCOperand::CreateReg(RD));
655 instr.addOperand(MCOperand::CreateReg(RS));
Wesley Pecka0603832010-10-27 00:23:01 +0000656 break;
657
658 case MBlazeII::FCRCS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000659 if (RS == UNSUPPORTED || RA == UNSUPPORTED)
660 return false;
661 instr.addOperand(MCOperand::CreateReg(RS));
662 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000663 break;
664
665 case MBlazeII::FCRCX:
Wesley Pecke53060f2011-04-11 21:35:21 +0000666 if (RA == UNSUPPORTED)
667 return false;
668 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000669 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000670 break;
671
672 case MBlazeII::FCX:
Wesley Peck0a67d922010-11-08 19:40:01 +0000673 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000674 break;
675
676 case MBlazeII::FCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000677 if (RB == UNSUPPORTED)
678 return false;
679 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000680 break;
681
682 case MBlazeII::FRIR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000683 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
684 return false;
685 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000686 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecke53060f2011-04-11 21:35:21 +0000687 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000688 break;
689 }
690
Wesley Pecke53060f2011-04-11 21:35:21 +0000691 // We always consume 4 bytes of data on success
692 size = 4;
693
Wesley Pecka0603832010-10-27 00:23:01 +0000694 return true;
695}
696
697static MCDisassembler *createMBlazeDisassembler(const Target &T) {
698 return new MBlazeDisassembler;
699}
700
Wesley Peckec57d532010-11-13 02:37:59 +0000701extern "C" void LLVMInitializeMBlazeDisassembler() {
Wesley Pecka0603832010-10-27 00:23:01 +0000702 // Register the disassembler.
Wesley Peckec57d532010-11-13 02:37:59 +0000703 TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
Wesley Pecka0603832010-10-27 00:23:01 +0000704 createMBlazeDisassembler);
705}