OSDN Git Service

gcc/ChangeLog
authorxguo <xguo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Oct 2012 02:12:06 +0000 (02:12 +0000)
committerxguo <xguo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Oct 2012 02:12:06 +0000 (02:12 +0000)
Backport from mainline
2012-10-23  Terry Guo  <terry.guo@arm.com>

PR target/55019
* config/arm/arm.c (thumb1_expand_prologue): Don't push high regs with
live argument regs.

gcc/testsuite/ChangeLog
Backport from mainline
2012-10-23  Terry Guo  <terry.guo@arm.com>

PR target/55019
* gcc.dg/pr55019.c: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@192831 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr55019.c [new file with mode: 0644]

index 3100b8d..2c9f512 100644 (file)
@@ -1,3 +1,12 @@
+2012-10-26  Terry Guo  <terry.guo@arm.com>
+
+       Backport from mainline
+       2012-10-23  Terry Guo  <terry.guo@arm.com>
+
+       PR target/55019
+       * config/arm/arm.c (thumb1_expand_prologue): Don't push high regs with
+       live argument regs.
+
 2012-10-26  Ralf Corsépius  <ralf.corsepius@rtems.org>
 
        * config/avr/rtems.h (TARGET_OS_CPP_BUILTINS): Remove
index 04630dd..69736ae 100644 (file)
@@ -22293,12 +22293,18 @@ thumb1_expand_prologue (void)
     {
       unsigned pushable_regs;
       unsigned next_hi_reg;
+      unsigned arg_regs_num = TARGET_AAPCS_BASED ? crtl->args.info.aapcs_ncrn
+                                                : crtl->args.info.nregs;
+      unsigned arg_regs_mask = (1 << arg_regs_num) - 1;
 
       for (next_hi_reg = 12; next_hi_reg > LAST_LO_REGNUM; next_hi_reg--)
        if (live_regs_mask & (1 << next_hi_reg))
          break;
 
-      pushable_regs = l_mask & 0xff;
+      /* Here we need to mask out registers used for passing arguments
+        even if they can be pushed.  This is to avoid using them to stash the high
+        registers.  Such kind of stash may clobber the use of arguments.  */
+      pushable_regs = l_mask & (~arg_regs_mask) & 0xff;
 
       if (pushable_regs == 0)
        pushable_regs = 1 << thumb_find_work_register (live_regs_mask);
index 07df245..198ad8f 100644 (file)
@@ -1,3 +1,11 @@
+2012-10-26  Terry Guo  <terry.guo@arm.com>
+
+       Backport from mainline
+       2012-10-23  Terry Guo  <terry.guo@arm.com>
+
+       PR target/55019
+       * gcc.dg/pr55019.c: New.
+
 2012-10-25  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/54902
diff --git a/gcc/testsuite/gcc.dg/pr55019.c b/gcc/testsuite/gcc.dg/pr55019.c
new file mode 100644 (file)
index 0000000..1548fb2
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -funroll-loops" } */
+/* { dg-add-options ieee } */
+
+extern void exit (int);
+extern void abort (void);
+
+void
+compare (double a, double b)
+{
+  do
+    {
+      double s1 = __builtin_copysign ((double) 1.0, a);
+      double s2 = __builtin_copysign ((double) 1.0, b);
+
+      if (s1 != s2)
+        abort ();
+
+      if ((__builtin_isnan (a) != 0) != (__builtin_isnan (b) != 0))
+        abort ();
+
+      if ((a != b) != (__builtin_isnan (a) != 0))
+        abort ();
+    } while (0);
+}
+
+int
+main ()
+{
+  double a = 0.0;
+  double b = 0.0;
+  _Complex double cr = __builtin_complex (a, b);
+  static _Complex double cs = __builtin_complex (0.0, 0.0);
+
+  compare (__real__ cr, 0.0);
+  compare (__imag__ cr, 0.0);
+  compare (__real__ cs, 0.0);
+  compare (__imag__ cs, 0.0);
+
+  exit (0);
+}