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 DecodeMSA128HRegisterClass(MCInst &Inst,
176 const void *Decoder);
178 static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
181 const void *Decoder);
183 static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
186 const void *Decoder);
188 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
191 const void *Decoder);
193 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
196 const void *Decoder);
198 static DecodeStatus DecodeMem(MCInst &Inst,
201 const void *Decoder);
203 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
206 const void *Decoder);
208 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
211 const void *Decoder);
213 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
215 const void *Decoder);
217 static DecodeStatus DecodeSimm16(MCInst &Inst,
220 const void *Decoder);
222 static DecodeStatus DecodeInsSize(MCInst &Inst,
225 const void *Decoder);
227 static DecodeStatus DecodeExtSize(MCInst &Inst,
230 const void *Decoder);
233 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
237 static MCDisassembler *createMipsDisassembler(
239 const MCSubtargetInfo &STI) {
240 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
243 static MCDisassembler *createMipselDisassembler(
245 const MCSubtargetInfo &STI) {
246 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
249 static MCDisassembler *createMips64Disassembler(
251 const MCSubtargetInfo &STI) {
252 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
255 static MCDisassembler *createMips64elDisassembler(
257 const MCSubtargetInfo &STI) {
258 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
261 extern "C" void LLVMInitializeMipsDisassembler() {
262 // Register the disassembler.
263 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
264 createMipsDisassembler);
265 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
266 createMipselDisassembler);
267 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
268 createMips64Disassembler);
269 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
270 createMips64elDisassembler);
274 #include "MipsGenDisassemblerTables.inc"
276 /// readInstruction - read four bytes from the MemoryObject
277 /// and return 32 bit word sorted according to the given endianess
278 static DecodeStatus readInstruction32(const MemoryObject ®ion,
286 // We want to read exactly 4 Bytes of data.
287 if (region.readBytes(address, 4, Bytes) == -1) {
289 return MCDisassembler::Fail;
293 // Encoded as a big-endian 32-bit word in the stream.
294 insn = (Bytes[3] << 0) |
300 // Encoded as a small-endian 32-bit word in the stream.
301 // Little-endian byte ordering:
302 // mips32r2: 4 | 3 | 2 | 1
303 // microMIPS: 2 | 1 | 4 | 3
305 insn = (Bytes[2] << 0) |
310 insn = (Bytes[0] << 0) |
317 return MCDisassembler::Success;
321 MipsDisassembler::getInstruction(MCInst &instr,
323 const MemoryObject &Region,
325 raw_ostream &vStream,
326 raw_ostream &cStream) const {
329 DecodeStatus Result = readInstruction32(Region, Address, Size,
330 Insn, isBigEndian, IsMicroMips);
331 if (Result == MCDisassembler::Fail)
332 return MCDisassembler::Fail;
335 // Calling the auto-generated decoder function.
336 Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
338 if (Result != MCDisassembler::Fail) {
342 return MCDisassembler::Fail;
345 // Calling the auto-generated decoder function.
346 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
348 if (Result != MCDisassembler::Fail) {
353 return MCDisassembler::Fail;
357 Mips64Disassembler::getInstruction(MCInst &instr,
359 const MemoryObject &Region,
361 raw_ostream &vStream,
362 raw_ostream &cStream) const {
365 DecodeStatus Result = readInstruction32(Region, Address, Size,
366 Insn, isBigEndian, false);
367 if (Result == MCDisassembler::Fail)
368 return MCDisassembler::Fail;
370 // Calling the auto-generated decoder function.
371 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
373 if (Result != MCDisassembler::Fail) {
377 // If we fail to decode in Mips64 decoder space we can try in Mips32
378 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
380 if (Result != MCDisassembler::Fail) {
385 return MCDisassembler::Fail;
388 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
389 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
390 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
393 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
396 const void *Decoder) {
398 return MCDisassembler::Fail;
402 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
405 const void *Decoder) {
408 return MCDisassembler::Fail;
410 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
411 Inst.addOperand(MCOperand::CreateReg(Reg));
412 return MCDisassembler::Success;
415 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
418 const void *Decoder) {
420 return MCDisassembler::Fail;
421 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
422 Inst.addOperand(MCOperand::CreateReg(Reg));
423 return MCDisassembler::Success;
426 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
429 const void *Decoder) {
430 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
431 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
433 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
436 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
439 const void *Decoder) {
440 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
443 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
446 const void *Decoder) {
448 return MCDisassembler::Fail;
450 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
451 Inst.addOperand(MCOperand::CreateReg(Reg));
452 return MCDisassembler::Success;
455 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
458 const void *Decoder) {
460 return MCDisassembler::Fail;
462 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
463 Inst.addOperand(MCOperand::CreateReg(Reg));
464 return MCDisassembler::Success;
467 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
470 const void *Decoder) {
472 return MCDisassembler::Fail;
474 unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
475 Inst.addOperand(MCOperand::CreateReg(Reg));
476 return MCDisassembler::Success;
479 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
482 const void *Decoder) {
484 return MCDisassembler::Fail;
485 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
486 Inst.addOperand(MCOperand::CreateReg(Reg));
487 return MCDisassembler::Success;
490 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
493 const void *Decoder) {
495 return MCDisassembler::Fail;
496 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
497 Inst.addOperand(MCOperand::CreateReg(Reg));
498 return MCDisassembler::Success;
501 static DecodeStatus DecodeMem(MCInst &Inst,
504 const void *Decoder) {
505 int Offset = SignExtend32<16>(Insn & 0xffff);
506 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
507 unsigned Base = fieldFromInstruction(Insn, 21, 5);
509 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
510 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
512 if(Inst.getOpcode() == Mips::SC){
513 Inst.addOperand(MCOperand::CreateReg(Reg));
516 Inst.addOperand(MCOperand::CreateReg(Reg));
517 Inst.addOperand(MCOperand::CreateReg(Base));
518 Inst.addOperand(MCOperand::CreateImm(Offset));
520 return MCDisassembler::Success;
523 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
526 const void *Decoder) {
527 int Offset = SignExtend32<12>(Insn & 0x0fff);
528 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
529 unsigned Base = fieldFromInstruction(Insn, 16, 5);
531 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
532 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
534 Inst.addOperand(MCOperand::CreateReg(Reg));
535 Inst.addOperand(MCOperand::CreateReg(Base));
536 Inst.addOperand(MCOperand::CreateImm(Offset));
538 return MCDisassembler::Success;
541 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
544 const void *Decoder) {
545 int Offset = SignExtend32<16>(Insn & 0xffff);
546 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
547 unsigned Base = fieldFromInstruction(Insn, 16, 5);
549 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
550 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
552 Inst.addOperand(MCOperand::CreateReg(Reg));
553 Inst.addOperand(MCOperand::CreateReg(Base));
554 Inst.addOperand(MCOperand::CreateImm(Offset));
556 return MCDisassembler::Success;
559 static DecodeStatus DecodeFMem(MCInst &Inst,
562 const void *Decoder) {
563 int Offset = SignExtend32<16>(Insn & 0xffff);
564 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
565 unsigned Base = fieldFromInstruction(Insn, 21, 5);
567 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
568 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
570 Inst.addOperand(MCOperand::CreateReg(Reg));
571 Inst.addOperand(MCOperand::CreateReg(Base));
572 Inst.addOperand(MCOperand::CreateImm(Offset));
574 return MCDisassembler::Success;
578 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
581 const void *Decoder) {
582 // Currently only hardware register 29 is supported.
584 return MCDisassembler::Fail;
585 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
586 return MCDisassembler::Success;
589 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
592 const void *Decoder) {
593 if (RegNo > 30 || RegNo %2)
594 return MCDisassembler::Fail;
597 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
598 Inst.addOperand(MCOperand::CreateReg(Reg));
599 return MCDisassembler::Success;
602 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
605 const void *Decoder) {
607 return MCDisassembler::Fail;
609 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
610 Inst.addOperand(MCOperand::CreateReg(Reg));
611 return MCDisassembler::Success;
614 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
617 const void *Decoder) {
619 return MCDisassembler::Fail;
621 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
622 Inst.addOperand(MCOperand::CreateReg(Reg));
623 return MCDisassembler::Success;
626 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
629 const void *Decoder) {
631 return MCDisassembler::Fail;
633 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
634 Inst.addOperand(MCOperand::CreateReg(Reg));
635 return MCDisassembler::Success;
638 static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
641 const void *Decoder) {
643 return MCDisassembler::Fail;
645 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
646 Inst.addOperand(MCOperand::CreateReg(Reg));
647 return MCDisassembler::Success;
650 static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
653 const void *Decoder) {
655 return MCDisassembler::Fail;
657 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
658 Inst.addOperand(MCOperand::CreateReg(Reg));
659 return MCDisassembler::Success;
662 static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
665 const void *Decoder) {
667 return MCDisassembler::Fail;
669 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
670 Inst.addOperand(MCOperand::CreateReg(Reg));
671 return MCDisassembler::Success;
674 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
677 const void *Decoder) {
678 unsigned BranchOffset = Offset & 0xffff;
679 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
680 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
681 return MCDisassembler::Success;
684 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
687 const void *Decoder) {
689 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
690 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
691 return MCDisassembler::Success;
695 static DecodeStatus DecodeSimm16(MCInst &Inst,
698 const void *Decoder) {
699 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
700 return MCDisassembler::Success;
703 static DecodeStatus DecodeInsSize(MCInst &Inst,
706 const void *Decoder) {
707 // First we need to grab the pos(lsb) from MCInst.
708 int Pos = Inst.getOperand(2).getImm();
709 int Size = (int) Insn - Pos + 1;
710 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
711 return MCDisassembler::Success;
714 static DecodeStatus DecodeExtSize(MCInst &Inst,
717 const void *Decoder) {
718 int Size = (int) Insn + 1;
719 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
720 return MCDisassembler::Success;