namespace {
-/// A disasembler class for Mips.
+/// A disassembler class for Mips.
class MipsDisassemblerBase : public MCDisassembler {
public:
MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
bool IsBigEndian;
};
-/// A disasembler class for Mips32.
+/// A disassembler class for Mips32.
class MipsDisassembler : public MipsDisassemblerBase {
bool IsMicroMips;
public:
raw_ostream &CStream) const override;
};
-/// A disasembler class for Mips64.
+/// A disassembler class for Mips64.
class Mips64Disassembler : public MipsDisassemblerBase {
public:
Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
+
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
uint64_t Address,
const void *Decoder);
+// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
+// shifted left by 1 bit.
+static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
+ unsigned Offset,
+ uint64_t Address,
+ const void *Decoder);
+
// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
// shifted left by 1 bit.
static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeCacheOpR6(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
+
static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
unsigned Insn,
uint64_t Address,
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
+
+static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
+
static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
unsigned Insn,
uint64_t Address,
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
+
static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
unsigned Insn,
uint64_t Address,
static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
+
/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
/// handle.
template <typename InsnType>
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
+
namespace llvm {
extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
TheMips64elTarget;
return MCDisassembler::Success;
}
+static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 7)
+ return MCDisassembler::Fail;
+ unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeCacheOpR6(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder) {
+ int Offset = fieldFromInstruction(Insn, 7, 9);
+ unsigned Hint = fieldFromInstruction(Insn, 16, 5);
+ unsigned Base = fieldFromInstruction(Insn, 21, 5);
+
+ Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
+
+ Inst.addOperand(MCOperand::CreateReg(Base));
+ Inst.addOperand(MCOperand::CreateImm(Offset));
+ Inst.addOperand(MCOperand::CreateImm(Hint));
+
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeSyncI(MCInst &Inst,
unsigned Insn,
uint64_t Address,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder) {
+ unsigned Offset = Insn & 0x7F;
+ unsigned Reg = fieldFromInstruction(Insn, 7, 3);
+
+ Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
+
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::CreateReg(Mips::GP));
+ Inst.addOperand(MCOperand::CreateImm(Offset << 2));
+
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder) {
+ int Offset = SignExtend32<4>(Insn & 0xf);
+
+ if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
+ == MCDisassembler::Fail)
+ return MCDisassembler::Fail;
+
+ Inst.addOperand(MCOperand::CreateReg(Mips::SP));
+ Inst.addOperand(MCOperand::CreateImm(Offset << 2));
+
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
unsigned Insn,
uint64_t Address,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder) {
+ int Offset = SignExtend32<11>(Insn & 0x07ff);
+ unsigned Reg = fieldFromInstruction(Insn, 16, 5);
+ unsigned Base = fieldFromInstruction(Insn, 11, 5);
+
+ Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
+ Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
+
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::CreateReg(Base));
+ Inst.addOperand(MCOperand::CreateImm(Offset));
+
+ return MCDisassembler::Success;
+}
static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
unsigned Insn,
uint64_t Address,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
+ unsigned Offset,
+ uint64_t Address,
+ const void *Decoder) {
+ int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
+ Inst.addOperand(MCOperand::CreateImm(BranchOffset));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
unsigned Offset,
uint64_t Address,
uint64_t Address,
const void *Decoder) {
unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
- unsigned RegNum;
-
unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
- // Empty register lists are not allowed.
- if (RegLst == 0)
- return MCDisassembler::Fail;
+ unsigned RegNum = RegLst & 0x3;
- RegNum = RegLst & 0x3;
- for (unsigned i = 0; i < RegNum - 1; i++)
+ for (unsigned i = 0; i <= RegNum; i++)
Inst.addOperand(MCOperand::CreateReg(Regs[i]));
Inst.addOperand(MCOperand::CreateReg(Mips::RA));
return MCDisassembler::Success;
}
+
+static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder) {
+
+ unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
+
+ switch (RegPair) {
+ default:
+ return MCDisassembler::Fail;
+ case 0:
+ Inst.addOperand(MCOperand::CreateReg(Mips::A1));
+ Inst.addOperand(MCOperand::CreateReg(Mips::A2));
+ break;
+ case 1:
+ Inst.addOperand(MCOperand::CreateReg(Mips::A1));
+ Inst.addOperand(MCOperand::CreateReg(Mips::A3));
+ break;
+ case 2:
+ Inst.addOperand(MCOperand::CreateReg(Mips::A2));
+ Inst.addOperand(MCOperand::CreateReg(Mips::A3));
+ break;
+ case 3:
+ Inst.addOperand(MCOperand::CreateReg(Mips::A0));
+ Inst.addOperand(MCOperand::CreateReg(Mips::S5));
+ break;
+ case 4:
+ Inst.addOperand(MCOperand::CreateReg(Mips::A0));
+ Inst.addOperand(MCOperand::CreateReg(Mips::S6));
+ break;
+ case 5:
+ Inst.addOperand(MCOperand::CreateReg(Mips::A0));
+ Inst.addOperand(MCOperand::CreateReg(Mips::A1));
+ break;
+ case 6:
+ Inst.addOperand(MCOperand::CreateReg(Mips::A0));
+ Inst.addOperand(MCOperand::CreateReg(Mips::A2));
+ break;
+ case 7:
+ Inst.addOperand(MCOperand::CreateReg(Mips::A0));
+ Inst.addOperand(MCOperand::CreateReg(Mips::A3));
+ break;
+ }
+
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder) {
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<23>(Insn) << 2));
+ return MCDisassembler::Success;
+}