* [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups
@ 2015-12-17 19:19 Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 01/10] target-i386: Create gen_lea_v_seg Richard Henderson
` (9 more replies)
0 siblings, 10 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
This is a rebase of the patch set I posted in July. There are no
substantive changes since then.
The only comment at the time was re 05/10, where Paolo suggests
optimizing access to CS overrides with the constant that we know
via the TB operands. I chose to defer that, leaving things as
they are with a simple load from ENV.
r~
Richard Henderson (10):
target-i386: Create gen_lea_v_seg
target-i386: Introduce mo_stacksize
target-i386: Use gen_lea_v_seg in gen_lea_modrm
target-i386: Use gen_lea_v_seg in stack subroutines
target-i386: Access segs via TCG registers
target-i386: Use gen_lea_v_seg in pusha/popa
target-i386: Rewrite gen_enter inline
target-i386: Rewrite leave
target-i386: Tidy gen_add_A0_im
target-i386: Deconstruct the cpu_T array
target-i386/helper.h | 4 -
target-i386/seg_helper.c | 74 --
target-i386/translate.c | 1714 +++++++++++++++++++++-------------------------
3 files changed, 776 insertions(+), 1016 deletions(-)
--
2.5.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 01/10] target-i386: Create gen_lea_v_seg
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 02/10] target-i386: Introduce mo_stacksize Richard Henderson
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
Add forgotten zero-extension in the TARGET_X86_64, !CODE64, ss32 case;
use this new function to implement gen_string_movl_A0_EDI,
gen_string_movl_A0_ESI, gen_add_A0_ds_seg.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/translate.c | 160 ++++++++++++++++--------------------------------
1 file changed, 53 insertions(+), 107 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index a3dd167..3cc17f7 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -416,64 +416,18 @@ static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
gen_op_mov_reg_v(size, reg, cpu_tmp0);
}
-static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
-{
- tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
- if (shift != 0)
- tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
- /* For x86_64, this sets the higher half of register to zero.
- For i386, this is equivalent to a nop. */
- tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
-}
-
-static inline void gen_op_movl_A0_seg(int reg)
-{
- tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base) + REG_L_OFFSET);
-}
-
static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)
{
tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
-#ifdef TARGET_X86_64
if (CODE64(s)) {
- tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
+ tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
} else {
tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
- tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
+ tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
}
-#else
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
-#endif
}
-#ifdef TARGET_X86_64
-static inline void gen_op_movq_A0_seg(int reg)
-{
- tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base));
-}
-
-static inline void gen_op_addq_A0_seg(int reg)
-{
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
-}
-
-static inline void gen_op_movq_A0_reg(int reg)
-{
- tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
-}
-
-static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
-{
- tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
- if (shift != 0)
- tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
-}
-#endif
-
static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
{
tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
@@ -499,70 +453,78 @@ static inline void gen_jmp_im(target_ulong pc)
gen_op_jmp_v(cpu_tmp0);
}
-static inline void gen_string_movl_A0_ESI(DisasContext *s)
+/* Compute SEG:REG into A0. SEG is selected from the override segment
+ (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
+ indicate no override. */
+static void gen_lea_v_seg(DisasContext *s, TCGv a0, int def_seg, int ovr_seg)
{
- int override;
+ TCGMemOp aflag = s->aflag;
- override = s->override;
- switch (s->aflag) {
+ switch (aflag) {
#ifdef TARGET_X86_64
case MO_64:
- if (override >= 0) {
- gen_op_movq_A0_seg(override);
- gen_op_addq_A0_reg_sN(0, R_ESI);
- } else {
- gen_op_movq_A0_reg(R_ESI);
+ if (ovr_seg < 0) {
+ tcg_gen_mov_tl(cpu_A0, a0);
+ return;
}
break;
#endif
case MO_32:
/* 32 bit address */
- if (s->addseg && override < 0)
- override = R_DS;
- if (override >= 0) {
- gen_op_movl_A0_seg(override);
- gen_op_addl_A0_reg_sN(0, R_ESI);
- } else {
- gen_op_movl_A0_reg(R_ESI);
+ if (ovr_seg < 0) {
+ if (s->addseg) {
+ ovr_seg = def_seg;
+ } else {
+ tcg_gen_ext32u_tl(cpu_A0, a0);
+ return;
+ }
}
break;
case MO_16:
- /* 16 address, always override */
- if (override < 0)
- override = R_DS;
- tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_ESI]);
- gen_op_addl_A0_seg(s, override);
+ /* 16 bit address */
+ if (ovr_seg < 0) {
+ ovr_seg = def_seg;
+ }
+ tcg_gen_ext16u_tl(cpu_A0, a0);
+ /* ADDSEG will only be false in 16-bit mode for LEA. */
+ if (!s->addseg) {
+ return;
+ }
+ a0 = cpu_A0;
break;
default:
tcg_abort();
}
-}
-static inline void gen_string_movl_A0_EDI(DisasContext *s)
-{
- switch (s->aflag) {
-#ifdef TARGET_X86_64
- case MO_64:
- gen_op_movq_A0_reg(R_EDI);
- break;
-#endif
- case MO_32:
- if (s->addseg) {
- gen_op_movl_A0_seg(R_ES);
- gen_op_addl_A0_reg_sN(0, R_EDI);
+ if (ovr_seg >= 0) {
+ TCGv seg = tcg_temp_new();
+
+ tcg_gen_ld_tl(seg, cpu_env, offsetof(CPUX86State, segs[ovr_seg].base));
+
+ if (aflag == MO_64) {
+ tcg_gen_add_tl(cpu_A0, a0, seg);
+ } else if (CODE64(s)) {
+ tcg_gen_ext32u_tl(cpu_A0, a0);
+ tcg_gen_add_tl(cpu_A0, cpu_A0, seg);
} else {
- gen_op_movl_A0_reg(R_EDI);
+ tcg_gen_add_tl(cpu_A0, a0, seg);
+ tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
}
- break;
- case MO_16:
- tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_EDI]);
- gen_op_addl_A0_seg(s, R_ES);
- break;
- default:
- tcg_abort();
+
+ tcg_temp_free(seg);
}
}
+static inline void gen_string_movl_A0_ESI(DisasContext *s)
+{
+ gen_lea_v_seg(s, cpu_regs[R_ESI], R_DS, s->override);
+}
+
+static inline void gen_string_movl_A0_EDI(DisasContext *s)
+{
+ gen_lea_v_seg(s, cpu_regs[R_EDI], R_ES, -1);
+}
+
static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
{
tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df));
@@ -2118,23 +2080,7 @@ static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
/* used for LEA and MOV AX, mem */
static void gen_add_A0_ds_seg(DisasContext *s)
{
- int override, must_add_seg;
- must_add_seg = s->addseg;
- override = R_DS;
- if (s->override >= 0) {
- override = s->override;
- must_add_seg = 1;
- }
- if (must_add_seg) {
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- gen_op_addq_A0_seg(override);
- } else
-#endif
- {
- gen_op_addl_A0_seg(s, override);
- }
- }
+ gen_lea_v_seg(s, cpu_A0, R_DS, s->override);
}
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 02/10] target-i386: Introduce mo_stacksize
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 01/10] target-i386: Create gen_lea_v_seg Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 03/10] target-i386: Use gen_lea_v_seg in gen_lea_modrm Richard Henderson
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
Centralize computation of a MO_SIZE for the stack pointer.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/translate.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 3cc17f7..e0df5c0 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -307,6 +307,12 @@ static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
}
}
+/* Select the size of the stack pointer. */
+static inline TCGMemOp mo_stacksize(DisasContext *s)
+{
+ return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
+}
+
/* Select only size 64 else 32. Used for SSE operand sizes. */
static inline TCGMemOp mo_64_32(TCGMemOp ot)
{
@@ -2292,31 +2298,22 @@ gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
static inline void gen_stack_update(DisasContext *s, int addend)
{
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- gen_op_add_reg_im(MO_64, R_ESP, addend);
- } else
-#endif
- if (s->ss32) {
- gen_op_add_reg_im(MO_32, R_ESP, addend);
- } else {
- gen_op_add_reg_im(MO_16, R_ESP, addend);
- }
+ gen_op_add_reg_im(mo_stacksize(s), R_ESP, addend);
}
/* Generate a push. It depends on ss32, addseg and dflag. */
static void gen_push_v(DisasContext *s, TCGv val)
{
- TCGMemOp a_ot, d_ot = mo_pushpop(s, s->dflag);
+ TCGMemOp d_ot = mo_pushpop(s, s->dflag);
+ TCGMemOp a_ot = mo_stacksize(s);
int size = 1 << d_ot;
TCGv new_esp = cpu_A0;
tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
if (CODE64(s)) {
- a_ot = MO_64;
+ /* No special handling. */
} else if (s->ss32) {
- a_ot = MO_32;
if (s->addseg) {
new_esp = cpu_tmp4;
tcg_gen_mov_tl(new_esp, cpu_A0);
@@ -2325,7 +2322,6 @@ static void gen_push_v(DisasContext *s, TCGv val)
tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
}
} else {
- a_ot = MO_16;
new_esp = cpu_tmp4;
tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
tcg_gen_mov_tl(new_esp, cpu_A0);
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 03/10] target-i386: Use gen_lea_v_seg in gen_lea_modrm
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 01/10] target-i386: Create gen_lea_v_seg Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 02/10] target-i386: Introduce mo_stacksize Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 04/10] target-i386: Use gen_lea_v_seg in stack subroutines Richard Henderson
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
Centralize handling of segment bases.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/translate.c | 82 ++++++++++++++-----------------------------------
1 file changed, 23 insertions(+), 59 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index e0df5c0..0a86c63 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -1844,17 +1844,12 @@ static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
{
target_long disp;
- int havesib;
- int base;
- int index;
- int scale;
- int mod, rm, code, override, must_add_seg;
+ int havesib, base, index, scale;
+ int mod, rm, code, def_seg, ovr_seg;
TCGv sum;
- override = s->override;
- must_add_seg = s->addseg;
- if (override >= 0)
- must_add_seg = 1;
+ def_seg = R_DS;
+ ovr_seg = s->override;
mod = (modrm >> 6) & 3;
rm = modrm & 7;
@@ -1924,61 +1919,34 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
}
if (TCGV_IS_UNUSED(sum)) {
tcg_gen_movi_tl(cpu_A0, disp);
- } else {
+ sum = cpu_A0;
+ } else if (disp != 0) {
tcg_gen_addi_tl(cpu_A0, sum, disp);
+ sum = cpu_A0;
}
- if (must_add_seg) {
- if (override < 0) {
- if (base == R_EBP || base == R_ESP) {
- override = R_SS;
- } else {
- override = R_DS;
- }
- }
-
- tcg_gen_ld_tl(cpu_tmp0, cpu_env,
- offsetof(CPUX86State, segs[override].base));
- if (CODE64(s)) {
- if (s->aflag == MO_32) {
- tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
- }
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
- return;
- }
-
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
- }
-
- if (s->aflag == MO_32) {
- tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
+ if (base == R_EBP || base == R_ESP) {
+ def_seg = R_SS;
}
break;
case MO_16:
- switch (mod) {
- case 0:
+ sum = cpu_A0;
+ if (mod == 0) {
if (rm == 6) {
disp = cpu_lduw_code(env, s->pc);
s->pc += 2;
tcg_gen_movi_tl(cpu_A0, disp);
- rm = 0; /* avoid SS override */
- goto no_rm;
- } else {
- disp = 0;
+ break;
}
- break;
- case 1:
+ disp = 0;
+ } else if (mod == 1) {
disp = (int8_t)cpu_ldub_code(env, s->pc++);
- break;
- default:
- case 2:
+ } else {
disp = (int16_t)cpu_lduw_code(env, s->pc);
s->pc += 2;
- break;
}
- sum = cpu_A0;
switch (rm) {
case 0:
tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBX], cpu_regs[R_ESI]);
@@ -1988,9 +1956,11 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
break;
case 2:
tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_ESI]);
+ def_seg = R_SS;
break;
case 3:
tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_EDI]);
+ def_seg = R_SS;
break;
case 4:
sum = cpu_regs[R_ESI];
@@ -2000,30 +1970,24 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
break;
case 6:
sum = cpu_regs[R_EBP];
+ def_seg = R_SS;
break;
default:
case 7:
sum = cpu_regs[R_EBX];
break;
}
- tcg_gen_addi_tl(cpu_A0, sum, disp);
- tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
- no_rm:
- if (must_add_seg) {
- if (override < 0) {
- if (rm == 2 || rm == 3 || rm == 6) {
- override = R_SS;
- } else {
- override = R_DS;
- }
- }
- gen_op_addl_A0_seg(s, override);
+ if (disp != 0) {
+ tcg_gen_addi_tl(cpu_A0, sum, disp);
+ sum = cpu_A0;
}
break;
default:
tcg_abort();
}
+
+ gen_lea_v_seg(s, sum, def_seg, ovr_seg);
}
static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 04/10] target-i386: Use gen_lea_v_seg in stack subroutines
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
` (2 preceding siblings ...)
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 03/10] target-i386: Use gen_lea_v_seg in gen_lea_modrm Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 05/10] target-i386: Access segs via TCG registers Richard Henderson
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
I.e. gen_push_v, gen_pop_T0, gen_stack_A0.
More centralization of handling of segment bases.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/translate.c | 52 +++++++++++++------------------------------------
1 file changed, 13 insertions(+), 39 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 0a86c63..1e6dccd 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -462,10 +462,9 @@ static inline void gen_jmp_im(target_ulong pc)
/* Compute SEG:REG into A0. SEG is selected from the override segment
(OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
indicate no override. */
-static void gen_lea_v_seg(DisasContext *s, TCGv a0, int def_seg, int ovr_seg)
+static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
+ int def_seg, int ovr_seg)
{
- TCGMemOp aflag = s->aflag;
-
switch (aflag) {
#ifdef TARGET_X86_64
case MO_64:
@@ -523,12 +522,12 @@ static void gen_lea_v_seg(DisasContext *s, TCGv a0, int def_seg, int ovr_seg)
static inline void gen_string_movl_A0_ESI(DisasContext *s)
{
- gen_lea_v_seg(s, cpu_regs[R_ESI], R_DS, s->override);
+ gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
}
static inline void gen_string_movl_A0_EDI(DisasContext *s)
{
- gen_lea_v_seg(s, cpu_regs[R_EDI], R_ES, -1);
+ gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
}
static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
@@ -1987,7 +1986,7 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
tcg_abort();
}
- gen_lea_v_seg(s, sum, def_seg, ovr_seg);
+ gen_lea_v_seg(s, s->aflag, sum, def_seg, ovr_seg);
}
static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
@@ -2050,7 +2049,7 @@ static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
/* used for LEA and MOV AX, mem */
static void gen_add_A0_ds_seg(DisasContext *s)
{
- gen_lea_v_seg(s, cpu_A0, R_DS, s->override);
+ gen_lea_v_seg(s, s->aflag, cpu_A0, R_DS, s->override);
}
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
@@ -2275,21 +2274,12 @@ static void gen_push_v(DisasContext *s, TCGv val)
tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
- if (CODE64(s)) {
- /* No special handling. */
- } else if (s->ss32) {
+ if (!CODE64(s)) {
if (s->addseg) {
new_esp = cpu_tmp4;
tcg_gen_mov_tl(new_esp, cpu_A0);
- gen_op_addl_A0_seg(s, R_SS);
- } else {
- tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
}
- } else {
- new_esp = cpu_tmp4;
- tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
- tcg_gen_mov_tl(new_esp, cpu_A0);
- gen_op_addl_A0_seg(s, R_SS);
+ gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
}
gen_op_st_v(s, d_ot, val, cpu_A0);
@@ -2300,37 +2290,21 @@ static void gen_push_v(DisasContext *s, TCGv val)
static TCGMemOp gen_pop_T0(DisasContext *s)
{
TCGMemOp d_ot = mo_pushpop(s, s->dflag);
- TCGv addr = cpu_A0;
- if (CODE64(s)) {
- addr = cpu_regs[R_ESP];
- } else if (!s->ss32) {
- tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_ESP]);
- gen_op_addl_A0_seg(s, R_SS);
- } else if (s->addseg) {
- tcg_gen_mov_tl(cpu_A0, cpu_regs[R_ESP]);
- gen_op_addl_A0_seg(s, R_SS);
- } else {
- tcg_gen_ext32u_tl(cpu_A0, cpu_regs[R_ESP]);
- }
+ gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
+ gen_op_ld_v(s, d_ot, cpu_T[0], cpu_A0);
- gen_op_ld_v(s, d_ot, cpu_T[0], addr);
return d_ot;
}
-static void gen_pop_update(DisasContext *s, TCGMemOp ot)
+static inline void gen_pop_update(DisasContext *s, TCGMemOp ot)
{
gen_stack_update(s, 1 << ot);
}
-static void gen_stack_A0(DisasContext *s)
+static inline void gen_stack_A0(DisasContext *s)
{
- gen_op_movl_A0_reg(R_ESP);
- if (!s->ss32)
- tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
- tcg_gen_mov_tl(cpu_T[1], cpu_A0);
- if (s->addseg)
- gen_op_addl_A0_seg(s, R_SS);
+ gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
}
/* NOTE: wrap around in 16 bit not fully handled */
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 05/10] target-i386: Access segs via TCG registers
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
` (3 preceding siblings ...)
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 04/10] target-i386: Use gen_lea_v_seg in stack subroutines Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 06/10] target-i386: Use gen_lea_v_seg in pusha/popa Richard Henderson
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
Having segs[].base as a register significantly improves code
generation for real and protected modes, particularly for TBs
that have multiple memory references where the segment base
can be held in a hard register through the TB.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/translate.c | 52 ++++++++++++++++++++++++++-----------------------
1 file changed, 28 insertions(+), 24 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 1e6dccd..b346ca5 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -67,6 +67,7 @@ static TCGv cpu_A0;
static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
static TCGv_i32 cpu_cc_op;
static TCGv cpu_regs[CPU_NB_REGS];
+static TCGv cpu_seg_base[6];
/* local temps */
static TCGv cpu_T[2];
/* local register indexes (only used inside old micro ops) */
@@ -424,12 +425,11 @@ static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)
{
- tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
if (CODE64(s)) {
tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
+ tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]);
} else {
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
+ tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]);
tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
}
}
@@ -502,9 +502,7 @@ static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
}
if (ovr_seg >= 0) {
- TCGv seg = tcg_temp_new();
-
- tcg_gen_ld_tl(seg, cpu_env, offsetof(CPUX86State, segs[ovr_seg].base));
+ TCGv seg = cpu_seg_base[ovr_seg];
if (aflag == MO_64) {
tcg_gen_add_tl(cpu_A0, a0, seg);
@@ -515,8 +513,6 @@ static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
tcg_gen_add_tl(cpu_A0, a0, seg);
tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
}
-
- tcg_temp_free(seg);
}
}
@@ -2207,12 +2203,10 @@ static inline void gen_op_movl_T0_seg(int seg_reg)
static inline void gen_op_movl_seg_T0_vm(int seg_reg)
{
- tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
+ tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
tcg_gen_st32_tl(cpu_T[0], cpu_env,
offsetof(CPUX86State,segs[seg_reg].selector));
- tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
- tcg_gen_st_tl(cpu_T[0], cpu_env,
- offsetof(CPUX86State,segs[seg_reg].base));
+ tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T[0], 4);
}
/* move T0 to seg_reg and compute if the CPU state may change. Never
@@ -7277,21 +7271,16 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
if (s->cpl != 0) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
- tcg_gen_ld_tl(cpu_T[0], cpu_env,
- offsetof(CPUX86State,segs[R_GS].base));
- tcg_gen_ld_tl(cpu_T[1], cpu_env,
- offsetof(CPUX86State,kernelgsbase));
- tcg_gen_st_tl(cpu_T[1], cpu_env,
- offsetof(CPUX86State,segs[R_GS].base));
+ tcg_gen_mov_tl(cpu_T[0], cpu_seg_base[R_GS]);
+ tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
+ offsetof(CPUX86State, kernelgsbase));
tcg_gen_st_tl(cpu_T[0], cpu_env,
- offsetof(CPUX86State,kernelgsbase));
+ offsetof(CPUX86State, kernelgsbase));
}
- } else
-#endif
- {
- goto illegal_op;
+ break;
}
- break;
+#endif
+ goto illegal_op;
case 1: /* rdtscp */
if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
goto illegal_op;
@@ -7740,6 +7729,14 @@ void optimize_flags_init(void)
[R_ESP] = "esp",
#endif
};
+ static const char seg_base_names[6][8] = {
+ [R_CS] = "cs_base",
+ [R_DS] = "ds_base",
+ [R_ES] = "es_base",
+ [R_FS] = "fs_base",
+ [R_GS] = "gs_base",
+ [R_SS] = "ss_base",
+ };
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
@@ -7758,6 +7755,13 @@ void optimize_flags_init(void)
reg_names[i]);
}
+ for (i = 0; i < 6; ++i) {
+ cpu_seg_base[i]
+ = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUX86State, segs[i].base),
+ seg_base_names[i]);
+ }
+
helper_lock_init();
}
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 06/10] target-i386: Use gen_lea_v_seg in pusha/popa
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
` (4 preceding siblings ...)
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 05/10] target-i386: Access segs via TCG registers Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 07/10] target-i386: Rewrite gen_enter inline Richard Henderson
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
More centralization of handling of segment bases.
Also fixes the note about 16-bit wrap around not fully handled.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/translate.c | 50 +++++++++++++++++++++++--------------------------
1 file changed, 23 insertions(+), 27 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index b346ca5..4c967f3 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -2301,45 +2301,41 @@ static inline void gen_stack_A0(DisasContext *s)
gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
}
-/* NOTE: wrap around in 16 bit not fully handled */
static void gen_pusha(DisasContext *s)
{
+ TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
+ TCGMemOp d_ot = s->dflag;
+ int size = 1 << d_ot;
int i;
- gen_op_movl_A0_reg(R_ESP);
- gen_op_addl_A0_im(-(8 << s->dflag));
- if (!s->ss32)
- tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
- tcg_gen_mov_tl(cpu_T[1], cpu_A0);
- if (s->addseg)
- gen_op_addl_A0_seg(s, R_SS);
- for(i = 0;i < 8; i++) {
- gen_op_mov_v_reg(MO_32, cpu_T[0], 7 - i);
- gen_op_st_v(s, s->dflag, cpu_T[0], cpu_A0);
- gen_op_addl_A0_im(1 << s->dflag);
+
+ for (i = 0; i < 8; i++) {
+ tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], (i - 8) * size);
+ gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
+ gen_op_st_v(s, d_ot, cpu_regs[7 - i], cpu_A0);
}
- gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]);
+
+ gen_stack_update(s, -8 * size);
}
-/* NOTE: wrap around in 16 bit not fully handled */
static void gen_popa(DisasContext *s)
{
+ TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
+ TCGMemOp d_ot = s->dflag;
+ int size = 1 << d_ot;
int i;
- gen_op_movl_A0_reg(R_ESP);
- if (!s->ss32)
- tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
- tcg_gen_mov_tl(cpu_T[1], cpu_A0);
- tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 8 << s->dflag);
- if (s->addseg)
- gen_op_addl_A0_seg(s, R_SS);
- for(i = 0;i < 8; i++) {
+
+ for (i = 0; i < 8; i++) {
/* ESP is not reloaded */
- if (i != 3) {
- gen_op_ld_v(s, s->dflag, cpu_T[0], cpu_A0);
- gen_op_mov_reg_v(s->dflag, 7 - i, cpu_T[0]);
+ if (7 - i == R_ESP) {
+ continue;
}
- gen_op_addl_A0_im(1 << s->dflag);
+ tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], i * size);
+ gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
+ gen_op_ld_v(s, d_ot, cpu_T[0], cpu_A0);
+ gen_op_mov_reg_v(d_ot, 7 - i, cpu_T[0]);
}
- gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]);
+
+ gen_stack_update(s, 8 * size);
}
static void gen_enter(DisasContext *s, int esp_addend, int level)
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 07/10] target-i386: Rewrite gen_enter inline
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
` (5 preceding siblings ...)
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 06/10] target-i386: Use gen_lea_v_seg in pusha/popa Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 08/10] target-i386: Rewrite leave Richard Henderson
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
Use gen_lea_v_seg for centralized segment base knowledge. Unify
code across 32- and 64-bit. Fix note about "must save state"
before using the out-of-line helpers.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/helper.h | 4 ---
target-i386/seg_helper.c | 74 --------------------------------------
target-i386/translate.c | 93 ++++++++++++++++++------------------------------
3 files changed, 34 insertions(+), 137 deletions(-)
diff --git a/target-i386/helper.h b/target-i386/helper.h
index ecfcfd1..3a25c3b 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -44,10 +44,6 @@ DEF_HELPER_FLAGS_3(set_dr, TCG_CALL_NO_WG, void, env, int, tl)
DEF_HELPER_FLAGS_2(get_dr, TCG_CALL_NO_WG, tl, env, int)
DEF_HELPER_2(invlpg, void, env, tl)
-DEF_HELPER_4(enter_level, void, env, int, int, tl)
-#ifdef TARGET_X86_64
-DEF_HELPER_4(enter64_level, void, env, int, int, tl)
-#endif
DEF_HELPER_1(sysenter, void, env)
DEF_HELPER_2(sysexit, void, env, int)
#ifdef TARGET_X86_64
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 20ee892..51da43b 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1377,80 +1377,6 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return ret;
}
-void helper_enter_level(CPUX86State *env, int level, int data32,
- target_ulong t1)
-{
- target_ulong ssp;
- uint32_t esp_mask, esp, ebp;
-
- esp_mask = get_sp_mask(env->segs[R_SS].flags);
- ssp = env->segs[R_SS].base;
- ebp = env->regs[R_EBP];
- esp = env->regs[R_ESP];
- if (data32) {
- /* 32 bit */
- esp -= 4;
- while (--level) {
- esp -= 4;
- ebp -= 4;
- cpu_stl_data_ra(env, ssp + (esp & esp_mask),
- cpu_ldl_data_ra(env, ssp + (ebp & esp_mask),
- GETPC()),
- GETPC());
- }
- esp -= 4;
- cpu_stl_data_ra(env, ssp + (esp & esp_mask), t1, GETPC());
- } else {
- /* 16 bit */
- esp -= 2;
- while (--level) {
- esp -= 2;
- ebp -= 2;
- cpu_stw_data_ra(env, ssp + (esp & esp_mask),
- cpu_lduw_data_ra(env, ssp + (ebp & esp_mask),
- GETPC()),
- GETPC());
- }
- esp -= 2;
- cpu_stw_data_ra(env, ssp + (esp & esp_mask), t1, GETPC());
- }
-}
-
-#ifdef TARGET_X86_64
-void helper_enter64_level(CPUX86State *env, int level, int data64,
- target_ulong t1)
-{
- target_ulong esp, ebp;
-
- ebp = env->regs[R_EBP];
- esp = env->regs[R_ESP];
-
- if (data64) {
- /* 64 bit */
- esp -= 8;
- while (--level) {
- esp -= 8;
- ebp -= 8;
- cpu_stq_data_ra(env, esp, cpu_ldq_data_ra(env, ebp, GETPC()),
- GETPC());
- }
- esp -= 8;
- cpu_stq_data_ra(env, esp, t1, GETPC());
- } else {
- /* 16 bit */
- esp -= 2;
- while (--level) {
- esp -= 2;
- ebp -= 2;
- cpu_stw_data_ra(env, esp, cpu_lduw_data_ra(env, ebp, GETPC()),
- GETPC());
- }
- esp -= 2;
- cpu_stw_data_ra(env, esp, t1, GETPC());
- }
-}
-#endif
-
void helper_lldt(CPUX86State *env, int selector)
{
SegmentCache *dt;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 4c967f3..b6749ff 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -376,11 +376,6 @@ static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
}
}
-static inline void gen_op_movl_A0_reg(int reg)
-{
- tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
-}
-
static inline void gen_op_addl_A0_im(int32_t val)
{
tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
@@ -423,17 +418,6 @@ static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
gen_op_mov_reg_v(size, reg, cpu_tmp0);
}
-static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)
-{
- if (CODE64(s)) {
- tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]);
- } else {
- tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]);
- tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
- }
-}
-
static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
{
tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
@@ -2340,51 +2324,42 @@ static void gen_popa(DisasContext *s)
static void gen_enter(DisasContext *s, int esp_addend, int level)
{
- TCGMemOp ot = mo_pushpop(s, s->dflag);
- int opsize = 1 << ot;
+ TCGMemOp d_ot = mo_pushpop(s, s->dflag);
+ TCGMemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
+ int size = 1 << d_ot;
- level &= 0x1f;
-#ifdef TARGET_X86_64
- if (CODE64(s)) {
- gen_op_movl_A0_reg(R_ESP);
- gen_op_addq_A0_im(-opsize);
- tcg_gen_mov_tl(cpu_T[1], cpu_A0);
-
- /* push bp */
- gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
- gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
- if (level) {
- /* XXX: must save state */
- gen_helper_enter64_level(cpu_env, tcg_const_i32(level),
- tcg_const_i32((ot == MO_64)),
- cpu_T[1]);
- }
- gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]);
- tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
- gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[1]);
- } else
-#endif
- {
- gen_op_movl_A0_reg(R_ESP);
- gen_op_addl_A0_im(-opsize);
- if (!s->ss32)
- tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
- tcg_gen_mov_tl(cpu_T[1], cpu_A0);
- if (s->addseg)
- gen_op_addl_A0_seg(s, R_SS);
- /* push bp */
- gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
- gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
- if (level) {
- /* XXX: must save state */
- gen_helper_enter_level(cpu_env, tcg_const_i32(level),
- tcg_const_i32(s->dflag - 1),
- cpu_T[1]);
- }
- gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]);
- tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
- gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]);
+ /* Push BP; compute FrameTemp into T1. */
+ tcg_gen_subi_tl(cpu_T[1], cpu_regs[R_ESP], size);
+ gen_lea_v_seg(s, a_ot, cpu_T[1], R_SS, -1);
+ gen_op_st_v(s, d_ot, cpu_regs[R_EBP], cpu_A0);
+
+ level &= 31;
+ if (level != 0) {
+ int i;
+
+ /* Copy level-1 pointers from the previous frame. */
+ for (i = 1; i < level; ++i) {
+ tcg_gen_subi_tl(cpu_A0, cpu_regs[R_EBP], size * i);
+ gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
+ gen_op_ld_v(s, d_ot, cpu_tmp0, cpu_A0);
+
+ tcg_gen_subi_tl(cpu_A0, cpu_T[1], size * i);
+ gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
+ gen_op_st_v(s, d_ot, cpu_tmp0, cpu_A0);
+ }
+
+ /* Push the current FrameTemp as the last level. */
+ tcg_gen_subi_tl(cpu_A0, cpu_T[1], size * level);
+ gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
+ gen_op_st_v(s, d_ot, cpu_T[1], cpu_A0);
}
+
+ /* Copy the FrameTemp value to EBP. */
+ gen_op_mov_reg_v(a_ot, R_EBP, cpu_T[1]);
+
+ /* Compute the final value of ESP. */
+ tcg_gen_subi_tl(cpu_T[1], cpu_T[1], esp_addend + size * level);
+ gen_op_mov_reg_v(a_ot, R_ESP, cpu_T[1]);
}
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 08/10] target-i386: Rewrite leave
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
` (6 preceding siblings ...)
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 07/10] target-i386: Rewrite gen_enter inline Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 09/10] target-i386: Tidy gen_add_A0_im Richard Henderson
2016-02-04 23:44 ` [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
Unify the code across stack pointer widths. Fix the note about
not updating ESP before the potential exception.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/translate.c | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index b6749ff..2be4ba8 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -2362,6 +2362,20 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
gen_op_mov_reg_v(a_ot, R_ESP, cpu_T[1]);
}
+static void gen_leave(DisasContext *s)
+{
+ TCGMemOp d_ot = mo_pushpop(s, s->dflag);
+ TCGMemOp a_ot = mo_stacksize(s);
+
+ gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
+ gen_op_ld_v(s, d_ot, cpu_T[0], cpu_A0);
+
+ tcg_gen_addi_tl(cpu_T[1], cpu_regs[R_EBP], 1 << d_ot);
+
+ gen_op_mov_reg_v(d_ot, R_EBP, cpu_T[0]);
+ gen_op_mov_reg_v(a_ot, R_ESP, cpu_T[1]);
+}
+
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
{
gen_update_cc_op(s);
@@ -5117,20 +5131,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
}
break;
case 0xc9: /* leave */
- /* XXX: exception not precise (ESP is updated before potential exception) */
- if (CODE64(s)) {
- gen_op_mov_v_reg(MO_64, cpu_T[0], R_EBP);
- gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[0]);
- } else if (s->ss32) {
- gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
- gen_op_mov_reg_v(MO_32, R_ESP, cpu_T[0]);
- } else {
- gen_op_mov_v_reg(MO_16, cpu_T[0], R_EBP);
- gen_op_mov_reg_v(MO_16, R_ESP, cpu_T[0]);
- }
- ot = gen_pop_T0(s);
- gen_op_mov_reg_v(ot, R_EBP, cpu_T[0]);
- gen_pop_update(s, ot);
+ gen_leave(s);
break;
case 0x06: /* push es */
case 0x0e: /* push cs */
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 09/10] target-i386: Tidy gen_add_A0_im
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
` (7 preceding siblings ...)
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 08/10] target-i386: Rewrite leave Richard Henderson
@ 2015-12-17 19:19 ` Richard Henderson
2016-02-04 23:44 ` [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
9 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2015-12-17 19:19 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
Merge gen_op_addl_A0_im and gen_op_addq_A0_im into gen_add_A0_im
and clean up the ifdef.
Replace the one remaining user of gen_op_addl_A0_im with gen_add_A0_im.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
target-i386/translate.c | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 2be4ba8..8059bbc 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -376,29 +376,12 @@ static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
}
}
-static inline void gen_op_addl_A0_im(int32_t val)
-{
- tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
-#ifdef TARGET_X86_64
- tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
-#endif
-}
-
-#ifdef TARGET_X86_64
-static inline void gen_op_addq_A0_im(int64_t val)
-{
- tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
-}
-#endif
-
static void gen_add_A0_im(DisasContext *s, int val)
{
-#ifdef TARGET_X86_64
- if (CODE64(s))
- gen_op_addq_A0_im(val);
- else
-#endif
- gen_op_addl_A0_im(val);
+ tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
+ if (!CODE64(s)) {
+ tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
+ }
}
static inline void gen_op_jmp_v(TCGv dest)
@@ -6232,7 +6215,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
exception */
gen_op_jmp_v(cpu_T[0]);
/* pop selector */
- gen_op_addl_A0_im(1 << dflag);
+ gen_add_A0_im(s, 1 << dflag);
gen_op_ld_v(s, dflag, cpu_T[0], cpu_A0);
gen_op_movl_seg_T0_vm(R_CS);
/* add stack offset */
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
` (8 preceding siblings ...)
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 09/10] target-i386: Tidy gen_add_A0_im Richard Henderson
@ 2016-02-04 23:44 ` Richard Henderson
2016-02-08 17:04 ` Paolo Bonzini
9 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2016-02-04 23:44 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, aurelien, peter.maydell
On 12/18/2015 06:19 AM, Richard Henderson wrote:
> This is a rebase of the patch set I posted in July. There are no
> substantive changes since then.
>
> The only comment at the time was re 05/10, where Paolo suggests
> optimizing access to CS overrides with the constant that we know
> via the TB operands. I chose to defer that, leaving things as
> they are with a simple load from ENV.
Ping.
> target-i386: Deconstruct the cpu_T array
This final patch needs updating to master, but is 100% mechanical.
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups
2016-02-04 23:44 ` [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
@ 2016-02-08 17:04 ` Paolo Bonzini
2016-02-08 20:35 ` Richard Henderson
0 siblings, 1 reply; 13+ messages in thread
From: Paolo Bonzini @ 2016-02-08 17:04 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: peter.maydell, aurelien
On 05/02/2016 00:44, Richard Henderson wrote:
> On 12/18/2015 06:19 AM, Richard Henderson wrote:
>> This is a rebase of the patch set I posted in July. There are no
>> substantive changes since then.
>>
>> The only comment at the time was re 05/10, where Paolo suggests
>> optimizing access to CS overrides with the constant that we know
>> via the TB operands. I chose to defer that, leaving things as
>> they are with a simple load from ENV.
>
> Ping.
>
>> target-i386: Deconstruct the cpu_T array
>
> This final patch needs updating to master, but is 100% mechanical.
v2 wasn't even sent to the list, actually. :)
Applied and sent out as pull request now, thanks!
Paolo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups
2016-02-08 17:04 ` Paolo Bonzini
@ 2016-02-08 20:35 ` Richard Henderson
0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2016-02-08 20:35 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel; +Cc: peter.maydell, aurelien
On 02/09/2016 04:04 AM, Paolo Bonzini wrote:
> Applied and sent out as pull request now, thanks!
Thanks!
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2016-02-08 20:35 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-17 19:19 [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 01/10] target-i386: Create gen_lea_v_seg Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 02/10] target-i386: Introduce mo_stacksize Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 03/10] target-i386: Use gen_lea_v_seg in gen_lea_modrm Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 04/10] target-i386: Use gen_lea_v_seg in stack subroutines Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 05/10] target-i386: Access segs via TCG registers Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 06/10] target-i386: Use gen_lea_v_seg in pusha/popa Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 07/10] target-i386: Rewrite gen_enter inline Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 08/10] target-i386: Rewrite leave Richard Henderson
2015-12-17 19:19 ` [Qemu-devel] [PATCH v2 09/10] target-i386: Tidy gen_add_A0_im Richard Henderson
2016-02-04 23:44 ` [Qemu-devel] [PATCH v2 00/10] target-i386 addressing cleanups Richard Henderson
2016-02-08 17:04 ` Paolo Bonzini
2016-02-08 20:35 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).