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;
34 /// MipsDisassembler - a disasembler class for Mips32.
35 class MipsDisassembler : public MCDisassembler {
37 /// Constructor - Initializes the disassembler.
39 MipsDisassembler(const MCSubtargetInfo &STI, bool bigEndian) :
40 MCDisassembler(STI), isBigEndian(bigEndian) {
46 /// getInstruction - See MCDisassembler.
47 DecodeStatus getInstruction(MCInst &instr,
49 const MemoryObject ®ion,
52 raw_ostream &cStream) const;
54 /// getEDInfo - See MCDisassembler.
55 const EDInstInfo *getEDInfo() const;
62 /// Mips64Disassembler - a disasembler class for Mips64.
63 class Mips64Disassembler : public MCDisassembler {
65 /// Constructor - Initializes the disassembler.
67 Mips64Disassembler(const MCSubtargetInfo &STI, bool bigEndian) :
68 MCDisassembler(STI), isBigEndian(bigEndian) {
71 ~Mips64Disassembler() {
74 /// getInstruction - See MCDisassembler.
75 DecodeStatus getInstruction(MCInst &instr,
77 const MemoryObject ®ion,
80 raw_ostream &cStream) const;
82 /// getEDInfo - See MCDisassembler.
83 const EDInstInfo *getEDInfo() const;
89 } // end anonymous namespace
91 const EDInstInfo *MipsDisassembler::getEDInfo() const {
95 const EDInstInfo *Mips64Disassembler::getEDInfo() const {
99 // Decoder tables for Mips register
100 static const uint16_t CPURegsTable[] = {
101 Mips::ZERO, Mips::AT, Mips::V0, Mips::V1,
102 Mips::A0, Mips::A1, Mips::A2, Mips::A3,
103 Mips::T0, Mips::T1, Mips::T2, Mips::T3,
104 Mips::T4, Mips::T5, Mips::T6, Mips::T7,
105 Mips::S0, Mips::S1, Mips::S2, Mips::S3,
106 Mips::S4, Mips::S5, Mips::S6, Mips::S7,
107 Mips::T8, Mips::T9, Mips::K0, Mips::K1,
108 Mips::GP, Mips::SP, Mips::FP, Mips::RA
111 static const uint16_t FGR32RegsTable[] = {
112 Mips::F0, Mips::F1, Mips::F2, Mips::F3,
113 Mips::F4, Mips::F5, Mips::F6, Mips::F7,
114 Mips::F8, Mips::F9, Mips::F10, Mips::F11,
115 Mips::F12, Mips::F13, Mips::F14, Mips::F15,
116 Mips::F16, Mips::F17, Mips::F18, Mips::F18,
117 Mips::F20, Mips::F21, Mips::F22, Mips::F23,
118 Mips::F24, Mips::F25, Mips::F26, Mips::F27,
119 Mips::F28, Mips::F29, Mips::F30, Mips::F31
122 static const uint16_t CPU64RegsTable[] = {
123 Mips::ZERO_64, Mips::AT_64, Mips::V0_64, Mips::V1_64,
124 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
125 Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64,
126 Mips::T4_64, Mips::T5_64, Mips::T6_64, Mips::T7_64,
127 Mips::S0_64, Mips::S1_64, Mips::S2_64, Mips::S3_64,
128 Mips::S4_64, Mips::S5_64, Mips::S6_64, Mips::S7_64,
129 Mips::T8_64, Mips::T9_64, Mips::K0_64, Mips::K1_64,
130 Mips::GP_64, Mips::SP_64, Mips::FP_64, Mips::RA_64
133 static const uint16_t FGR64RegsTable[] = {
134 Mips::D0_64, Mips::D1_64, Mips::D2_64, Mips::D3_64,
135 Mips::D4_64, Mips::D5_64, Mips::D6_64, Mips::D7_64,
136 Mips::D8_64, Mips::D9_64, Mips::D10_64, Mips::D11_64,
137 Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,
138 Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64,
139 Mips::D20_64, Mips::D21_64, Mips::D22_64, Mips::D23_64,
140 Mips::D24_64, Mips::D25_64, Mips::D26_64, Mips::D27_64,
141 Mips::D28_64, Mips::D29_64, Mips::D30_64, Mips::D31_64
144 static const uint16_t AFGR64RegsTable[] = {
145 Mips::D0, Mips::D1, Mips::D2, Mips::D3,
146 Mips::D4, Mips::D5, Mips::D6, Mips::D7,
147 Mips::D8, Mips::D9, Mips::D10, Mips::D11,
148 Mips::D12, Mips::D13, Mips::D14, Mips::D15
151 // Forward declare these because the autogenerated code will reference them.
152 // Definitions are further down.
153 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
156 const void *Decoder);
158 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
161 const void *Decoder);
163 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
166 const void *Decoder);
168 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
171 const void *Decoder);
173 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
176 const void *Decoder);
178 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
181 const void *Decoder);
183 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
186 const void *Decoder);
188 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
191 const void *Decoder);
193 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
196 const void *Decoder);
198 static DecodeStatus DecodeBC1(MCInst &Inst,
201 const void *Decoder);
204 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
207 const void *Decoder);
209 static DecodeStatus DecodeMem(MCInst &Inst,
212 const void *Decoder);
214 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
216 const void *Decoder);
218 static DecodeStatus DecodeSimm16(MCInst &Inst,
221 const void *Decoder);
223 static DecodeStatus DecodeCondCode(MCInst &Inst,
226 const void *Decoder);
228 static DecodeStatus DecodeInsSize(MCInst &Inst,
231 const void *Decoder);
233 static DecodeStatus DecodeExtSize(MCInst &Inst,
236 const void *Decoder);
239 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
243 static MCDisassembler *createMipsDisassembler(
245 const MCSubtargetInfo &STI) {
246 return new MipsDisassembler(STI,true);
249 static MCDisassembler *createMipselDisassembler(
251 const MCSubtargetInfo &STI) {
252 return new MipsDisassembler(STI,false);
255 static MCDisassembler *createMips64Disassembler(
257 const MCSubtargetInfo &STI) {
258 return new Mips64Disassembler(STI,true);
261 static MCDisassembler *createMips64elDisassembler(
263 const MCSubtargetInfo &STI) {
264 return new Mips64Disassembler(STI, false);
267 extern "C" void LLVMInitializeMipsDisassembler() {
268 // Register the disassembler.
269 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
270 createMipsDisassembler);
271 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
272 createMipselDisassembler);
273 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
274 createMips64Disassembler);
275 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
276 createMips64elDisassembler);
280 #include "MipsGenDisassemblerTables.inc"
282 /// readInstruction - read four bytes from the MemoryObject
283 /// and return 32 bit word sorted according to the given endianess
284 static DecodeStatus readInstruction32(const MemoryObject ®ion,
291 // We want to read exactly 4 Bytes of data.
292 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
294 return MCDisassembler::Fail;
298 // Encoded as a big-endian 32-bit word in the stream.
299 insn = (Bytes[3] << 0) |
305 // Encoded as a small-endian 32-bit word in the stream.
306 insn = (Bytes[0] << 0) |
312 return MCDisassembler::Success;
316 MipsDisassembler::getInstruction(MCInst &instr,
318 const MemoryObject &Region,
320 raw_ostream &vStream,
321 raw_ostream &cStream) const {
324 DecodeStatus Result = readInstruction32(Region, Address, Size,
326 if (Result == MCDisassembler::Fail)
327 return MCDisassembler::Fail;
329 // Calling the auto-generated decoder function.
330 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
331 if (Result != MCDisassembler::Fail) {
336 return MCDisassembler::Fail;
340 Mips64Disassembler::getInstruction(MCInst &instr,
342 const MemoryObject &Region,
344 raw_ostream &vStream,
345 raw_ostream &cStream) const {
348 DecodeStatus Result = readInstruction32(Region, Address, Size,
350 if (Result == MCDisassembler::Fail)
351 return MCDisassembler::Fail;
353 // Calling the auto-generated decoder function.
354 Result = decodeMips64Instruction32(instr, Insn, Address, this, STI);
355 if (Result != MCDisassembler::Fail) {
359 // If we fail to decode in Mips64 decoder space we can try in Mips32
360 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
361 if (Result != MCDisassembler::Fail) {
366 return MCDisassembler::Fail;
369 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
372 const void *Decoder) {
375 return MCDisassembler::Fail;
377 Inst.addOperand(MCOperand::CreateReg(CPU64RegsTable[RegNo]));
378 return MCDisassembler::Success;
381 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
384 const void *Decoder) {
386 return MCDisassembler::Fail;
388 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[RegNo]));
389 return MCDisassembler::Success;
392 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
395 const void *Decoder) {
397 return MCDisassembler::Fail;
399 Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[RegNo]));
400 return MCDisassembler::Success;
403 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
406 const void *Decoder) {
408 return MCDisassembler::Fail;
410 Inst.addOperand(MCOperand::CreateReg(FGR32RegsTable[RegNo]));
411 return MCDisassembler::Success;
414 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
417 const void *Decoder) {
418 Inst.addOperand(MCOperand::CreateReg(RegNo));
419 return MCDisassembler::Success;
422 static DecodeStatus DecodeMem(MCInst &Inst,
425 const void *Decoder) {
426 int Offset = SignExtend32<16>(Insn & 0xffff);
427 int Reg = (int)fieldFromInstruction32(Insn, 16, 5);
428 int Base = (int)fieldFromInstruction32(Insn, 21, 5);
430 if(Inst.getOpcode() == Mips::SC){
431 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg]));
434 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg]));
435 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base]));
436 Inst.addOperand(MCOperand::CreateImm(Offset));
438 return MCDisassembler::Success;
441 static DecodeStatus DecodeFMem(MCInst &Inst,
444 const void *Decoder) {
445 int Offset = SignExtend32<16>(Insn & 0xffff);
446 int Reg = (int)fieldFromInstruction32(Insn, 16, 5);
447 int Base = (int)fieldFromInstruction32(Insn, 21, 5);
449 Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[Reg]));
450 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base]));
451 Inst.addOperand(MCOperand::CreateImm(Offset));
453 return MCDisassembler::Success;
457 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
460 const void *Decoder) {
461 // Currently only hardware register 29 is supported.
463 return MCDisassembler::Fail;
464 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
465 return MCDisassembler::Success;
468 static DecodeStatus DecodeCondCode(MCInst &Inst,
471 const void *Decoder) {
472 int CondCode = Insn & 0xf;
473 Inst.addOperand(MCOperand::CreateImm(CondCode));
474 return MCDisassembler::Success;
477 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
480 const void *Decoder) {
482 return MCDisassembler::Fail;
484 Inst.addOperand(MCOperand::CreateReg(AFGR64RegsTable[RegNo]));
485 return MCDisassembler::Success;
488 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
491 const void *Decoder) {
492 //Currently only hardware register 29 is supported
494 return MCDisassembler::Fail;
495 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
496 return MCDisassembler::Success;
499 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
502 const void *Decoder) {
503 unsigned BranchOffset = Offset & 0xffff;
504 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
505 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
506 return MCDisassembler::Success;
509 static DecodeStatus DecodeBC1(MCInst &Inst,
512 const void *Decoder) {
513 unsigned BranchOffset = Insn & 0xffff;
514 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
515 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
516 return MCDisassembler::Success;
519 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
522 const void *Decoder) {
524 unsigned JumpOffset = fieldFromInstruction32(Insn, 0, 26) << 2;
525 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
526 return MCDisassembler::Success;
530 static DecodeStatus DecodeSimm16(MCInst &Inst,
533 const void *Decoder) {
534 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
535 return MCDisassembler::Success;
538 static DecodeStatus DecodeInsSize(MCInst &Inst,
541 const void *Decoder) {
542 // First we need to grab the pos(lsb) from MCInst.
543 int Pos = Inst.getOperand(2).getImm();
544 int Size = (int) Insn - Pos + 1;
545 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
546 return MCDisassembler::Success;
549 static DecodeStatus DecodeExtSize(MCInst &Inst,
552 const void *Decoder) {
553 int Size = (int) Insn + 1;
554 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
555 return MCDisassembler::Success;