target-i386: Fix ucomis and comis memory access

We were loading 16 bytes for both single and double-precision
scalar comparisons.

Reported-by: Alexander Bluhm <bluhm@openbsd.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
(cherry picked from commit cb48da7f81)

Conflicts:
	target-i386/translate.c

*removed dependency on 323d1876

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
This commit is contained in:
Richard Henderson 2014-02-24 15:53:40 -08:00 committed by Michael Roth
parent 2e191f8e54
commit 6be38ee9e7
1 changed files with 36 additions and 10 deletions

View File

@ -4565,21 +4565,47 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
if (is_xmm) {
op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
if (mod != 3) {
int sz = 4;
gen_lea_modrm(env, s, modrm, &reg_addr, &offset_addr);
op2_offset = offsetof(CPUX86State,xmm_t0);
if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
b == 0xc2)) {
/* specific case for SSE single instructions */
switch (b) {
case 0x50 ... 0x5a:
case 0x5c ... 0x5f:
case 0xc2:
/* Most sse scalar operations. */
if (b1 == 2) {
/* 32 bit access */
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
} else {
/* 64 bit access */
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
sz = 2;
} else if (b1 == 3) {
sz = 3;
}
} else {
break;
case 0x2e: /* ucomis[sd] */
case 0x2f: /* comis[sd] */
if (b1 == 0) {
sz = 2;
} else {
sz = 3;
}
break;
}
switch (sz) {
case 2:
/* 32 bit access */
gen_op_ld_T0_A0(OT_LONG + s->mem_index);
tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
break;
case 3:
/* 64 bit access */
gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
break;
default:
/* 128 bit access */
gen_ldo_env_A0(s->mem_index, op2_offset);
break;
}
} else {
rm = (modrm & 7) | REX_B(s);