blob: ccc3a05f5076be46f8f3cc6d676d6a3bfc1b85c8 [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"
Wesley Pecka0603832010-10-27 00:23:01 +000016#include "MBlazeDisassembler.h"
17
18#include "llvm/MC/EDInstInfo.h"
19#include "llvm/MC/MCDisassembler.h"
Wesley Pecka0603832010-10-27 00:23:01 +000020#include "llvm/MC/MCInst.h"
Benjamin Kramer7fb12ef2011-11-11 12:39:35 +000021#include "llvm/MC/MCInstrDesc.h"
Wesley Pecka0603832010-10-27 00:23:01 +000022#include "llvm/Support/Debug.h"
23#include "llvm/Support/MemoryObject.h"
Evan Cheng3e74d6f2011-08-24 18:08:43 +000024#include "llvm/Support/TargetRegistry.h"
Wesley Pecka0603832010-10-27 00:23:01 +000025#include "llvm/Support/raw_ostream.h"
26
27// #include "MBlazeGenDecoderTables.inc"
28// #include "MBlazeGenRegisterNames.inc"
Wesley Pecka0603832010-10-27 00:23:01 +000029#include "MBlazeGenEDInfo.inc"
30
Evan Chengc60f9b72011-07-14 20:59:42 +000031namespace llvm {
Benjamin Kramer1a2f9882011-10-22 16:50:00 +000032extern const MCInstrDesc MBlazeInsts[];
Evan Chengc60f9b72011-07-14 20:59:42 +000033}
34
Wesley Pecka0603832010-10-27 00:23:01 +000035using namespace llvm;
36
37const unsigned UNSUPPORTED = -1;
38
Benjamin Kramer1a2f9882011-10-22 16:50:00 +000039static const unsigned mblazeBinary2Opcode[] = {
Wesley Pecka0603832010-10-27 00:23:01 +000040 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
Wesley Peck0a67d922010-11-08 19:40:01 +000061static unsigned getRD(uint32_t insn) {
Evan Chengd1200aa2011-07-25 21:29:26 +000062 if (!isMBlazeRegister((insn>>21)&0x1F))
Wesley Pecke53060f2011-04-11 21:35:21 +000063 return UNSUPPORTED;
Evan Cheng617793d2011-07-25 22:16:37 +000064 return getMBlazeRegisterFromNumbering((insn>>21)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000065}
66
Wesley Peck0a67d922010-11-08 19:40:01 +000067static unsigned getRA(uint32_t insn) {
Evan Cheng617793d2011-07-25 22:16:37 +000068 if (!getMBlazeRegisterFromNumbering((insn>>16)&0x1F))
Wesley Pecke53060f2011-04-11 21:35:21 +000069 return UNSUPPORTED;
Evan Cheng617793d2011-07-25 22:16:37 +000070 return getMBlazeRegisterFromNumbering((insn>>16)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000071}
72
Wesley Peck0a67d922010-11-08 19:40:01 +000073static unsigned getRB(uint32_t insn) {
Evan Cheng617793d2011-07-25 22:16:37 +000074 if (!getMBlazeRegisterFromNumbering((insn>>11)&0x1F))
Wesley Pecke53060f2011-04-11 21:35:21 +000075 return UNSUPPORTED;
Evan Cheng617793d2011-07-25 22:16:37 +000076 return getMBlazeRegisterFromNumbering((insn>>11)&0x1F);
Wesley Pecka0603832010-10-27 00:23:01 +000077}
78
Wesley Peck0a67d922010-11-08 19:40:01 +000079static int64_t getRS(uint32_t insn) {
Evan Chengd1200aa2011-07-25 21:29:26 +000080 if (!isSpecialMBlazeRegister(insn&0x3FFF))
Wesley Pecke53060f2011-04-11 21:35:21 +000081 return UNSUPPORTED;
Evan Chengd1200aa2011-07-25 21:29:26 +000082 return getSpecialMBlazeRegisterFromNumbering(insn&0x3FFF);
Wesley Pecka0603832010-10-27 00:23:01 +000083}
84
Wesley Peck0a67d922010-11-08 19:40:01 +000085static int64_t getIMM(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000086 int16_t val = (insn & 0xFFFF);
87 return val;
88}
89
Wesley Peck0a67d922010-11-08 19:40:01 +000090static int64_t getSHT(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000091 int16_t val = (insn & 0x1F);
92 return val;
93}
94
Wesley Peck0a67d922010-11-08 19:40:01 +000095static unsigned getFLAGS(int32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +000096 return (insn & 0x7FF);
97}
98
Wesley Peck0a67d922010-11-08 19:40:01 +000099static int64_t getFSL(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +0000100 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) {
Wesley Peckec57d532010-11-13 02:37:59 +0000115 switch (insn&0x7FF) {
Wesley Pecka0603832010-10-27 00:23:01 +0000116 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;
Wesley Peck4c729f12011-11-27 05:16:58 +0000126 case 0xE0: return MBlaze::CLZ;
Wesley Pecka0603832010-10-27 00:23:01 +0000127 }
128}
129
130static unsigned decodeBEQ(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000131 switch ((insn>>21)&0x1F) {
Wesley Pecka0603832010-10-27 00:23:01 +0000132 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) {
Wesley Peckec57d532010-11-13 02:37:59 +0000149 switch ((insn>>21)&0x1F) {
Wesley Pecka0603832010-10-27 00:23:01 +0000150 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) {
Wesley Peck4c729f12011-11-27 05:16:58 +0000180 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
Wesley Pecka0603832010-10-27 00:23:01 +0000187 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
Wesley Peckec57d532010-11-13 02:37:59 +0000362static 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
Wesley Pecka0603832010-10-27 00:23:01 +0000378static 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
Wesley Peckec57d532010-11-13 02:37:59 +0000387static 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
Wesley Pecka0603832010-10-27 00:23:01 +0000403static 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:
Wesley Peckec57d532010-11-13 02:37:59 +0000416 switch ((insn>>16)&0x1) {
Wesley Pecka0603832010-10-27 00:23:01 +0000417 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000418 case 0x0: return MBlaze::MSRSET;
419 case 0x1: return MBlaze::MSRCLR;
Wesley Pecka0603832010-10-27 00:23:01 +0000420 }
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;
Wesley Peckec57d532010-11-13 02:37:59 +0000441 case 0x000: return MBlaze::XOR;
Wesley Pecka0603832010-10-27 00:23:01 +0000442 case 0x400: return MBlaze::PCMPEQ;
443 }
444}
445
446static unsigned decodeANDN(uint32_t insn) {
447 switch (getFLAGS(insn)) {
448 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000449 case 0x000: return MBlaze::ANDN;
Wesley Pecka0603832010-10-27 00:23:01 +0000450 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
Wesley Peck0a67d922010-11-08 19:40:01 +0000464static unsigned getOPCODE(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +0000465 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);
Wesley Peckec57d532010-11-13 02:37:59 +0000480 case MBlaze::LBU: return decodeLBU(insn);
481 case MBlaze::LHU: return decodeLHU(insn);
Wesley Pecka0603832010-10-27 00:23:01 +0000482 case MBlaze::LW: return decodeLW(insn);
Wesley Peckec57d532010-11-13 02:37:59 +0000483 case MBlaze::SB: return decodeSB(insn);
484 case MBlaze::SH: return decodeSH(insn);
Wesley Pecka0603832010-10-27 00:23:01 +0000485 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
495EDInstInfo *MBlazeDisassembler::getEDInfo() const {
496 return instInfoMBlaze;
497}
498
499//
500// Public interface for the disassembler
501//
502
Owen Anderson83e3f672011-08-17 17:44:15 +0000503MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr,
Wesley Pecka0603832010-10-27 00:23:01 +0000504 uint64_t &size,
505 const MemoryObject &region,
506 uint64_t address,
Owen Anderson98c5dda2011-09-15 23:38:46 +0000507 raw_ostream &vStream,
508 raw_ostream &cStream) const {
Wesley Pecka0603832010-10-27 00:23:01 +0000509 // The machine instruction.
510 uint32_t insn;
Wesley Pecke53060f2011-04-11 21:35:21 +0000511 uint64_t read;
Wesley Pecka0603832010-10-27 00:23:01 +0000512 uint8_t bytes[4];
Wesley Peckec57d532010-11-13 02:37:59 +0000513
Wesley Pecke53060f2011-04-11 21:35:21 +0000514 // By default we consume 1 byte on failure
515 size = 1;
Wesley Peck90eff732010-11-13 05:48:21 +0000516
Wesley Pecka0603832010-10-27 00:23:01 +0000517 // We want to read exactly 4 bytes of data.
Wesley Pecke53060f2011-04-11 21:35:21 +0000518 if (region.readBytes(address, 4, (uint8_t*)bytes, &read) == -1 || read < 4)
Owen Anderson83e3f672011-08-17 17:44:15 +0000519 return Fail;
Wesley Pecka0603832010-10-27 00:23:01 +0000520
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.
Wesley Peck0a67d922010-11-08 19:40:01 +0000526 unsigned opcode = getOPCODE(insn);
527 if (opcode == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000528 return Fail;
Wesley Pecka0603832010-10-27 00:23:01 +0000529
530 instr.setOpcode(opcode);
531
Wesley Pecke53060f2011-04-11 21:35:21 +0000532 unsigned RD = getRD(insn);
533 unsigned RA = getRA(insn);
534 unsigned RB = getRB(insn);
535 unsigned RS = getRS(insn);
536
Wesley Pecka0603832010-10-27 00:23:01 +0000537 uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
Wesley Peck0a67d922010-11-08 19:40:01 +0000538 switch ((tsFlags & MBlazeII::FormMask)) {
Wesley Pecke53060f2011-04-11 21:35:21 +0000539 default:
Owen Anderson83e3f672011-08-17 17:44:15 +0000540 return Fail;
Wesley Pecka0603832010-10-27 00:23:01 +0000541
Wesley Peck4c729f12011-11-27 05:16:58 +0000542 case MBlazeII::FC:
543 break;
544
Wesley Peckec57d532010-11-13 02:37:59 +0000545 case MBlazeII::FRRRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000546 if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000547 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000548 instr.addOperand(MCOperand::CreateReg(RD));
549 instr.addOperand(MCOperand::CreateReg(RB));
550 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000551 break;
552
Wesley Pecka0603832010-10-27 00:23:01 +0000553 case MBlazeII::FRRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000554 if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000555 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000556 instr.addOperand(MCOperand::CreateReg(RD));
557 instr.addOperand(MCOperand::CreateReg(RA));
558 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000559 break;
560
Wesley Peck4c729f12011-11-27 05:16:58 +0000561 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
Wesley Peckec57d532010-11-13 02:37:59 +0000568 case MBlazeII::FRI:
569 switch (opcode) {
Wesley Pecke53060f2011-04-11 21:35:21 +0000570 default:
Owen Anderson83e3f672011-08-17 17:44:15 +0000571 return Fail;
Wesley Peckec57d532010-11-13 02:37:59 +0000572 case MBlaze::MFS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000573 if (RD == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000574 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000575 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peckec57d532010-11-13 02:37:59 +0000576 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
577 break;
578 case MBlaze::MTS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000579 if (RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000580 return Fail;
Wesley Peckec57d532010-11-13 02:37:59 +0000581 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
Wesley Pecke53060f2011-04-11 21:35:21 +0000582 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000583 break;
584 case MBlaze::MSRSET:
585 case MBlaze::MSRCLR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000586 if (RD == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000587 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000588 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peckec57d532010-11-13 02:37:59 +0000589 instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
590 break;
591 }
592 break;
593
Wesley Pecka0603832010-10-27 00:23:01 +0000594 case MBlazeII::FRRI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000595 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000596 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000597 instr.addOperand(MCOperand::CreateReg(RD));
598 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000599 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 }
Wesley Pecka0603832010-10-27 00:23:01 +0000609 break;
610
611 case MBlazeII::FCRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000612 if (RA == UNSUPPORTED || RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000613 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000614 instr.addOperand(MCOperand::CreateReg(RA));
615 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000616 break;
617
618 case MBlazeII::FCRI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000619 if (RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000620 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000621 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000622 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000623 break;
624
625 case MBlazeII::FRCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000626 if (RD == UNSUPPORTED || RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000627 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000628 instr.addOperand(MCOperand::CreateReg(RD));
629 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000630 break;
631
632 case MBlazeII::FRCI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000633 if (RD == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000634 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000635 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000636 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000637 break;
638
639 case MBlazeII::FCCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000640 if (RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000641 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000642 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000643 break;
644
645 case MBlazeII::FCCI:
Wesley Peck0a67d922010-11-08 19:40:01 +0000646 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000647 break;
648
649 case MBlazeII::FRRCI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000650 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000651 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000652 instr.addOperand(MCOperand::CreateReg(RD));
653 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000654 instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000655 break;
656
657 case MBlazeII::FRRC:
Wesley Pecke53060f2011-04-11 21:35:21 +0000658 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000659 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000660 instr.addOperand(MCOperand::CreateReg(RD));
661 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000662 break;
663
664 case MBlazeII::FRCX:
Wesley Pecke53060f2011-04-11 21:35:21 +0000665 if (RD == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000666 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000667 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000668 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000669 break;
670
671 case MBlazeII::FRCS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000672 if (RD == UNSUPPORTED || RS == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000673 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000674 instr.addOperand(MCOperand::CreateReg(RD));
675 instr.addOperand(MCOperand::CreateReg(RS));
Wesley Pecka0603832010-10-27 00:23:01 +0000676 break;
677
678 case MBlazeII::FCRCS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000679 if (RS == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000680 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000681 instr.addOperand(MCOperand::CreateReg(RS));
682 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000683 break;
684
685 case MBlazeII::FCRCX:
Wesley Pecke53060f2011-04-11 21:35:21 +0000686 if (RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000687 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000688 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000689 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000690 break;
691
692 case MBlazeII::FCX:
Wesley Peck0a67d922010-11-08 19:40:01 +0000693 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000694 break;
695
696 case MBlazeII::FCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000697 if (RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000698 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000699 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000700 break;
701
702 case MBlazeII::FRIR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000703 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000704 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000705 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000706 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecke53060f2011-04-11 21:35:21 +0000707 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000708 break;
709 }
710
Wesley Pecke53060f2011-04-11 21:35:21 +0000711 // We always consume 4 bytes of data on success
712 size = 4;
713
Owen Anderson83e3f672011-08-17 17:44:15 +0000714 return Success;
Wesley Pecka0603832010-10-27 00:23:01 +0000715}
716
James Molloyb9505852011-09-07 17:24:38 +0000717static MCDisassembler *createMBlazeDisassembler(const Target &T,
718 const MCSubtargetInfo &STI) {
719 return new MBlazeDisassembler(STI);
Wesley Pecka0603832010-10-27 00:23:01 +0000720}
721
Wesley Peckec57d532010-11-13 02:37:59 +0000722extern "C" void LLVMInitializeMBlazeDisassembler() {
Wesley Pecka0603832010-10-27 00:23:01 +0000723 // Register the disassembler.
Wesley Peckec57d532010-11-13 02:37:59 +0000724 TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
Wesley Pecka0603832010-10-27 00:23:01 +0000725 createMBlazeDisassembler);
726}