@@ -271,16 +271,23 @@ typedef struct X86DecodedOp {
bool has_ea;
int offset; /* For MMX and SSE */
- /*
- * This field is used internally by macros OP0_PTR/OP1_PTR/OP2_PTR,
- * do not access directly!
- */
- TCGv_ptr v_ptr;
+ union {
+ target_ulong imm;
+ /*
+ * This field is used internally by macros OP0_PTR/OP1_PTR/OP2_PTR,
+ * do not access directly!
+ */
+ TCGv_ptr v_ptr;
+ };
} X86DecodedOp;
struct X86DecodedInsn {
X86OpEntry e;
X86DecodedOp op[3];
+ /*
+ * Rightmost immediate, for convenience since most instructions have
+ * one (and also for 4-operand instructions).
+ */
target_ulong immediate;
AddressParts mem;
@@ -1473,7 +1473,7 @@ static bool decode_op(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode,
case X86_TYPE_I: /* Immediate */
case X86_TYPE_J: /* Relative offset for a jump */
op->unit = X86_OP_IMM;
- decode->immediate = insn_get_signed(env, s, op->ot);
+ decode->immediate = op->imm = insn_get_signed(env, s, op->ot);
break;
case X86_TYPE_L: /* The upper 4 bits of the immediate select a 128-bit register */
@@ -259,7 +259,7 @@ static void gen_load(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
}
break;
case X86_OP_IMM:
- tcg_gen_movi_tl(v, decode->immediate);
+ tcg_gen_movi_tl(v, op->imm);
break;
case X86_OP_MMX:
@@ -283,6 +283,8 @@ static void gen_load(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
static TCGv_ptr op_ptr(X86DecodedInsn *decode, int opn)
{
X86DecodedOp *op = &decode->op[opn];
+
+ assert(op->unit == X86_OP_MMX || op->unit == X86_OP_SSE);
if (op->v_ptr) {
return op->v_ptr;
}