Beispiel #1
0
static DecodeStatus DecodeHWRegsRegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
{
	// Currently only hardware register 29 is supported.
	if (RegNo != 29)
		return  MCDisassembler_Fail;
	MCInst_addOperand(Inst, MCOperand_CreateReg(Mips_HWR29));
	return MCDisassembler_Success;
}
Beispiel #2
0
static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst,
		unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
{
	if (RegNo > 31)
		return MCDisassembler_Fail;
	unsigned Reg = getReg(Decoder, Mips_GPR32RegClassID, RegNo);
	MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
	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 DecodeFCCRegsRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	if (RegNo > 3)
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateReg(FCCRegDecoderTable[RegNo]));

	return MCDisassembler_Success;
}
static DecodeStatus DecodeMem(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_GPR32RegClassID, Reg);
	Base = getReg(Decoder, Mips_GPR32RegClassID, Base);

	if(MCInst_getOpcode(Inst) == Mips_SC){
		MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
	}

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

	return MCDisassembler_Success;
}
Beispiel #6
0
/// translateRegister - Translates an internal register to the appropriate LLVM
///   register, and appends it as an operand to an MCInst.
///
/// @param mcInst     - The MCInst to append to.
/// @param reg        - The Reg to append.
static void translateRegister(MCInst *mcInst, Reg reg)
{
//#define ENTRY(x) X86_x,
#define ENTRY(x) X86_##x,
	uint8_t llvmRegnums[] = {
		ALL_REGS
			0
	};
#undef ENTRY

	uint8_t llvmRegnum = llvmRegnums[reg];
	MCInst_addOperand(mcInst, MCOperand_CreateReg(llvmRegnum));
}
Beispiel #7
0
/// translateSrcIndex   - Appends a source index operand to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param insn         - The internal instruction.
static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)
{
	unsigned baseRegNo;
	MCOperand *segmentReg;
	MCOperand *baseReg;

	if (insn->mode == MODE_64BIT)
		baseRegNo = insn->prefixPresent[0x67] ? X86_ESI : X86_RSI;
	else if (insn->mode == MODE_32BIT)
		baseRegNo = insn->prefixPresent[0x67] ? X86_SI : X86_ESI;
	else {
		// assert(insn->mode == MODE_16BIT);
		baseRegNo = insn->prefixPresent[0x67] ? X86_ESI : X86_SI;
	}

	baseReg = MCOperand_CreateReg(baseRegNo);
	MCInst_addOperand(mcInst, baseReg);

	segmentReg = MCOperand_CreateReg(segmentRegnums[insn->segmentOverride]);
	MCInst_addOperand(mcInst, segmentReg);

	return false;
}
static DecodeStatus DecodeQFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
		uint64_t Address, const void *Decoder)
{
	unsigned Reg;

	if (RegNo > 31)
		return MCDisassembler_Fail;

	Reg = QFPRegDecoderTable[RegNo];
	if (Reg == ~0U)
		return MCDisassembler_Fail;

	MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));

	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;
}
Beispiel #10
0
/// translateDstIndex   - Appends a destination index operand to an MCInst.
///
/// @param mcInst       - The MCInst to append to.
/// @param insn         - The internal instruction.
static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn)
{
	unsigned baseRegNo;
	MCOperand *baseReg;

	if (insn->mode == MODE_64BIT)
		baseRegNo = insn->prefixPresent[0x67] ? X86_EDI : X86_RDI;
	else if (insn->mode == MODE_32BIT)
		baseRegNo = insn->prefixPresent[0x67] ? X86_DI : X86_EDI;
	else {
		// assert(insn->mode == MODE_16BIT);
		baseRegNo = insn->prefixPresent[0x67] ? X86_EDI : X86_DI;
	}

	baseReg = MCOperand_CreateReg(baseRegNo);
	MCInst_addOperand(mcInst, baseReg);

	return false;
}
Beispiel #11
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;
}
Beispiel #12
0
static DecodeStatus DecodeSimm16(MCInst *Inst,
		unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
{
	MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Insn, 16)));
	return MCDisassembler_Success;
}
Beispiel #13
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);
	}
}