aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2009-09-27 18:08:16 +0200
committerAurelien Jarno <aurelien@aurel32.net>2009-09-27 18:08:16 +0200
commita4b18c6ddbc9135f86f8b93806f7f5198ed90674 (patch)
tree00f7a14e51401085fec400fff0fa79f67eebb8c4
parentb461cdc9b3a30ec43ef3bda1752b902b209abe27 (diff)
tcg/x86_64: generated dec/inc instead of sub/add when possible
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r--tcg/x86_64/tcg-target.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/tcg/x86_64/tcg-target.c b/tcg/x86_64/tcg-target.c
index 9709430c6f..b4ba65f972 100644
--- a/tcg/x86_64/tcg-target.c
+++ b/tcg/x86_64/tcg-target.c
@@ -397,7 +397,13 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
static inline void tgen_arithi32(TCGContext *s, int c, int r0, int32_t val)
{
- if (val == (int8_t)val) {
+ if ((c == ARITH_ADD && val == 1) || (c == ARITH_SUB && val == -1)) {
+ /* inc */
+ tcg_out_modrm(s, 0xff, 0, r0);
+ } else if ((c == ARITH_ADD && val == -1) || (c == ARITH_SUB && val == 1)) {
+ /* dec */
+ tcg_out_modrm(s, 0xff, 1, r0);
+ } else if (val == (int8_t)val) {
tcg_out_modrm(s, 0x83, c, r0);
tcg_out8(s, val);
} else if (c == ARITH_AND && val == 0xffu) {
@@ -414,7 +420,13 @@ static inline void tgen_arithi32(TCGContext *s, int c, int r0, int32_t val)
static inline void tgen_arithi64(TCGContext *s, int c, int r0, int64_t val)
{
- if (val == (int8_t)val) {
+ if ((c == ARITH_ADD && val == 1) || (c == ARITH_SUB && val == -1)) {
+ /* inc */
+ tcg_out_modrm(s, 0xff | P_REXW, 0, r0);
+ } else if ((c == ARITH_ADD && val == -1) || (c == ARITH_SUB && val == 1)) {
+ /* dec */
+ tcg_out_modrm(s, 0xff | P_REXW, 1, r0);
+ } else if (val == (int8_t)val) {
tcg_out_modrm(s, 0x83 | P_REXW, c, r0);
tcg_out8(s, val);
} else if (c == ARITH_AND && val == 0xffu) {