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 "MipsRegisterInfo.h"
17 #include "llvm/MC/EDInstInfo.h"
18 #include "llvm/MC/MCDisassembler.h"
19 #include "llvm/MC/MCFixedLenDisassembler.h"
20 #include "llvm/Support/MemoryObject.h"
21 #include "llvm/Support/TargetRegistry.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/Support/MathExtras.h"
26 #include "MipsGenEDInfo.inc"
30 typedef MCDisassembler::DecodeStatus DecodeStatus;
34 /// MipsDisassemblerBase - a disasembler class for Mips.
35 class MipsDisassemblerBase : public MCDisassembler {
37 /// Constructor - Initializes the disassembler.
39 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
41 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
43 virtual ~MipsDisassemblerBase() {}
45 /// getEDInfo - See MCDisassembler.
46 const EDInstInfo *getEDInfo() const;
48 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
51 const MCRegisterInfo *RegInfo;
56 /// MipsDisassembler - a disasembler class for Mips32.
57 class MipsDisassembler : public MipsDisassemblerBase {
59 /// Constructor - Initializes the disassembler.
61 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
63 MipsDisassemblerBase(STI, Info, bigEndian) {}
65 /// getInstruction - See MCDisassembler.
66 virtual DecodeStatus getInstruction(MCInst &instr,
68 const MemoryObject ®ion,
71 raw_ostream &cStream) const;
75 /// Mips64Disassembler - a disasembler class for Mips64.
76 class Mips64Disassembler : public MipsDisassemblerBase {
78 /// Constructor - Initializes the disassembler.
80 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
82 MipsDisassemblerBase(STI, Info, bigEndian) {}
84 /// getInstruction - See MCDisassembler.
85 virtual DecodeStatus getInstruction(MCInst &instr,
87 const MemoryObject ®ion,
90 raw_ostream &cStream) const;
93 } // end anonymous namespace
95 const EDInstInfo *MipsDisassemblerBase::getEDInfo() const {
99 // Forward declare these because the autogenerated code will reference them.
100 // Definitions are further down.
101 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
104 const void *Decoder);
106 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
109 const void *Decoder);
111 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
114 const void *Decoder);
116 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
119 const void *Decoder);
121 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
124 const void *Decoder);
126 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
129 const void *Decoder);
131 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
134 const void *Decoder);
136 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
139 const void *Decoder);
141 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
144 const void *Decoder);
146 static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
149 const void *Decoder);
151 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
154 const void *Decoder);
156 static DecodeStatus DecodeBC1(MCInst &Inst,
159 const void *Decoder);
162 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
165 const void *Decoder);
167 static DecodeStatus DecodeMem(MCInst &Inst,
170 const void *Decoder);
172 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
174 const void *Decoder);
176 static DecodeStatus DecodeSimm16(MCInst &Inst,
179 const void *Decoder);
181 static DecodeStatus DecodeCondCode(MCInst &Inst,
184 const void *Decoder);
186 static DecodeStatus DecodeInsSize(MCInst &Inst,
189 const void *Decoder);
191 static DecodeStatus DecodeExtSize(MCInst &Inst,
194 const void *Decoder);
197 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
201 static MCDisassembler *createMipsDisassembler(
203 const MCSubtargetInfo &STI) {
204 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
207 static MCDisassembler *createMipselDisassembler(
209 const MCSubtargetInfo &STI) {
210 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
213 static MCDisassembler *createMips64Disassembler(
215 const MCSubtargetInfo &STI) {
216 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
219 static MCDisassembler *createMips64elDisassembler(
221 const MCSubtargetInfo &STI) {
222 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
225 extern "C" void LLVMInitializeMipsDisassembler() {
226 // Register the disassembler.
227 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
228 createMipsDisassembler);
229 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
230 createMipselDisassembler);
231 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
232 createMips64Disassembler);
233 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
234 createMips64elDisassembler);
238 #include "MipsGenDisassemblerTables.inc"
240 /// readInstruction - read four bytes from the MemoryObject
241 /// and return 32 bit word sorted according to the given endianess
242 static DecodeStatus readInstruction32(const MemoryObject ®ion,
249 // We want to read exactly 4 Bytes of data.
250 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
252 return MCDisassembler::Fail;
256 // Encoded as a big-endian 32-bit word in the stream.
257 insn = (Bytes[3] << 0) |
263 // Encoded as a small-endian 32-bit word in the stream.
264 insn = (Bytes[0] << 0) |
270 return MCDisassembler::Success;
274 MipsDisassembler::getInstruction(MCInst &instr,
276 const MemoryObject &Region,
278 raw_ostream &vStream,
279 raw_ostream &cStream) const {
282 DecodeStatus Result = readInstruction32(Region, Address, Size,
284 if (Result == MCDisassembler::Fail)
285 return MCDisassembler::Fail;
287 // Calling the auto-generated decoder function.
288 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
290 if (Result != MCDisassembler::Fail) {
295 return MCDisassembler::Fail;
299 Mips64Disassembler::getInstruction(MCInst &instr,
301 const MemoryObject &Region,
303 raw_ostream &vStream,
304 raw_ostream &cStream) const {
307 DecodeStatus Result = readInstruction32(Region, Address, Size,
309 if (Result == MCDisassembler::Fail)
310 return MCDisassembler::Fail;
312 // Calling the auto-generated decoder function.
313 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
315 if (Result != MCDisassembler::Fail) {
319 // If we fail to decode in Mips64 decoder space we can try in Mips32
320 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
322 if (Result != MCDisassembler::Fail) {
327 return MCDisassembler::Fail;
330 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
331 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
332 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
335 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
338 const void *Decoder) {
341 return MCDisassembler::Fail;
343 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
344 Inst.addOperand(MCOperand::CreateReg(Reg));
345 return MCDisassembler::Success;
348 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
351 const void *Decoder) {
353 return MCDisassembler::Fail;
354 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
355 Inst.addOperand(MCOperand::CreateReg(Reg));
356 return MCDisassembler::Success;
359 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
362 const void *Decoder) {
363 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
366 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
369 const void *Decoder) {
371 return MCDisassembler::Fail;
373 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
374 Inst.addOperand(MCOperand::CreateReg(Reg));
375 return MCDisassembler::Success;
378 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
381 const void *Decoder) {
383 return MCDisassembler::Fail;
385 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
386 Inst.addOperand(MCOperand::CreateReg(Reg));
387 return MCDisassembler::Success;
390 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
393 const void *Decoder) {
394 Inst.addOperand(MCOperand::CreateReg(RegNo));
395 return MCDisassembler::Success;
398 static DecodeStatus DecodeMem(MCInst &Inst,
401 const void *Decoder) {
402 int Offset = SignExtend32<16>(Insn & 0xffff);
403 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
404 unsigned Base = fieldFromInstruction(Insn, 21, 5);
406 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
407 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
409 if(Inst.getOpcode() == Mips::SC){
410 Inst.addOperand(MCOperand::CreateReg(Reg));
413 Inst.addOperand(MCOperand::CreateReg(Reg));
414 Inst.addOperand(MCOperand::CreateReg(Base));
415 Inst.addOperand(MCOperand::CreateImm(Offset));
417 return MCDisassembler::Success;
420 static DecodeStatus DecodeFMem(MCInst &Inst,
423 const void *Decoder) {
424 int Offset = SignExtend32<16>(Insn & 0xffff);
425 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
426 unsigned Base = fieldFromInstruction(Insn, 21, 5);
428 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
429 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
431 Inst.addOperand(MCOperand::CreateReg(Reg));
432 Inst.addOperand(MCOperand::CreateReg(Base));
433 Inst.addOperand(MCOperand::CreateImm(Offset));
435 return MCDisassembler::Success;
439 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
442 const void *Decoder) {
443 // Currently only hardware register 29 is supported.
445 return MCDisassembler::Fail;
446 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
447 return MCDisassembler::Success;
450 static DecodeStatus DecodeCondCode(MCInst &Inst,
453 const void *Decoder) {
454 int CondCode = Insn & 0xf;
455 Inst.addOperand(MCOperand::CreateImm(CondCode));
456 return MCDisassembler::Success;
459 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
462 const void *Decoder) {
463 if (RegNo > 30 || RegNo %2)
464 return MCDisassembler::Fail;
467 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
468 Inst.addOperand(MCOperand::CreateReg(Reg));
469 return MCDisassembler::Success;
472 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
475 const void *Decoder) {
476 //Currently only hardware register 29 is supported
478 return MCDisassembler::Fail;
479 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
480 return MCDisassembler::Success;
483 static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
486 const void *Decoder) {
488 return MCDisassembler::Fail;
490 unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo);
491 Inst.addOperand(MCOperand::CreateReg(Reg));
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 = fieldFromInstruction(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;