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 DecodeMSACtrlRegisterClass(MCInst &Inst,
196 const void *Decoder);
198 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
201 const void *Decoder);
203 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
206 const void *Decoder);
208 static DecodeStatus DecodeMem(MCInst &Inst,
211 const void *Decoder);
213 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
216 const void *Decoder);
218 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
221 const void *Decoder);
223 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
225 const void *Decoder);
227 static DecodeStatus DecodeSimm16(MCInst &Inst,
230 const void *Decoder);
232 static DecodeStatus DecodeInsSize(MCInst &Inst,
235 const void *Decoder);
237 static DecodeStatus DecodeExtSize(MCInst &Inst,
240 const void *Decoder);
243 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
247 static MCDisassembler *createMipsDisassembler(
249 const MCSubtargetInfo &STI) {
250 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
253 static MCDisassembler *createMipselDisassembler(
255 const MCSubtargetInfo &STI) {
256 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
259 static MCDisassembler *createMips64Disassembler(
261 const MCSubtargetInfo &STI) {
262 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
265 static MCDisassembler *createMips64elDisassembler(
267 const MCSubtargetInfo &STI) {
268 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
271 extern "C" void LLVMInitializeMipsDisassembler() {
272 // Register the disassembler.
273 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
274 createMipsDisassembler);
275 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
276 createMipselDisassembler);
277 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
278 createMips64Disassembler);
279 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
280 createMips64elDisassembler);
284 #include "MipsGenDisassemblerTables.inc"
286 /// readInstruction - read four bytes from the MemoryObject
287 /// and return 32 bit word sorted according to the given endianess
288 static DecodeStatus readInstruction32(const MemoryObject ®ion,
296 // We want to read exactly 4 Bytes of data.
297 if (region.readBytes(address, 4, Bytes) == -1) {
299 return MCDisassembler::Fail;
303 // Encoded as a big-endian 32-bit word in the stream.
304 insn = (Bytes[3] << 0) |
310 // Encoded as a small-endian 32-bit word in the stream.
311 // Little-endian byte ordering:
312 // mips32r2: 4 | 3 | 2 | 1
313 // microMIPS: 2 | 1 | 4 | 3
315 insn = (Bytes[2] << 0) |
320 insn = (Bytes[0] << 0) |
327 return MCDisassembler::Success;
331 MipsDisassembler::getInstruction(MCInst &instr,
333 const MemoryObject &Region,
335 raw_ostream &vStream,
336 raw_ostream &cStream) const {
339 DecodeStatus Result = readInstruction32(Region, Address, Size,
340 Insn, isBigEndian, IsMicroMips);
341 if (Result == MCDisassembler::Fail)
342 return MCDisassembler::Fail;
345 // Calling the auto-generated decoder function.
346 Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
348 if (Result != MCDisassembler::Fail) {
352 return MCDisassembler::Fail;
355 // Calling the auto-generated decoder function.
356 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
358 if (Result != MCDisassembler::Fail) {
363 return MCDisassembler::Fail;
367 Mips64Disassembler::getInstruction(MCInst &instr,
369 const MemoryObject &Region,
371 raw_ostream &vStream,
372 raw_ostream &cStream) const {
375 DecodeStatus Result = readInstruction32(Region, Address, Size,
376 Insn, isBigEndian, false);
377 if (Result == MCDisassembler::Fail)
378 return MCDisassembler::Fail;
380 // Calling the auto-generated decoder function.
381 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
383 if (Result != MCDisassembler::Fail) {
387 // If we fail to decode in Mips64 decoder space we can try in Mips32
388 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
390 if (Result != MCDisassembler::Fail) {
395 return MCDisassembler::Fail;
398 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
399 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
400 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
403 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
406 const void *Decoder) {
408 return MCDisassembler::Fail;
412 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
415 const void *Decoder) {
418 return MCDisassembler::Fail;
420 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
421 Inst.addOperand(MCOperand::CreateReg(Reg));
422 return MCDisassembler::Success;
425 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
428 const void *Decoder) {
430 return MCDisassembler::Fail;
431 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
432 Inst.addOperand(MCOperand::CreateReg(Reg));
433 return MCDisassembler::Success;
436 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
439 const void *Decoder) {
440 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
441 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
443 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
446 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
449 const void *Decoder) {
450 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
453 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
456 const void *Decoder) {
458 return MCDisassembler::Fail;
460 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
461 Inst.addOperand(MCOperand::CreateReg(Reg));
462 return MCDisassembler::Success;
465 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
468 const void *Decoder) {
470 return MCDisassembler::Fail;
472 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
473 Inst.addOperand(MCOperand::CreateReg(Reg));
474 return MCDisassembler::Success;
477 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
480 const void *Decoder) {
482 return MCDisassembler::Fail;
484 unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
485 Inst.addOperand(MCOperand::CreateReg(Reg));
486 return MCDisassembler::Success;
489 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
492 const void *Decoder) {
494 return MCDisassembler::Fail;
495 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
496 Inst.addOperand(MCOperand::CreateReg(Reg));
497 return MCDisassembler::Success;
500 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
503 const void *Decoder) {
505 return MCDisassembler::Fail;
506 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
507 Inst.addOperand(MCOperand::CreateReg(Reg));
508 return MCDisassembler::Success;
511 static DecodeStatus DecodeMem(MCInst &Inst,
514 const void *Decoder) {
515 int Offset = SignExtend32<16>(Insn & 0xffff);
516 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
517 unsigned Base = fieldFromInstruction(Insn, 21, 5);
519 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
520 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
522 if(Inst.getOpcode() == Mips::SC){
523 Inst.addOperand(MCOperand::CreateReg(Reg));
526 Inst.addOperand(MCOperand::CreateReg(Reg));
527 Inst.addOperand(MCOperand::CreateReg(Base));
528 Inst.addOperand(MCOperand::CreateImm(Offset));
530 return MCDisassembler::Success;
533 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
536 const void *Decoder) {
537 int Offset = SignExtend32<12>(Insn & 0x0fff);
538 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
539 unsigned Base = fieldFromInstruction(Insn, 16, 5);
541 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
542 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
544 Inst.addOperand(MCOperand::CreateReg(Reg));
545 Inst.addOperand(MCOperand::CreateReg(Base));
546 Inst.addOperand(MCOperand::CreateImm(Offset));
548 return MCDisassembler::Success;
551 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
554 const void *Decoder) {
555 int Offset = SignExtend32<16>(Insn & 0xffff);
556 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
557 unsigned Base = fieldFromInstruction(Insn, 16, 5);
559 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
560 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
562 Inst.addOperand(MCOperand::CreateReg(Reg));
563 Inst.addOperand(MCOperand::CreateReg(Base));
564 Inst.addOperand(MCOperand::CreateImm(Offset));
566 return MCDisassembler::Success;
569 static DecodeStatus DecodeFMem(MCInst &Inst,
572 const void *Decoder) {
573 int Offset = SignExtend32<16>(Insn & 0xffff);
574 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
575 unsigned Base = fieldFromInstruction(Insn, 21, 5);
577 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
578 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
580 Inst.addOperand(MCOperand::CreateReg(Reg));
581 Inst.addOperand(MCOperand::CreateReg(Base));
582 Inst.addOperand(MCOperand::CreateImm(Offset));
584 return MCDisassembler::Success;
588 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
591 const void *Decoder) {
592 // Currently only hardware register 29 is supported.
594 return MCDisassembler::Fail;
595 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
596 return MCDisassembler::Success;
599 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
602 const void *Decoder) {
603 if (RegNo > 30 || RegNo %2)
604 return MCDisassembler::Fail;
607 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
608 Inst.addOperand(MCOperand::CreateReg(Reg));
609 return MCDisassembler::Success;
612 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
615 const void *Decoder) {
617 return MCDisassembler::Fail;
619 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
620 Inst.addOperand(MCOperand::CreateReg(Reg));
621 return MCDisassembler::Success;
624 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
627 const void *Decoder) {
629 return MCDisassembler::Fail;
631 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
632 Inst.addOperand(MCOperand::CreateReg(Reg));
633 return MCDisassembler::Success;
636 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
639 const void *Decoder) {
641 return MCDisassembler::Fail;
643 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
644 Inst.addOperand(MCOperand::CreateReg(Reg));
645 return MCDisassembler::Success;
648 static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
651 const void *Decoder) {
653 return MCDisassembler::Fail;
655 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
656 Inst.addOperand(MCOperand::CreateReg(Reg));
657 return MCDisassembler::Success;
660 static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
663 const void *Decoder) {
665 return MCDisassembler::Fail;
667 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
668 Inst.addOperand(MCOperand::CreateReg(Reg));
669 return MCDisassembler::Success;
672 static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
675 const void *Decoder) {
677 return MCDisassembler::Fail;
679 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
680 Inst.addOperand(MCOperand::CreateReg(Reg));
681 return MCDisassembler::Success;
684 static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
687 const void *Decoder) {
689 return MCDisassembler::Fail;
691 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
692 Inst.addOperand(MCOperand::CreateReg(Reg));
693 return MCDisassembler::Success;
696 static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
699 const void *Decoder) {
701 return MCDisassembler::Fail;
703 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
704 Inst.addOperand(MCOperand::CreateReg(Reg));
705 return MCDisassembler::Success;
708 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
711 const void *Decoder) {
712 unsigned BranchOffset = Offset & 0xffff;
713 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
714 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
715 return MCDisassembler::Success;
718 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
721 const void *Decoder) {
723 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
724 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
725 return MCDisassembler::Success;
729 static DecodeStatus DecodeSimm16(MCInst &Inst,
732 const void *Decoder) {
733 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
734 return MCDisassembler::Success;
737 static DecodeStatus DecodeInsSize(MCInst &Inst,
740 const void *Decoder) {
741 // First we need to grab the pos(lsb) from MCInst.
742 int Pos = Inst.getOperand(2).getImm();
743 int Size = (int) Insn - Pos + 1;
744 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
745 return MCDisassembler::Success;
748 static DecodeStatus DecodeExtSize(MCInst &Inst,
751 const void *Decoder) {
752 int Size = (int) Insn + 1;
753 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
754 return MCDisassembler::Success;