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 "MipsRegisterInfo.h"
16 #include "MipsSubtarget.h"
17 #include "llvm/MC/EDInstInfo.h"
18 #include "llvm/MC/MCDisassembler.h"
19 #include "llvm/MC/MCFixedLenDisassembler.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/MemoryObject.h"
24 #include "llvm/Support/TargetRegistry.h"
26 // Not a normal header, this must come last.
27 #include "MipsGenEDInfo.inc"
31 typedef MCDisassembler::DecodeStatus DecodeStatus;
35 /// MipsDisassemblerBase - a disasembler class for Mips.
36 class MipsDisassemblerBase : public MCDisassembler {
38 /// Constructor - Initializes the disassembler.
40 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
42 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
44 virtual ~MipsDisassemblerBase() {}
46 /// getEDInfo - See MCDisassembler.
47 const EDInstInfo *getEDInfo() const;
49 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
52 const MCRegisterInfo *RegInfo;
57 /// MipsDisassembler - a disasembler class for Mips32.
58 class MipsDisassembler : public MipsDisassemblerBase {
60 /// Constructor - Initializes the disassembler.
62 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
64 MipsDisassemblerBase(STI, Info, bigEndian) {}
66 /// getInstruction - See MCDisassembler.
67 virtual DecodeStatus getInstruction(MCInst &instr,
69 const MemoryObject ®ion,
72 raw_ostream &cStream) const;
76 /// Mips64Disassembler - a disasembler class for Mips64.
77 class Mips64Disassembler : public MipsDisassemblerBase {
79 /// Constructor - Initializes the disassembler.
81 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
83 MipsDisassemblerBase(STI, Info, bigEndian) {}
85 /// getInstruction - See MCDisassembler.
86 virtual DecodeStatus getInstruction(MCInst &instr,
88 const MemoryObject ®ion,
91 raw_ostream &cStream) const;
94 } // end anonymous namespace
96 const EDInstInfo *MipsDisassemblerBase::getEDInfo() const {
100 // Forward declare these because the autogenerated code will reference them.
101 // Definitions are further down.
102 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
105 const void *Decoder);
107 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
110 const void *Decoder);
112 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
115 const void *Decoder);
117 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
120 const void *Decoder);
122 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
125 const void *Decoder);
127 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
130 const void *Decoder);
132 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
135 const void *Decoder);
137 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
140 const void *Decoder);
142 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
145 const void *Decoder);
147 static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
150 const void *Decoder);
152 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
155 const void *Decoder);
157 static DecodeStatus DecodeBC1(MCInst &Inst,
160 const void *Decoder);
163 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
166 const void *Decoder);
168 static DecodeStatus DecodeMem(MCInst &Inst,
171 const void *Decoder);
173 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
175 const void *Decoder);
177 static DecodeStatus DecodeSimm16(MCInst &Inst,
180 const void *Decoder);
182 static DecodeStatus DecodeCondCode(MCInst &Inst,
185 const void *Decoder);
187 static DecodeStatus DecodeInsSize(MCInst &Inst,
190 const void *Decoder);
192 static DecodeStatus DecodeExtSize(MCInst &Inst,
195 const void *Decoder);
198 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
202 static MCDisassembler *createMipsDisassembler(
204 const MCSubtargetInfo &STI) {
205 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
208 static MCDisassembler *createMipselDisassembler(
210 const MCSubtargetInfo &STI) {
211 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
214 static MCDisassembler *createMips64Disassembler(
216 const MCSubtargetInfo &STI) {
217 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
220 static MCDisassembler *createMips64elDisassembler(
222 const MCSubtargetInfo &STI) {
223 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
226 extern "C" void LLVMInitializeMipsDisassembler() {
227 // Register the disassembler.
228 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
229 createMipsDisassembler);
230 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
231 createMipselDisassembler);
232 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
233 createMips64Disassembler);
234 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
235 createMips64elDisassembler);
239 #include "MipsGenDisassemblerTables.inc"
241 /// readInstruction - read four bytes from the MemoryObject
242 /// and return 32 bit word sorted according to the given endianess
243 static DecodeStatus readInstruction32(const MemoryObject ®ion,
250 // We want to read exactly 4 Bytes of data.
251 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
253 return MCDisassembler::Fail;
257 // Encoded as a big-endian 32-bit word in the stream.
258 insn = (Bytes[3] << 0) |
264 // Encoded as a small-endian 32-bit word in the stream.
265 insn = (Bytes[0] << 0) |
271 return MCDisassembler::Success;
275 MipsDisassembler::getInstruction(MCInst &instr,
277 const MemoryObject &Region,
279 raw_ostream &vStream,
280 raw_ostream &cStream) const {
283 DecodeStatus Result = readInstruction32(Region, Address, Size,
285 if (Result == MCDisassembler::Fail)
286 return MCDisassembler::Fail;
288 // Calling the auto-generated decoder function.
289 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
291 if (Result != MCDisassembler::Fail) {
296 return MCDisassembler::Fail;
300 Mips64Disassembler::getInstruction(MCInst &instr,
302 const MemoryObject &Region,
304 raw_ostream &vStream,
305 raw_ostream &cStream) const {
308 DecodeStatus Result = readInstruction32(Region, Address, Size,
310 if (Result == MCDisassembler::Fail)
311 return MCDisassembler::Fail;
313 // Calling the auto-generated decoder function.
314 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
316 if (Result != MCDisassembler::Fail) {
320 // If we fail to decode in Mips64 decoder space we can try in Mips32
321 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
323 if (Result != MCDisassembler::Fail) {
328 return MCDisassembler::Fail;
331 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
332 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
333 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
336 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
339 const void *Decoder) {
342 return MCDisassembler::Fail;
344 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
345 Inst.addOperand(MCOperand::CreateReg(Reg));
346 return MCDisassembler::Success;
349 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
352 const void *Decoder) {
354 return MCDisassembler::Fail;
355 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
356 Inst.addOperand(MCOperand::CreateReg(Reg));
357 return MCDisassembler::Success;
360 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
363 const void *Decoder) {
364 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
367 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
370 const void *Decoder) {
372 return MCDisassembler::Fail;
374 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
375 Inst.addOperand(MCOperand::CreateReg(Reg));
376 return MCDisassembler::Success;
379 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
382 const void *Decoder) {
384 return MCDisassembler::Fail;
386 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
387 Inst.addOperand(MCOperand::CreateReg(Reg));
388 return MCDisassembler::Success;
391 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
394 const void *Decoder) {
395 Inst.addOperand(MCOperand::CreateReg(RegNo));
396 return MCDisassembler::Success;
399 static DecodeStatus DecodeMem(MCInst &Inst,
402 const void *Decoder) {
403 int Offset = SignExtend32<16>(Insn & 0xffff);
404 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
405 unsigned Base = fieldFromInstruction(Insn, 21, 5);
407 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
408 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
410 if(Inst.getOpcode() == Mips::SC){
411 Inst.addOperand(MCOperand::CreateReg(Reg));
414 Inst.addOperand(MCOperand::CreateReg(Reg));
415 Inst.addOperand(MCOperand::CreateReg(Base));
416 Inst.addOperand(MCOperand::CreateImm(Offset));
418 return MCDisassembler::Success;
421 static DecodeStatus DecodeFMem(MCInst &Inst,
424 const void *Decoder) {
425 int Offset = SignExtend32<16>(Insn & 0xffff);
426 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
427 unsigned Base = fieldFromInstruction(Insn, 21, 5);
429 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
430 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
432 Inst.addOperand(MCOperand::CreateReg(Reg));
433 Inst.addOperand(MCOperand::CreateReg(Base));
434 Inst.addOperand(MCOperand::CreateImm(Offset));
436 return MCDisassembler::Success;
440 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
443 const void *Decoder) {
444 // Currently only hardware register 29 is supported.
446 return MCDisassembler::Fail;
447 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
448 return MCDisassembler::Success;
451 static DecodeStatus DecodeCondCode(MCInst &Inst,
454 const void *Decoder) {
455 int CondCode = Insn & 0xf;
456 Inst.addOperand(MCOperand::CreateImm(CondCode));
457 return MCDisassembler::Success;
460 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
463 const void *Decoder) {
464 if (RegNo > 30 || RegNo %2)
465 return MCDisassembler::Fail;
468 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
469 Inst.addOperand(MCOperand::CreateReg(Reg));
470 return MCDisassembler::Success;
473 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
476 const void *Decoder) {
477 //Currently only hardware register 29 is supported
479 return MCDisassembler::Fail;
480 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
481 return MCDisassembler::Success;
484 static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
487 const void *Decoder) {
489 return MCDisassembler::Fail;
491 unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo);
492 Inst.addOperand(MCOperand::CreateReg(Reg));
493 return MCDisassembler::Success;
496 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
499 const void *Decoder) {
500 unsigned BranchOffset = Offset & 0xffff;
501 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
502 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
503 return MCDisassembler::Success;
506 static DecodeStatus DecodeBC1(MCInst &Inst,
509 const void *Decoder) {
510 unsigned BranchOffset = Insn & 0xffff;
511 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
512 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
513 return MCDisassembler::Success;
516 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
519 const void *Decoder) {
521 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
522 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
523 return MCDisassembler::Success;
527 static DecodeStatus DecodeSimm16(MCInst &Inst,
530 const void *Decoder) {
531 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
532 return MCDisassembler::Success;
535 static DecodeStatus DecodeInsSize(MCInst &Inst,
538 const void *Decoder) {
539 // First we need to grab the pos(lsb) from MCInst.
540 int Pos = Inst.getOperand(2).getImm();
541 int Size = (int) Insn - Pos + 1;
542 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
543 return MCDisassembler::Success;
546 static DecodeStatus DecodeExtSize(MCInst &Inst,
549 const void *Decoder) {
550 int Size = (int) Insn + 1;
551 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
552 return MCDisassembler::Success;