diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/i386/tcg/translate.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 849c40b..097c895 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -3888,6 +3888,12 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, gen_ldo_env_A0(s, op2_offset); } } + if (!op6->op[b1]) { + goto illegal_op; + } + tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); + tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); + op6->op[b1](cpu_env, s->ptr0, s->ptr1); } else { if ((op6->flags & SSE_OPF_MMX) == 0) { goto unknown_op; @@ -3900,15 +3906,11 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, op2_offset); } - } - if (!op6->op[b1]) { - goto illegal_op; + tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); + tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); + op6->op[0](cpu_env, s->ptr0, s->ptr1); } - tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); - tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); - op6->op[b1](cpu_env, s->ptr0, s->ptr1); - if (op6->flags & SSE_OPF_CMP) { set_cc_op(s, CC_OP_EFLAGS); } @@ -4427,16 +4429,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, return; } - if (b1) { - op1_offset = ZMM_OFFSET(reg); - if (mod == 3) { - op2_offset = ZMM_OFFSET(rm | REX_B(s)); - } else { - op2_offset = offsetof(CPUX86State,xmm_t0); - gen_lea_modrm(env, s, modrm); - gen_ldo_env_A0(s, op2_offset); - } - } else { + if (b1 == 0) { + /* MMX */ if ((op7->flags & SSE_OPF_MMX) == 0) { goto illegal_op; } @@ -4448,9 +4442,29 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, op2_offset); } + val = x86_ldub_code(env, s); + tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset); + tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); + + /* We only actually have one MMX instuction (palignr) */ + assert(b == 0x0f); + + op7->op[0](cpu_env, s->ptr0, s->ptr1, + tcg_const_i32(val)); + break; } - val = x86_ldub_code(env, s); + /* SSE */ + op1_offset = ZMM_OFFSET(reg); + if (mod == 3) { + op2_offset = ZMM_OFFSET(rm | REX_B(s)); + } else { + op2_offset = offsetof(CPUX86State, xmm_t0); + gen_lea_modrm(env, s, modrm); + gen_ldo_env_A0(s, op2_offset); + } + + val = x86_ldub_code(env, s); if ((b & 0xfc) == 0x60) { /* pcmpXstrX */ set_cc_op(s, CC_OP_EFLAGS); |