aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2024-02-28 11:15:43 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2024-05-07 08:53:26 +0200
commitb603136402d2ae217b5051cd041a8591f09b04ba (patch)
treee65d23ac6a1438892580a8d72958ea8affe71348
parent5e9e21bcc4d22dbd4473cab494a1beefbd3786a9 (diff)
downloadqemu-b603136402d2ae217b5051cd041a8591f09b04ba.zip
qemu-b603136402d2ae217b5051cd041a8591f09b04ba.tar.gz
qemu-b603136402d2ae217b5051cd041a8591f09b04ba.tar.bz2
target/i386: generalize gen_movl_seg_T0
In the new decoder it is sometimes easier to put the segment in T1 instead of T0, usually because another operand was loaded by common code in T0. Genrealize gen_movl_seg_T0 to allow using any source. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--target/i386/tcg/emit.c.inc4
-rw-r--r--target/i386/tcg/translate.c16
2 files changed, 10 insertions, 10 deletions
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 5834f8e..56ce0d2 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -306,8 +306,8 @@ static void gen_writeback(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv
case X86_OP_SKIP:
break;
case X86_OP_SEG:
- /* Note that gen_movl_seg_T0 takes care of interrupt shadow and TF. */
- gen_movl_seg_T0(s, op->n);
+ /* Note that gen_movl_seg takes care of interrupt shadow and TF. */
+ gen_movl_seg(s, op->n, s->T0);
break;
case X86_OP_INT:
if (op->has_ea) {
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 4f47c40..e09bfda 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2525,12 +2525,12 @@ static void gen_op_movl_seg_real(DisasContext *s, X86Seg seg_reg, TCGv seg)
tcg_gen_shli_tl(cpu_seg_base[seg_reg], selector, 4);
}
-/* move T0 to seg_reg and compute if the CPU state may change. Never
+/* move SRC to seg_reg and compute if the CPU state may change. Never
call this function with seg_reg == R_CS */
-static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
+static void gen_movl_seg(DisasContext *s, X86Seg seg_reg, TCGv src)
{
if (PE(s) && !VM86(s)) {
- tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
+ tcg_gen_trunc_tl_i32(s->tmp2_i32, src);
gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32);
/* abort translation because the addseg value may change or
because ss32 may change. For R_SS, translation must always
@@ -2542,7 +2542,7 @@ static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
s->base.is_jmp = DISAS_EOB_NEXT;
}
} else {
- gen_op_movl_seg_real(s, seg_reg, s->T0);
+ gen_op_movl_seg_real(s, seg_reg, src);
if (seg_reg == R_SS) {
s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
}
@@ -4084,13 +4084,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
reg = b >> 3;
ot = gen_pop_T0(s);
- gen_movl_seg_T0(s, reg);
+ gen_movl_seg(s, reg, s->T0);
gen_pop_update(s, ot);
break;
case 0x1a1: /* pop fs */
case 0x1a9: /* pop gs */
ot = gen_pop_T0(s);
- gen_movl_seg_T0(s, (b >> 3) & 7);
+ gen_movl_seg(s, (b >> 3) & 7, s->T0);
gen_pop_update(s, ot);
break;
@@ -4137,7 +4137,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (reg >= 6 || reg == R_CS)
goto illegal_op;
gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
- gen_movl_seg_T0(s, reg);
+ gen_movl_seg(s, reg, s->T0);
break;
case 0x8c: /* mov Gv, seg */
modrm = x86_ldub_code(env, s);
@@ -4323,7 +4323,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_add_A0_im(s, 1 << ot);
/* load the segment first to handle exceptions properly */
gen_op_ld_v(s, MO_16, s->T0, s->A0);
- gen_movl_seg_T0(s, op);
+ gen_movl_seg(s, op, s->T0);
/* then put the data */
gen_op_mov_reg_v(s, ot, reg, s->T1);
break;