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/MCDisassembler.h"
18 #include "llvm/MC/MCFixedLenDisassembler.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Support/MathExtras.h"
22 #include "llvm/Support/MemoryObject.h"
23 #include "llvm/Support/TargetRegistry.h"
27 typedef MCDisassembler::DecodeStatus DecodeStatus;
31 /// MipsDisassemblerBase - a disasembler class for Mips.
32 class MipsDisassemblerBase : public MCDisassembler {
34 /// Constructor - Initializes the disassembler.
36 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
38 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
40 virtual ~MipsDisassemblerBase() {}
42 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
45 const MCRegisterInfo *RegInfo;
50 /// MipsDisassembler - a disasembler class for Mips32.
51 class MipsDisassembler : public MipsDisassemblerBase {
53 /// Constructor - Initializes the disassembler.
55 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
57 MipsDisassemblerBase(STI, Info, bigEndian) {}
59 /// getInstruction - See MCDisassembler.
60 virtual DecodeStatus getInstruction(MCInst &instr,
62 const MemoryObject ®ion,
65 raw_ostream &cStream) const;
69 /// Mips64Disassembler - a disasembler class for Mips64.
70 class Mips64Disassembler : public MipsDisassemblerBase {
72 /// Constructor - Initializes the disassembler.
74 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
76 MipsDisassemblerBase(STI, Info, bigEndian) {}
78 /// getInstruction - See MCDisassembler.
79 virtual DecodeStatus getInstruction(MCInst &instr,
81 const MemoryObject ®ion,
84 raw_ostream &cStream) const;
87 } // end anonymous namespace
89 // Forward declare these because the autogenerated code will reference them.
90 // Definitions are further down.
91 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
96 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
101 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
104 const void *Decoder);
106 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
109 const void *Decoder);
111 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
114 const void *Decoder);
116 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
119 const void *Decoder);
121 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
124 const void *Decoder);
126 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
129 const void *Decoder);
131 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
134 const void *Decoder);
136 static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
139 const void *Decoder);
141 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
144 const void *Decoder);
146 static DecodeStatus DecodeBC1(MCInst &Inst,
149 const void *Decoder);
152 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
155 const void *Decoder);
157 static DecodeStatus DecodeMem(MCInst &Inst,
160 const void *Decoder);
162 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
164 const void *Decoder);
166 static DecodeStatus DecodeSimm16(MCInst &Inst,
169 const void *Decoder);
171 static DecodeStatus DecodeCondCode(MCInst &Inst,
174 const void *Decoder);
176 static DecodeStatus DecodeInsSize(MCInst &Inst,
179 const void *Decoder);
181 static DecodeStatus DecodeExtSize(MCInst &Inst,
184 const void *Decoder);
187 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
191 static MCDisassembler *createMipsDisassembler(
193 const MCSubtargetInfo &STI) {
194 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
197 static MCDisassembler *createMipselDisassembler(
199 const MCSubtargetInfo &STI) {
200 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
203 static MCDisassembler *createMips64Disassembler(
205 const MCSubtargetInfo &STI) {
206 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
209 static MCDisassembler *createMips64elDisassembler(
211 const MCSubtargetInfo &STI) {
212 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
215 extern "C" void LLVMInitializeMipsDisassembler() {
216 // Register the disassembler.
217 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
218 createMipsDisassembler);
219 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
220 createMipselDisassembler);
221 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
222 createMips64Disassembler);
223 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
224 createMips64elDisassembler);
228 #include "MipsGenDisassemblerTables.inc"
230 /// readInstruction - read four bytes from the MemoryObject
231 /// and return 32 bit word sorted according to the given endianess
232 static DecodeStatus readInstruction32(const MemoryObject ®ion,
239 // We want to read exactly 4 Bytes of data.
240 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
242 return MCDisassembler::Fail;
246 // Encoded as a big-endian 32-bit word in the stream.
247 insn = (Bytes[3] << 0) |
253 // Encoded as a small-endian 32-bit word in the stream.
254 insn = (Bytes[0] << 0) |
260 return MCDisassembler::Success;
264 MipsDisassembler::getInstruction(MCInst &instr,
266 const MemoryObject &Region,
268 raw_ostream &vStream,
269 raw_ostream &cStream) const {
272 DecodeStatus Result = readInstruction32(Region, Address, Size,
274 if (Result == MCDisassembler::Fail)
275 return MCDisassembler::Fail;
277 // Calling the auto-generated decoder function.
278 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
280 if (Result != MCDisassembler::Fail) {
285 return MCDisassembler::Fail;
289 Mips64Disassembler::getInstruction(MCInst &instr,
291 const MemoryObject &Region,
293 raw_ostream &vStream,
294 raw_ostream &cStream) const {
297 DecodeStatus Result = readInstruction32(Region, Address, Size,
299 if (Result == MCDisassembler::Fail)
300 return MCDisassembler::Fail;
302 // Calling the auto-generated decoder function.
303 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
305 if (Result != MCDisassembler::Fail) {
309 // If we fail to decode in Mips64 decoder space we can try in Mips32
310 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
312 if (Result != MCDisassembler::Fail) {
317 return MCDisassembler::Fail;
320 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
321 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
322 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
325 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
328 const void *Decoder) {
331 return MCDisassembler::Fail;
333 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
334 Inst.addOperand(MCOperand::CreateReg(Reg));
335 return MCDisassembler::Success;
338 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
341 const void *Decoder) {
343 return MCDisassembler::Fail;
344 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
345 Inst.addOperand(MCOperand::CreateReg(Reg));
346 return MCDisassembler::Success;
349 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
352 const void *Decoder) {
353 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
356 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
359 const void *Decoder) {
361 return MCDisassembler::Fail;
363 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
364 Inst.addOperand(MCOperand::CreateReg(Reg));
365 return MCDisassembler::Success;
368 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
371 const void *Decoder) {
373 return MCDisassembler::Fail;
375 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
376 Inst.addOperand(MCOperand::CreateReg(Reg));
377 return MCDisassembler::Success;
380 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
383 const void *Decoder) {
384 Inst.addOperand(MCOperand::CreateReg(RegNo));
385 return MCDisassembler::Success;
388 static DecodeStatus DecodeMem(MCInst &Inst,
391 const void *Decoder) {
392 int Offset = SignExtend32<16>(Insn & 0xffff);
393 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
394 unsigned Base = fieldFromInstruction(Insn, 21, 5);
396 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
397 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
399 if(Inst.getOpcode() == Mips::SC){
400 Inst.addOperand(MCOperand::CreateReg(Reg));
403 Inst.addOperand(MCOperand::CreateReg(Reg));
404 Inst.addOperand(MCOperand::CreateReg(Base));
405 Inst.addOperand(MCOperand::CreateImm(Offset));
407 return MCDisassembler::Success;
410 static DecodeStatus DecodeFMem(MCInst &Inst,
413 const void *Decoder) {
414 int Offset = SignExtend32<16>(Insn & 0xffff);
415 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
416 unsigned Base = fieldFromInstruction(Insn, 21, 5);
418 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
419 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
421 Inst.addOperand(MCOperand::CreateReg(Reg));
422 Inst.addOperand(MCOperand::CreateReg(Base));
423 Inst.addOperand(MCOperand::CreateImm(Offset));
425 return MCDisassembler::Success;
429 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
432 const void *Decoder) {
433 // Currently only hardware register 29 is supported.
435 return MCDisassembler::Fail;
436 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
437 return MCDisassembler::Success;
440 static DecodeStatus DecodeCondCode(MCInst &Inst,
443 const void *Decoder) {
444 int CondCode = Insn & 0xf;
445 Inst.addOperand(MCOperand::CreateImm(CondCode));
446 return MCDisassembler::Success;
449 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
452 const void *Decoder) {
453 if (RegNo > 30 || RegNo %2)
454 return MCDisassembler::Fail;
457 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
458 Inst.addOperand(MCOperand::CreateReg(Reg));
459 return MCDisassembler::Success;
462 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
465 const void *Decoder) {
466 //Currently only hardware register 29 is supported
468 return MCDisassembler::Fail;
469 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
470 return MCDisassembler::Success;
473 static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
476 const void *Decoder) {
478 return MCDisassembler::Fail;
480 unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo);
481 Inst.addOperand(MCOperand::CreateReg(Reg));
482 return MCDisassembler::Success;
485 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
488 const void *Decoder) {
489 unsigned BranchOffset = Offset & 0xffff;
490 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
491 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
492 return MCDisassembler::Success;
495 static DecodeStatus DecodeBC1(MCInst &Inst,
498 const void *Decoder) {
499 unsigned BranchOffset = Insn & 0xffff;
500 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
501 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
502 return MCDisassembler::Success;
505 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
508 const void *Decoder) {
510 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
511 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
512 return MCDisassembler::Success;
516 static DecodeStatus DecodeSimm16(MCInst &Inst,
519 const void *Decoder) {
520 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
521 return MCDisassembler::Success;
524 static DecodeStatus DecodeInsSize(MCInst &Inst,
527 const void *Decoder) {
528 // First we need to grab the pos(lsb) from MCInst.
529 int Pos = Inst.getOperand(2).getImm();
530 int Size = (int) Insn - Pos + 1;
531 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
532 return MCDisassembler::Success;
535 static DecodeStatus DecodeExtSize(MCInst &Inst,
538 const void *Decoder) {
539 int Size = (int) Insn + 1;
540 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
541 return MCDisassembler::Success;