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),
39 IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
41 virtual ~MipsDisassemblerBase() {}
43 const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
45 bool isN64() const { return IsN64; }
48 OwningPtr<const MCRegisterInfo> RegInfo;
54 /// MipsDisassembler - a disasembler class for Mips32.
55 class MipsDisassembler : public MipsDisassemblerBase {
57 /// Constructor - Initializes the disassembler.
59 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
61 MipsDisassemblerBase(STI, Info, bigEndian) {}
63 /// getInstruction - See MCDisassembler.
64 virtual DecodeStatus getInstruction(MCInst &instr,
66 const MemoryObject ®ion,
69 raw_ostream &cStream) const;
73 /// Mips64Disassembler - a disasembler class for Mips64.
74 class Mips64Disassembler : public MipsDisassemblerBase {
76 /// Constructor - Initializes the disassembler.
78 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
80 MipsDisassemblerBase(STI, Info, bigEndian) {}
82 /// getInstruction - See MCDisassembler.
83 virtual DecodeStatus getInstruction(MCInst &instr,
85 const MemoryObject ®ion,
88 raw_ostream &cStream) const;
91 } // end anonymous namespace
93 // Forward declare these because the autogenerated code will reference them.
94 // Definitions are further down.
95 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
100 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
103 const void *Decoder);
105 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
108 const void *Decoder);
110 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
113 const void *Decoder);
115 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
118 const void *Decoder);
120 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
123 const void *Decoder);
125 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
128 const void *Decoder);
130 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
133 const void *Decoder);
135 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
138 const void *Decoder);
140 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
143 const void *Decoder);
145 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
148 const void *Decoder);
150 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
153 const void *Decoder);
155 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
158 const void *Decoder);
160 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
163 const void *Decoder);
165 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
168 const void *Decoder);
170 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
173 const void *Decoder);
175 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
178 const void *Decoder);
180 static DecodeStatus DecodeMem(MCInst &Inst,
183 const void *Decoder);
185 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
187 const void *Decoder);
189 static DecodeStatus DecodeSimm16(MCInst &Inst,
192 const void *Decoder);
194 static DecodeStatus DecodeInsSize(MCInst &Inst,
197 const void *Decoder);
199 static DecodeStatus DecodeExtSize(MCInst &Inst,
202 const void *Decoder);
205 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
209 static MCDisassembler *createMipsDisassembler(
211 const MCSubtargetInfo &STI) {
212 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
215 static MCDisassembler *createMipselDisassembler(
217 const MCSubtargetInfo &STI) {
218 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
221 static MCDisassembler *createMips64Disassembler(
223 const MCSubtargetInfo &STI) {
224 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
227 static MCDisassembler *createMips64elDisassembler(
229 const MCSubtargetInfo &STI) {
230 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
233 extern "C" void LLVMInitializeMipsDisassembler() {
234 // Register the disassembler.
235 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
236 createMipsDisassembler);
237 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
238 createMipselDisassembler);
239 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
240 createMips64Disassembler);
241 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
242 createMips64elDisassembler);
246 #include "MipsGenDisassemblerTables.inc"
248 /// readInstruction - read four bytes from the MemoryObject
249 /// and return 32 bit word sorted according to the given endianess
250 static DecodeStatus readInstruction32(const MemoryObject ®ion,
257 // We want to read exactly 4 Bytes of data.
258 if (region.readBytes(address, 4, Bytes) == -1) {
260 return MCDisassembler::Fail;
264 // Encoded as a big-endian 32-bit word in the stream.
265 insn = (Bytes[3] << 0) |
271 // Encoded as a small-endian 32-bit word in the stream.
272 insn = (Bytes[0] << 0) |
278 return MCDisassembler::Success;
282 MipsDisassembler::getInstruction(MCInst &instr,
284 const MemoryObject &Region,
286 raw_ostream &vStream,
287 raw_ostream &cStream) const {
290 DecodeStatus Result = readInstruction32(Region, Address, Size,
292 if (Result == MCDisassembler::Fail)
293 return MCDisassembler::Fail;
295 // Calling the auto-generated decoder function.
296 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
298 if (Result != MCDisassembler::Fail) {
303 return MCDisassembler::Fail;
307 Mips64Disassembler::getInstruction(MCInst &instr,
309 const MemoryObject &Region,
311 raw_ostream &vStream,
312 raw_ostream &cStream) const {
315 DecodeStatus Result = readInstruction32(Region, Address, Size,
317 if (Result == MCDisassembler::Fail)
318 return MCDisassembler::Fail;
320 // Calling the auto-generated decoder function.
321 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
323 if (Result != MCDisassembler::Fail) {
327 // If we fail to decode in Mips64 decoder space we can try in Mips32
328 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
330 if (Result != MCDisassembler::Fail) {
335 return MCDisassembler::Fail;
338 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
339 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
340 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
343 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
346 const void *Decoder) {
348 return MCDisassembler::Fail;
352 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
355 const void *Decoder) {
358 return MCDisassembler::Fail;
360 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
361 Inst.addOperand(MCOperand::CreateReg(Reg));
362 return MCDisassembler::Success;
365 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
368 const void *Decoder) {
370 return MCDisassembler::Fail;
371 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
372 Inst.addOperand(MCOperand::CreateReg(Reg));
373 return MCDisassembler::Success;
376 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
379 const void *Decoder) {
380 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
381 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
383 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
386 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
389 const void *Decoder) {
390 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
393 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
396 const void *Decoder) {
398 return MCDisassembler::Fail;
400 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
401 Inst.addOperand(MCOperand::CreateReg(Reg));
402 return MCDisassembler::Success;
405 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
408 const void *Decoder) {
410 return MCDisassembler::Fail;
412 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
413 Inst.addOperand(MCOperand::CreateReg(Reg));
414 return MCDisassembler::Success;
417 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
420 const void *Decoder) {
422 return MCDisassembler::Fail;
424 unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
425 Inst.addOperand(MCOperand::CreateReg(Reg));
426 return MCDisassembler::Success;
429 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
432 const void *Decoder) {
434 return MCDisassembler::Fail;
435 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
436 Inst.addOperand(MCOperand::CreateReg(Reg));
437 return MCDisassembler::Success;
440 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
443 const void *Decoder) {
445 return MCDisassembler::Fail;
446 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
447 Inst.addOperand(MCOperand::CreateReg(Reg));
448 return MCDisassembler::Success;
451 static DecodeStatus DecodeMem(MCInst &Inst,
454 const void *Decoder) {
455 int Offset = SignExtend32<16>(Insn & 0xffff);
456 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
457 unsigned Base = fieldFromInstruction(Insn, 21, 5);
459 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
460 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
462 if(Inst.getOpcode() == Mips::SC){
463 Inst.addOperand(MCOperand::CreateReg(Reg));
466 Inst.addOperand(MCOperand::CreateReg(Reg));
467 Inst.addOperand(MCOperand::CreateReg(Base));
468 Inst.addOperand(MCOperand::CreateImm(Offset));
470 return MCDisassembler::Success;
473 static DecodeStatus DecodeFMem(MCInst &Inst,
476 const void *Decoder) {
477 int Offset = SignExtend32<16>(Insn & 0xffff);
478 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
479 unsigned Base = fieldFromInstruction(Insn, 21, 5);
481 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
482 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
484 Inst.addOperand(MCOperand::CreateReg(Reg));
485 Inst.addOperand(MCOperand::CreateReg(Base));
486 Inst.addOperand(MCOperand::CreateImm(Offset));
488 return MCDisassembler::Success;
492 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
495 const void *Decoder) {
496 // Currently only hardware register 29 is supported.
498 return MCDisassembler::Fail;
499 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
500 return MCDisassembler::Success;
503 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
506 const void *Decoder) {
507 if (RegNo > 30 || RegNo %2)
508 return MCDisassembler::Fail;
511 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
512 Inst.addOperand(MCOperand::CreateReg(Reg));
513 return MCDisassembler::Success;
516 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
519 const void *Decoder) {
521 return MCDisassembler::Fail;
523 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
524 Inst.addOperand(MCOperand::CreateReg(Reg));
525 return MCDisassembler::Success;
528 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
531 const void *Decoder) {
533 return MCDisassembler::Fail;
535 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
536 Inst.addOperand(MCOperand::CreateReg(Reg));
537 return MCDisassembler::Success;
540 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
543 const void *Decoder) {
545 return MCDisassembler::Fail;
547 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
548 Inst.addOperand(MCOperand::CreateReg(Reg));
549 return MCDisassembler::Success;
552 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
555 const void *Decoder) {
556 unsigned BranchOffset = Offset & 0xffff;
557 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
558 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
559 return MCDisassembler::Success;
562 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
565 const void *Decoder) {
567 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
568 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
569 return MCDisassembler::Success;
573 static DecodeStatus DecodeSimm16(MCInst &Inst,
576 const void *Decoder) {
577 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
578 return MCDisassembler::Success;
581 static DecodeStatus DecodeInsSize(MCInst &Inst,
584 const void *Decoder) {
585 // First we need to grab the pos(lsb) from MCInst.
586 int Pos = Inst.getOperand(2).getImm();
587 int Size = (int) Insn - Pos + 1;
588 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
589 return MCDisassembler::Success;
592 static DecodeStatus DecodeExtSize(MCInst &Inst,
595 const void *Decoder) {
596 int Size = (int) Insn + 1;
597 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
598 return MCDisassembler::Success;