aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog3
-rw-r--r--gcc/config/rs6000/rs6000.md23
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/ppc-mov-1.c52
4 files changed, 81 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 195080d..3f4b7a3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
2004-11-11 Nathan Sidwell <nathan@codesourcery.com>
+ PR target/16796
+ * config/rs6000/rs6000.md: Add DF & SF reg move peepholes.
+
PR target/16458
* config/rs6000/rs6000.c (rs6000_generate_compare): Generate an
unsigned equality compare when we know the operands are unsigned.
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 9c6f088..6b1c0b6 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -9716,6 +9716,29 @@
(match_dup 1))]
"operands[0] = widen_memory_access (operands[0], TFmode, 0);
operands[1] = gen_rtx_REG (TFmode, REGNO (operands[1]));")
+
+;; after inserting conditional returns we can sometimes have
+;; unnecessary register moves. Unfortunately we cannot have a
+;; modeless peephole here, because some single SImode sets have early
+;; clobber outputs. Although those sets expand to multi-ppc-insn
+;; sequences, using get_attr_length here will smash the operands
+;; array. Neither is there an early_cobbler_p predicate.
+(define_peephole2
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (match_operand:DF 1 "any_operand" ""))
+ (set (match_operand:DF 2 "gpc_reg_operand" "")
+ (match_dup 0))]
+ "peep2_reg_dead_p (2, operands[0])"
+ [(set (match_dup 2) (match_dup 1))])
+
+(define_peephole2
+ [(set (match_operand:SF 0 "gpc_reg_operand" "")
+ (match_operand:SF 1 "any_operand" ""))
+ (set (match_operand:SF 2 "gpc_reg_operand" "")
+ (match_dup 0))]
+ "peep2_reg_dead_p (2, operands[0])"
+ [(set (match_dup 2) (match_dup 1))])
+
;; TLS support.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 814b05b..64da733 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2004-11-11 Nathan Sidwell <nathan@codesourcery.com>
+ PR target/16796
+ * gcc.dg/ppc-mov-1.c: New.
+
PR target/16458
* gcc.dg/ppc-compare-1.c: New.
diff --git a/gcc/testsuite/gcc.dg/ppc-mov-1.c b/gcc/testsuite/gcc.dg/ppc-mov-1.c
new file mode 100644
index 0000000..4256b60
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ppc-mov-1.c
@@ -0,0 +1,52 @@
+/* { dg-do compile { target powerpc64-*-* } } */
+/* { dg-options "-m64 -O2" } */
+
+/* { dg-final { scan-assembler-not "fmr \[0-9\]+,\[0-9\]+" } }
+
+/* Origin:Pete Steinmetz <steinmtz@us.ibm.com> */
+
+/* PR 16796: Extraneous move. */
+
+static const double huge = 1.0e300;
+typedef int int64_t __attribute__ ((__mode__ (__DI__)));
+typedef unsigned int u_int64_t __attribute__ ((__mode__ (__DI__)));
+
+double __floor(double x)
+{
+ union {
+ double dbl_val;
+ long int long_val;
+ } temp;
+
+ int64_t i0,j0;
+ u_int64_t i;
+ temp.dbl_val = x;
+ i0 = temp.long_val;
+
+ j0 = ((i0>>52)&0x7ff)-0x3ff;
+ if(j0<52) {
+ if(j0<0) {
+ if(huge+x>0.0) {
+ if(i0>=0) {i0=0;}
+ else if((i0&0x7fffffffffffffff)!=0)
+ { i0=0xbff0000000000000;}
+ }
+ } else {
+ i = (0x000fffffffffffff)>>j0;
+ if((i0&i)==0) return x;
+ if(huge+x>0.0) {
+ if(i0<0) i0 += (0x0010000000000000)>>j0;
+ i0 &= (~i);
+ }
+ }
+ } else {
+ if (j0==0x400)
+ return x+x;
+ else
+ return x;
+ }
+ temp.long_val = i0;
+ x = temp.dbl_val;
+ return x;
+}
+