summaryrefslogtreecommitdiff
path: root/gcc/config/sparc
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-19 09:03:45 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-19 09:03:45 +0000
commitb11e16d5eacc6bee8aa7ea50be5f2b3f95581b4b (patch)
tree8029b8a046840a43572ac9c006c6c8f55d2b096e /gcc/config/sparc
parentf0620a215a807d40102f6165c6002a94b4bc283e (diff)
downloadgcc-b11e16d5eacc6bee8aa7ea50be5f2b3f95581b4b.tar.gz
2011-12-19 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 182471 using svnmerge git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@182472 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r--gcc/config/sparc/sparc.c13
-rw-r--r--gcc/config/sparc/sparc.md20
2 files changed, 32 insertions, 1 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 20efb00c451..19ab54a1304 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 37ac1701b69..f67ee83d048 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))]
""