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 {
58 /// Constructor - Initializes the disassembler.
60 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
62 MipsDisassemblerBase(STI, Info, bigEndian) {
63 IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
66 /// getInstruction - See MCDisassembler.
67 virtual DecodeStatus getInstruction(MCInst &instr,
69 const MemoryObject ®ion,
72 raw_ostream &cStream) const;
76 /// Mips64Disassembler - a disasembler class for Mips64.
77 class Mips64Disassembler : public MipsDisassemblerBase {
79 /// Constructor - Initializes the disassembler.
81 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
83 MipsDisassemblerBase(STI, Info, bigEndian) {}
85 /// getInstruction - See MCDisassembler.
86 virtual DecodeStatus getInstruction(MCInst &instr,
88 const MemoryObject ®ion,
91 raw_ostream &cStream) const;
94 } // end anonymous namespace
96 // Forward declare these because the autogenerated code will reference them.
97 // Definitions are further down.
98 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
101 const void *Decoder);
103 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
106 const void *Decoder);
108 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
111 const void *Decoder);
113 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
116 const void *Decoder);
118 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
121 const void *Decoder);
123 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
126 const void *Decoder);
128 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
131 const void *Decoder);
133 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
136 const void *Decoder);
138 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
141 const void *Decoder);
143 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
146 const void *Decoder);
148 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
151 const void *Decoder);
153 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
156 const void *Decoder);
158 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
161 const void *Decoder);
163 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
166 const void *Decoder);
168 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
171 const void *Decoder);
173 static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
176 const void *Decoder);
178 static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
181 const void *Decoder);
183 static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
186 const void *Decoder);
188 static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
191 const void *Decoder);
193 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
196 const void *Decoder);
198 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
201 const void *Decoder);
203 static DecodeStatus DecodeMem(MCInst &Inst,
206 const void *Decoder);
208 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
211 const void *Decoder);
213 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
216 const void *Decoder);
218 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
220 const void *Decoder);
222 static DecodeStatus DecodeSimm16(MCInst &Inst,
225 const void *Decoder);
227 static DecodeStatus DecodeInsSize(MCInst &Inst,
230 const void *Decoder);
232 static DecodeStatus DecodeExtSize(MCInst &Inst,
235 const void *Decoder);
238 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
242 static MCDisassembler *createMipsDisassembler(
244 const MCSubtargetInfo &STI) {
245 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
248 static MCDisassembler *createMipselDisassembler(
250 const MCSubtargetInfo &STI) {
251 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
254 static MCDisassembler *createMips64Disassembler(
256 const MCSubtargetInfo &STI) {
257 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
260 static MCDisassembler *createMips64elDisassembler(
262 const MCSubtargetInfo &STI) {
263 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
266 extern "C" void LLVMInitializeMipsDisassembler() {
267 // Register the disassembler.
268 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
269 createMipsDisassembler);
270 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
271 createMipselDisassembler);
272 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
273 createMips64Disassembler);
274 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
275 createMips64elDisassembler);
279 #include "MipsGenDisassemblerTables.inc"
281 /// readInstruction - read four bytes from the MemoryObject
282 /// and return 32 bit word sorted according to the given endianess
283 static DecodeStatus readInstruction32(const MemoryObject ®ion,
291 // We want to read exactly 4 Bytes of data.
292 if (region.readBytes(address, 4, Bytes) == -1) {
294 return MCDisassembler::Fail;
298 // Encoded as a big-endian 32-bit word in the stream.
299 insn = (Bytes[3] << 0) |
305 // Encoded as a small-endian 32-bit word in the stream.
306 // Little-endian byte ordering:
307 // mips32r2: 4 | 3 | 2 | 1
308 // microMIPS: 2 | 1 | 4 | 3
310 insn = (Bytes[2] << 0) |
315 insn = (Bytes[0] << 0) |
322 return MCDisassembler::Success;
326 MipsDisassembler::getInstruction(MCInst &instr,
328 const MemoryObject &Region,
330 raw_ostream &vStream,
331 raw_ostream &cStream) const {
334 DecodeStatus Result = readInstruction32(Region, Address, Size,
335 Insn, isBigEndian, IsMicroMips);
336 if (Result == MCDisassembler::Fail)
337 return MCDisassembler::Fail;
340 // Calling the auto-generated decoder function.
341 Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
343 if (Result != MCDisassembler::Fail) {
347 return MCDisassembler::Fail;
350 // Calling the auto-generated decoder function.
351 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
353 if (Result != MCDisassembler::Fail) {
358 return MCDisassembler::Fail;
362 Mips64Disassembler::getInstruction(MCInst &instr,
364 const MemoryObject &Region,
366 raw_ostream &vStream,
367 raw_ostream &cStream) const {
370 DecodeStatus Result = readInstruction32(Region, Address, Size,
371 Insn, isBigEndian, false);
372 if (Result == MCDisassembler::Fail)
373 return MCDisassembler::Fail;
375 // Calling the auto-generated decoder function.
376 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
378 if (Result != MCDisassembler::Fail) {
382 // If we fail to decode in Mips64 decoder space we can try in Mips32
383 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
385 if (Result != MCDisassembler::Fail) {
390 return MCDisassembler::Fail;
393 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
394 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
395 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
398 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
401 const void *Decoder) {
403 return MCDisassembler::Fail;
407 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
410 const void *Decoder) {
413 return MCDisassembler::Fail;
415 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
416 Inst.addOperand(MCOperand::CreateReg(Reg));
417 return MCDisassembler::Success;
420 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
423 const void *Decoder) {
425 return MCDisassembler::Fail;
426 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
427 Inst.addOperand(MCOperand::CreateReg(Reg));
428 return MCDisassembler::Success;
431 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
434 const void *Decoder) {
435 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
436 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
438 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
441 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
444 const void *Decoder) {
445 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
448 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
451 const void *Decoder) {
453 return MCDisassembler::Fail;
455 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
456 Inst.addOperand(MCOperand::CreateReg(Reg));
457 return MCDisassembler::Success;
460 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
463 const void *Decoder) {
465 return MCDisassembler::Fail;
467 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
468 Inst.addOperand(MCOperand::CreateReg(Reg));
469 return MCDisassembler::Success;
472 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
475 const void *Decoder) {
477 return MCDisassembler::Fail;
479 unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
480 Inst.addOperand(MCOperand::CreateReg(Reg));
481 return MCDisassembler::Success;
484 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
487 const void *Decoder) {
489 return MCDisassembler::Fail;
490 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
491 Inst.addOperand(MCOperand::CreateReg(Reg));
492 return MCDisassembler::Success;
495 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
498 const void *Decoder) {
500 return MCDisassembler::Fail;
501 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
502 Inst.addOperand(MCOperand::CreateReg(Reg));
503 return MCDisassembler::Success;
506 static DecodeStatus DecodeMem(MCInst &Inst,
509 const void *Decoder) {
510 int Offset = SignExtend32<16>(Insn & 0xffff);
511 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
512 unsigned Base = fieldFromInstruction(Insn, 21, 5);
514 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
515 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
517 if(Inst.getOpcode() == Mips::SC){
518 Inst.addOperand(MCOperand::CreateReg(Reg));
521 Inst.addOperand(MCOperand::CreateReg(Reg));
522 Inst.addOperand(MCOperand::CreateReg(Base));
523 Inst.addOperand(MCOperand::CreateImm(Offset));
525 return MCDisassembler::Success;
528 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
531 const void *Decoder) {
532 int Offset = SignExtend32<12>(Insn & 0x0fff);
533 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
534 unsigned Base = fieldFromInstruction(Insn, 16, 5);
536 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
537 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
539 Inst.addOperand(MCOperand::CreateReg(Reg));
540 Inst.addOperand(MCOperand::CreateReg(Base));
541 Inst.addOperand(MCOperand::CreateImm(Offset));
543 return MCDisassembler::Success;
546 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
549 const void *Decoder) {
550 int Offset = SignExtend32<16>(Insn & 0xffff);
551 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
552 unsigned Base = fieldFromInstruction(Insn, 16, 5);
554 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
555 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
557 Inst.addOperand(MCOperand::CreateReg(Reg));
558 Inst.addOperand(MCOperand::CreateReg(Base));
559 Inst.addOperand(MCOperand::CreateImm(Offset));
561 return MCDisassembler::Success;
564 static DecodeStatus DecodeFMem(MCInst &Inst,
567 const void *Decoder) {
568 int Offset = SignExtend32<16>(Insn & 0xffff);
569 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
570 unsigned Base = fieldFromInstruction(Insn, 21, 5);
572 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
573 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
575 Inst.addOperand(MCOperand::CreateReg(Reg));
576 Inst.addOperand(MCOperand::CreateReg(Base));
577 Inst.addOperand(MCOperand::CreateImm(Offset));
579 return MCDisassembler::Success;
583 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
586 const void *Decoder) {
587 // Currently only hardware register 29 is supported.
589 return MCDisassembler::Fail;
590 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
591 return MCDisassembler::Success;
594 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
597 const void *Decoder) {
598 if (RegNo > 30 || RegNo %2)
599 return MCDisassembler::Fail;
602 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
603 Inst.addOperand(MCOperand::CreateReg(Reg));
604 return MCDisassembler::Success;
607 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
610 const void *Decoder) {
612 return MCDisassembler::Fail;
614 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
615 Inst.addOperand(MCOperand::CreateReg(Reg));
616 return MCDisassembler::Success;
619 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
622 const void *Decoder) {
624 return MCDisassembler::Fail;
626 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
627 Inst.addOperand(MCOperand::CreateReg(Reg));
628 return MCDisassembler::Success;
631 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
634 const void *Decoder) {
636 return MCDisassembler::Fail;
638 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
639 Inst.addOperand(MCOperand::CreateReg(Reg));
640 return MCDisassembler::Success;
643 static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
646 const void *Decoder) {
648 return MCDisassembler::Fail;
650 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
651 Inst.addOperand(MCOperand::CreateReg(Reg));
652 return MCDisassembler::Success;
655 static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
658 const void *Decoder) {
660 return MCDisassembler::Fail;
662 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
663 Inst.addOperand(MCOperand::CreateReg(Reg));
664 return MCDisassembler::Success;
667 static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
670 const void *Decoder) {
672 return MCDisassembler::Fail;
674 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
675 Inst.addOperand(MCOperand::CreateReg(Reg));
676 return MCDisassembler::Success;
679 static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
682 const void *Decoder) {
684 return MCDisassembler::Fail;
686 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
687 Inst.addOperand(MCOperand::CreateReg(Reg));
688 return MCDisassembler::Success;
691 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
694 const void *Decoder) {
695 unsigned BranchOffset = Offset & 0xffff;
696 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
697 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
698 return MCDisassembler::Success;
701 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
704 const void *Decoder) {
706 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
707 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
708 return MCDisassembler::Success;
712 static DecodeStatus DecodeSimm16(MCInst &Inst,
715 const void *Decoder) {
716 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
717 return MCDisassembler::Success;
720 static DecodeStatus DecodeInsSize(MCInst &Inst,
723 const void *Decoder) {
724 // First we need to grab the pos(lsb) from MCInst.
725 int Pos = Inst.getOperand(2).getImm();
726 int Size = (int) Insn - Pos + 1;
727 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
728 return MCDisassembler::Success;
731 static DecodeStatus DecodeExtSize(MCInst &Inst,
734 const void *Decoder) {
735 int Size = (int) Insn + 1;
736 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
737 return MCDisassembler::Success;