aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2024-11-21 13:01:45 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2025-01-10 23:34:44 +0100
commitef682b08a0b52f4e6d9d790e26291f146e05734a (patch)
treeabdf8f8ba3833ac9794ab9658ad6309d9c70c83a
parent88716ae79f89bd6510f0c9e182a73ad40d1ff531 (diff)
downloadqemu-ef682b08a0b52f4e6d9d790e26291f146e05734a.zip
qemu-ef682b08a0b52f4e6d9d790e26291f146e05734a.tar.gz
qemu-ef682b08a0b52f4e6d9d790e26291f146e05734a.tar.bz2
target/i386: use shr to load high-byte registers into T0/T1
Using a sextract or extract operation is only necessary if a sign or zero extended value is needed. If not, a shift is enough. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--target/i386/tcg/emit.c.inc23
-rw-r--r--target/i386/tcg/translate.c2
2 files changed, 13 insertions, 12 deletions
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 5c11542..c4cc5f4 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -286,24 +286,25 @@ static void gen_load(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
gen_op_ld_v(s, op->ot, v, s->A0);
}
- } else if (op->ot == MO_8 && byte_reg_is_xH(s, op->n)) {
- if (v == s->T0 && decode->e.special == X86_SPECIAL_SExtT0) {
- tcg_gen_sextract_tl(v, cpu_regs[op->n - 4], 8, 8);
- } else {
- tcg_gen_extract_tl(v, cpu_regs[op->n - 4], 8, 8);
- }
-
} else if (op->ot < MO_TL && v == s->T0 &&
(decode->e.special == X86_SPECIAL_SExtT0 ||
decode->e.special == X86_SPECIAL_ZExtT0)) {
- if (decode->e.special == X86_SPECIAL_SExtT0) {
- tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot | MO_SIGN);
+ if (op->ot == MO_8 && byte_reg_is_xH(s, op->n)) {
+ if (decode->e.special == X86_SPECIAL_SExtT0) {
+ tcg_gen_sextract_tl(v, cpu_regs[op->n - 4], 8, 8);
+ } else {
+ tcg_gen_extract_tl(v, cpu_regs[op->n - 4], 8, 8);
+ }
} else {
- tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot);
+ if (decode->e.special == X86_SPECIAL_SExtT0) {
+ tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot | MO_SIGN);
+ } else {
+ tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot);
+ }
}
} else {
- tcg_gen_mov_tl(v, cpu_regs[op->n]);
+ gen_op_mov_v_reg(s, op->ot, v, op->n);
}
break;
case X86_OP_IMM:
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 834aea1..dbc9d63 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -486,7 +486,7 @@ static inline
void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg)
{
if (ot == MO_8 && byte_reg_is_xH(s, reg)) {
- tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
+ tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
} else {
tcg_gen_mov_tl(t0, cpu_regs[reg]);
}