SOURCES: gcc-pr24419.patch (NEW) - major fix / ix86 prologue clobb...
pluto
pluto at pld-linux.org
Wed Oct 19 10:53:45 CEST 2005
Author: pluto Date: Wed Oct 19 08:53:45 2005 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- major fix / ix86 prologue clobbers memory when it shouldn't.
---- Files affected:
SOURCES:
gcc-pr24419.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/gcc-pr24419.patch
diff -u /dev/null SOURCES/gcc-pr24419.patch:1.1
--- /dev/null Wed Oct 19 10:53:45 2005
+++ SOURCES/gcc-pr24419.patch Wed Oct 19 10:53:40 2005
@@ -0,0 +1,183 @@
+
+ PR target/24419
+ * i386.c (pro_epilogue_adjust_stack): Add another argument to
+ indicate if memory should be clobbered or not. Adjust stack
+ pointer directly if memory shouldn't be clobbered.
+ (ix86_expand_prologue): Updated. Don't clobber member if
+ adjusting stack after registers have been saved on stack.
+ (ix86_expand_epilogue): Updated to call
+ pro_epilogue_adjust_stack with memory clobbered.
+
+ * i386.md: Don't convert stack pointer subtractions to push
+ when memory isn't clobbered if red zone is enabled.
+
+--- gcc/gcc/config/i386/i386.c 2005-10-18 17:26:40.000000000 -0700
++++ gcc/gcc/config/i386/i386.c 2005-10-18 20:35:19.000000000 -0700
+@@ -4761,22 +4761,38 @@ ix86_emit_save_regs_using_mov (rtx point
+ otherwise. */
+
+ static void
+-pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style)
++pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style,
++ bool clobber_memory)
+ {
+ rtx insn;
+
+ if (! TARGET_64BIT)
+- insn = emit_insn (gen_pro_epilogue_adjust_stack_1 (dest, src, offset));
++ {
++ if (clobber_memory)
++ insn = emit_insn (gen_pro_epilogue_adjust_stack_1 (dest, src,
++ offset));
++ else
++ insn = emit_insn (gen_addsi3 (dest, src, offset));
++ }
+ else if (x86_64_immediate_operand (offset, DImode))
+- insn = emit_insn (gen_pro_epilogue_adjust_stack_rex64 (dest, src, offset));
++ {
++ if (clobber_memory)
++ insn = emit_insn (gen_pro_epilogue_adjust_stack_rex64 (dest,
++ src,
++ offset));
++ else
++ insn = emit_insn (gen_adddi3 (dest, src, offset));
++ }
+ else
+ {
+ rtx r11;
+ /* r11 is used by indirect sibcall return as well, set before the
+ epilogue and used after the epilogue. ATM indirect sibcall
+ shouldn't be used together with huge frame sizes in one
+- function because of the frame_size check in sibcall.c. */
+- gcc_assert (style);
++ function because of the frame_size check in sibcall.c. If
++ huge frame size is used, memory should always be clobbered
++ when stack is adjusted. */
++ gcc_assert (style && clobber_memory);
+ r11 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
+ insn = emit_insn (gen_rtx_SET (DImode, r11, offset));
+ if (style < 0)
+@@ -4797,6 +4813,7 @@ ix86_expand_prologue (void)
+ bool pic_reg_used;
+ struct ix86_frame frame;
+ HOST_WIDE_INT allocate;
++ bool using_mov;
+
+ ix86_compute_frame_layout (&frame);
+
+@@ -4821,7 +4838,8 @@ ix86_expand_prologue (void)
+
+ /* When using red zone we may start register saving before allocating
+ the stack frame saving one cycle of the prologue. */
+- if (TARGET_RED_ZONE && frame.save_regs_using_mov)
++ using_mov = TARGET_RED_ZONE && frame.save_regs_using_mov;
++ if (using_mov)
+ ix86_emit_save_regs_using_mov (frame_pointer_needed ? hard_frame_pointer_rtx
+ : stack_pointer_rtx,
+ -frame.nregs * UNITS_PER_WORD);
+@@ -4830,7 +4848,7 @@ ix86_expand_prologue (void)
+ ;
+ else if (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)
+ pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+- GEN_INT (-allocate), -1);
++ GEN_INT (-allocate), -1, !using_mov);
+ else
+ {
+ /* Only valid for Win32. */
+@@ -5011,7 +5029,7 @@ ix86_expand_epilogue (int style)
+ emit_move_insn (hard_frame_pointer_rtx, tmp);
+
+ pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
+- const0_rtx, style);
++ const0_rtx, style, true);
+ }
+ else
+ {
+@@ -5025,7 +5043,7 @@ ix86_expand_epilogue (int style)
+ pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (frame.to_allocate
+ + frame.nregs * UNITS_PER_WORD),
+- style);
++ style, true);
+ /* If not an i386, mov & pop is faster than "leave". */
+ else if (TARGET_USE_LEAVE || optimize_size
+ || !cfun->machine->use_fast_prologue_epilogue)
+@@ -5034,7 +5052,7 @@ ix86_expand_epilogue (int style)
+ {
+ pro_epilogue_adjust_stack (stack_pointer_rtx,
+ hard_frame_pointer_rtx,
+- const0_rtx, style);
++ const0_rtx, style, true);
+ if (TARGET_64BIT)
+ emit_insn (gen_popdi1 (hard_frame_pointer_rtx));
+ else
+@@ -5050,11 +5068,12 @@ ix86_expand_epilogue (int style)
+ gcc_assert (frame_pointer_needed);
+ pro_epilogue_adjust_stack (stack_pointer_rtx,
+ hard_frame_pointer_rtx,
+- GEN_INT (offset), style);
++ GEN_INT (offset), style, true);
+ }
+ else if (frame.to_allocate)
+ pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+- GEN_INT (frame.to_allocate), style);
++ GEN_INT (frame.to_allocate), style,
++ true);
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (ix86_save_reg (regno, false))
+--- gcc/gcc/config/i386/i386.md 2005-10-18 17:26:40.000000000 -0700
++++ gcc/gcc/config/i386/i386.md 2005-10-18 17:26:40.000000000 -0700
+@@ -19532,11 +19532,15 @@
+ (clobber (mem:BLK (scratch)))])])
+
+ ;; Convert esp subtractions to push.
++;; This conversion is safe only under assumption that unallocated stack is
++;; implicitly clobbered as specified by 32bit ABI (for signal handlers and such).
++;; This is not valid with red zone, but we can work harder and enable the
++;; optimization for functions that are not using it.
+ (define_peephole2
+ [(match_scratch:SI 0 "r")
+ (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
+ (clobber (reg:CC FLAGS_REG))])]
+- "optimize_size || !TARGET_SUB_ESP_4"
++ "(optimize_size || !TARGET_SUB_ESP_4) && !TARGET_RED_ZONE"
+ [(clobber (match_dup 0))
+ (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
+
+@@ -19544,7 +19548,7 @@
+ [(match_scratch:SI 0 "r")
+ (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
+ (clobber (reg:CC FLAGS_REG))])]
+- "optimize_size || !TARGET_SUB_ESP_8"
++ "(optimize_size || !TARGET_SUB_ESP_8) && !TARGET_RED_ZONE"
+ [(clobber (match_dup 0))
+ (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
+ (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
+@@ -19664,11 +19668,15 @@
+ (clobber (mem:BLK (scratch)))])])
+
+ ;; Convert esp subtractions to push.
++;; This conversion is safe only under assumption that unallocated stack is
++;; implicitly clobbered as specified by 32bit ABI (for signal handlers and such).
++;; This is not valid with red zone, but we can work harder and enable the
++;; optimization for functions that are not using it.
+ (define_peephole2
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
+ (clobber (reg:CC FLAGS_REG))])]
+- "optimize_size || !TARGET_SUB_ESP_4"
++ "(optimize_size || !TARGET_SUB_ESP_4) && !TARGET_RED_ZONE"
+ [(clobber (match_dup 0))
+ (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
+
+@@ -19676,7 +19684,7 @@
+ [(match_scratch:DI 0 "r")
+ (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
+ (clobber (reg:CC FLAGS_REG))])]
+- "optimize_size || !TARGET_SUB_ESP_8"
++ "(optimize_size || !TARGET_SUB_ESP_8) && !TARGET_RED_ZONE"
+ [(clobber (match_dup 0))
+ (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
+ (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
+
================================================================
More information about the pld-cvs-commit
mailing list