1 //===- MBlazeDisassembler.cpp - Disassembler for MicroBlaze ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is part of the MBlaze Disassembler. It contains code to translate
11 // the data produced by the decoder into MCInsts.
13 //===----------------------------------------------------------------------===//
16 #include "MBlazeInstrInfo.h"
17 #include "MBlazeDisassembler.h"
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"
28 // #include "MBlazeGenDecoderTables.inc"
29 // #include "MBlazeGenRegisterNames.inc"
30 #include "MBlazeGenInstrInfo.inc"
31 #include "MBlazeGenEDInfo.inc"
35 const unsigned UNSUPPORTED
= -1;
37 static 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
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
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
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
59 static unsigned getRD( uint32_t insn
) {
60 return MBlazeRegisterInfo::getRegisterFromNumbering( (insn
>>21)&0x1F );
63 static unsigned getRA( uint32_t insn
) {
64 return MBlazeRegisterInfo::getRegisterFromNumbering( (insn
>>16)&0x1F );
67 static unsigned getRB( uint32_t insn
) {
68 return MBlazeRegisterInfo::getRegisterFromNumbering( (insn
>>11)&0x1F );
71 static int64_t getRS( uint32_t insn
) {
72 int16_t val
= (insn
& 0x3FFF);
76 static int64_t getIMM( uint32_t insn
) {
77 int16_t val
= (insn
& 0xFFFF);
81 static int64_t getSHT( uint32_t insn
) {
82 int16_t val
= (insn
& 0x1F);
86 static unsigned getFLAGS( int32_t insn
) {
87 return (insn
& 0x7FF);
90 static int64_t getFSL( uint32_t insn
) {
91 int16_t val
= (insn
& 0xF);
95 static unsigned decodeMUL(uint32_t insn
) {
96 switch (getFLAGS(insn
)) {
97 default: return UNSUPPORTED
;
98 case 0: return MBlaze::MUL
;
99 case 1: return MBlaze::MULH
;
100 case 2: return MBlaze::MULHSU
;
101 case 3: return MBlaze::MULHU
;
105 static unsigned decodeSEXT(uint32_t insn
) {
106 switch (getIMM(insn
)) {
107 default: return UNSUPPORTED
;
108 case 0x60: return MBlaze::SEXT8
;
109 case 0x68: return MBlaze::WIC
;
110 case 0x64: return MBlaze::WDC
;
111 case 0x66: return MBlaze::WDCC
;
112 case 0x74: return MBlaze::WDCF
;
113 case 0x61: return MBlaze::SEXT16
;
114 case 0x41: return MBlaze::SRL
;
115 case 0x21: return MBlaze::SRC
;
116 case 0x01: return MBlaze::SRA
;
120 static unsigned decodeBEQ(uint32_t insn
) {
121 switch (getRD(insn
)) {
122 default: return UNSUPPORTED
;
123 case 0x00: return MBlaze::BEQ
;
124 case 0x10: return MBlaze::BEQD
;
125 case 0x05: return MBlaze::BGE
;
126 case 0x15: return MBlaze::BGED
;
127 case 0x04: return MBlaze::BGT
;
128 case 0x14: return MBlaze::BGTD
;
129 case 0x03: return MBlaze::BLE
;
130 case 0x13: return MBlaze::BLED
;
131 case 0x02: return MBlaze::BLT
;
132 case 0x12: return MBlaze::BLTD
;
133 case 0x01: return MBlaze::BNE
;
134 case 0x11: return MBlaze::BNED
;
138 static unsigned decodeBEQI(uint32_t insn
) {
139 switch (getRD(insn
)) {
140 default: return UNSUPPORTED
;
141 case 0x00: return MBlaze::BEQI
;
142 case 0x10: return MBlaze::BEQID
;
143 case 0x05: return MBlaze::BGEI
;
144 case 0x15: return MBlaze::BGEID
;
145 case 0x04: return MBlaze::BGTI
;
146 case 0x14: return MBlaze::BGTID
;
147 case 0x03: return MBlaze::BLEI
;
148 case 0x13: return MBlaze::BLEID
;
149 case 0x02: return MBlaze::BLTI
;
150 case 0x12: return MBlaze::BLTID
;
151 case 0x01: return MBlaze::BNEI
;
152 case 0x11: return MBlaze::BNEID
;
156 static unsigned decodeBR(uint32_t insn
) {
157 switch ((insn
>>16)&0x1F) {
158 default: return UNSUPPORTED
;
159 case 0x00: return MBlaze::BR
;
160 case 0x08: return MBlaze::BRA
;
161 case 0x0C: return MBlaze::BRK
;
162 case 0x10: return MBlaze::BRD
;
163 case 0x14: return MBlaze::BRLD
;
164 case 0x18: return MBlaze::BRAD
;
165 case 0x1C: return MBlaze::BRALD
;
169 static unsigned decodeBRI(uint32_t insn
) {
170 switch ((insn
>>16)&0x1F) {
171 default: return UNSUPPORTED
;
172 case 0x00: return MBlaze::BRI
;
173 case 0x08: return MBlaze::BRAI
;
174 case 0x0C: return MBlaze::BRKI
;
175 case 0x10: return MBlaze::BRID
;
176 case 0x14: return MBlaze::BRLID
;
177 case 0x18: return MBlaze::BRAID
;
178 case 0x1C: return MBlaze::BRALID
;
182 static unsigned decodeBSRL(uint32_t insn
) {
183 switch ((insn
>>9)&0x3) {
184 default: return UNSUPPORTED
;
185 case 0x2: return MBlaze::BSLL
;
186 case 0x1: return MBlaze::BSRA
;
187 case 0x0: return MBlaze::BSRL
;
191 static unsigned decodeBSRLI(uint32_t insn
) {
192 switch ((insn
>>9)&0x3) {
193 default: return UNSUPPORTED
;
194 case 0x2: return MBlaze::BSLLI
;
195 case 0x1: return MBlaze::BSRAI
;
196 case 0x0: return MBlaze::BSRLI
;
200 static unsigned decodeRSUBK(uint32_t insn
) {
201 switch (getFLAGS(insn
)) {
202 default: return UNSUPPORTED
;
203 case 0x0: return MBlaze::RSUBK
;
204 case 0x1: return MBlaze::CMP
;
205 case 0x3: return MBlaze::CMPU
;
209 static unsigned decodeFADD(uint32_t insn
) {
210 switch (getFLAGS(insn
)) {
211 default: return UNSUPPORTED
;
212 case 0x000: return MBlaze::FADD
;
213 case 0x080: return MBlaze::FRSUB
;
214 case 0x100: return MBlaze::FMUL
;
215 case 0x180: return MBlaze::FDIV
;
216 case 0x200: return MBlaze::FCMP_UN
;
217 case 0x210: return MBlaze::FCMP_LT
;
218 case 0x220: return MBlaze::FCMP_EQ
;
219 case 0x230: return MBlaze::FCMP_LE
;
220 case 0x240: return MBlaze::FCMP_GT
;
221 case 0x250: return MBlaze::FCMP_NE
;
222 case 0x260: return MBlaze::FCMP_GE
;
223 case 0x280: return MBlaze::FLT
;
224 case 0x300: return MBlaze::FINT
;
225 case 0x380: return MBlaze::FSQRT
;
229 static unsigned decodeGET(uint32_t insn
) {
230 switch ((insn
>>10)&0x3F) {
231 default: return UNSUPPORTED
;
232 case 0x00: return MBlaze::GET
;
233 case 0x01: return MBlaze::EGET
;
234 case 0x02: return MBlaze::AGET
;
235 case 0x03: return MBlaze::EAGET
;
236 case 0x04: return MBlaze::TGET
;
237 case 0x05: return MBlaze::TEGET
;
238 case 0x06: return MBlaze::TAGET
;
239 case 0x07: return MBlaze::TEAGET
;
240 case 0x08: return MBlaze::CGET
;
241 case 0x09: return MBlaze::ECGET
;
242 case 0x0A: return MBlaze::CAGET
;
243 case 0x0B: return MBlaze::ECAGET
;
244 case 0x0C: return MBlaze::TCGET
;
245 case 0x0D: return MBlaze::TECGET
;
246 case 0x0E: return MBlaze::TCAGET
;
247 case 0x0F: return MBlaze::TECAGET
;
248 case 0x10: return MBlaze::NGET
;
249 case 0x11: return MBlaze::NEGET
;
250 case 0x12: return MBlaze::NAGET
;
251 case 0x13: return MBlaze::NEAGET
;
252 case 0x14: return MBlaze::TNGET
;
253 case 0x15: return MBlaze::TNEGET
;
254 case 0x16: return MBlaze::TNAGET
;
255 case 0x17: return MBlaze::TNEAGET
;
256 case 0x18: return MBlaze::NCGET
;
257 case 0x19: return MBlaze::NECGET
;
258 case 0x1A: return MBlaze::NCAGET
;
259 case 0x1B: return MBlaze::NECAGET
;
260 case 0x1C: return MBlaze::TNCGET
;
261 case 0x1D: return MBlaze::TNECGET
;
262 case 0x1E: return MBlaze::TNCAGET
;
263 case 0x1F: return MBlaze::TNECAGET
;
264 case 0x20: return MBlaze::PUT
;
265 case 0x22: return MBlaze::APUT
;
266 case 0x24: return MBlaze::TPUT
;
267 case 0x26: return MBlaze::TAPUT
;
268 case 0x28: return MBlaze::CPUT
;
269 case 0x2A: return MBlaze::CAPUT
;
270 case 0x2C: return MBlaze::TCPUT
;
271 case 0x2E: return MBlaze::TCAPUT
;
272 case 0x30: return MBlaze::NPUT
;
273 case 0x32: return MBlaze::NAPUT
;
274 case 0x34: return MBlaze::TNPUT
;
275 case 0x36: return MBlaze::TNAPUT
;
276 case 0x38: return MBlaze::NCPUT
;
277 case 0x3A: return MBlaze::NCAPUT
;
278 case 0x3C: return MBlaze::TNCPUT
;
279 case 0x3E: return MBlaze::TNCAPUT
;
283 static unsigned decodeGETD(uint32_t insn
) {
284 switch ((insn
>>5)&0x3F) {
285 default: return UNSUPPORTED
;
286 case 0x00: return MBlaze::GETD
;
287 case 0x01: return MBlaze::EGETD
;
288 case 0x02: return MBlaze::AGETD
;
289 case 0x03: return MBlaze::EAGETD
;
290 case 0x04: return MBlaze::TGETD
;
291 case 0x05: return MBlaze::TEGETD
;
292 case 0x06: return MBlaze::TAGETD
;
293 case 0x07: return MBlaze::TEAGETD
;
294 case 0x08: return MBlaze::CGETD
;
295 case 0x09: return MBlaze::ECGETD
;
296 case 0x0A: return MBlaze::CAGETD
;
297 case 0x0B: return MBlaze::ECAGETD
;
298 case 0x0C: return MBlaze::TCGETD
;
299 case 0x0D: return MBlaze::TECGETD
;
300 case 0x0E: return MBlaze::TCAGETD
;
301 case 0x0F: return MBlaze::TECAGETD
;
302 case 0x10: return MBlaze::NGETD
;
303 case 0x11: return MBlaze::NEGETD
;
304 case 0x12: return MBlaze::NAGETD
;
305 case 0x13: return MBlaze::NEAGETD
;
306 case 0x14: return MBlaze::TNGETD
;
307 case 0x15: return MBlaze::TNEGETD
;
308 case 0x16: return MBlaze::TNAGETD
;
309 case 0x17: return MBlaze::TNEAGETD
;
310 case 0x18: return MBlaze::NCGETD
;
311 case 0x19: return MBlaze::NECGETD
;
312 case 0x1A: return MBlaze::NCAGETD
;
313 case 0x1B: return MBlaze::NECAGETD
;
314 case 0x1C: return MBlaze::TNCGETD
;
315 case 0x1D: return MBlaze::TNECGETD
;
316 case 0x1E: return MBlaze::TNCAGETD
;
317 case 0x1F: return MBlaze::TNECAGETD
;
318 case 0x20: return MBlaze::PUTD
;
319 case 0x22: return MBlaze::APUTD
;
320 case 0x24: return MBlaze::TPUTD
;
321 case 0x26: return MBlaze::TAPUTD
;
322 case 0x28: return MBlaze::CPUTD
;
323 case 0x2A: return MBlaze::CAPUTD
;
324 case 0x2C: return MBlaze::TCPUTD
;
325 case 0x2E: return MBlaze::TCAPUTD
;
326 case 0x30: return MBlaze::NPUTD
;
327 case 0x32: return MBlaze::NAPUTD
;
328 case 0x34: return MBlaze::TNPUTD
;
329 case 0x36: return MBlaze::TNAPUTD
;
330 case 0x38: return MBlaze::NCPUTD
;
331 case 0x3A: return MBlaze::NCAPUTD
;
332 case 0x3C: return MBlaze::TNCPUTD
;
333 case 0x3E: return MBlaze::TNCAPUTD
;
337 static unsigned decodeIDIV(uint32_t insn
) {
339 default: return UNSUPPORTED
;
340 case 0x0: return MBlaze::IDIV
;
341 case 0x2: return MBlaze::IDIVU
;
345 static unsigned decodeLW(uint32_t insn
) {
346 switch ((insn
>>9)&0x3) {
347 default: return UNSUPPORTED
;
348 case 0x0: return MBlaze::LW
;
349 case 0x1: return MBlaze::LWR
;
350 case 0x2: return MBlaze::LWX
;
354 static unsigned decodeSW(uint32_t insn
) {
355 switch ((insn
>>9)&0x3) {
356 default: return UNSUPPORTED
;
357 case 0x0: return MBlaze::SW
;
358 case 0x1: return MBlaze::SWR
;
359 case 0x2: return MBlaze::SWX
;
363 static unsigned decodeMFS(uint32_t insn
) {
364 switch ((insn
>>15)&0x1) {
365 default: return UNSUPPORTED
;
367 switch ((insn
>>16)&0x1F) {
368 default: return UNSUPPORTED
;
369 case 0x22: return MBlaze::MSRCLR
;
370 case 0x20: return MBlaze::MSRSET
;
373 switch ((insn
>>14)&0x1) {
374 default: return UNSUPPORTED
;
375 case 0x0: return MBlaze::MFS
;
376 case 0x1: return MBlaze::MTS
;
381 static unsigned decodeOR(uint32_t insn
) {
382 switch (getFLAGS(insn
)) {
383 default: return UNSUPPORTED
;
384 case 0x000: return MBlaze::OR
;
385 case 0x400: return MBlaze::PCMPBF
;
389 static unsigned decodeXOR(uint32_t insn
) {
390 switch (getFLAGS(insn
)) {
391 default: return UNSUPPORTED
;
392 case 0x000: return MBlaze::OR
;
393 case 0x400: return MBlaze::PCMPEQ
;
397 static unsigned decodeANDN(uint32_t insn
) {
398 switch (getFLAGS(insn
)) {
399 default: return UNSUPPORTED
;
400 case 0x000: return MBlaze::OR
;
401 case 0x400: return MBlaze::PCMPNE
;
405 static unsigned decodeRTSD(uint32_t insn
) {
406 switch ((insn
>>21)&0x1F) {
407 default: return UNSUPPORTED
;
408 case 0x10: return MBlaze::RTSD
;
409 case 0x11: return MBlaze::RTID
;
410 case 0x12: return MBlaze::RTBD
;
411 case 0x14: return MBlaze::RTED
;
415 static unsigned getOPCODE( uint32_t insn
) {
416 unsigned opcode
= mblazeBinary2Opcode
[ (insn
>>26)&0x3F ];
418 case MBlaze::MUL
: return decodeMUL(insn
);
419 case MBlaze::SEXT8
: return decodeSEXT(insn
);
420 case MBlaze::BEQ
: return decodeBEQ(insn
);
421 case MBlaze::BEQI
: return decodeBEQI(insn
);
422 case MBlaze::BR
: return decodeBR(insn
);
423 case MBlaze::BRI
: return decodeBRI(insn
);
424 case MBlaze::BSRL
: return decodeBSRL(insn
);
425 case MBlaze::BSRLI
: return decodeBSRLI(insn
);
426 case MBlaze::RSUBK
: return decodeRSUBK(insn
);
427 case MBlaze::FADD
: return decodeFADD(insn
);
428 case MBlaze::GET
: return decodeGET(insn
);
429 case MBlaze::GETD
: return decodeGETD(insn
);
430 case MBlaze::IDIV
: return decodeIDIV(insn
);
431 case MBlaze::LW
: return decodeLW(insn
);
432 case MBlaze::SW
: return decodeSW(insn
);
433 case MBlaze::MFS
: return decodeMFS(insn
);
434 case MBlaze::OR
: return decodeOR(insn
);
435 case MBlaze::XOR
: return decodeXOR(insn
);
436 case MBlaze::ANDN
: return decodeANDN(insn
);
437 case MBlaze::RTSD
: return decodeRTSD(insn
);
438 default: return opcode
;
442 EDInstInfo
*MBlazeDisassembler::getEDInfo() const {
443 return instInfoMBlaze
;
447 // Public interface for the disassembler
450 bool MBlazeDisassembler::getInstruction(MCInst
&instr
,
452 const MemoryObject
®ion
,
454 raw_ostream
&vStream
) const {
455 // The machine instruction.
459 // We want to read exactly 4 bytes of data.
460 if (region
.readBytes(address
, 4, (uint8_t*)bytes
, NULL
) == -1)
463 // Encoded as a big-endian 32-bit word in the stream.
464 insn
= (bytes
[0]<<24) | (bytes
[1]<<16) | (bytes
[2]<< 8) | (bytes
[3]<<0);
466 // Get the MCInst opcode from the binary instruction and make sure
467 // that it is a valid instruction.
468 unsigned opcode
= getOPCODE( insn
);
469 if( opcode
== UNSUPPORTED
)
472 instr
.setOpcode(opcode
);
474 uint64_t tsFlags
= MBlazeInsts
[opcode
].TSFlags
;
475 switch( (tsFlags
& MBlazeII::FormMask
) ) {
477 errs() << "Opcode: " << MBlazeInsts
[opcode
].Name
<< "\n";
478 errs() << "Flags: "; errs().write_hex( tsFlags
); errs() << "\n";
482 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
483 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
484 instr
.addOperand( MCOperand::CreateReg( getRB(insn
) ) );
488 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
489 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
490 instr
.addOperand( MCOperand::CreateImm( getIMM(insn
) ) );
494 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
495 instr
.addOperand( MCOperand::CreateReg( getRB(insn
) ) );
499 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
500 instr
.addOperand( MCOperand::CreateImm( getIMM(insn
) ) );
504 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
505 instr
.addOperand( MCOperand::CreateReg( getRB(insn
) ) );
509 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
510 instr
.addOperand( MCOperand::CreateImm( getIMM(insn
) ) );
514 instr
.addOperand( MCOperand::CreateReg( getRB(insn
) ) );
518 instr
.addOperand( MCOperand::CreateImm( getIMM(insn
) ) );
521 case MBlazeII::FRRCI
:
522 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
523 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
524 instr
.addOperand( MCOperand::CreateImm( getSHT(insn
) ) );
528 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
529 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
533 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
534 instr
.addOperand( MCOperand::CreateImm( getFSL(insn
) ) );
538 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
539 instr
.addOperand( MCOperand::CreateImm( getRS(insn
) ) );
542 case MBlazeII::FCRCS
:
543 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
544 instr
.addOperand( MCOperand::CreateImm( getRS(insn
) ) );
547 case MBlazeII::FCRCX
:
548 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
549 instr
.addOperand( MCOperand::CreateImm( getFSL(insn
) ) );
553 instr
.addOperand( MCOperand::CreateImm( getFSL(insn
) ) );
557 instr
.addOperand( MCOperand::CreateReg( getRB(insn
) ) );
561 instr
.addOperand( MCOperand::CreateReg( getRD(insn
) ) );
562 instr
.addOperand( MCOperand::CreateImm( getIMM(insn
) ) );
563 instr
.addOperand( MCOperand::CreateReg( getRA(insn
) ) );
570 static MCDisassembler
*createMBlazeDisassembler(const Target
&T
) {
571 return new MBlazeDisassembler
;
574 extern "C" void LLVMInitializeMBlazeDisassembler() {
575 // Register the disassembler.
576 TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget
,
577 createMBlazeDisassembler
);