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.get(); }
45 OwningPtr<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 DecodeGPR64RegisterClass(MCInst &Inst,
96 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
101 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
104 const void *Decoder);
106 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
109 const void *Decoder);
111 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
114 const void *Decoder);
116 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
119 const void *Decoder);
121 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
124 const void *Decoder);
126 static DecodeStatus DecodeFCCRegisterClass(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 DecodeACC64DSPRegisterClass(MCInst &Inst,
144 const void *Decoder);
146 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst,
149 const void *Decoder);
151 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst,
154 const void *Decoder);
156 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
159 const void *Decoder);
161 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
164 const void *Decoder);
166 static DecodeStatus DecodeMem(MCInst &Inst,
169 const void *Decoder);
171 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
173 const void *Decoder);
175 static DecodeStatus DecodeSimm16(MCInst &Inst,
178 const void *Decoder);
180 static DecodeStatus DecodeInsSize(MCInst &Inst,
183 const void *Decoder);
185 static DecodeStatus DecodeExtSize(MCInst &Inst,
188 const void *Decoder);
191 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
195 static MCDisassembler *createMipsDisassembler(
197 const MCSubtargetInfo &STI) {
198 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
201 static MCDisassembler *createMipselDisassembler(
203 const MCSubtargetInfo &STI) {
204 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
207 static MCDisassembler *createMips64Disassembler(
209 const MCSubtargetInfo &STI) {
210 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
213 static MCDisassembler *createMips64elDisassembler(
215 const MCSubtargetInfo &STI) {
216 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
219 extern "C" void LLVMInitializeMipsDisassembler() {
220 // Register the disassembler.
221 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
222 createMipsDisassembler);
223 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
224 createMipselDisassembler);
225 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
226 createMips64Disassembler);
227 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
228 createMips64elDisassembler);
232 #include "MipsGenDisassemblerTables.inc"
234 /// readInstruction - read four bytes from the MemoryObject
235 /// and return 32 bit word sorted according to the given endianess
236 static DecodeStatus readInstruction32(const MemoryObject ®ion,
243 // We want to read exactly 4 Bytes of data.
244 if (region.readBytes(address, 4, Bytes) == -1) {
246 return MCDisassembler::Fail;
250 // Encoded as a big-endian 32-bit word in the stream.
251 insn = (Bytes[3] << 0) |
257 // Encoded as a small-endian 32-bit word in the stream.
258 insn = (Bytes[0] << 0) |
264 return MCDisassembler::Success;
268 MipsDisassembler::getInstruction(MCInst &instr,
270 const MemoryObject &Region,
272 raw_ostream &vStream,
273 raw_ostream &cStream) const {
276 DecodeStatus Result = readInstruction32(Region, Address, Size,
278 if (Result == MCDisassembler::Fail)
279 return MCDisassembler::Fail;
281 // Calling the auto-generated decoder function.
282 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
284 if (Result != MCDisassembler::Fail) {
289 return MCDisassembler::Fail;
293 Mips64Disassembler::getInstruction(MCInst &instr,
295 const MemoryObject &Region,
297 raw_ostream &vStream,
298 raw_ostream &cStream) const {
301 DecodeStatus Result = readInstruction32(Region, Address, Size,
303 if (Result == MCDisassembler::Fail)
304 return MCDisassembler::Fail;
306 // Calling the auto-generated decoder function.
307 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
309 if (Result != MCDisassembler::Fail) {
313 // If we fail to decode in Mips64 decoder space we can try in Mips32
314 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
316 if (Result != MCDisassembler::Fail) {
321 return MCDisassembler::Fail;
324 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
325 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
326 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
329 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
332 const void *Decoder) {
334 return MCDisassembler::Fail;
338 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
341 const void *Decoder) {
344 return MCDisassembler::Fail;
346 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
347 Inst.addOperand(MCOperand::CreateReg(Reg));
348 return MCDisassembler::Success;
351 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
354 const void *Decoder) {
356 return MCDisassembler::Fail;
357 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
358 Inst.addOperand(MCOperand::CreateReg(Reg));
359 return MCDisassembler::Success;
362 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
365 const void *Decoder) {
366 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
369 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
372 const void *Decoder) {
374 return MCDisassembler::Fail;
376 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
377 Inst.addOperand(MCOperand::CreateReg(Reg));
378 return MCDisassembler::Success;
381 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
384 const void *Decoder) {
386 return MCDisassembler::Fail;
388 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
389 Inst.addOperand(MCOperand::CreateReg(Reg));
390 return MCDisassembler::Success;
393 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
396 const void *Decoder) {
398 return MCDisassembler::Fail;
399 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
400 Inst.addOperand(MCOperand::CreateReg(Reg));
401 return MCDisassembler::Success;
404 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
407 const void *Decoder) {
409 return MCDisassembler::Fail;
410 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
411 Inst.addOperand(MCOperand::CreateReg(Reg));
412 return MCDisassembler::Success;
415 static DecodeStatus DecodeMem(MCInst &Inst,
418 const void *Decoder) {
419 int Offset = SignExtend32<16>(Insn & 0xffff);
420 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
421 unsigned Base = fieldFromInstruction(Insn, 21, 5);
423 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
424 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
426 if(Inst.getOpcode() == Mips::SC){
427 Inst.addOperand(MCOperand::CreateReg(Reg));
430 Inst.addOperand(MCOperand::CreateReg(Reg));
431 Inst.addOperand(MCOperand::CreateReg(Base));
432 Inst.addOperand(MCOperand::CreateImm(Offset));
434 return MCDisassembler::Success;
437 static DecodeStatus DecodeFMem(MCInst &Inst,
440 const void *Decoder) {
441 int Offset = SignExtend32<16>(Insn & 0xffff);
442 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
443 unsigned Base = fieldFromInstruction(Insn, 21, 5);
445 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
446 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
448 Inst.addOperand(MCOperand::CreateReg(Reg));
449 Inst.addOperand(MCOperand::CreateReg(Base));
450 Inst.addOperand(MCOperand::CreateImm(Offset));
452 return MCDisassembler::Success;
456 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
459 const void *Decoder) {
460 // Currently only hardware register 29 is supported.
462 return MCDisassembler::Fail;
463 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
464 return MCDisassembler::Success;
467 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
470 const void *Decoder) {
471 if (RegNo > 30 || RegNo %2)
472 return MCDisassembler::Fail;
475 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
476 Inst.addOperand(MCOperand::CreateReg(Reg));
477 return MCDisassembler::Success;
480 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
483 const void *Decoder) {
485 return MCDisassembler::Fail;
487 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
488 Inst.addOperand(MCOperand::CreateReg(Reg));
489 return MCDisassembler::Success;
492 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst,
495 const void *Decoder) {
497 return MCDisassembler::Fail;
499 unsigned Reg = getReg(Decoder, Mips::HIRegsDSPRegClassID, RegNo);
500 Inst.addOperand(MCOperand::CreateReg(Reg));
501 return MCDisassembler::Success;
504 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst,
507 const void *Decoder) {
509 return MCDisassembler::Fail;
511 unsigned Reg = getReg(Decoder, Mips::LORegsDSPRegClassID, RegNo);
512 Inst.addOperand(MCOperand::CreateReg(Reg));
513 return MCDisassembler::Success;
516 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
519 const void *Decoder) {
520 unsigned BranchOffset = Offset & 0xffff;
521 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
522 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
523 return MCDisassembler::Success;
526 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
529 const void *Decoder) {
531 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
532 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
533 return MCDisassembler::Success;
537 static DecodeStatus DecodeSimm16(MCInst &Inst,
540 const void *Decoder) {
541 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
542 return MCDisassembler::Success;
545 static DecodeStatus DecodeInsSize(MCInst &Inst,
548 const void *Decoder) {
549 // First we need to grab the pos(lsb) from MCInst.
550 int Pos = Inst.getOperand(2).getImm();
551 int Size = (int) Insn - Pos + 1;
552 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
553 return MCDisassembler::Success;
556 static DecodeStatus DecodeExtSize(MCInst &Inst,
559 const void *Decoder) {
560 int Size = (int) Insn + 1;
561 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
562 return MCDisassembler::Success;