From e5b84c6d5915bc3ce35a9f1532bbc3b715c2ea54 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Sun, 4 Mar 2018 01:41:37 -0500 Subject: [PATCH] target/i386: set rip_offset for some SSE4.1 instructions When emulating various SSE4.1 instructions such as pinsrd, the address of a memory operand is computed without allowing for the 8-bit immediate operand located after the memory operand, meaning that the memory operand uses the wrong address in the case where it is rip-relative. This patch adds the required rip_offset setting for those instructions, so fixing some GCC test failures (13 in the gcc testsuite in my GCC 6-based testing) when testing with a default CPU setting enabling those instructions. Backports commit ab6ab3e9972a49a359f59895a88bed311472ca97 from qemu --- qemu/qom/cpu.c | 8 ++++---- qemu/target/i386/translate.c | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qemu/qom/cpu.c b/qemu/qom/cpu.c index a78df8b8..fa7aa78a 100644 --- a/qemu/qom/cpu.c +++ b/qemu/qom/cpu.c @@ -76,14 +76,14 @@ out: void *cpu_alloc_env(CPUState *cpu) { - CPUClass *cc = CPU_GET_CLASS(cpu); + CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu); return cc->alloc_env ? cc->alloc_env(cpu) : NULL; } void cpu_get_env(CPUState *cpu, void *env) { - CPUClass *cc = CPU_GET_CLASS(cpu); + CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu); if (cc->get_env) { cc->get_env(cpu, env); @@ -92,7 +92,7 @@ void cpu_get_env(CPUState *cpu, void *env) void cpu_set_env(CPUState *cpu, void *env) { - CPUClass *cc = CPU_GET_CLASS(cpu); + CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu); if (cc->set_env) { cc->set_env(cpu, env); @@ -101,7 +101,7 @@ void cpu_set_env(CPUState *cpu, void *env) void cpu_free_env(CPUState *cpu, void *env) { - CPUClass *cc = CPU_GET_CLASS(cpu); + CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu); if (cc->free_env) { cc->free_env(cpu, env); diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index 74da7f71..2c6a9744 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -4646,6 +4646,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, if (sse_fn_eppi == SSE_SPECIAL) { ot = mo_64_32(s->dflag); rm = (modrm & 7) | REX_B(s); + s->rip_offset = 1; if (mod != 3) gen_lea_modrm(env, s, modrm); reg = ((modrm >> 3) & 7) | rex_r;