summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
939ca63)
(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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182420
138bc75d-0d04-0410-961f-
82ee72b054a4
+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.
2011-12-16 Tristan Gingold <gingold@adacore.com>
* config/alpha/vms.h (USE_TM_CLONE_REGISTRY): Define.
else if (size <= 8192)
{
insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-4096)));
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;
RTX_FRAME_RELATED_P (insn) = 1;
+
+ /* %sp is still the CFA register. */
insn = emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
}
else
insn = emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
}
else
else if (size <= 8192)
{
emit_window_save (GEN_INT (-4096));
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)));
/* %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 ());
[(UNSPEC_MOVE_PIC 0)
(UNSPEC_UPDATE_RETURN 1)
(UNSPEC_LOAD_PCREL_SYM 2)
[(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)
(UNSPEC_MOVE_PIC_LABEL 5)
(UNSPEC_SETH44 6)
(UNSPEC_SETM44 7)
""
[(set_attr "length" "0")])
""
[(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))]
""
(define_expand "probe_stack"
[(set (match_operand 0 "memory_operand" "") (const_int 0))]
""