Example #1
0
static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address,
		const void *Decoder)
{
	DecodeStatus status;
	unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
	unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
	unsigned rs2 = 0;
	unsigned simm13 = 0;
	if (isImm)
		simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
	else
		rs2 = fieldFromInstruction_4(insn, 0, 5);

	// Decode RS1.
	status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
	if (status != MCDisassembler_Success)
		return status;

	// Decode RS2 | SIMM13.
	if (isImm)
		MCInst_addOperand(MI, MCOperand_CreateImm(simm13));
	else {
		status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
		if (status != MCDisassembler_Success)
			return status;
	}

	return MCDisassembler_Success;
}
Example #2
0
static DecodeStatus DecodeExtSize(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
	int Size = (int) Insn  + 1;
	MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Size, 16)));
	return MCDisassembler_Success;
}
Example #3
0
static DecodeStatus DecodeBranchTargetMM(MCInst *Inst,
		unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder)
{
	unsigned BranchOffset = Offset & 0xffff;
	BranchOffset = SignExtend32(BranchOffset << 1, 18);
	MCInst_addOperand(Inst, MCOperand_CreateImm(BranchOffset));
	return MCDisassembler_Success;
}
Example #4
0
static DecodeStatus DecodeSIMM13(MCInst *MI, unsigned insn,
		uint64_t Address, const void *Decoder)
{
	unsigned tgt = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);

	MCInst_addOperand(MI, MCOperand_CreateImm(tgt));

	return MCDisassembler_Success;
}
Example #5
0
static DecodeStatus DecodeInsSize(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
	// First we need to grab the pos(lsb) from MCInst.
	int Pos = MCOperand_getImm(MCInst_getOperand(Inst, 2));
	int Size = (int) Insn - Pos + 1;
	MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Size, 16)));
	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;
}
Example #7
0
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;
}
Example #8
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;
}
Example #9
0
static DecodeStatus DecodeMem(MCInst *MI, unsigned insn, uint64_t Address,
		const void *Decoder,
		bool isLoad, DecodeFunc DecodeRD)
{
	DecodeStatus status;
	unsigned rd = fieldFromInstruction_4(insn, 25, 5);
	unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
	bool isImm = fieldFromInstruction_4(insn, 13, 1);
	unsigned rs2 = 0;
	unsigned simm13 = 0;

	if (isImm)
		simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
	else
		rs2 = fieldFromInstruction_4(insn, 0, 5);

	if (isLoad) {
		status = DecodeRD(MI, rd, Address, Decoder);
		if (status != MCDisassembler_Success)
			return status;
	}

	// Decode rs1.
	status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
	if (status != MCDisassembler_Success)
		return status;

	// Decode imm|rs2.
	if (isImm)
		MCInst_addOperand(MI, MCOperand_CreateImm(simm13));
	else {
		status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
		if (status != MCDisassembler_Success)
			return status;
	}

	if (!isLoad) {
		status = DecodeRD(MI, rd, Address, Decoder);
		if (status != MCDisassembler_Success)
			return status;
	}

	return MCDisassembler_Success;
}
Example #10
0
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;
}
Example #11
0
static void printS5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
	Value = SignExtend32(Value, 5);

	if (Value >= 0) {
		if (Value > HEX_THRESHOLD)
			SStream_concat(O, "0x%x", Value);
		else
			SStream_concat(O, "%u", Value);
	} else {
		if (Value < -HEX_THRESHOLD)
			SStream_concat(O, "-0x%x", -Value);
		else
			SStream_concat(O, "-%u", -Value);
	}

	if (MI->csh->detail) {
		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
		MI->flat_insn->detail->ppc.op_count++;
	}
}
Example #12
0
static void printOperand(MCInst *MI, int opNum, SStream *O)
{
	int Imm;
	unsigned reg;
	MCOperand *MO = MCInst_getOperand(MI, opNum);

	if (MCOperand_isReg(MO)) {
		reg = MCOperand_getReg(MO);
		printRegName(O, reg);
		reg = Sparc_map_register(reg);

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				if (MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base)
					MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.index = reg;
				else
					MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = reg;
			} else {
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG;
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg;
				MI->flat_insn->detail->sparc.op_count++;
			}
		}

		return;
	}

	if (MCOperand_isImm(MO)) {
		Imm = (int)MCOperand_getImm(MO);

		// Conditional branches displacements needs to be signextended to be
		// able to jump backwards.
		//
		// Displacements are measured as the number of instructions forward or
		// backward, so they need to be multiplied by 4
		switch (MI->Opcode) {
			case SP_CALL:
				Imm = SignExtend32(Imm, 30);
				Imm += (uint32_t)MI->address;
				break;

			// Branch on integer condition with prediction (BPcc)
			// Branch on floating point condition with prediction (FBPfcc)
			case SP_BPICC:
			case SP_BPICCA:
			case SP_BPICCANT:
			case SP_BPICCNT:
			case SP_BPXCC:
			case SP_BPXCCA:
			case SP_BPXCCANT:
			case SP_BPXCCNT:
			case SP_BPFCC:
			case SP_BPFCCA:
			case SP_BPFCCANT:
			case SP_BPFCCNT:
				Imm = SignExtend32(Imm, 19);
				Imm = (uint32_t)MI->address + Imm * 4;
				break;

			// Branch on integer condition (Bicc)
			// Branch on floating point condition (FBfcc)
			case SP_BA:
			case SP_BCOND:
			case SP_BCONDA:
			case SP_FBCOND:
			case SP_FBCONDA:
				Imm = SignExtend32(Imm, 22);
				Imm = (uint32_t)MI->address + Imm * 4;
				break;

			// Branch on integer register with prediction (BPr)
			case SP_BPGEZapn:
			case SP_BPGEZapt:
			case SP_BPGEZnapn:
			case SP_BPGEZnapt:
			case SP_BPGZapn:
			case SP_BPGZapt:
			case SP_BPGZnapn:
			case SP_BPGZnapt:
			case SP_BPLEZapn:
			case SP_BPLEZapt:
			case SP_BPLEZnapn:
			case SP_BPLEZnapt:
			case SP_BPLZapn:
			case SP_BPLZapt:
			case SP_BPLZnapn:
			case SP_BPLZnapt:
			case SP_BPNZapn:
			case SP_BPNZapt:
			case SP_BPNZnapn:
			case SP_BPNZnapt:
			case SP_BPZapn:
			case SP_BPZapt:
			case SP_BPZnapn:
			case SP_BPZnapt:
				Imm = SignExtend32(Imm, 16);
				Imm = (uint32_t)MI->address + Imm * 4;
				break;
		}

		if (Imm >= 0) {
			if (Imm > HEX_THRESHOLD)
				SStream_concat(O, "0x%x", Imm);
			else
				SStream_concat(O, "%u", Imm);
		} else {
			if (Imm < -HEX_THRESHOLD)
				SStream_concat(O, "-0x%x", -Imm);
			else
				SStream_concat(O, "-%u", -Imm);
		}

		if (MI->csh->detail) {
			if (MI->csh->doing_mem) {
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = Imm;
			} else {
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_IMM;
				MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].imm = Imm;
				MI->flat_insn->detail->sparc.op_count++;
			}
		}
	}

	return;
}