1 //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- 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 Mips Disassembler.
12 //===----------------------------------------------------------------------===//
15 #include "MipsSubtarget.h"
16 #include "llvm/MC/EDInstInfo.h"
17 #include "llvm/MC/MCDisassembler.h"
18 #include "llvm/Support/MemoryObject.h"
19 #include "llvm/Support/TargetRegistry.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/Support/MathExtras.h"
26 #include "MipsGenEDInfo.inc"
30 typedef MCDisassembler::DecodeStatus DecodeStatus;
32 /// MipsDisassembler - a disasembler class for Mips32.
33 class MipsDisassembler : public MCDisassembler {
35 /// Constructor - Initializes the disassembler.
37 MipsDisassembler(const MCSubtargetInfo &STI, bool bigEndian) :
38 MCDisassembler(STI), isBigEndian(bigEndian) {
44 /// getInstruction - See MCDisassembler.
45 DecodeStatus getInstruction(MCInst &instr,
47 const MemoryObject ®ion,
50 raw_ostream &cStream) const;
52 /// getEDInfo - See MCDisassembler.
53 const EDInstInfo *getEDInfo() const;
60 /// Mips64Disassembler - a disasembler class for Mips64.
61 class Mips64Disassembler : public MCDisassembler {
63 /// Constructor - Initializes the disassembler.
65 Mips64Disassembler(const MCSubtargetInfo &STI, bool bigEndian) :
66 MCDisassembler(STI), isBigEndian(bigEndian) {
69 ~Mips64Disassembler() {
72 /// getInstruction - See MCDisassembler.
73 DecodeStatus getInstruction(MCInst &instr,
75 const MemoryObject ®ion,
78 raw_ostream &cStream) const;
80 /// getEDInfo - See MCDisassembler.
81 const EDInstInfo *getEDInfo() const;
87 const EDInstInfo *MipsDisassembler::getEDInfo() const {
91 const EDInstInfo *Mips64Disassembler::getEDInfo() const {
95 // Decoder tables for Mips register
96 static const unsigned CPURegsTable[] = {
97 Mips::ZERO, Mips::AT, Mips::V0, Mips::V1,
98 Mips::A0, Mips::A1, Mips::A2, Mips::A3,
99 Mips::T0, Mips::T1, Mips::T2, Mips::T3,
100 Mips::T4, Mips::T5, Mips::T6, Mips::T7,
101 Mips::S0, Mips::S1, Mips::S2, Mips::S3,
102 Mips::S4, Mips::S5, Mips::S6, Mips::S7,
103 Mips::T8, Mips::T9, Mips::K0, Mips::K1,
104 Mips::GP, Mips::SP, Mips::FP, Mips::RA
107 static const unsigned FGR32RegsTable[] = {
108 Mips::F0, Mips::F1, Mips::F2, Mips::F3,
109 Mips::F4, Mips::F5, Mips::F6, Mips::F7,
110 Mips::F8, Mips::F9, Mips::F10, Mips::F11,
111 Mips::F12, Mips::F13, Mips::F14, Mips::F15,
112 Mips::F16, Mips::F17, Mips::F18, Mips::F18,
113 Mips::F20, Mips::F21, Mips::F22, Mips::F23,
114 Mips::F24, Mips::F25, Mips::F26, Mips::F27,
115 Mips::F28, Mips::F29, Mips::F30, Mips::F31
118 static const unsigned CPU64RegsTable[] = {
119 Mips::ZERO_64, Mips::AT_64, Mips::V0_64, Mips::V1_64,
120 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
121 Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64,
122 Mips::T4_64, Mips::T5_64, Mips::T6_64, Mips::T7_64,
123 Mips::S0_64, Mips::S1_64, Mips::S2_64, Mips::S3_64,
124 Mips::S4_64, Mips::S5_64, Mips::S6_64, Mips::S7_64,
125 Mips::T8_64, Mips::T9_64, Mips::K0_64, Mips::K1_64,
126 Mips::GP_64, Mips::SP_64, Mips::FP_64, Mips::RA_64
129 static const unsigned FGR64RegsTable[] = {
130 Mips::D0_64, Mips::D1_64, Mips::D2_64, Mips::D3_64,
131 Mips::D4_64, Mips::D5_64, Mips::D6_64, Mips::D7_64,
132 Mips::D8_64, Mips::D9_64, Mips::D10_64, Mips::D11_64,
133 Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,
134 Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64,
135 Mips::D20_64, Mips::D21_64, Mips::D22_64, Mips::D23_64,
136 Mips::D24_64, Mips::D25_64, Mips::D26_64, Mips::D27_64,
137 Mips::D28_64, Mips::D29_64, Mips::D30_64, Mips::D31_64
140 static const unsigned AFGR64RegsTable[] = {
141 Mips::D0, Mips::D1, Mips::D2, Mips::D3,
142 Mips::D4, Mips::D5, Mips::D6, Mips::D7,
143 Mips::D8, Mips::D9, Mips::D10, Mips::D11,
144 Mips::D12, Mips::D13, Mips::D14, Mips::D15
147 // Forward declare these because the autogenerated code will reference them.
148 // Definitions are further down.
149 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
152 const void *Decoder);
154 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
157 const void *Decoder);
159 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
162 const void *Decoder);
164 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
167 const void *Decoder);
169 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
172 const void *Decoder);
174 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
177 const void *Decoder);
179 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
182 const void *Decoder);
184 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
187 const void *Decoder);
189 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
192 const void *Decoder);
194 static DecodeStatus DecodeBC1(MCInst &Inst,
197 const void *Decoder);
200 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
203 const void *Decoder);
205 static DecodeStatus DecodeMem(MCInst &Inst,
208 const void *Decoder);
210 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
212 const void *Decoder);
214 static DecodeStatus DecodeSimm16(MCInst &Inst,
217 const void *Decoder);
219 static DecodeStatus DecodeCondCode(MCInst &Inst,
222 const void *Decoder);
224 static DecodeStatus DecodeInsSize(MCInst &Inst,
227 const void *Decoder);
229 static DecodeStatus DecodeExtSize(MCInst &Inst,
232 const void *Decoder);
235 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
239 static MCDisassembler *createMipsDisassembler(
241 const MCSubtargetInfo &STI) {
242 return new MipsDisassembler(STI,true);
245 static MCDisassembler *createMipselDisassembler(
247 const MCSubtargetInfo &STI) {
248 return new MipsDisassembler(STI,false);
251 static MCDisassembler *createMips64Disassembler(
253 const MCSubtargetInfo &STI) {
254 return new Mips64Disassembler(STI,true);
257 static MCDisassembler *createMips64elDisassembler(
259 const MCSubtargetInfo &STI) {
260 return new Mips64Disassembler(STI, false);
263 extern "C" void LLVMInitializeMipsDisassembler() {
264 // Register the disassembler.
265 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
266 createMipsDisassembler);
267 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
268 createMipselDisassembler);
269 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
270 createMips64Disassembler);
271 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
272 createMips64elDisassembler);
276 #include "MipsGenDisassemblerTables.inc"
278 /// readInstruction - read four bytes from the MemoryObject
279 /// and return 32 bit word sorted according to the given endianess
280 static DecodeStatus readInstruction32(const MemoryObject ®ion,
287 // We want to read exactly 4 Bytes of data.
288 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
290 return MCDisassembler::Fail;
294 // Encoded as a big-endian 32-bit word in the stream.
295 insn = (Bytes[3] << 0) |
301 // Encoded as a small-endian 32-bit word in the stream.
302 insn = (Bytes[0] << 0) |
308 return MCDisassembler::Success;
312 MipsDisassembler::getInstruction(MCInst &instr,
314 const MemoryObject &Region,
316 raw_ostream &vStream,
317 raw_ostream &cStream) const {
320 DecodeStatus Result = readInstruction32(Region, Address, Size,
322 if (Result == MCDisassembler::Fail)
323 return MCDisassembler::Fail;
325 // Calling the auto-generated decoder function.
326 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
327 if (Result != MCDisassembler::Fail) {
332 return MCDisassembler::Fail;
336 Mips64Disassembler::getInstruction(MCInst &instr,
338 const MemoryObject &Region,
340 raw_ostream &vStream,
341 raw_ostream &cStream) const {
344 DecodeStatus Result = readInstruction32(Region, Address, Size,
346 if (Result == MCDisassembler::Fail)
347 return MCDisassembler::Fail;
349 // Calling the auto-generated decoder function.
350 Result = decodeMips64Instruction32(instr, Insn, Address, this, STI);
351 if (Result != MCDisassembler::Fail) {
355 // If we fail to decode in Mips64 decoder space we can try in Mips32
356 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
357 if (Result != MCDisassembler::Fail) {
362 return MCDisassembler::Fail;
365 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
368 const void *Decoder) {
371 return MCDisassembler::Fail;
373 Inst.addOperand(MCOperand::CreateReg(CPU64RegsTable[RegNo]));
374 return MCDisassembler::Success;
377 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
380 const void *Decoder) {
382 return MCDisassembler::Fail;
384 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[RegNo]));
385 return MCDisassembler::Success;
388 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
391 const void *Decoder) {
393 return MCDisassembler::Fail;
395 Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[RegNo]));
396 return MCDisassembler::Success;
399 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
402 const void *Decoder) {
404 return MCDisassembler::Fail;
406 Inst.addOperand(MCOperand::CreateReg(FGR32RegsTable[RegNo]));
407 return MCDisassembler::Success;
410 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
413 const void *Decoder) {
414 Inst.addOperand(MCOperand::CreateReg(RegNo));
415 return MCDisassembler::Success;
418 static DecodeStatus DecodeMem(MCInst &Inst,
421 const void *Decoder) {
422 int Offset = SignExtend32<16>(Insn & 0xffff);
423 int Reg = (int)fieldFromInstruction32(Insn, 16, 5);
424 int Base = (int)fieldFromInstruction32(Insn, 21, 5);
426 if(Inst.getOpcode() == Mips::SC){
427 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg]));
430 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg]));
431 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base]));
432 Inst.addOperand(MCOperand::CreateImm(Offset));
434 return MCDisassembler::Success;
437 static DecodeStatus DecodeFMem(MCInst &Inst,
440 const void *Decoder) {
441 int Offset = SignExtend32<16>(Insn & 0xffff);
442 int Reg = (int)fieldFromInstruction32(Insn, 16, 5);
443 int Base = (int)fieldFromInstruction32(Insn, 21, 5);
445 Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[Reg]));
446 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base]));
447 Inst.addOperand(MCOperand::CreateImm(Offset));
449 return MCDisassembler::Success;
453 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
456 const void *Decoder) {
457 // Currently only hardware register 29 is supported.
459 return MCDisassembler::Fail;
460 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
461 return MCDisassembler::Success;
464 static DecodeStatus DecodeCondCode(MCInst &Inst,
467 const void *Decoder) {
468 int CondCode = Insn & 0xf;
469 Inst.addOperand(MCOperand::CreateImm(CondCode));
470 return MCDisassembler::Success;
473 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
476 const void *Decoder) {
478 return MCDisassembler::Fail;
480 Inst.addOperand(MCOperand::CreateReg(AFGR64RegsTable[RegNo]));
481 return MCDisassembler::Success;
484 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
487 const void *Decoder) {
488 //Currently only hardware register 29 is supported
490 return MCDisassembler::Fail;
491 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
492 return MCDisassembler::Success;
495 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
498 const void *Decoder) {
499 unsigned BranchOffset = Offset & 0xffff;
500 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
501 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
502 return MCDisassembler::Success;
505 static DecodeStatus DecodeBC1(MCInst &Inst,
508 const void *Decoder) {
509 unsigned BranchOffset = Insn & 0xffff;
510 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
511 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
512 return MCDisassembler::Success;
515 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
518 const void *Decoder) {
520 unsigned JumpOffset = fieldFromInstruction32(Insn, 0, 26) << 2;
521 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
522 return MCDisassembler::Success;
526 static DecodeStatus DecodeSimm16(MCInst &Inst,
529 const void *Decoder) {
530 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
531 return MCDisassembler::Success;
534 static DecodeStatus DecodeInsSize(MCInst &Inst,
537 const void *Decoder) {
538 // First we need to grab the pos(lsb) from MCInst.
539 int Pos = Inst.getOperand(2).getImm();
540 int Size = (int) Insn - Pos + 1;
541 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
542 return MCDisassembler::Success;
545 static DecodeStatus DecodeExtSize(MCInst &Inst,
548 const void *Decoder) {
549 int Size = (int) Insn + 1;
550 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
551 return MCDisassembler::Success;