static DecodeStatus DecodeDaddiGroupBranch_4(MCInst *MI, uint32_t insn,
		uint64_t Address, MCRegisterInfo *Decoder)
{
	// If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
	// (otherwise we would have matched the ADDI instruction from the earlier
	// ISA's instead).
	//
	// We have:
	//    0b011000 sssss ttttt iiiiiiiiiiiiiiii
	//      BNVC if rs >= rt
	//      BNEZALC if rs == 0 && rt != 0
	//      BNEC if rs < rt && rs != 0

	uint32_t Rs = fieldFromInstruction(insn, 21, 5);
	uint32_t Rt = fieldFromInstruction(insn, 16, 5);
	uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
	bool HasRs = false;

	if (Rs >= Rt) {
		MCInst_setOpcode(MI, Mips_BNVC);
		HasRs = true;
	} else if (Rs != 0 && Rs < Rt) {
		MCInst_setOpcode(MI, Mips_BNEC);
		HasRs = true;
	} else
		MCInst_setOpcode(MI, Mips_BNEZALC);

	if (HasRs)
		MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs));

	MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt));
	MCOperand_CreateImm0(MI, Imm);

	return MCDisassembler_Success;
}
static DecodeStatus DecodeINSVE_DF_4(MCInst *MI, uint32_t insn,
		uint64_t Address, MCRegisterInfo *Decoder)
{
	typedef DecodeStatus (*DecodeFN)(MCInst *, unsigned, uint64_t, MCRegisterInfo *);
	// The size of the n field depends on the element size
	// The register class also depends on this.
	uint32_t tmp = fieldFromInstruction(insn, 17, 5);
	unsigned NSize = 0;
	DecodeFN RegDecoder = NULL;

	if ((tmp & 0x18) == 0x00) { // INSVE_B
		NSize = 4;
		RegDecoder = DecodeMSA128BRegisterClass;
	} else if ((tmp & 0x1c) == 0x10) { // INSVE_H
		NSize = 3;
		RegDecoder = DecodeMSA128HRegisterClass;
	} else if ((tmp & 0x1e) == 0x18) { // INSVE_W
		NSize = 2;
		RegDecoder = DecodeMSA128WRegisterClass;
	} else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
		NSize = 1;
		RegDecoder = DecodeMSA128DRegisterClass;
	} //else llvm_unreachable("Invalid encoding");

	//assert(NSize != 0 && RegDecoder != nullptr);

	if (RegDecoder == NULL)
		return MCDisassembler_Fail;

	// $wd
	tmp = fieldFromInstruction(insn, 6, 5);
	if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
		return MCDisassembler_Fail;

	// $wd_in
	if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
		return MCDisassembler_Fail;

	// $n
	tmp = fieldFromInstruction(insn, 16, NSize);
	MCOperand_CreateImm0(MI, tmp);

	// $ws
	tmp = fieldFromInstruction(insn, 11, 5);
	if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
		return MCDisassembler_Fail;

	// $n2
	MCOperand_CreateImm0(MI, 0);

	return MCDisassembler_Success;
}
static DecodeStatus DecodeCachePref(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
	int Offset = SignExtend32(Insn & 0xffff, 16);
	unsigned Hint = fieldFromInstruction(Insn, 16, 5);
	unsigned Base = fieldFromInstruction(Insn, 21, 5);

	Base = getReg(Decoder, Mips_GPR32RegClassID, Base);

	MCOperand_CreateReg0(Inst, Base);
	MCOperand_CreateImm0(Inst, Offset);
	MCOperand_CreateImm0(Inst, Hint);

	return MCDisassembler_Success;
}
static DecodeStatus DecodeJumpTargetMM(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
	unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
	MCInst_addOperand(Inst, MCOperand_CreateImm(JumpOffset));
	return MCDisassembler_Success;
}
static DecodeStatus DecodeFMem(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
	int Offset = SignExtend32(Insn & 0xffff, 16);
	unsigned Reg = fieldFromInstruction(Insn, 16, 5);
	unsigned Base = fieldFromInstruction(Insn, 21, 5);

	Reg = getReg(Decoder, Mips_FGR64RegClassID, Reg);
	Base = getReg(Decoder, Mips_GPR32RegClassID, Base);

	MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
	MCInst_addOperand(Inst, MCOperand_CreateReg(Base));
	MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));

	return MCDisassembler_Success;
}
Beispiel #6
0
static DecodeStatus DecodeMSA128Mem(MCInst *Inst, unsigned Insn,
		uint64_t Address, MCRegisterInfo *Decoder)
{
	int Offset = SignExtend32(fieldFromInstruction(Insn, 16, 10), 10);
	unsigned Reg = fieldFromInstruction(Insn, 6, 5);
	unsigned Base = fieldFromInstruction(Insn, 11, 5);

	Reg = getReg(Decoder, Mips_MSA128BRegClassID, Reg);
	Base = getReg(Decoder, Mips_GPR32RegClassID, Base);

	MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
	MCInst_addOperand(Inst, MCOperand_CreateReg(Base));
	// MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));

	// The immediate field of an LD/ST instruction is scaled which means it must
	// be multiplied (when decoding) by the size (in bytes) of the instructions'
	// data format.
	// .b - 1 byte
	// .h - 2 bytes
	// .w - 4 bytes
	// .d - 8 bytes
	switch(MCInst_getOpcode(Inst))
	{
		default:
			//assert (0 && "Unexpected instruction");
			return MCDisassembler_Fail;
			break;
		case Mips_LD_B:
		case Mips_ST_B:
			MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));
			break;
		case Mips_LD_H:
		case Mips_ST_H:
			MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 1));
			break;
		case Mips_LD_W:
		case Mips_ST_W:
			MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 2));
			break;
		case Mips_LD_D:
		case Mips_ST_D:
			MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 3));
			break;
	}

	return MCDisassembler_Success;
}
static DecodeStatus DecodeMemMMImm12(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
	int Offset = SignExtend32(Insn & 0x0fff, 12);
	unsigned Reg = fieldFromInstruction(Insn, 21, 5);
	unsigned Base = fieldFromInstruction(Insn, 16, 5);

	Reg = getReg(Decoder, Mips_GPR32RegClassID, Reg);
	Base = getReg(Decoder, Mips_GPR32RegClassID, Base);

	if (MCInst_getOpcode(Inst) == Mips_SC_MM)
		MCOperand_CreateReg0(Inst, Reg);

	MCOperand_CreateReg0(Inst, Reg);
	MCOperand_CreateReg0(Inst, Base);
	MCOperand_CreateImm0(Inst, Offset);

	return MCDisassembler_Success;
}
static DecodeStatus DecodeBgtzlGroupBranch_4(MCInst *MI, uint32_t insn,
		uint64_t Address, MCRegisterInfo *Decoder)
{
	// If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
	// (otherwise we would have matched the BGTZL instruction from the earlier
	// ISA's instead).
	//
	// We have:
	//    0b010111 sssss ttttt iiiiiiiiiiiiiiii
	//      Invalid if rs == 0
	//      BGTZC   if rs == 0  && rt != 0
	//      BLTZC   if rs == rt && rt != 0
	//      BLTC    if rs != rt && rs != 0  && rt != 0

	bool HasRs = false;

	uint32_t Rs = fieldFromInstruction(insn, 21, 5);
	uint32_t Rt = fieldFromInstruction(insn, 16, 5);
	uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;

	if (Rt == 0)
		return MCDisassembler_Fail;
	else if (Rs == 0)
		MCInst_setOpcode(MI, Mips_BGTZC);
	else if (Rs == Rt)
		MCInst_setOpcode(MI, Mips_BLTZC);
	else {
		MCInst_setOpcode(MI, Mips_BLTC);
		HasRs = true;
	}

	if (HasRs)
		MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs));

	MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt));
	MCOperand_CreateImm0(MI, Imm);

	return MCDisassembler_Success;
}
	Reg = getReg(Decoder, Mips_COP3RegClassID, Reg);
	Base = getReg(Decoder, Mips_GPR32RegClassID, Base);

	MCOperand_CreateReg0(Inst, Reg);
	MCOperand_CreateReg0(Inst, Base);
	MCOperand_CreateImm0(Inst, Offset);

	return MCDisassembler_Success;
}

static DecodeStatus DecodeSpecial3LlSc(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
	int64_t Offset = SignExtend64((Insn >> 7) & 0x1ff, 9);
	unsigned Rt = fieldFromInstruction(Insn, 16, 5);
	unsigned Base = fieldFromInstruction(Insn, 21, 5);

	Rt = getReg(Decoder, Mips_GPR32RegClassID, Rt);
	Base = getReg(Decoder, Mips_GPR32RegClassID, Base);

	if (MCInst_getOpcode(Inst) == Mips_SC_R6 ||
			MCInst_getOpcode(Inst) == Mips_SCD_R6) {
		MCOperand_CreateReg0(Inst, Rt);
	}

	MCOperand_CreateReg0(Inst, Rt);
	MCOperand_CreateReg0(Inst, Base);
	MCOperand_CreateImm0(Inst, Offset);

	return MCDisassembler_Success;