aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/aarch64/aarch64.c58
-rw-r--r--gcc/testsuite/ChangeLog12
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_fp_attribute_1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_1.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_10.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_2.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_4.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_6.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_7.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_8.c5
11 files changed, 91 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa627c5..cf3a2d9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2014-07-24 Jiong Wang <jiong.wang@arm.com>
+ * config/aarch64/aarch64.c (aarch64_pushwb_single_reg): New function.
+ (aarch64_expand_prologue): Optimize prologue when !frame_pointer_needed.
+
+2014-07-24 Jiong Wang <jiong.wang@arm.com>
+
* config/aarch64/aarch64.c (aarch64_restore_callee_saves)
(aarch64_save_callee_saves): New parameter "skip_wb".
(aarch64_expand_prologue, aarch64_expand_epilogue): Update call site.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 163dfcd..76e6027 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1930,6 +1930,22 @@ aarch64_next_callee_save (unsigned regno, unsigned limit)
return regno;
}
+static void
+aarch64_pushwb_single_reg (enum machine_mode mode, unsigned regno,
+ HOST_WIDE_INT adjustment)
+ {
+ rtx base_rtx = stack_pointer_rtx;
+ rtx insn, reg, mem;
+
+ reg = gen_rtx_REG (mode, regno);
+ mem = gen_rtx_PRE_MODIFY (Pmode, base_rtx,
+ plus_constant (Pmode, base_rtx, -adjustment));
+ mem = gen_rtx_MEM (mode, mem);
+
+ insn = emit_move_insn (mem, reg);
+ RTX_FRAME_RELATED_P (insn) = 1;
+}
+
static rtx
aarch64_gen_storewb_pair (enum machine_mode mode, rtx base, rtx reg, rtx reg2,
HOST_WIDE_INT adjustment)
@@ -2279,11 +2295,10 @@ aarch64_expand_prologue (void)
{
bool skip_wb = false;
- /* Save the frame pointer and lr if the frame pointer is needed
- first. Make the frame pointer point to the location of the
- old frame pointer on the stack. */
if (frame_pointer_needed)
{
+ skip_wb = true;
+
if (fp_offset)
{
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
@@ -2291,12 +2306,11 @@ aarch64_expand_prologue (void)
RTX_FRAME_RELATED_P (insn) = 1;
aarch64_set_frame_expr (gen_rtx_SET
(Pmode, stack_pointer_rtx,
- gen_rtx_MINUS (Pmode,
- stack_pointer_rtx,
+ gen_rtx_MINUS (Pmode, stack_pointer_rtx,
GEN_INT (offset))));
aarch64_save_callee_saves (DImode, fp_offset, R29_REGNUM,
- R30_REGNUM, skip_wb);
+ R30_REGNUM, false);
}
else
aarch64_pushwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset);
@@ -2314,20 +2328,36 @@ aarch64_expand_prologue (void)
RTX_FRAME_RELATED_P (insn) = 1;
insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
hard_frame_pointer_rtx));
-
- aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R28_REGNUM,
- skip_wb);
}
else
{
- insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
- GEN_INT (-offset)));
- RTX_FRAME_RELATED_P (insn) = 1;
+ unsigned reg1 = cfun->machine->frame.wb_candidate1;
+ unsigned reg2 = cfun->machine->frame.wb_candidate2;
- aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R30_REGNUM,
- skip_wb);
+ if (fp_offset
+ || reg1 == FIRST_PSEUDO_REGISTER
+ || (reg2 == FIRST_PSEUDO_REGISTER
+ && offset >= 256))
+ {
+ insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
+ GEN_INT (-offset)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else
+ {
+ enum machine_mode mode1 = (reg1 <= R30_REGNUM) ? DImode : DFmode;
+
+ skip_wb = true;
+
+ if (reg2 == FIRST_PSEUDO_REGISTER)
+ aarch64_pushwb_single_reg (mode1, reg1, offset);
+ else
+ aarch64_pushwb_pair_reg (mode1, reg1, reg2, offset);
+ }
}
+ aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R30_REGNUM,
+ skip_wb);
aarch64_save_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM,
skip_wb);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 42ac62f..901343c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2014-07-24 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/aarch64/test_frame_1.c: Match optimized instruction
+ sequences.
+ * gcc.target/aarch64/test_frame_10.c: Likewise.
+ * gcc.target/aarch64/test_frame_2.c: Likewise.
+ * gcc.target/aarch64/test_frame_4.c: Likewise.
+ * gcc.target/aarch64/test_frame_6.c: Likewise.
+ * gcc.target/aarch64/test_frame_7.c: Likewise.
+ * gcc.target/aarch64/test_frame_8.c: Likewise.
+ * gcc.target/aarch64/test_fp_attribute_1.c: Likewise.
+
2014-07-24 Martin Jambor <mjambor@suse.cz>
PR ipa/61160
diff --git a/gcc/testsuite/gcc.target/aarch64/test_fp_attribute_1.c b/gcc/testsuite/gcc.target/aarch64/test_fp_attribute_1.c
index 7538250..960174a 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_fp_attribute_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_fp_attribute_1.c
@@ -21,6 +21,6 @@ non_leaf_2 (void)
leaf ();
}
-/* { dg-final { scan-assembler-times "str\tx30, \\\[sp\\\]" 2 } } */
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_1.c b/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
index feea7a2..e9d04aa 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
@@ -6,9 +6,12 @@
* optimized code should use "str !" for stack adjustment. */
/* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
#include "test_frame_common.h"
t_frame_pattern (test1, 200, )
t_frame_run (test1)
+
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_10.c b/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
index 2892c5f..b646a71 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
@@ -8,9 +8,12 @@
the first subtractions could be optimized into "stp !". */
/* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
#include "test_frame_common.h"
t_frame_pattern_outgoing (test10, 480, "x19", 24, a[8], a[9], a[10])
t_frame_run (test10)
+
+/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_2.c b/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
index aa15dae..b972664 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
@@ -6,9 +6,13 @@
* optimized code should use "stp !" for stack adjustment. */
/* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
#include "test_frame_common.h"
t_frame_pattern (test2, 200, "x19")
t_frame_run (test2)
+
+
+/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_4.c b/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
index c45e740..5a9a919 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
@@ -6,9 +6,12 @@
* we can use "stp !" to optimize stack adjustment. */
/* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
#include "test_frame_common.h"
t_frame_pattern (test4, 400, "x19")
t_frame_run (test4)
+
+/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_6.c b/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
index 54f646b..6056f57 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
@@ -7,9 +7,12 @@
the second subtraction should use "str !". */
/* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
#include "test_frame_common.h"
t_frame_pattern (test6, 700, )
t_frame_run (test6)
+
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_7.c b/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
index aa97bc0..991860c 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
@@ -7,9 +7,12 @@
the second subtraction should use "stp !". */
/* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
#include "test_frame_common.h"
t_frame_pattern (test7, 700, "x19")
t_frame_run (test7)
+
+/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_8.c b/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
index f75f080..4a4d93b 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
@@ -5,9 +5,12 @@
* number of callee-saved reg == 1. */
/* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
#include "test_frame_common.h"
t_frame_pattern_outgoing (test8, 700, , 8, a[8])
t_frame_run (test8)
+
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 3 } } */
+/* { dg-final { cleanup-saved-temps } } */