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 DecodeACRegsRegisterClass(MCInst &Inst,
134 const void *Decoder);
136 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
139 const void *Decoder);
141 static DecodeStatus DecodeBC1(MCInst &Inst,
144 const void *Decoder);
147 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
150 const void *Decoder);
152 static DecodeStatus DecodeMem(MCInst &Inst,
155 const void *Decoder);
157 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
159 const void *Decoder);
161 static DecodeStatus DecodeSimm16(MCInst &Inst,
164 const void *Decoder);
166 static DecodeStatus DecodeCondCode(MCInst &Inst,
169 const void *Decoder);
171 static DecodeStatus DecodeInsSize(MCInst &Inst,
174 const void *Decoder);
176 static DecodeStatus DecodeExtSize(MCInst &Inst,
179 const void *Decoder);
182 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
186 static MCDisassembler *createMipsDisassembler(
188 const MCSubtargetInfo &STI) {
189 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
192 static MCDisassembler *createMipselDisassembler(
194 const MCSubtargetInfo &STI) {
195 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
198 static MCDisassembler *createMips64Disassembler(
200 const MCSubtargetInfo &STI) {
201 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
204 static MCDisassembler *createMips64elDisassembler(
206 const MCSubtargetInfo &STI) {
207 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
210 extern "C" void LLVMInitializeMipsDisassembler() {
211 // Register the disassembler.
212 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
213 createMipsDisassembler);
214 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
215 createMipselDisassembler);
216 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
217 createMips64Disassembler);
218 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
219 createMips64elDisassembler);
223 #include "MipsGenDisassemblerTables.inc"
225 /// readInstruction - read four bytes from the MemoryObject
226 /// and return 32 bit word sorted according to the given endianess
227 static DecodeStatus readInstruction32(const MemoryObject ®ion,
234 // We want to read exactly 4 Bytes of data.
235 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
237 return MCDisassembler::Fail;
241 // Encoded as a big-endian 32-bit word in the stream.
242 insn = (Bytes[3] << 0) |
248 // Encoded as a small-endian 32-bit word in the stream.
249 insn = (Bytes[0] << 0) |
255 return MCDisassembler::Success;
259 MipsDisassembler::getInstruction(MCInst &instr,
261 const MemoryObject &Region,
263 raw_ostream &vStream,
264 raw_ostream &cStream) const {
267 DecodeStatus Result = readInstruction32(Region, Address, Size,
269 if (Result == MCDisassembler::Fail)
270 return MCDisassembler::Fail;
272 // Calling the auto-generated decoder function.
273 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
275 if (Result != MCDisassembler::Fail) {
280 return MCDisassembler::Fail;
284 Mips64Disassembler::getInstruction(MCInst &instr,
286 const MemoryObject &Region,
288 raw_ostream &vStream,
289 raw_ostream &cStream) const {
292 DecodeStatus Result = readInstruction32(Region, Address, Size,
294 if (Result == MCDisassembler::Fail)
295 return MCDisassembler::Fail;
297 // Calling the auto-generated decoder function.
298 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
300 if (Result != MCDisassembler::Fail) {
304 // If we fail to decode in Mips64 decoder space we can try in Mips32
305 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
307 if (Result != MCDisassembler::Fail) {
312 return MCDisassembler::Fail;
315 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
316 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
317 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
320 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
323 const void *Decoder) {
326 return MCDisassembler::Fail;
328 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
329 Inst.addOperand(MCOperand::CreateReg(Reg));
330 return MCDisassembler::Success;
333 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
336 const void *Decoder) {
338 return MCDisassembler::Fail;
339 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
340 Inst.addOperand(MCOperand::CreateReg(Reg));
341 return MCDisassembler::Success;
344 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
347 const void *Decoder) {
348 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
351 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
354 const void *Decoder) {
356 return MCDisassembler::Fail;
358 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
359 Inst.addOperand(MCOperand::CreateReg(Reg));
360 return MCDisassembler::Success;
363 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
366 const void *Decoder) {
368 return MCDisassembler::Fail;
370 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
371 Inst.addOperand(MCOperand::CreateReg(Reg));
372 return MCDisassembler::Success;
375 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
378 const void *Decoder) {
379 Inst.addOperand(MCOperand::CreateReg(RegNo));
380 return MCDisassembler::Success;
383 static DecodeStatus DecodeMem(MCInst &Inst,
386 const void *Decoder) {
387 int Offset = SignExtend32<16>(Insn & 0xffff);
388 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
389 unsigned Base = fieldFromInstruction(Insn, 21, 5);
391 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
392 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
394 if(Inst.getOpcode() == Mips::SC){
395 Inst.addOperand(MCOperand::CreateReg(Reg));
398 Inst.addOperand(MCOperand::CreateReg(Reg));
399 Inst.addOperand(MCOperand::CreateReg(Base));
400 Inst.addOperand(MCOperand::CreateImm(Offset));
402 return MCDisassembler::Success;
405 static DecodeStatus DecodeFMem(MCInst &Inst,
408 const void *Decoder) {
409 int Offset = SignExtend32<16>(Insn & 0xffff);
410 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
411 unsigned Base = fieldFromInstruction(Insn, 21, 5);
413 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
414 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
416 Inst.addOperand(MCOperand::CreateReg(Reg));
417 Inst.addOperand(MCOperand::CreateReg(Base));
418 Inst.addOperand(MCOperand::CreateImm(Offset));
420 return MCDisassembler::Success;
424 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
427 const void *Decoder) {
428 // Currently only hardware register 29 is supported.
430 return MCDisassembler::Fail;
431 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
432 return MCDisassembler::Success;
435 static DecodeStatus DecodeCondCode(MCInst &Inst,
438 const void *Decoder) {
439 int CondCode = Insn & 0xf;
440 Inst.addOperand(MCOperand::CreateImm(CondCode));
441 return MCDisassembler::Success;
444 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
447 const void *Decoder) {
448 if (RegNo > 30 || RegNo %2)
449 return MCDisassembler::Fail;
452 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
453 Inst.addOperand(MCOperand::CreateReg(Reg));
454 return MCDisassembler::Success;
457 static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
460 const void *Decoder) {
462 return MCDisassembler::Fail;
464 unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo);
465 Inst.addOperand(MCOperand::CreateReg(Reg));
466 return MCDisassembler::Success;
469 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
472 const void *Decoder) {
473 unsigned BranchOffset = Offset & 0xffff;
474 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
475 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
476 return MCDisassembler::Success;
479 static DecodeStatus DecodeBC1(MCInst &Inst,
482 const void *Decoder) {
483 unsigned BranchOffset = Insn & 0xffff;
484 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
485 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
486 return MCDisassembler::Success;
489 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
492 const void *Decoder) {
494 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
495 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
496 return MCDisassembler::Success;
500 static DecodeStatus DecodeSimm16(MCInst &Inst,
503 const void *Decoder) {
504 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
505 return MCDisassembler::Success;
508 static DecodeStatus DecodeInsSize(MCInst &Inst,
511 const void *Decoder) {
512 // First we need to grab the pos(lsb) from MCInst.
513 int Pos = Inst.getOperand(2).getImm();
514 int Size = (int) Insn - Pos + 1;
515 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
516 return MCDisassembler::Success;
519 static DecodeStatus DecodeExtSize(MCInst &Inst,
522 const void *Decoder) {
523 int Size = (int) Insn + 1;
524 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
525 return MCDisassembler::Success;