aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2011-12-16 23:37:48 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2011-12-16 23:37:48 +0000
commite98b1defdd2c6b5dc643a6e2a64a7e72a0c249c8 (patch)
tree171fe758184ff4979f967e638160977eccfc8c94
parent8a76ce4e34c38b9825af59a58e260201a2e6518c (diff)
downloadgcc-e98b1defdd2c6b5dc643a6e2a64a7e72a0c249c8.zip
gcc-e98b1defdd2c6b5dc643a6e2a64a7e72a0c249c8.tar.gz
gcc-e98b1defdd2c6b5dc643a6e2a64a7e72a0c249c8.tar.bz2
sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant.
* config/sparc/sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant. (frame_blockage): New expander. (frame_blockage<P:mode>): New instruction. * config/sparc/sparc.c (sparc_expand_prologue): When the sequence of instructions establishing the frame isn't atomic, emit frame blockage. From-SVN: r182420
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/sparc/sparc.c13
-rw-r--r--gcc/config/sparc/sparc.md20
3 files changed, 40 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5849861..1c8b3a2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2011-12-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/sparc/sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant.
+ (frame_blockage): New expander.
+ (frame_blockage<P:mode>): New instruction.
+ * config/sparc/sparc.c (sparc_expand_prologue): When the sequence of
+ instructions establishing the frame isn't atomic, emit frame blockage.
+
2011-12-16 Tristan Gingold <gingold@adacore.com>
* config/alpha/vms.h (USE_TM_CLONE_REGISTRY): Define.
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 20efb00..19ab54a 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -4972,8 +4972,9 @@ sparc_expand_prologue (void)
else if (size <= 8192)
{
insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-4096)));
- /* %sp is still the CFA register. */
RTX_FRAME_RELATED_P (insn) = 1;
+
+ /* %sp is still the CFA register. */
insn = emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
}
else
@@ -4996,8 +4997,18 @@ sparc_expand_prologue (void)
else if (size <= 8192)
{
emit_window_save (GEN_INT (-4096));
+
/* %sp is not the CFA register anymore. */
emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
+
+ /* Make sure no %fp-based store is issued until after the frame is
+ established. The offset between the frame pointer and the stack
+ pointer is calculated relative to the value of the stack pointer
+ at the end of the function prologue, and moving instructions that
+ access the stack via the frame pointer between the instructions
+ that decrement the stack pointer could result in accessing the
+ register window save area, which is volatile. */
+ emit_insn (gen_frame_blockage ());
}
else
{
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 37ac170..f67ee83 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -28,6 +28,7 @@
[(UNSPEC_MOVE_PIC 0)
(UNSPEC_UPDATE_RETURN 1)
(UNSPEC_LOAD_PCREL_SYM 2)
+ (UNSPEC_FRAME_BLOCKAGE 3)
(UNSPEC_MOVE_PIC_LABEL 5)
(UNSPEC_SETH44 6)
(UNSPEC_SETM44 7)
@@ -6375,6 +6376,25 @@
""
[(set_attr "length" "0")])
+;; Do not schedule instructions accessing memory before this point.
+
+(define_expand "frame_blockage"
+ [(set (match_dup 0)
+ (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
+ ""
+{
+ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (operands[0]) = 1;
+ operands[1] = stack_pointer_rtx;
+})
+
+(define_insn "*frame_blockage<P:mode>"
+ [(set (match_operand:BLK 0 "" "")
+ (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
(define_expand "probe_stack"
[(set (match_operand 0 "memory_operand" "") (const_int 0))]
""