mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-26 11:32:23 -06:00
tcg/i386: convert add/sub of 128 to sub/add of -128
Extend the existing conditional that generates INC/DEC, to also swap an ADD for a SUB and vice versa when the immediate is 128. This facilitates using OPC_ARITH_EvIb instead of OPC_ARITH_EvIz. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20231228120514.70205-1-pbonzini@redhat.com> [rth: Use a switch on C] Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
34eac35f89
commit
64708db302
1 changed files with 34 additions and 15 deletions
|
@ -1316,14 +1316,22 @@ static void tgen_arithi(TCGContext *s, int c, int r0,
|
||||||
c &= 7;
|
c &= 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
|
switch (c) {
|
||||||
partial flags update stalls on Pentium4 and are not recommended
|
case ARITH_ADD:
|
||||||
by current Intel optimization manuals. */
|
case ARITH_SUB:
|
||||||
if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
|
if (!cf) {
|
||||||
|
/*
|
||||||
|
* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
|
||||||
|
* partial flags update stalls on Pentium4 and are not recommended
|
||||||
|
* by current Intel optimization manuals.
|
||||||
|
*/
|
||||||
|
if (val == 1 || val == -1) {
|
||||||
int is_inc = (c == ARITH_ADD) ^ (val < 0);
|
int is_inc = (c == ARITH_ADD) ^ (val < 0);
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
/* The single-byte increment encodings are re-tasked as the
|
/*
|
||||||
REX prefixes. Use the MODRM encoding. */
|
* The single-byte increment encodings are re-tasked
|
||||||
|
* as the REX prefixes. Use the MODRM encoding.
|
||||||
|
*/
|
||||||
tcg_out_modrm(s, OPC_GRP5 + rexw,
|
tcg_out_modrm(s, OPC_GRP5 + rexw,
|
||||||
(is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0);
|
(is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1331,8 +1339,18 @@ static void tgen_arithi(TCGContext *s, int c, int r0,
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (val == 128) {
|
||||||
|
/*
|
||||||
|
* Facilitate using an 8-bit immediate. Carry is inverted
|
||||||
|
* by this transformation, so do it only if cf == 0.
|
||||||
|
*/
|
||||||
|
c ^= ARITH_ADD ^ ARITH_SUB;
|
||||||
|
val = -128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
if (c == ARITH_AND) {
|
case ARITH_AND:
|
||||||
if (TCG_TARGET_REG_BITS == 64) {
|
if (TCG_TARGET_REG_BITS == 64) {
|
||||||
if (val == 0xffffffffu) {
|
if (val == 0xffffffffu) {
|
||||||
tcg_out_ext32u(s, r0, r0);
|
tcg_out_ext32u(s, r0, r0);
|
||||||
|
@ -1351,6 +1369,7 @@ static void tgen_arithi(TCGContext *s, int c, int r0,
|
||||||
tcg_out_ext16u(s, r0, r0);
|
tcg_out_ext16u(s, r0, r0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val == (int8_t)val) {
|
if (val == (int8_t)val) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue