diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-10-12 09:23:39 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-10-24 15:27:19 +0200 |
commit | 620abfb004543404bef1953e25da2ad77352941a (patch) | |
tree | 1268f6527bb2357d6011ba215d804311851d3e81 | |
parent | 03514ac25c40ec3f2ffc493f1862ddd1353419f8 (diff) |
target-i386: fix 32-bit addresses in LEA
This was found with test-i386. The issue is that instructions
such as
addr32 lea (%eax), %rax
did not perform a 32-bit extension, because the LEA translation
skipped the gen_lea_v_seg step. That step does not just add
segments, it also takes care of extending from address size to
pointer size.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | target-i386/translate.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c index 9447557911..23fde58547 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -457,13 +457,12 @@ static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0, #endif case MO_32: /* 32 bit address */ + if (ovr_seg < 0 && s->addseg) { + ovr_seg = def_seg; + } if (ovr_seg < 0) { - if (s->addseg) { - ovr_seg = def_seg; - } else { - tcg_gen_ext32u_tl(cpu_A0, a0); - return; - } + tcg_gen_ext32u_tl(cpu_A0, a0); + return; } break; case MO_16: @@ -5372,7 +5371,8 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, { AddressParts a = gen_lea_modrm_0(env, s, modrm); TCGv ea = gen_lea_modrm_1(a); - gen_op_mov_reg_v(dflag, reg, ea); + gen_lea_v_seg(s, s->aflag, ea, -1, -1); + gen_op_mov_reg_v(dflag, reg, cpu_A0); } break; |