aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/config/sparc/sparc.h5
-rw-r--r--gcc/config/sparc/sparc.md112
-rw-r--r--gcc/doc/md.texi3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030604-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/sparc-constant-1.c12
7 files changed, 94 insertions, 83 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b8ffc6a..31ba84f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2003-06-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/10876
+ * config/sparc/sparc.h (CONST_OK_FOR_LETTER): Add
+ new 'O' constraint for constant 4096.
+ (CONST_DOUBLE_OK_FOR_LETTER_P): Likewise.
+ * config/sparc/sparc.md (adddi3 expander): Canonicalize pattern.
+ Do not transform into MINUS insn for constant 4096.
+ (*adddi3_sp64 insn): Canonicalize pattern. Add new alternative
+ for constant 4096 as third operand.
+ (addsi3 expander): Remove.
+ (*addsi3 insn): Rename into 'addsi3'. Canonicalize pattern. Add
+ new alternative for constant 4096 as third operand.
+ (subdi3 expander): Do not transform into PLUS insn for constant 4096.
+ (*subdi3_sp64 insn): Add new alternative for constant 4096 as third
+ operand.
+ (subsi3 expander): Remove.
+ (*subsi3 insn): Rename into 'subsi3'. Add new alternative for
+ constant 4096 as third operand.
+ * doc/md.texi (Machine Constraints): Document new 'O' constraint for
+ the SPARC port.
+
2003-06-03 Chris Demetriou <cgd@broadcom.com>
* config/mips/t-linux64 (CRTSTUFF_T_CFLAGS_S): Define.
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index e08e403..49f9a38 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1381,7 +1381,8 @@ extern char leaf_reg_remap[];
`K' is used for constants which can be loaded with a single sethi insn.
`L' is used for the range of constants supported by the movcc insns.
`M' is used for the range of constants supported by the movrcc insns.
- `N' is like K, but for constants wider than 32 bits. */
+ `N' is like K, but for constants wider than 32 bits.
+ `O' is used for the range which is just 4096. */
#define SPARC_SIMM10_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x200 < 0x400)
#define SPARC_SIMM11_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x400 < 0x800)
@@ -1405,6 +1406,7 @@ extern char leaf_reg_remap[];
: (C) == 'L' ? SPARC_SIMM11_P (VALUE) \
: (C) == 'M' ? SPARC_SIMM10_P (VALUE) \
: (C) == 'N' ? SPARC_SETHI_P (VALUE) \
+ : (C) == 'O' ? (VALUE) == 4096 \
: 0)
/* Similar, but for floating constants, and defining letters G and H.
@@ -1413,6 +1415,7 @@ extern char leaf_reg_remap[];
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'G' ? fp_zero_operand (VALUE, GET_MODE (VALUE)) \
: (C) == 'H' ? arith_double_operand (VALUE, DImode) \
+ : (C) == 'O' ? arith_double_4096_operand (VALUE, DImode) \
: 0)
/* Given an rtx X being reloaded into a reg required to be
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 4c66a78..ebe9d2b 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -4748,13 +4748,11 @@
;;- arithmetic instructions
(define_expand "adddi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
- (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "arith_double_add_operand" "")))]
""
{
- HOST_WIDE_INT i;
-
if (! TARGET_ARCH64)
{
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
@@ -4765,21 +4763,6 @@
gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
DONE;
}
- if (arith_double_4096_operand(operands[2], DImode))
- {
- switch (GET_CODE (operands[1]))
- {
- case CONST_INT: i = INTVAL (operands[1]); break;
- case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
- default:
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_MINUS (DImode, operands[1],
- GEN_INT(-4096))));
- DONE;
- }
- emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
- DONE;
- }
})
(define_insn_and_split "adddi3_insn_sp32"
@@ -4945,40 +4928,24 @@
[(set_attr "length" "2")])
(define_insn "*adddi3_sp64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
- (match_operand:DI 2 "arith_double_operand" "rHI")))]
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
+ (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
"TARGET_ARCH64"
- "add\t%1, %2, %0")
-
-(define_expand "addsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,d")
- (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
- (match_operand:SI 2 "arith_add_operand" "rI,d")))]
- ""
-{
- if (arith_4096_operand(operands[2], SImode))
- {
- if (GET_CODE (operands[1]) == CONST_INT)
- emit_insn (gen_movsi (operands[0],
- GEN_INT (INTVAL (operands[1]) + 4096)));
- else
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_MINUS (SImode, operands[1],
- GEN_INT(-4096))));
- DONE;
- }
-})
+ "@
+ add\t%1, %2, %0
+ sub\t%1, -%2, %0")
-(define_insn "*addsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,d")
- (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
- (match_operand:SI 2 "arith_operand" "rI,d")))]
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,d")
+ (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
+ (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
""
"@
add\t%1, %2, %0
+ sub\t%1, -%2, %0
fpadd32s\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,*,fp")])
(define_insn "*cmp_cc_plus"
[(set (reg:CC_NOOV 100)
@@ -5021,9 +4988,9 @@
[(set_attr "type" "compare")])
(define_expand "subdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
+ [(set (match_operand:DI 0 "register_operand" "")
+ (minus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "arith_double_add_operand" "")))]
""
{
if (! TARGET_ARCH64)
@@ -5036,13 +5003,6 @@
gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
DONE;
}
- if (arith_double_4096_operand(operands[2], DImode))
- {
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_PLUS (DImode, operands[1],
- GEN_INT(-4096))));
- DONE;
- }
})
(define_insn_and_split "*subdi3_sp32"
@@ -5124,36 +5084,24 @@
[(set_attr "length" "2")])
(define_insn "*subdi3_sp64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "arith_double_operand" "rHI")))]
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (minus:DI (match_operand:DI 1 "register_operand" "r,r")
+ (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
"TARGET_ARCH64"
- "sub\t%1, %2, %0")
-
-(define_expand "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,d")
- (minus:SI (match_operand:SI 1 "register_operand" "r,d")
- (match_operand:SI 2 "arith_add_operand" "rI,d")))]
- ""
-{
- if (arith_4096_operand(operands[2], SImode))
- {
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_PLUS (SImode, operands[1],
- GEN_INT(-4096))));
- DONE;
- }
-})
+ "@
+ sub\t%1, %2, %0
+ add\t%1, -%2, %0")
-(define_insn "*subsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,d")
- (minus:SI (match_operand:SI 1 "register_operand" "r,d")
- (match_operand:SI 2 "arith_operand" "rI,d")))]
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
+ (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
""
"@
sub\t%1, %2, %0
+ add\t%1, -%2, %0
fpsub32s\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,*,fp")])
(define_insn "*cmp_minus_cc"
[(set (reg:CC_NOOV 100)
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 9b15991..8b319cf 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -2057,6 +2057,9 @@ Same as @samp{K}, except that it verifies that bits that are not in the
lower 32-bit range are all zero. Must be used instead of @samp{K} for
modes wider than @code{SImode}
+@item O
+The constant 4096
+
@item G
Floating-point zero
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b381412..c5c95070 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-06-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * gcc.c-torture/compile/20030604-1.c: New test.
+ * gcc.dg/sparc-constant-1.c: New test.
+
2003-06-03 Glen Nakamura <glen@imodulo.com>
* gcc.dg/20020525-1.c: Replace 0x5a5a5a5a with -1.
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030604-1.c b/gcc/testsuite/gcc.c-torture/compile/20030604-1.c
new file mode 100644
index 0000000..7e36bfe
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030604-1.c
@@ -0,0 +1,18 @@
+/* PR optimization/10876 */
+/* Contributed by Christian Ehrhardt */
+
+/* Verify that the SPARC port doesn't emit
+ (minus) (reg) (const_int) insns. */
+
+void f(void)
+{
+ unsigned int butterfly, block, offset;
+ double *Z;
+
+ for (block = 0; block < 512; block += 512) {
+ double T1re, T2re;
+ offset = butterfly + block;
+ T1re += T2re;
+ T2re = Z[offset] + T1re;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/sparc-constant-1.c b/gcc/testsuite/gcc.dg/sparc-constant-1.c
new file mode 100644
index 0000000..bb4b1bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sparc-constant-1.c
@@ -0,0 +1,12 @@
+/* PR optimization/10876 */
+/* { dg-do compile { target sparc*-*-* } } */
+
+/* Verify that adding the constant 4096 is turned
+ into substracting the constant -4096. */
+
+int foo(int a)
+{
+ return a+4096;
+}
+
+/* { dg-final { scan-assembler "sub" } } */