diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-05-31 21:45:33 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-05-31 21:45:33 +0000 |
commit | 09e9f553ec9da7530047c5f86b3f4cd0b5cad6aa (patch) | |
tree | 0187b5e0903bee9b706101a393f6867b54a6b274 | |
parent | 1224d4c98f0cffe7aaaba0a0b35e293fcc98b760 (diff) | |
download | gcc-09e9f553ec9da7530047c5f86b3f4cd0b5cad6aa.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/branches/gcc-3_3-branch@82504 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 28 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 1 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 |
5 files changed, 51 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 15d13c9c7bc..3a10fe3e5fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-05-31 Eric Botcazou <ebotcazou@libertysurf.fr> + + 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. + 2004-05-29 Eric Botcazou <ebotcazou@libertysurf.fr> PR optimization/13653 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 324ec0549cf..931114f5db8 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -1357,6 +1357,34 @@ input_operand (op, mode) return 0; } +/* Return 1 if OP is valid for the lhs of a compare insn. */ + +int +compare_operand (op, mode) + 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 guarentees this. */ diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 30a7181b4e1..9f5911c13ae 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -3059,6 +3059,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}}, diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 01e031ebadb..8c3e7c03f7c 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -290,10 +290,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; @@ -301,10 +304,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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6b936943bef..cf551285321 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-05-31 Eric Botcazou <ebotcazou@libertysurf.fr> + + * gcc.dg/sparc-trap-1.c: New test. + 2004-05-26 Hans-Peter Nilsson <hp@axis.com> PR optimization/15296 |