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 DecodeBranchTarget(MCInst &Inst,
176 const void *Decoder);
178 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
181 const void *Decoder);
183 static DecodeStatus DecodeMem(MCInst &Inst,
186 const void *Decoder);
188 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
191 const void *Decoder);
193 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
196 const void *Decoder);
198 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
200 const void *Decoder);
202 static DecodeStatus DecodeSimm16(MCInst &Inst,
205 const void *Decoder);
207 static DecodeStatus DecodeInsSize(MCInst &Inst,
210 const void *Decoder);
212 static DecodeStatus DecodeExtSize(MCInst &Inst,
215 const void *Decoder);
218 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
222 static MCDisassembler *createMipsDisassembler(
224 const MCSubtargetInfo &STI) {
225 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
228 static MCDisassembler *createMipselDisassembler(
230 const MCSubtargetInfo &STI) {
231 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
234 static MCDisassembler *createMips64Disassembler(
236 const MCSubtargetInfo &STI) {
237 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
240 static MCDisassembler *createMips64elDisassembler(
242 const MCSubtargetInfo &STI) {
243 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
246 extern "C" void LLVMInitializeMipsDisassembler() {
247 // Register the disassembler.
248 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
249 createMipsDisassembler);
250 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
251 createMipselDisassembler);
252 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
253 createMips64Disassembler);
254 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
255 createMips64elDisassembler);
259 #include "MipsGenDisassemblerTables.inc"
261 /// readInstruction - read four bytes from the MemoryObject
262 /// and return 32 bit word sorted according to the given endianess
263 static DecodeStatus readInstruction32(const MemoryObject ®ion,
271 // We want to read exactly 4 Bytes of data.
272 if (region.readBytes(address, 4, Bytes) == -1) {
274 return MCDisassembler::Fail;
278 // Encoded as a big-endian 32-bit word in the stream.
279 insn = (Bytes[3] << 0) |
285 // Encoded as a small-endian 32-bit word in the stream.
286 // Little-endian byte ordering:
287 // mips32r2: 4 | 3 | 2 | 1
288 // microMIPS: 2 | 1 | 4 | 3
290 insn = (Bytes[2] << 0) |
295 insn = (Bytes[0] << 0) |
302 return MCDisassembler::Success;
306 MipsDisassembler::getInstruction(MCInst &instr,
308 const MemoryObject &Region,
310 raw_ostream &vStream,
311 raw_ostream &cStream) const {
314 DecodeStatus Result = readInstruction32(Region, Address, Size,
315 Insn, isBigEndian, IsMicroMips);
316 if (Result == MCDisassembler::Fail)
317 return MCDisassembler::Fail;
320 // Calling the auto-generated decoder function.
321 Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
323 if (Result != MCDisassembler::Fail) {
327 return MCDisassembler::Fail;
330 // Calling the auto-generated decoder function.
331 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
333 if (Result != MCDisassembler::Fail) {
338 return MCDisassembler::Fail;
342 Mips64Disassembler::getInstruction(MCInst &instr,
344 const MemoryObject &Region,
346 raw_ostream &vStream,
347 raw_ostream &cStream) const {
350 DecodeStatus Result = readInstruction32(Region, Address, Size,
351 Insn, isBigEndian, false);
352 if (Result == MCDisassembler::Fail)
353 return MCDisassembler::Fail;
355 // Calling the auto-generated decoder function.
356 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
358 if (Result != MCDisassembler::Fail) {
362 // If we fail to decode in Mips64 decoder space we can try in Mips32
363 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
365 if (Result != MCDisassembler::Fail) {
370 return MCDisassembler::Fail;
373 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
374 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
375 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
378 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
381 const void *Decoder) {
383 return MCDisassembler::Fail;
387 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
390 const void *Decoder) {
393 return MCDisassembler::Fail;
395 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
396 Inst.addOperand(MCOperand::CreateReg(Reg));
397 return MCDisassembler::Success;
400 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
403 const void *Decoder) {
405 return MCDisassembler::Fail;
406 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
407 Inst.addOperand(MCOperand::CreateReg(Reg));
408 return MCDisassembler::Success;
411 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
414 const void *Decoder) {
415 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
416 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
418 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
421 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
424 const void *Decoder) {
425 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
428 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
431 const void *Decoder) {
433 return MCDisassembler::Fail;
435 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
436 Inst.addOperand(MCOperand::CreateReg(Reg));
437 return MCDisassembler::Success;
440 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
443 const void *Decoder) {
445 return MCDisassembler::Fail;
447 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
448 Inst.addOperand(MCOperand::CreateReg(Reg));
449 return MCDisassembler::Success;
452 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
455 const void *Decoder) {
457 return MCDisassembler::Fail;
459 unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
460 Inst.addOperand(MCOperand::CreateReg(Reg));
461 return MCDisassembler::Success;
464 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
467 const void *Decoder) {
469 return MCDisassembler::Fail;
470 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
471 Inst.addOperand(MCOperand::CreateReg(Reg));
472 return MCDisassembler::Success;
475 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
478 const void *Decoder) {
480 return MCDisassembler::Fail;
481 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
482 Inst.addOperand(MCOperand::CreateReg(Reg));
483 return MCDisassembler::Success;
486 static DecodeStatus DecodeMem(MCInst &Inst,
489 const void *Decoder) {
490 int Offset = SignExtend32<16>(Insn & 0xffff);
491 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
492 unsigned Base = fieldFromInstruction(Insn, 21, 5);
494 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
495 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
497 if(Inst.getOpcode() == Mips::SC){
498 Inst.addOperand(MCOperand::CreateReg(Reg));
501 Inst.addOperand(MCOperand::CreateReg(Reg));
502 Inst.addOperand(MCOperand::CreateReg(Base));
503 Inst.addOperand(MCOperand::CreateImm(Offset));
505 return MCDisassembler::Success;
508 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
511 const void *Decoder) {
512 int Offset = SignExtend32<12>(Insn & 0x0fff);
513 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
514 unsigned Base = fieldFromInstruction(Insn, 16, 5);
516 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
517 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
519 Inst.addOperand(MCOperand::CreateReg(Reg));
520 Inst.addOperand(MCOperand::CreateReg(Base));
521 Inst.addOperand(MCOperand::CreateImm(Offset));
523 return MCDisassembler::Success;
526 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
529 const void *Decoder) {
530 int Offset = SignExtend32<16>(Insn & 0xffff);
531 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
532 unsigned Base = fieldFromInstruction(Insn, 16, 5);
534 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
535 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
537 Inst.addOperand(MCOperand::CreateReg(Reg));
538 Inst.addOperand(MCOperand::CreateReg(Base));
539 Inst.addOperand(MCOperand::CreateImm(Offset));
541 return MCDisassembler::Success;
544 static DecodeStatus DecodeFMem(MCInst &Inst,
547 const void *Decoder) {
548 int Offset = SignExtend32<16>(Insn & 0xffff);
549 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
550 unsigned Base = fieldFromInstruction(Insn, 21, 5);
552 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
553 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
555 Inst.addOperand(MCOperand::CreateReg(Reg));
556 Inst.addOperand(MCOperand::CreateReg(Base));
557 Inst.addOperand(MCOperand::CreateImm(Offset));
559 return MCDisassembler::Success;
563 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
566 const void *Decoder) {
567 // Currently only hardware register 29 is supported.
569 return MCDisassembler::Fail;
570 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
571 return MCDisassembler::Success;
574 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
577 const void *Decoder) {
578 if (RegNo > 30 || RegNo %2)
579 return MCDisassembler::Fail;
582 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
583 Inst.addOperand(MCOperand::CreateReg(Reg));
584 return MCDisassembler::Success;
587 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
590 const void *Decoder) {
592 return MCDisassembler::Fail;
594 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
595 Inst.addOperand(MCOperand::CreateReg(Reg));
596 return MCDisassembler::Success;
599 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
602 const void *Decoder) {
604 return MCDisassembler::Fail;
606 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
607 Inst.addOperand(MCOperand::CreateReg(Reg));
608 return MCDisassembler::Success;
611 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
614 const void *Decoder) {
616 return MCDisassembler::Fail;
618 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
619 Inst.addOperand(MCOperand::CreateReg(Reg));
620 return MCDisassembler::Success;
623 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
626 const void *Decoder) {
627 unsigned BranchOffset = Offset & 0xffff;
628 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
629 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
630 return MCDisassembler::Success;
633 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
636 const void *Decoder) {
638 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
639 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
640 return MCDisassembler::Success;
644 static DecodeStatus DecodeSimm16(MCInst &Inst,
647 const void *Decoder) {
648 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
649 return MCDisassembler::Success;
652 static DecodeStatus DecodeInsSize(MCInst &Inst,
655 const void *Decoder) {
656 // First we need to grab the pos(lsb) from MCInst.
657 int Pos = Inst.getOperand(2).getImm();
658 int Size = (int) Insn - Pos + 1;
659 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
660 return MCDisassembler::Success;
663 static DecodeStatus DecodeExtSize(MCInst &Inst,
666 const void *Decoder) {
667 int Size = (int) Insn + 1;
668 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
669 return MCDisassembler::Success;