Esempio n. 1
0
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;
}
Esempio n. 2
0
void Mips_printInst(MCInst *MI, SStream *O, void *info)
{
	switch (MCInst_getOpcode(MI)) {
		default: break;
		case Mips_RDHWR:
		case Mips_RDHWR64:
			SStream_concat(O, ".set\tpush\n");
			SStream_concat(O, ".set\tmips32r2\n");
			break;
		case Mips_Save16:
			SStream_concat(O, "\tsave\t");
			printSaveRestore(MI, O);
			SStream_concat(O, " # 16 bit inst\n");
			return;
		case Mips_SaveX16:
			SStream_concat(O, "\tsave\t");
			printSaveRestore(MI, O);
			SStream_concat(O, "\n");
			return;
		case Mips_Restore16:
			SStream_concat(O, "\trestore\t");
			printSaveRestore(MI, O);
			SStream_concat(O, " # 16 bit inst\n");
			return;
		case Mips_RestoreX16:
			SStream_concat(O, "\trestore\t");
			printSaveRestore(MI, O);
			SStream_concat(O, "\n");
			return;
	}

	// Try to print any aliases first.
	if (!printAliasInstr(MI, O, info) && !printAlias(MI, O))
		printInstruction(MI, O, NULL);
	else {
		// fixup instruction id due to the change in alias instruction
		char *mnem = cs_strdup(O->buffer);
		char *tab = strchr(mnem, '\t');
		if (tab)
			*tab = '\0';

		// reflect the new insn name (alias) in the opcode
		unsigned id = Mips_map_insn(mnem);
		MCInst_setOpcode(MI, Mips_get_insn_id2(id));
		MCInst_setOpcodePub(MI, id);
		cs_mem_free(mnem);
	}

	switch (MCInst_getOpcode(MI)) {
		default: break;
		case Mips_RDHWR:
		case Mips_RDHWR64:
			SStream_concat(O, "\n.set\tpop");
			break;
	}
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
static DecodeStatus DecodeL5RInstructionFail(MCInst *Inst, unsigned Insn, uint64_t Address,
        void *Decoder)
{
    unsigned Opcode;

    // Try and decode as a L6R instruction.
    MCInst_clear(Inst);
    Opcode = fieldFromInstruction_4(Insn, 27, 5);
    switch (Opcode) {
    default:
        break;
    case 0x00:
        MCInst_setOpcode(Inst, XCore_LMUL_l6r);
        return DecodeL6RInstruction(Inst, Insn, Address, Decoder);
    }

    return MCDisassembler_Fail;
}
Esempio n. 5
0
void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
{
	//if (TSFlags & X86II::LOCK)
	//  O << "\tlock\n";

	if (printAliasInstr(MI, O)) {
		char *mnem = cs_strdup(O->buffer);
		char *tab = strchr(mnem, '\t');
		if (tab)
			*tab = '\0';
		// reflect the new insn name (alias) in the opcode
		MCInst_setOpcode(MI, X86_get_insn_id2(X86_map_insn(mnem)));
		cs_mem_free(mnem);
	} else
		printInstruction(MI, O, NULL);

	if (MI->csh->detail) {
		char tmp[64];
		if (get_first_op(O->buffer, tmp)) {
			int post;
			char *acc_regs[] = { "al", "ax", "eax", "rax", NULL };
			unsigned int acc_regs_id[] = { X86_REG_AL,  X86_REG_AX, X86_REG_EAX, X86_REG_RAX };
			if (tmp[0] != 0 && ((post = str_in_list(acc_regs, tmp)) != -1)) {
				// first op is register, so set operand size following register size
				MI->flat_insn.x86.op_size = 1 << post;
				// tmp is a register
				if ((MI->flat_insn.x86.operands[0].type != X86_OP_INVALID) &&
						((MI->flat_insn.x86.operands[0].type != X86_OP_REG) ||
						(MI->flat_insn.x86.operands[0].reg != acc_regs_id[post]))) {
					// first op is register, so insert its detail to position 0
					int i;
					for (i = MI->flat_insn.x86.op_count; i > 0; i--) {
						memcpy(&(MI->flat_insn.x86.operands[i]), &(MI->flat_insn.x86.operands[i - 1]),
								sizeof(MI->flat_insn.x86.operands[0]));
					}
					MI->flat_insn.x86.operands[0].type = X86_OP_REG;
					MI->flat_insn.x86.operands[0].reg = x86_map_regname(tmp);
					MI->flat_insn.x86.op_count++;
				}
			}
		}
	}
}
Esempio n. 6
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;

	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 || type == TYPE_IMMv) {
		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 (
#ifndef CAPSTONE_X86_REDUCE
						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 &&
#endif
						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;
		}
	} else if (type == TYPE_IMM3) {
#ifndef CAPSTONE_X86_REDUCE
		// Check for immediates that printSSECC can't handle.
		if (immediate >= 8) {
			unsigned NewOpc = 0;

			switch (MCInst_getOpcode(mcInst)) {
				default: break;	// never reach
				case X86_CMPPDrmi: NewOpc = X86_CMPPDrmi_alt; break;
				case X86_CMPPDrri: NewOpc = X86_CMPPDrri_alt; break;
				case X86_CMPPSrmi: NewOpc = X86_CMPPSrmi_alt; break;
				case X86_CMPPSrri: NewOpc = X86_CMPPSrri_alt; break;
				case X86_CMPSDrm:  NewOpc = X86_CMPSDrm_alt;  break;
				case X86_CMPSDrr:  NewOpc = X86_CMPSDrr_alt;  break;
				case X86_CMPSSrm:  NewOpc = X86_CMPSSrm_alt;  break;
				case X86_CMPSSrr:  NewOpc = X86_CMPSSrr_alt;  break;
			}
			// Switch opcode to the one that doesn't get special printing.
			MCInst_setOpcode(mcInst, NewOpc);
		}
#endif
	} else if (type == TYPE_IMM5) {
#ifndef CAPSTONE_X86_REDUCE
		// Check for immediates that printAVXCC can't handle.
		if (immediate >= 32) {
			unsigned NewOpc = 0;

			switch (MCInst_getOpcode(mcInst)) {
				default: break; // unexpected opcode
				case X86_VCMPPDrmi:  NewOpc = X86_VCMPPDrmi_alt;  break;
				case X86_VCMPPDrri:  NewOpc = X86_VCMPPDrri_alt;  break;
				case X86_VCMPPSrmi:  NewOpc = X86_VCMPPSrmi_alt;  break;
				case X86_VCMPPSrri:  NewOpc = X86_VCMPPSrri_alt;  break;
				case X86_VCMPSDrm:   NewOpc = X86_VCMPSDrm_alt;   break;
				case X86_VCMPSDrr:   NewOpc = X86_VCMPSDrr_alt;   break;
				case X86_VCMPSSrm:   NewOpc = X86_VCMPSSrm_alt;   break;
				case X86_VCMPSSrr:   NewOpc = X86_VCMPSSrr_alt;   break;
				case X86_VCMPPDYrmi: NewOpc = X86_VCMPPDYrmi_alt; break;
				case X86_VCMPPDYrri: NewOpc = X86_VCMPPDYrri_alt; break;
				case X86_VCMPPSYrmi: NewOpc = X86_VCMPPSYrmi_alt; break;
				case X86_VCMPPSYrri: NewOpc = X86_VCMPPSYrri_alt; break;
				case X86_VCMPPDZrmi: NewOpc = X86_VCMPPDZrmi_alt; break;
				case X86_VCMPPDZrri: NewOpc = X86_VCMPPDZrri_alt; break;
				case X86_VCMPPSZrmi: NewOpc = X86_VCMPPSZrmi_alt; break;
				case X86_VCMPPSZrri: NewOpc = X86_VCMPPSZrri_alt; break;
				case X86_VCMPSDZrm:  NewOpc = X86_VCMPSDZrmi_alt; break;
				case X86_VCMPSDZrr:  NewOpc = X86_VCMPSDZrri_alt; break;
				case X86_VCMPSSZrm:  NewOpc = X86_VCMPSSZrmi_alt; break;
				case X86_VCMPSSZrr:  NewOpc = X86_VCMPSSZrri_alt; break;
			}
			// Switch opcode to the one that doesn't get special printing.
			MCInst_setOpcode(mcInst, NewOpc);
		}
#endif
	}

	switch (type) {
		case TYPE_XMM32:
		case TYPE_XMM64:
		case TYPE_XMM128:
			MCOperand_CreateReg0(mcInst, X86_XMM0 + ((uint32_t)immediate >> 4));
			return;
		case TYPE_XMM256:
			MCOperand_CreateReg0(mcInst, X86_YMM0 + ((uint32_t)immediate >> 4));
			return;
		case TYPE_XMM512:
			MCOperand_CreateReg0(mcInst, 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;
	}

	MCOperand_CreateImm0(mcInst, immediate);

	if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 ||
			type == TYPE_MOFFS32 || type == TYPE_MOFFS64) {
		MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
	}
}
Esempio n. 7
0
static DecodeStatus DecodeL2OpInstructionFail(MCInst *Inst, unsigned Insn, uint64_t Address,
        void *Decoder)
{
    // Try and decode as a L3R / L2RUS instruction.
    unsigned Opcode = fieldFromInstruction_4(Insn, 16, 4) |
                      fieldFromInstruction_4(Insn, 27, 5) << 4;
    switch (Opcode) {
    case 0x0c:
        MCInst_setOpcode(Inst, XCore_STW_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x1c:
        MCInst_setOpcode(Inst, XCore_XOR_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x2c:
        MCInst_setOpcode(Inst, XCore_ASHR_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x3c:
        MCInst_setOpcode(Inst, XCore_LDAWF_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x4c:
        MCInst_setOpcode(Inst, XCore_LDAWB_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x5c:
        MCInst_setOpcode(Inst, XCore_LDA16F_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x6c:
        MCInst_setOpcode(Inst, XCore_LDA16B_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x7c:
        MCInst_setOpcode(Inst, XCore_MUL_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x8c:
        MCInst_setOpcode(Inst, XCore_DIVS_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x9c:
        MCInst_setOpcode(Inst, XCore_DIVU_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x10c:
        MCInst_setOpcode(Inst, XCore_ST16_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x11c:
        MCInst_setOpcode(Inst, XCore_ST8_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x12c:
        MCInst_setOpcode(Inst, XCore_ASHR_l2rus);
        return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder);
    case 0x12d:
        MCInst_setOpcode(Inst, XCore_OUTPW_l2rus);
        return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder);
    case 0x12e:
        MCInst_setOpcode(Inst, XCore_INPW_l2rus);
        return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder);
    case 0x13c:
        MCInst_setOpcode(Inst, XCore_LDAWF_l2rus);
        return DecodeL2RUSInstruction(Inst, Insn, Address, Decoder);
    case 0x14c:
        MCInst_setOpcode(Inst, XCore_LDAWB_l2rus);
        return DecodeL2RUSInstruction(Inst, Insn, Address, Decoder);
    case 0x15c:
        MCInst_setOpcode(Inst, XCore_CRC_l3r);
        return DecodeL3RSrcDstInstruction(Inst, Insn, Address, Decoder);
    case 0x18c:
        MCInst_setOpcode(Inst, XCore_REMS_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    case 0x19c:
        MCInst_setOpcode(Inst, XCore_REMU_l3r);
        return DecodeL3RInstruction(Inst, Insn, Address, Decoder);
    }

    return MCDisassembler_Fail;
}
Esempio n. 8
0
static DecodeStatus Decode2OpInstructionFail(MCInst *Inst, unsigned Insn, uint64_t Address,
        void *Decoder)
{
    // Try and decode as a 3R instruction.
    unsigned Opcode = fieldFromInstruction_4(Insn, 11, 5);
    switch (Opcode) {
    case 0x0:
        MCInst_setOpcode(Inst, XCore_STW_2rus);
        return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
    case 0x1:
        MCInst_setOpcode(Inst, XCore_LDW_2rus);
        return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
    case 0x2:
        MCInst_setOpcode(Inst, XCore_ADD_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x3:
        MCInst_setOpcode(Inst, XCore_SUB_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x4:
        MCInst_setOpcode(Inst, XCore_SHL_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x5:
        MCInst_setOpcode(Inst, XCore_SHR_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x6:
        MCInst_setOpcode(Inst, XCore_EQ_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x7:
        MCInst_setOpcode(Inst, XCore_AND_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x8:
        MCInst_setOpcode(Inst, XCore_OR_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x9:
        MCInst_setOpcode(Inst, XCore_LDW_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x10:
        MCInst_setOpcode(Inst, XCore_LD16S_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x11:
        MCInst_setOpcode(Inst, XCore_LD8U_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x12:
        MCInst_setOpcode(Inst, XCore_ADD_2rus);
        return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
    case 0x13:
        MCInst_setOpcode(Inst, XCore_SUB_2rus);
        return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
    case 0x14:
        MCInst_setOpcode(Inst, XCore_SHL_2rus);
        return Decode2RUSBitpInstruction(Inst, Insn, Address, Decoder);
    case 0x15:
        MCInst_setOpcode(Inst, XCore_SHR_2rus);
        return Decode2RUSBitpInstruction(Inst, Insn, Address, Decoder);
    case 0x16:
        MCInst_setOpcode(Inst, XCore_EQ_2rus);
        return Decode2RUSInstruction(Inst, Insn, Address, Decoder);
    case 0x17:
        MCInst_setOpcode(Inst, XCore_TSETR_3r);
        return Decode3RImmInstruction(Inst, Insn, Address, Decoder);
    case 0x18:
        MCInst_setOpcode(Inst, XCore_LSS_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    case 0x19:
        MCInst_setOpcode(Inst, XCore_LSU_3r);
        return Decode3RInstruction(Inst, Insn, Address, Decoder);
    }

    return MCDisassembler_Fail;
}