blob: 30873172921180fd1692f3a40a5d6c2fc83abfb4 [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;
126 }
127}
128
129static unsigned decodeBEQ(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000130 switch ((insn>>21)&0x1F) {
Wesley Pecka0603832010-10-27 00:23:01 +0000131 default: return UNSUPPORTED;
132 case 0x00: return MBlaze::BEQ;
133 case 0x10: return MBlaze::BEQD;
134 case 0x05: return MBlaze::BGE;
135 case 0x15: return MBlaze::BGED;
136 case 0x04: return MBlaze::BGT;
137 case 0x14: return MBlaze::BGTD;
138 case 0x03: return MBlaze::BLE;
139 case 0x13: return MBlaze::BLED;
140 case 0x02: return MBlaze::BLT;
141 case 0x12: return MBlaze::BLTD;
142 case 0x01: return MBlaze::BNE;
143 case 0x11: return MBlaze::BNED;
144 }
145}
146
147static unsigned decodeBEQI(uint32_t insn) {
Wesley Peckec57d532010-11-13 02:37:59 +0000148 switch ((insn>>21)&0x1F) {
Wesley Pecka0603832010-10-27 00:23:01 +0000149 default: return UNSUPPORTED;
150 case 0x00: return MBlaze::BEQI;
151 case 0x10: return MBlaze::BEQID;
152 case 0x05: return MBlaze::BGEI;
153 case 0x15: return MBlaze::BGEID;
154 case 0x04: return MBlaze::BGTI;
155 case 0x14: return MBlaze::BGTID;
156 case 0x03: return MBlaze::BLEI;
157 case 0x13: return MBlaze::BLEID;
158 case 0x02: return MBlaze::BLTI;
159 case 0x12: return MBlaze::BLTID;
160 case 0x01: return MBlaze::BNEI;
161 case 0x11: return MBlaze::BNEID;
162 }
163}
164
165static unsigned decodeBR(uint32_t insn) {
166 switch ((insn>>16)&0x1F) {
167 default: return UNSUPPORTED;
168 case 0x00: return MBlaze::BR;
169 case 0x08: return MBlaze::BRA;
170 case 0x0C: return MBlaze::BRK;
171 case 0x10: return MBlaze::BRD;
172 case 0x14: return MBlaze::BRLD;
173 case 0x18: return MBlaze::BRAD;
174 case 0x1C: return MBlaze::BRALD;
175 }
176}
177
178static unsigned decodeBRI(uint32_t insn) {
179 switch ((insn>>16)&0x1F) {
180 default: return UNSUPPORTED;
181 case 0x00: return MBlaze::BRI;
182 case 0x08: return MBlaze::BRAI;
183 case 0x0C: return MBlaze::BRKI;
184 case 0x10: return MBlaze::BRID;
185 case 0x14: return MBlaze::BRLID;
186 case 0x18: return MBlaze::BRAID;
187 case 0x1C: return MBlaze::BRALID;
188 }
189}
190
191static unsigned decodeBSRL(uint32_t insn) {
192 switch ((insn>>9)&0x3) {
193 default: return UNSUPPORTED;
194 case 0x2: return MBlaze::BSLL;
195 case 0x1: return MBlaze::BSRA;
196 case 0x0: return MBlaze::BSRL;
197 }
198}
199
200static unsigned decodeBSRLI(uint32_t insn) {
201 switch ((insn>>9)&0x3) {
202 default: return UNSUPPORTED;
203 case 0x2: return MBlaze::BSLLI;
204 case 0x1: return MBlaze::BSRAI;
205 case 0x0: return MBlaze::BSRLI;
206 }
207}
208
209static unsigned decodeRSUBK(uint32_t insn) {
210 switch (getFLAGS(insn)) {
211 default: return UNSUPPORTED;
212 case 0x0: return MBlaze::RSUBK;
213 case 0x1: return MBlaze::CMP;
214 case 0x3: return MBlaze::CMPU;
215 }
216}
217
218static unsigned decodeFADD(uint32_t insn) {
219 switch (getFLAGS(insn)) {
220 default: return UNSUPPORTED;
221 case 0x000: return MBlaze::FADD;
222 case 0x080: return MBlaze::FRSUB;
223 case 0x100: return MBlaze::FMUL;
224 case 0x180: return MBlaze::FDIV;
225 case 0x200: return MBlaze::FCMP_UN;
226 case 0x210: return MBlaze::FCMP_LT;
227 case 0x220: return MBlaze::FCMP_EQ;
228 case 0x230: return MBlaze::FCMP_LE;
229 case 0x240: return MBlaze::FCMP_GT;
230 case 0x250: return MBlaze::FCMP_NE;
231 case 0x260: return MBlaze::FCMP_GE;
232 case 0x280: return MBlaze::FLT;
233 case 0x300: return MBlaze::FINT;
234 case 0x380: return MBlaze::FSQRT;
235 }
236}
237
238static unsigned decodeGET(uint32_t insn) {
239 switch ((insn>>10)&0x3F) {
240 default: return UNSUPPORTED;
241 case 0x00: return MBlaze::GET;
242 case 0x01: return MBlaze::EGET;
243 case 0x02: return MBlaze::AGET;
244 case 0x03: return MBlaze::EAGET;
245 case 0x04: return MBlaze::TGET;
246 case 0x05: return MBlaze::TEGET;
247 case 0x06: return MBlaze::TAGET;
248 case 0x07: return MBlaze::TEAGET;
249 case 0x08: return MBlaze::CGET;
250 case 0x09: return MBlaze::ECGET;
251 case 0x0A: return MBlaze::CAGET;
252 case 0x0B: return MBlaze::ECAGET;
253 case 0x0C: return MBlaze::TCGET;
254 case 0x0D: return MBlaze::TECGET;
255 case 0x0E: return MBlaze::TCAGET;
256 case 0x0F: return MBlaze::TECAGET;
257 case 0x10: return MBlaze::NGET;
258 case 0x11: return MBlaze::NEGET;
259 case 0x12: return MBlaze::NAGET;
260 case 0x13: return MBlaze::NEAGET;
261 case 0x14: return MBlaze::TNGET;
262 case 0x15: return MBlaze::TNEGET;
263 case 0x16: return MBlaze::TNAGET;
264 case 0x17: return MBlaze::TNEAGET;
265 case 0x18: return MBlaze::NCGET;
266 case 0x19: return MBlaze::NECGET;
267 case 0x1A: return MBlaze::NCAGET;
268 case 0x1B: return MBlaze::NECAGET;
269 case 0x1C: return MBlaze::TNCGET;
270 case 0x1D: return MBlaze::TNECGET;
271 case 0x1E: return MBlaze::TNCAGET;
272 case 0x1F: return MBlaze::TNECAGET;
273 case 0x20: return MBlaze::PUT;
274 case 0x22: return MBlaze::APUT;
275 case 0x24: return MBlaze::TPUT;
276 case 0x26: return MBlaze::TAPUT;
277 case 0x28: return MBlaze::CPUT;
278 case 0x2A: return MBlaze::CAPUT;
279 case 0x2C: return MBlaze::TCPUT;
280 case 0x2E: return MBlaze::TCAPUT;
281 case 0x30: return MBlaze::NPUT;
282 case 0x32: return MBlaze::NAPUT;
283 case 0x34: return MBlaze::TNPUT;
284 case 0x36: return MBlaze::TNAPUT;
285 case 0x38: return MBlaze::NCPUT;
286 case 0x3A: return MBlaze::NCAPUT;
287 case 0x3C: return MBlaze::TNCPUT;
288 case 0x3E: return MBlaze::TNCAPUT;
289 }
290}
291
292static unsigned decodeGETD(uint32_t insn) {
293 switch ((insn>>5)&0x3F) {
294 default: return UNSUPPORTED;
295 case 0x00: return MBlaze::GETD;
296 case 0x01: return MBlaze::EGETD;
297 case 0x02: return MBlaze::AGETD;
298 case 0x03: return MBlaze::EAGETD;
299 case 0x04: return MBlaze::TGETD;
300 case 0x05: return MBlaze::TEGETD;
301 case 0x06: return MBlaze::TAGETD;
302 case 0x07: return MBlaze::TEAGETD;
303 case 0x08: return MBlaze::CGETD;
304 case 0x09: return MBlaze::ECGETD;
305 case 0x0A: return MBlaze::CAGETD;
306 case 0x0B: return MBlaze::ECAGETD;
307 case 0x0C: return MBlaze::TCGETD;
308 case 0x0D: return MBlaze::TECGETD;
309 case 0x0E: return MBlaze::TCAGETD;
310 case 0x0F: return MBlaze::TECAGETD;
311 case 0x10: return MBlaze::NGETD;
312 case 0x11: return MBlaze::NEGETD;
313 case 0x12: return MBlaze::NAGETD;
314 case 0x13: return MBlaze::NEAGETD;
315 case 0x14: return MBlaze::TNGETD;
316 case 0x15: return MBlaze::TNEGETD;
317 case 0x16: return MBlaze::TNAGETD;
318 case 0x17: return MBlaze::TNEAGETD;
319 case 0x18: return MBlaze::NCGETD;
320 case 0x19: return MBlaze::NECGETD;
321 case 0x1A: return MBlaze::NCAGETD;
322 case 0x1B: return MBlaze::NECAGETD;
323 case 0x1C: return MBlaze::TNCGETD;
324 case 0x1D: return MBlaze::TNECGETD;
325 case 0x1E: return MBlaze::TNCAGETD;
326 case 0x1F: return MBlaze::TNECAGETD;
327 case 0x20: return MBlaze::PUTD;
328 case 0x22: return MBlaze::APUTD;
329 case 0x24: return MBlaze::TPUTD;
330 case 0x26: return MBlaze::TAPUTD;
331 case 0x28: return MBlaze::CPUTD;
332 case 0x2A: return MBlaze::CAPUTD;
333 case 0x2C: return MBlaze::TCPUTD;
334 case 0x2E: return MBlaze::TCAPUTD;
335 case 0x30: return MBlaze::NPUTD;
336 case 0x32: return MBlaze::NAPUTD;
337 case 0x34: return MBlaze::TNPUTD;
338 case 0x36: return MBlaze::TNAPUTD;
339 case 0x38: return MBlaze::NCPUTD;
340 case 0x3A: return MBlaze::NCAPUTD;
341 case 0x3C: return MBlaze::TNCPUTD;
342 case 0x3E: return MBlaze::TNCAPUTD;
343 }
344}
345
346static unsigned decodeIDIV(uint32_t insn) {
347 switch (insn&0x3) {
348 default: return UNSUPPORTED;
349 case 0x0: return MBlaze::IDIV;
350 case 0x2: return MBlaze::IDIVU;
351 }
352}
353
Wesley Peckec57d532010-11-13 02:37:59 +0000354static unsigned decodeLBU(uint32_t insn) {
355 switch ((insn>>9)&0x1) {
356 default: return UNSUPPORTED;
357 case 0x0: return MBlaze::LBU;
358 case 0x1: return MBlaze::LBUR;
359 }
360}
361
362static unsigned decodeLHU(uint32_t insn) {
363 switch ((insn>>9)&0x1) {
364 default: return UNSUPPORTED;
365 case 0x0: return MBlaze::LHU;
366 case 0x1: return MBlaze::LHUR;
367 }
368}
369
Wesley Pecka0603832010-10-27 00:23:01 +0000370static unsigned decodeLW(uint32_t insn) {
371 switch ((insn>>9)&0x3) {
372 default: return UNSUPPORTED;
373 case 0x0: return MBlaze::LW;
374 case 0x1: return MBlaze::LWR;
375 case 0x2: return MBlaze::LWX;
376 }
377}
378
Wesley Peckec57d532010-11-13 02:37:59 +0000379static unsigned decodeSB(uint32_t insn) {
380 switch ((insn>>9)&0x1) {
381 default: return UNSUPPORTED;
382 case 0x0: return MBlaze::SB;
383 case 0x1: return MBlaze::SBR;
384 }
385}
386
387static unsigned decodeSH(uint32_t insn) {
388 switch ((insn>>9)&0x1) {
389 default: return UNSUPPORTED;
390 case 0x0: return MBlaze::SH;
391 case 0x1: return MBlaze::SHR;
392 }
393}
394
Wesley Pecka0603832010-10-27 00:23:01 +0000395static unsigned decodeSW(uint32_t insn) {
396 switch ((insn>>9)&0x3) {
397 default: return UNSUPPORTED;
398 case 0x0: return MBlaze::SW;
399 case 0x1: return MBlaze::SWR;
400 case 0x2: return MBlaze::SWX;
401 }
402}
403
404static unsigned decodeMFS(uint32_t insn) {
405 switch ((insn>>15)&0x1) {
406 default: return UNSUPPORTED;
407 case 0x0:
Wesley Peckec57d532010-11-13 02:37:59 +0000408 switch ((insn>>16)&0x1) {
Wesley Pecka0603832010-10-27 00:23:01 +0000409 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000410 case 0x0: return MBlaze::MSRSET;
411 case 0x1: return MBlaze::MSRCLR;
Wesley Pecka0603832010-10-27 00:23:01 +0000412 }
413 case 0x1:
414 switch ((insn>>14)&0x1) {
415 default: return UNSUPPORTED;
416 case 0x0: return MBlaze::MFS;
417 case 0x1: return MBlaze::MTS;
418 }
419 }
420}
421
422static unsigned decodeOR(uint32_t insn) {
423 switch (getFLAGS(insn)) {
424 default: return UNSUPPORTED;
425 case 0x000: return MBlaze::OR;
426 case 0x400: return MBlaze::PCMPBF;
427 }
428}
429
430static unsigned decodeXOR(uint32_t insn) {
431 switch (getFLAGS(insn)) {
432 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000433 case 0x000: return MBlaze::XOR;
Wesley Pecka0603832010-10-27 00:23:01 +0000434 case 0x400: return MBlaze::PCMPEQ;
435 }
436}
437
438static unsigned decodeANDN(uint32_t insn) {
439 switch (getFLAGS(insn)) {
440 default: return UNSUPPORTED;
Wesley Peckec57d532010-11-13 02:37:59 +0000441 case 0x000: return MBlaze::ANDN;
Wesley Pecka0603832010-10-27 00:23:01 +0000442 case 0x400: return MBlaze::PCMPNE;
443 }
444}
445
446static unsigned decodeRTSD(uint32_t insn) {
447 switch ((insn>>21)&0x1F) {
448 default: return UNSUPPORTED;
449 case 0x10: return MBlaze::RTSD;
450 case 0x11: return MBlaze::RTID;
451 case 0x12: return MBlaze::RTBD;
452 case 0x14: return MBlaze::RTED;
453 }
454}
455
Wesley Peck0a67d922010-11-08 19:40:01 +0000456static unsigned getOPCODE(uint32_t insn) {
Wesley Pecka0603832010-10-27 00:23:01 +0000457 unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
458 switch (opcode) {
459 case MBlaze::MUL: return decodeMUL(insn);
460 case MBlaze::SEXT8: return decodeSEXT(insn);
461 case MBlaze::BEQ: return decodeBEQ(insn);
462 case MBlaze::BEQI: return decodeBEQI(insn);
463 case MBlaze::BR: return decodeBR(insn);
464 case MBlaze::BRI: return decodeBRI(insn);
465 case MBlaze::BSRL: return decodeBSRL(insn);
466 case MBlaze::BSRLI: return decodeBSRLI(insn);
467 case MBlaze::RSUBK: return decodeRSUBK(insn);
468 case MBlaze::FADD: return decodeFADD(insn);
469 case MBlaze::GET: return decodeGET(insn);
470 case MBlaze::GETD: return decodeGETD(insn);
471 case MBlaze::IDIV: return decodeIDIV(insn);
Wesley Peckec57d532010-11-13 02:37:59 +0000472 case MBlaze::LBU: return decodeLBU(insn);
473 case MBlaze::LHU: return decodeLHU(insn);
Wesley Pecka0603832010-10-27 00:23:01 +0000474 case MBlaze::LW: return decodeLW(insn);
Wesley Peckec57d532010-11-13 02:37:59 +0000475 case MBlaze::SB: return decodeSB(insn);
476 case MBlaze::SH: return decodeSH(insn);
Wesley Pecka0603832010-10-27 00:23:01 +0000477 case MBlaze::SW: return decodeSW(insn);
478 case MBlaze::MFS: return decodeMFS(insn);
479 case MBlaze::OR: return decodeOR(insn);
480 case MBlaze::XOR: return decodeXOR(insn);
481 case MBlaze::ANDN: return decodeANDN(insn);
482 case MBlaze::RTSD: return decodeRTSD(insn);
483 default: return opcode;
484 }
485}
486
487EDInstInfo *MBlazeDisassembler::getEDInfo() const {
488 return instInfoMBlaze;
489}
490
491//
492// Public interface for the disassembler
493//
494
Owen Anderson83e3f672011-08-17 17:44:15 +0000495MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr,
Wesley Pecka0603832010-10-27 00:23:01 +0000496 uint64_t &size,
497 const MemoryObject &region,
498 uint64_t address,
Owen Anderson98c5dda2011-09-15 23:38:46 +0000499 raw_ostream &vStream,
500 raw_ostream &cStream) const {
Wesley Pecka0603832010-10-27 00:23:01 +0000501 // The machine instruction.
502 uint32_t insn;
Wesley Pecke53060f2011-04-11 21:35:21 +0000503 uint64_t read;
Wesley Pecka0603832010-10-27 00:23:01 +0000504 uint8_t bytes[4];
Wesley Peckec57d532010-11-13 02:37:59 +0000505
Wesley Pecke53060f2011-04-11 21:35:21 +0000506 // By default we consume 1 byte on failure
507 size = 1;
Wesley Peck90eff732010-11-13 05:48:21 +0000508
Wesley Pecka0603832010-10-27 00:23:01 +0000509 // We want to read exactly 4 bytes of data.
Wesley Pecke53060f2011-04-11 21:35:21 +0000510 if (region.readBytes(address, 4, (uint8_t*)bytes, &read) == -1 || read < 4)
Owen Anderson83e3f672011-08-17 17:44:15 +0000511 return Fail;
Wesley Pecka0603832010-10-27 00:23:01 +0000512
513 // Encoded as a big-endian 32-bit word in the stream.
514 insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
515
516 // Get the MCInst opcode from the binary instruction and make sure
517 // that it is a valid instruction.
Wesley Peck0a67d922010-11-08 19:40:01 +0000518 unsigned opcode = getOPCODE(insn);
519 if (opcode == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000520 return Fail;
Wesley Pecka0603832010-10-27 00:23:01 +0000521
522 instr.setOpcode(opcode);
523
Wesley Pecke53060f2011-04-11 21:35:21 +0000524 unsigned RD = getRD(insn);
525 unsigned RA = getRA(insn);
526 unsigned RB = getRB(insn);
527 unsigned RS = getRS(insn);
528
Wesley Pecka0603832010-10-27 00:23:01 +0000529 uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
Wesley Peck0a67d922010-11-08 19:40:01 +0000530 switch ((tsFlags & MBlazeII::FormMask)) {
Wesley Pecke53060f2011-04-11 21:35:21 +0000531 default:
Owen Anderson83e3f672011-08-17 17:44:15 +0000532 return Fail;
Wesley Pecka0603832010-10-27 00:23:01 +0000533
Wesley Peckec57d532010-11-13 02:37:59 +0000534 case MBlazeII::FRRRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000535 if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000536 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000537 instr.addOperand(MCOperand::CreateReg(RD));
538 instr.addOperand(MCOperand::CreateReg(RB));
539 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000540 break;
541
Wesley Pecka0603832010-10-27 00:23:01 +0000542 case MBlazeII::FRRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000543 if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000544 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000545 instr.addOperand(MCOperand::CreateReg(RD));
546 instr.addOperand(MCOperand::CreateReg(RA));
547 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000548 break;
549
Wesley Peckec57d532010-11-13 02:37:59 +0000550 case MBlazeII::FRI:
551 switch (opcode) {
Wesley Pecke53060f2011-04-11 21:35:21 +0000552 default:
Owen Anderson83e3f672011-08-17 17:44:15 +0000553 return Fail;
Wesley Peckec57d532010-11-13 02:37:59 +0000554 case MBlaze::MFS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000555 if (RD == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000556 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000557 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peckec57d532010-11-13 02:37:59 +0000558 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
559 break;
560 case MBlaze::MTS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000561 if (RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000562 return Fail;
Wesley Peckec57d532010-11-13 02:37:59 +0000563 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
Wesley Pecke53060f2011-04-11 21:35:21 +0000564 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000565 break;
566 case MBlaze::MSRSET:
567 case MBlaze::MSRCLR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000568 if (RD == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000569 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000570 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peckec57d532010-11-13 02:37:59 +0000571 instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
572 break;
573 }
574 break;
575
Wesley Pecka0603832010-10-27 00:23:01 +0000576 case MBlazeII::FRRI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000577 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000578 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000579 instr.addOperand(MCOperand::CreateReg(RD));
580 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peckec57d532010-11-13 02:37:59 +0000581 switch (opcode) {
582 default:
583 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
584 break;
585 case MBlaze::BSRLI:
586 case MBlaze::BSRAI:
587 case MBlaze::BSLLI:
588 instr.addOperand(MCOperand::CreateImm(insn&0x1F));
589 break;
590 }
Wesley Pecka0603832010-10-27 00:23:01 +0000591 break;
592
593 case MBlazeII::FCRR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000594 if (RA == UNSUPPORTED || RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000595 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000596 instr.addOperand(MCOperand::CreateReg(RA));
597 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000598 break;
599
600 case MBlazeII::FCRI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000601 if (RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000602 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000603 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000604 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000605 break;
606
607 case MBlazeII::FRCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000608 if (RD == UNSUPPORTED || RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000609 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000610 instr.addOperand(MCOperand::CreateReg(RD));
611 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000612 break;
613
614 case MBlazeII::FRCI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000615 if (RD == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000616 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000617 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000618 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000619 break;
620
621 case MBlazeII::FCCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000622 if (RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000623 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000624 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000625 break;
626
627 case MBlazeII::FCCI:
Wesley Peck0a67d922010-11-08 19:40:01 +0000628 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000629 break;
630
631 case MBlazeII::FRRCI:
Wesley Pecke53060f2011-04-11 21:35:21 +0000632 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000633 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000634 instr.addOperand(MCOperand::CreateReg(RD));
635 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000636 instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000637 break;
638
639 case MBlazeII::FRRC:
Wesley Pecke53060f2011-04-11 21:35:21 +0000640 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000641 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000642 instr.addOperand(MCOperand::CreateReg(RD));
643 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000644 break;
645
646 case MBlazeII::FRCX:
Wesley Pecke53060f2011-04-11 21:35:21 +0000647 if (RD == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000648 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000649 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000650 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000651 break;
652
653 case MBlazeII::FRCS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000654 if (RD == UNSUPPORTED || RS == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000655 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000656 instr.addOperand(MCOperand::CreateReg(RD));
657 instr.addOperand(MCOperand::CreateReg(RS));
Wesley Pecka0603832010-10-27 00:23:01 +0000658 break;
659
660 case MBlazeII::FCRCS:
Wesley Pecke53060f2011-04-11 21:35:21 +0000661 if (RS == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000662 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000663 instr.addOperand(MCOperand::CreateReg(RS));
664 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000665 break;
666
667 case MBlazeII::FCRCX:
Wesley Pecke53060f2011-04-11 21:35:21 +0000668 if (RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000669 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000670 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Peck0a67d922010-11-08 19:40:01 +0000671 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000672 break;
673
674 case MBlazeII::FCX:
Wesley Peck0a67d922010-11-08 19:40:01 +0000675 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
Wesley Pecka0603832010-10-27 00:23:01 +0000676 break;
677
678 case MBlazeII::FCR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000679 if (RB == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000680 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000681 instr.addOperand(MCOperand::CreateReg(RB));
Wesley Pecka0603832010-10-27 00:23:01 +0000682 break;
683
684 case MBlazeII::FRIR:
Wesley Pecke53060f2011-04-11 21:35:21 +0000685 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
Owen Anderson83e3f672011-08-17 17:44:15 +0000686 return Fail;
Wesley Pecke53060f2011-04-11 21:35:21 +0000687 instr.addOperand(MCOperand::CreateReg(RD));
Wesley Peck0a67d922010-11-08 19:40:01 +0000688 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
Wesley Pecke53060f2011-04-11 21:35:21 +0000689 instr.addOperand(MCOperand::CreateReg(RA));
Wesley Pecka0603832010-10-27 00:23:01 +0000690 break;
691 }
692
Wesley Pecke53060f2011-04-11 21:35:21 +0000693 // We always consume 4 bytes of data on success
694 size = 4;
695
Owen Anderson83e3f672011-08-17 17:44:15 +0000696 return Success;
Wesley Pecka0603832010-10-27 00:23:01 +0000697}
698
James Molloyb9505852011-09-07 17:24:38 +0000699static MCDisassembler *createMBlazeDisassembler(const Target &T,
700 const MCSubtargetInfo &STI) {
701 return new MBlazeDisassembler(STI);
Wesley Pecka0603832010-10-27 00:23:01 +0000702}
703
Wesley Peckec57d532010-11-13 02:37:59 +0000704extern "C" void LLVMInitializeMBlazeDisassembler() {
Wesley Pecka0603832010-10-27 00:23:01 +0000705 // Register the disassembler.
Wesley Peckec57d532010-11-13 02:37:59 +0000706 TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
Wesley Pecka0603832010-10-27 00:23:01 +0000707 createMBlazeDisassembler);
708}