diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-05-31 21:34:26 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-05-31 21:34:26 +0000 |
commit | f94175587902c17989ad6545bcb27099c2ee1f5d (patch) | |
tree | d91d56afe424dca67642ecfc22d5d221aeaf7799 /gcc/config/sparc | |
parent | 334f6ce156d98fd9e492d39059919b9e6684fb8a (diff) | |
download | gcc-f94175587902c17989ad6545bcb27099c2ee1f5d.tar.gz |
PR target/15693
* config/sparc/sparc.c (compare_operand): New predicate.
* config/sparc/sparc.h (PREDICATE_CODES): Add it.
* config/sparc/sparc.md (cmpsi expander): Use it. If the first
operand is a ZERO_EXTRACT and the second operand is not zero,
force the former to a register.
(cmpdi expander): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@82500 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r-- | gcc/config/sparc/sparc.c | 26 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 1 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 10 |
3 files changed, 35 insertions, 2 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 278ca9a26b0..30fbb878b66 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -1348,6 +1348,32 @@ input_operand (rtx op, enum machine_mode mode) return 0; } +/* Return 1 if OP is valid for the lhs of a compare insn. */ + +int +compare_operand (rtx op, enum machine_mode mode) +{ + if (GET_CODE (op) == ZERO_EXTRACT) + return (register_operand (XEXP (op, 0), mode) + && small_int_or_double (XEXP (op, 1), mode) + && small_int_or_double (XEXP (op, 2), mode) + /* This matches cmp_zero_extract. */ + && ((mode == SImode + && ((GET_CODE (XEXP (op, 2)) == CONST_INT + && INTVAL (XEXP (op, 2)) > 19) + || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE + && CONST_DOUBLE_LOW (XEXP (op, 2)) > 19))) + /* This matches cmp_zero_extract_sp64. */ + || (mode == DImode + && TARGET_ARCH64 + && ((GET_CODE (XEXP (op, 2)) == CONST_INT + && INTVAL (XEXP (op, 2)) > 51) + || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE + && CONST_DOUBLE_LOW (XEXP (op, 2)) > 51))))); + else + return register_operand (op, mode); +} + /* We know it can't be done in one insn when we get here, the movsi expander guarantees this. */ diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 33c1256e805..3e0b1c91461 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -2612,6 +2612,7 @@ do { \ {"uns_arith_operand", {SUBREG, REG, CONST_INT}}, \ {"clobbered_register", {REG}}, \ {"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}}, \ +{"compare_operand", {SUBREG, REG, ZERO_EXTRACT}}, \ {"const64_operand", {CONST_INT, CONST_DOUBLE}}, \ {"const64_high_operand", {CONST_INT, CONST_DOUBLE}}, \ {"tgd_symbolic_operand", {SYMBOL_REF}}, \ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 130d58c84f8..b6e45e8d066 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -299,10 +299,13 @@ (define_expand "cmpsi" [(set (reg:CC 100) - (compare:CC (match_operand:SI 0 "register_operand" "") + (compare:CC (match_operand:SI 0 "compare_operand" "") (match_operand:SI 1 "arith_operand" "")))] "" { + if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx) + operands[0] = force_reg (SImode, operands[0]); + sparc_compare_op0 = operands[0]; sparc_compare_op1 = operands[1]; DONE; @@ -310,10 +313,13 @@ (define_expand "cmpdi" [(set (reg:CCX 100) - (compare:CCX (match_operand:DI 0 "register_operand" "") + (compare:CCX (match_operand:DI 0 "compare_operand" "") (match_operand:DI 1 "arith_double_operand" "")))] "TARGET_ARCH64" { + if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx) + operands[0] = force_reg (DImode, operands[0]); + sparc_compare_op0 = operands[0]; sparc_compare_op1 = operands[1]; DONE; |