aboutsummaryrefslogtreecommitdiff
path: root/target/i386/tcg/translate.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2022-09-18 09:52:24 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2022-09-19 15:16:00 +0200
commitca4b1b43bc5ac25c56a3a7a4a2252d6fdc8dcf02 (patch)
treedc74ed91f4801fe548cf36d1476f5b4f224c2b9d /target/i386/tcg/translate.c
parent034668c329bb3e257a1f259571bd462938522e7a (diff)
target/i386: fix INSERTQ implementation
INSERTQ is defined to not modify any bits in the lower 64 bits of the destination, other than the ones being replaced with bits from the source operand. QEMU instead is using unshifted bits from the source for those bits. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target/i386/tcg/translate.c')
-rw-r--r--target/i386/tcg/translate.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 8ec91d17af..5f31a59fb8 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -3506,10 +3506,20 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
gen_helper_extrq_i(cpu_env, s->ptr0,
tcg_const_i32(bit_index),
tcg_const_i32(field_length));
- else
- gen_helper_insertq_i(cpu_env, s->ptr0,
+ else {
+ if (mod != 3) {
+ gen_lea_modrm(env, s, modrm);
+ op2_offset = offsetof(CPUX86State, xmm_t0);
+ gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
+ } else {
+ rm = (modrm & 7) | REX_B(s);
+ op2_offset = ZMM_OFFSET(rm);
+ }
+ tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
+ gen_helper_insertq_i(cpu_env, s->ptr0, s->ptr1,
tcg_const_i32(bit_index),
tcg_const_i32(field_length));
+ }
}
break;
case 0x7e: /* movd ea, mm */