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/Support/MemoryObject.h"
20 #include "llvm/Support/TargetRegistry.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/Support/MathExtras.h"
25 #include "MipsGenEDInfo.inc"
29 typedef MCDisassembler::DecodeStatus DecodeStatus;
33 /// MipsDisassemblerBase - a disasembler class for Mips.
34 class MipsDisassemblerBase : public MCDisassembler {
36 /// Constructor - Initializes the disassembler.
38 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
40 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
42 virtual ~MipsDisassemblerBase() {}
44 /// getEDInfo - See MCDisassembler.
45 const EDInstInfo *getEDInfo() const;
47 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
50 const MCRegisterInfo *RegInfo;
55 /// MipsDisassembler - a disasembler class for Mips32.
56 class MipsDisassembler : public MipsDisassemblerBase {
58 /// Constructor - Initializes the disassembler.
60 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
62 MipsDisassemblerBase(STI, Info, bigEndian) {}
64 /// getInstruction - See MCDisassembler.
65 virtual DecodeStatus getInstruction(MCInst &instr,
67 const MemoryObject ®ion,
70 raw_ostream &cStream) const;
74 /// Mips64Disassembler - a disasembler class for Mips64.
75 class Mips64Disassembler : public MipsDisassemblerBase {
77 /// Constructor - Initializes the disassembler.
79 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
81 MipsDisassemblerBase(STI, Info, bigEndian) {}
83 /// getInstruction - See MCDisassembler.
84 virtual DecodeStatus getInstruction(MCInst &instr,
86 const MemoryObject ®ion,
89 raw_ostream &cStream) const;
92 } // end anonymous namespace
94 const EDInstInfo *MipsDisassemblerBase::getEDInfo() const {
98 // Forward declare these because the autogenerated code will reference them.
99 // Definitions are further down.
100 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
103 const void *Decoder);
105 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
108 const void *Decoder);
110 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
113 const void *Decoder);
115 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
118 const void *Decoder);
120 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
123 const void *Decoder);
125 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
128 const void *Decoder);
130 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
133 const void *Decoder);
135 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
138 const void *Decoder);
140 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
143 const void *Decoder);
145 static DecodeStatus DecodeBC1(MCInst &Inst,
148 const void *Decoder);
151 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
154 const void *Decoder);
156 static DecodeStatus DecodeMem(MCInst &Inst,
159 const void *Decoder);
161 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
163 const void *Decoder);
165 static DecodeStatus DecodeSimm16(MCInst &Inst,
168 const void *Decoder);
170 static DecodeStatus DecodeCondCode(MCInst &Inst,
173 const void *Decoder);
175 static DecodeStatus DecodeInsSize(MCInst &Inst,
178 const void *Decoder);
180 static DecodeStatus DecodeExtSize(MCInst &Inst,
183 const void *Decoder);
186 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
190 static MCDisassembler *createMipsDisassembler(
192 const MCSubtargetInfo &STI) {
193 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
196 static MCDisassembler *createMipselDisassembler(
198 const MCSubtargetInfo &STI) {
199 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
202 static MCDisassembler *createMips64Disassembler(
204 const MCSubtargetInfo &STI) {
205 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
208 static MCDisassembler *createMips64elDisassembler(
210 const MCSubtargetInfo &STI) {
211 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
214 extern "C" void LLVMInitializeMipsDisassembler() {
215 // Register the disassembler.
216 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
217 createMipsDisassembler);
218 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
219 createMipselDisassembler);
220 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
221 createMips64Disassembler);
222 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
223 createMips64elDisassembler);
227 #include "MipsGenDisassemblerTables.inc"
229 /// readInstruction - read four bytes from the MemoryObject
230 /// and return 32 bit word sorted according to the given endianess
231 static DecodeStatus readInstruction32(const MemoryObject ®ion,
238 // We want to read exactly 4 Bytes of data.
239 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
241 return MCDisassembler::Fail;
245 // Encoded as a big-endian 32-bit word in the stream.
246 insn = (Bytes[3] << 0) |
252 // Encoded as a small-endian 32-bit word in the stream.
253 insn = (Bytes[0] << 0) |
259 return MCDisassembler::Success;
263 MipsDisassembler::getInstruction(MCInst &instr,
265 const MemoryObject &Region,
267 raw_ostream &vStream,
268 raw_ostream &cStream) const {
271 DecodeStatus Result = readInstruction32(Region, Address, Size,
273 if (Result == MCDisassembler::Fail)
274 return MCDisassembler::Fail;
276 // Calling the auto-generated decoder function.
277 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
278 if (Result != MCDisassembler::Fail) {
283 return MCDisassembler::Fail;
287 Mips64Disassembler::getInstruction(MCInst &instr,
289 const MemoryObject &Region,
291 raw_ostream &vStream,
292 raw_ostream &cStream) const {
295 DecodeStatus Result = readInstruction32(Region, Address, Size,
297 if (Result == MCDisassembler::Fail)
298 return MCDisassembler::Fail;
300 // Calling the auto-generated decoder function.
301 Result = decodeMips64Instruction32(instr, Insn, Address, this, STI);
302 if (Result != MCDisassembler::Fail) {
306 // If we fail to decode in Mips64 decoder space we can try in Mips32
307 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
308 if (Result != MCDisassembler::Fail) {
313 return MCDisassembler::Fail;
316 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
317 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
318 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
321 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
324 const void *Decoder) {
327 return MCDisassembler::Fail;
329 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
330 Inst.addOperand(MCOperand::CreateReg(Reg));
331 return MCDisassembler::Success;
334 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
337 const void *Decoder) {
339 return MCDisassembler::Fail;
340 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
341 Inst.addOperand(MCOperand::CreateReg(Reg));
342 return MCDisassembler::Success;
345 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
348 const void *Decoder) {
350 return MCDisassembler::Fail;
352 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
353 Inst.addOperand(MCOperand::CreateReg(Reg));
354 return MCDisassembler::Success;
357 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
360 const void *Decoder) {
362 return MCDisassembler::Fail;
364 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
365 Inst.addOperand(MCOperand::CreateReg(Reg));
366 return MCDisassembler::Success;
369 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
372 const void *Decoder) {
373 Inst.addOperand(MCOperand::CreateReg(RegNo));
374 return MCDisassembler::Success;
377 static DecodeStatus DecodeMem(MCInst &Inst,
380 const void *Decoder) {
381 int Offset = SignExtend32<16>(Insn & 0xffff);
382 unsigned Reg = fieldFromInstruction32(Insn, 16, 5);
383 unsigned Base = fieldFromInstruction32(Insn, 21, 5);
385 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
386 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
388 if(Inst.getOpcode() == Mips::SC){
389 Inst.addOperand(MCOperand::CreateReg(Reg));
392 Inst.addOperand(MCOperand::CreateReg(Reg));
393 Inst.addOperand(MCOperand::CreateReg(Base));
394 Inst.addOperand(MCOperand::CreateImm(Offset));
396 return MCDisassembler::Success;
399 static DecodeStatus DecodeFMem(MCInst &Inst,
402 const void *Decoder) {
403 int Offset = SignExtend32<16>(Insn & 0xffff);
404 unsigned Reg = fieldFromInstruction32(Insn, 16, 5);
405 unsigned Base = fieldFromInstruction32(Insn, 21, 5);
407 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
408 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
410 Inst.addOperand(MCOperand::CreateReg(Reg));
411 Inst.addOperand(MCOperand::CreateReg(Base));
412 Inst.addOperand(MCOperand::CreateImm(Offset));
414 return MCDisassembler::Success;
418 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
421 const void *Decoder) {
422 // Currently only hardware register 29 is supported.
424 return MCDisassembler::Fail;
425 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
426 return MCDisassembler::Success;
429 static DecodeStatus DecodeCondCode(MCInst &Inst,
432 const void *Decoder) {
433 int CondCode = Insn & 0xf;
434 Inst.addOperand(MCOperand::CreateImm(CondCode));
435 return MCDisassembler::Success;
438 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
441 const void *Decoder) {
442 if (RegNo > 30 || RegNo %2)
443 return MCDisassembler::Fail;
446 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
447 Inst.addOperand(MCOperand::CreateReg(Reg));
448 return MCDisassembler::Success;
451 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
454 const void *Decoder) {
455 //Currently only hardware register 29 is supported
457 return MCDisassembler::Fail;
458 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
459 return MCDisassembler::Success;
462 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
465 const void *Decoder) {
466 unsigned BranchOffset = Offset & 0xffff;
467 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
468 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
469 return MCDisassembler::Success;
472 static DecodeStatus DecodeBC1(MCInst &Inst,
475 const void *Decoder) {
476 unsigned BranchOffset = Insn & 0xffff;
477 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
478 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
479 return MCDisassembler::Success;
482 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
485 const void *Decoder) {
487 unsigned JumpOffset = fieldFromInstruction32(Insn, 0, 26) << 2;
488 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
489 return MCDisassembler::Success;
493 static DecodeStatus DecodeSimm16(MCInst &Inst,
496 const void *Decoder) {
497 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
498 return MCDisassembler::Success;
501 static DecodeStatus DecodeInsSize(MCInst &Inst,
504 const void *Decoder) {
505 // First we need to grab the pos(lsb) from MCInst.
506 int Pos = Inst.getOperand(2).getImm();
507 int Size = (int) Insn - Pos + 1;
508 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
509 return MCDisassembler::Success;
512 static DecodeStatus DecodeExtSize(MCInst &Inst,
515 const void *Decoder) {
516 int Size = (int) Insn + 1;
517 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
518 return MCDisassembler::Success;