diff options
author | Richard Henderson <rth@twiddle.net> | 2014-04-15 18:54:07 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2014-05-24 08:46:08 -0700 |
commit | 070603f62b6e97bfdc3f33798fbdc2772798cdfc (patch) | |
tree | 5fa907a9e1aad3fd2249116c8b2216ffd1d9f481 /tcg | |
parent | ac0f3b12636f58062129064e3e8f8f65ccc18b1e (diff) |
tcg-mips: Fix subtract immediate range
Since we must use ADDUI, we would generate incorrect code for -32768.
Leaving off subtract of +32768 makes things easier for a follow-on patch.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/mips/tcg-target.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 920208a3a6..5021dea5f8 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -156,9 +156,10 @@ static void patch_reloc(tcg_insn_unit *code_ptr, int type, } #define TCG_CT_CONST_ZERO 0x100 -#define TCG_CT_CONST_U16 0x200 -#define TCG_CT_CONST_S16 0x400 -#define TCG_CT_CONST_P2M1 0x800 +#define TCG_CT_CONST_U16 0x200 /* Unsigned 16-bit: 0 - 0xffff. */ +#define TCG_CT_CONST_S16 0x400 /* Signed 16-bit: -32768 - 32767 */ +#define TCG_CT_CONST_P2M1 0x800 /* Power of 2 minus 1. */ +#define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */ static inline bool is_p2m1(tcg_target_long val) { @@ -213,6 +214,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) case 'K': ct->ct |= TCG_CT_CONST_P2M1; break; + case 'N': + ct->ct |= TCG_CT_CONST_N16; + break; case 'Z': /* We are cheating a bit here, using the fact that the register ZERO is also the register number 0. Hence there is no need @@ -241,6 +245,8 @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type, return 1; } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) { return 1; + } else if ((ct & TCG_CT_CONST_N16) && val >= -32767 && val <= 32767) { + return 1; } else if ((ct & TCG_CT_CONST_P2M1) && use_mips32r2_instructions && is_p2m1(val)) { return 1; @@ -1642,7 +1648,7 @@ static const TCGTargetOpDef mips_op_defs[] = { { INDEX_op_divu_i32, { "r", "rZ", "rZ" } }, { INDEX_op_rem_i32, { "r", "rZ", "rZ" } }, { INDEX_op_remu_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_sub_i32, { "r", "rZ", "rJ" } }, + { INDEX_op_sub_i32, { "r", "rZ", "rN" } }, { INDEX_op_and_i32, { "r", "rZ", "rIK" } }, { INDEX_op_nor_i32, { "r", "rZ", "rZ" } }, @@ -1670,7 +1676,7 @@ static const TCGTargetOpDef mips_op_defs[] = { { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } }, { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } }, - { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } }, + { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } }, { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } }, #if TARGET_LONG_BITS == 32 |