From: Eric Botcazou Date: Fri, 16 Dec 2011 23:39:23 +0000 (+0000) Subject: sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant. X-Git-Tag: releases/gcc-4.5.4~319 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=115a99616ca7389131af901c95ae9d146840c930;p=thirdparty%2Fgcc.git sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant. * config/sparc/sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant. (frame_blockage): New expander. (frame_blockage): 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: r182422 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 304a9580d4b3..4beccabf492a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-12-16 Eric Botcazou + + * config/sparc/sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant. + (frame_blockage): New expander. + (frame_blockage): 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-13 Eric Botcazou * lto-streamer-out.c (write_symbol): Use proper 64-bit host type. diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index f812e3cc1b5e..0404b44e654c 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -4236,8 +4236,9 @@ sparc_expand_prologue (void) else if (actual_fsize <= 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-actual_fsize))); } @@ -4259,8 +4260,18 @@ sparc_expand_prologue (void) else if (actual_fsize <= 8192) { insn = emit_insn (gen_save_register_window (GEN_INT (-4096))); + /* %sp is not the CFA register anymore. */ emit_insn (gen_stack_pointer_inc (GEN_INT (4096-actual_fsize))); + + /* 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 a55a56a9397b..eddef724b6ad 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) @@ -6331,6 +6332,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" + [(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))] ""