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;
}
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;
}
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;
}
Exemple #4
0
static DecodeStatus DecodeLSAImm(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
  // We add one to the immediate field as it was encoded as 'imm - 1'.
  MCInst_addOperand(Inst, MCOperand_CreateImm(Insn + 1));
  return MCDisassembler_Success;
}
Exemple #5
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 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;
}
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;
}
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 DecodeCall(MCInst *MI, unsigned insn,
		uint64_t Address, const void *Decoder)
{
	unsigned tgt = fieldFromInstruction_4(insn, 0, 30);
	tgt <<= 2;

	MCInst_addOperand(MI, MCOperand_CreateImm(tgt));

	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;
}
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;
}
Exemple #12
0
/// translateImmediate  - Appends an immediate operand to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param immediate    - The immediate value to append.
/// @param operand      - The operand, as stored in the descriptor table.
/// @param insn         - The internal instruction.
static void translateImmediate(MCInst *mcInst, uint64_t immediate,
		const OperandSpecifier *operand, InternalInstruction *insn)
{
	OperandType type;
	MCOperand *segmentReg;

	type = (OperandType)operand->type;
	if (type == TYPE_RELv) {
		//isBranch = true;
		//pcrel = insn->startLocation + insn->immediateOffset + insn->immediateSize;
		switch (insn->displacementSize) {
			case 1:
				if (immediate & 0x80)
					immediate |= ~(0xffull);
				break;
			case 2:
				if (immediate & 0x8000)
					immediate |= ~(0xffffull);
				break;
			case 4:
				if (immediate & 0x80000000)
					immediate |= ~(0xffffffffull);
				break;
			case 8:
				break;
			default:
				break;
		}
	} // By default sign-extend all X86 immediates based on their encoding.
	else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 ||
			type == TYPE_IMM64) {
		uint32_t Opcode = MCInst_getOpcode(mcInst);
		switch (operand->encoding) {
			default:
				break;
			case ENCODING_IB:
				// Special case those X86 instructions that use the imm8 as a set of
				// bits, bit count, etc. and are not sign-extend.
				if (Opcode != X86_BLENDPSrri && Opcode != X86_BLENDPDrri &&
						Opcode != X86_PBLENDWrri && Opcode != X86_MPSADBWrri &&
						Opcode != X86_DPPSrri && Opcode != X86_DPPDrri &&
						Opcode != X86_INSERTPSrr && Opcode != X86_VBLENDPSYrri &&
						Opcode != X86_VBLENDPSYrmi && Opcode != X86_VBLENDPDYrri &&
						Opcode != X86_VBLENDPDYrmi && Opcode != X86_VPBLENDWrri &&
						Opcode != X86_VMPSADBWrri && Opcode != X86_VDPPSYrri &&
						Opcode != X86_VDPPSYrmi && Opcode != X86_VDPPDrri &&
						Opcode != X86_VINSERTPSrr && Opcode != X86_INT)
					if(immediate & 0x80)
						immediate |= ~(0xffull);
				break;
			case ENCODING_IW:
				if(immediate & 0x8000)
					immediate |= ~(0xffffull);
				break;
			case ENCODING_ID:
				if(immediate & 0x80000000)
					immediate |= ~(0xffffffffull);
				break;
			case ENCODING_IO:
				break;
		}
	}

	switch (type) {
		case TYPE_XMM32:
		case TYPE_XMM64:
		case TYPE_XMM128:
			MCInst_addOperand(mcInst, MCOperand_CreateReg(X86_XMM0 + ((uint32_t)immediate >> 4)));
			return;
		case TYPE_XMM256:
			MCInst_addOperand(mcInst, MCOperand_CreateReg(X86_YMM0 + ((uint32_t)immediate >> 4)));
			return;
		case TYPE_XMM512:
			MCInst_addOperand(mcInst, MCOperand_CreateReg(X86_ZMM0 + ((uint32_t)immediate >> 4)));
			return;
		case TYPE_REL8:
			if(immediate & 0x80)
				immediate |= ~(0xffull);
			break;
		case TYPE_REL32:
		case TYPE_REL64:
			if(immediate & 0x80000000)
				immediate |= ~(0xffffffffull);
			break;
		default:
			// operand is 64 bits wide.  Do nothing.
			break;
	}

	MCInst_addOperand(mcInst, MCOperand_CreateImm(immediate));

	if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 ||
			type == TYPE_MOFFS32 || type == TYPE_MOFFS64) {
		segmentReg = MCOperand_CreateReg(segmentRegnums[insn->segmentOverride]);
		MCInst_addOperand(mcInst, segmentReg);
	}
}