aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstuart <stuart@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-28 01:47:16 +0000
committerstuart <stuart@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-28 01:47:16 +0000
commite57006d8631eb5c97821c4b835be7514b0f3f1fd (patch)
treec80188f881ddf3000e21e33ce6e404877ffa55aa
parent99fc9835504e937657002792f30bc2b57d909660 (diff)
2006-02-17 Stuart Hastings <stuart@apple.com>apple/gcc-5325
* Radar 4356747 (marked APPLE LOCAL "4356747 stack realign") doc/extend.texi (force_align_arg_pointer): Document. doc/invoke.texi (-mstackrealign): Document. config/i386/i386.h (TARGET_OPTIONS): Add -mstackrealgin. config/i386/i386.c (ix86_force_align_arg_pointer): New. (ix86_force_align_arg_pointer_string): New. (ix86_attribute_table): Add "force_align_arg_pointer" attribute. (ix86_function_regparm): Compensate for new attribute. (ix86_internal_arg_pointer): Check for new attribute. 2005-11-02 Richard Henderson <rth@redhat.com> (marked APPLE LOCAL "mainline 2006-02-17 4356747 stack realign") PR target/9350 PR target/24374 * dwarf2out.c (dwarf2out_reg_save_reg): New. (dwarf2out_frame_debug_expr): Return after dwarf_handle_frame_unspec. * function.c (assign_parms): Use calls.internal_arg_pointer. (expand_main_function): Remove FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN code. * target-def.h (TARGET_INTERNAL_ARG_POINTER): New. (TARGET_CALLS): Add it. * target.h (struct gcc_target): Add calls.internal_arg_pointer. * targhooks.c (default_internal_arg_pointer): New. * targhooks.h (default_internal_arg_pointer): Declare. * tree.h (dwarf2out_reg_save_reg): Declare. * doc/tm.texi (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): Remove. * config/i386/i386.c (dbx_register_map): Add return column. (dbx64_register_map, svr4_dbx_register_map): Likewise. (TARGET_INTERNAL_ARG_POINTER, ix86_internal_arg_pointer): New. (TARGET_DWARF_HANDLE_FRAME_UNSPEC, ix86_dwarf_handle_frame_unspec): New. (ix86_function_ok_for_sibcall): Disable if force_align_arg_pointer. (ix86_save_reg): Save force_align_arg_pointer. (ix86_emit_save_regs): Make regno unsigned. (ix86_emit_save_regs_using_mov): Likewise. (ix86_expand_prologue): Handle force_align_arg_pointer. (ix86_expand_epilogue): Likewise. * config/i386/i386.h: (dbx_register_map): Update. (dbx64_register_map, svr4_dbx_register_map): Update. (struct machine_function): Add force_align_arg_pointer. * config/i386/i386.md (UNSPEC_REG_SAVE, UNSPEC_DEF_CFA): New. (UNSPEC_TP, UNSPEC_TLS_GD, UNSPEC_TLS_LD_BASE): Renumber. (TARGET_PUSH_MEMORY peepholes): Disable if RTX_FRAME_RELATED_P. 2006-02-27 Stuart Hastings <stuart@apple.com> Radar 4448096 * testsuite/gcc.target/i386/4448096-1.c: New. * testsuite/g++.dg/4448096-2.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/apple-local-200502-branch@111503 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.apple-ppc47
-rw-r--r--gcc/config/i386/i386-protos.h5
-rw-r--r--gcc/config/i386/i386.c213
-rw-r--r--gcc/config/i386/i386.h15
-rw-r--r--gcc/config/i386/i386.md35
-rw-r--r--gcc/doc/extend.texi16
-rw-r--r--gcc/doc/invoke.texi18
-rw-r--r--gcc/dwarf2out.c29
-rw-r--r--gcc/emit-rtl.c27
-rw-r--r--gcc/function.c57
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/target-def.h9
-rw-r--r--gcc/target.h6
-rw-r--r--gcc/targhooks.c19
-rw-r--r--gcc/targhooks.h3
-rw-r--r--gcc/testsuite/ChangeLog.apple-ppc8
-rw-r--r--gcc/testsuite/gcc.target/i386/20060210-1.c39
-rw-r--r--gcc/testsuite/gcc.target/i386/20060210-2.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/20060210-3.c39
-rw-r--r--gcc/testsuite/gcc.target/i386/20060210-4.c19
-rw-r--r--gcc/tree.h6
21 files changed, 555 insertions, 76 deletions
diff --git a/gcc/ChangeLog.apple-ppc b/gcc/ChangeLog.apple-ppc
index 6ce5864f83a..74bfa4dbc09 100644
--- a/gcc/ChangeLog.apple-ppc
+++ b/gcc/ChangeLog.apple-ppc
@@ -1,3 +1,50 @@
+2006-02-17 Stuart Hastings <stuart@apple.com>
+
+ * Radar 4356747
+ (marked APPLE LOCAL "4356747 stack realign")
+ doc/extend.texi (force_align_arg_pointer): Document.
+ doc/invoke.texi (-mstackrealign): Document.
+ config/i386/i386.h (TARGET_OPTIONS): Add -mstackrealgin.
+ config/i386/i386.c (ix86_force_align_arg_pointer): New.
+ (ix86_force_align_arg_pointer_string): New.
+ (ix86_attribute_table): Add "force_align_arg_pointer" attribute.
+ (ix86_function_regparm): Compensate for new attribute.
+ (ix86_internal_arg_pointer): Check for new attribute.
+
+2005-11-02 Richard Henderson <rth@redhat.com>
+
+ (marked APPLE LOCAL "mainline 2006-02-17 4356747 stack realign")
+ PR target/9350
+ PR target/24374
+ * dwarf2out.c (dwarf2out_reg_save_reg): New.
+ (dwarf2out_frame_debug_expr): Return after dwarf_handle_frame_unspec.
+ * function.c (assign_parms): Use calls.internal_arg_pointer.
+ (expand_main_function): Remove FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
+ code.
+ * target-def.h (TARGET_INTERNAL_ARG_POINTER): New.
+ (TARGET_CALLS): Add it.
+ * target.h (struct gcc_target): Add calls.internal_arg_pointer.
+ * targhooks.c (default_internal_arg_pointer): New.
+ * targhooks.h (default_internal_arg_pointer): Declare.
+ * tree.h (dwarf2out_reg_save_reg): Declare.
+ * doc/tm.texi (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): Remove.
+ * config/i386/i386.c (dbx_register_map): Add return column.
+ (dbx64_register_map, svr4_dbx_register_map): Likewise.
+ (TARGET_INTERNAL_ARG_POINTER, ix86_internal_arg_pointer): New.
+ (TARGET_DWARF_HANDLE_FRAME_UNSPEC, ix86_dwarf_handle_frame_unspec): New.
+ (ix86_function_ok_for_sibcall): Disable if force_align_arg_pointer.
+ (ix86_save_reg): Save force_align_arg_pointer.
+ (ix86_emit_save_regs): Make regno unsigned.
+ (ix86_emit_save_regs_using_mov): Likewise.
+ (ix86_expand_prologue): Handle force_align_arg_pointer.
+ (ix86_expand_epilogue): Likewise.
+ * config/i386/i386.h: (dbx_register_map): Update.
+ (dbx64_register_map, svr4_dbx_register_map): Update.
+ (struct machine_function): Add force_align_arg_pointer.
+ * config/i386/i386.md (UNSPEC_REG_SAVE, UNSPEC_DEF_CFA): New.
+ (UNSPEC_TP, UNSPEC_TLS_GD, UNSPEC_TLS_LD_BASE): Renumber.
+ (TARGET_PUSH_MEMORY peepholes): Disable if RTX_FRAME_RELATED_P.
+
2006-02-27 Stuart Hastings <stuart@apple.com>
Radar 4448096
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 226326da18f..53b52aa72ca 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -285,3 +285,8 @@ extern bool cw_print_op (char *buf, tree arg, unsigned argnum, tree *uses,
bool must_be_reg, bool must_not_be_reg, void *);
extern void x86_cw_print_prefix (char *buf, tree prefix_list);
/* APPLE LOCAL end CW asm blocks */
+
+/* APPLE LOCAL begin 4356747 stack realign */
+/* Note to merger: this decl will vanish when the i386.opt file arrives in the merge. */
+extern int ix86_force_align_arg_pointer;
+/* APPLE LOCAL end 4356747 stack realign */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 123400c734a..6d2302e92b4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -664,7 +664,8 @@ enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
/* The "default" register map used in 32bit mode. */
-int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+int const dbx_register_map[FIRST_PSEUDO_REGISTER+1] =
{
0, 2, 1, 3, 6, 7, 4, 5, /* general regs */
12, 13, 14, 15, 16, 17, 18, 19, /* fp regs */
@@ -673,7 +674,9 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
29, 30, 31, 32, 33, 34, 35, 36, /* MMX */
-1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */
-1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
+ 8 /* return column */
};
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
static int const x86_64_int_parameter_registers[6] =
{
@@ -687,7 +690,8 @@ static int const x86_64_int_return_registers[4] =
};
/* The "default" register map used in 64bit mode. */
-int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+int const dbx64_register_map[FIRST_PSEUDO_REGISTER+1] =
{
0, 1, 2, 3, 4, 5, 6, 7, /* general regs */
33, 34, 35, 36, 37, 38, 39, 40, /* fp regs */
@@ -696,7 +700,9 @@ int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
41, 42, 43, 44, 45, 46, 47, 48, /* MMX */
8,9,10,11,12,13,14,15, /* extended integer registers */
25, 26, 27, 28, 29, 30, 31, 32, /* extended SSE registers */
+ 16 /* return column */
};
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
/* Define the register numbers to be used in Dwarf debugging information.
The SVR4 reference port C compiler uses the following register numbers
@@ -752,7 +758,8 @@ int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
17 for %st(6) (gcc regno = 14)
18 for %st(7) (gcc regno = 15)
*/
-int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER+1] =
{
0, 2, 1, 3, 6, 7, 5, 4, /* general regs */
11, 12, 13, 14, 15, 16, 17, 18, /* fp regs */
@@ -761,7 +768,9 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
29, 30, 31, 32, 33, 34, 35, 36, /* MMX registers */
-1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */
-1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
+ 8 /* return column */
};
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
/* Test and compare insns in i386.md store the information needed to
generate branch and scc insns here. */
@@ -869,6 +878,25 @@ const char *ix86_align_jumps_string;
/* Power of two alignment for stack boundary in bytes. */
const char *ix86_preferred_stack_boundary_string;
+/* APPLE LOCAL begin 4356747 stack realign */
+/* -mstackrealign option */
+/* extern *//* Note #1 to merger: This decl will move to "i386.opt" in
+ the next FSF merge, and then we'll need an 'extern'
+ here. */
+const char *ix86_force_align_arg_pointer;
+static const char const ix86_force_align_arg_pointer_string[] = "force_align_arg_pointer";
+/* Note #2 to merger: The -mstackrealign stuff was submitted to FSF trunk
+on 10feb2006: http://gcc.gnu.org/ml/gcc-patches/2006-02/msg00854.html
+Apple needed this enhancement promptly (before the FSF acted on that patch), so
+A) I copied in a previous, necessary trunk patch:
+ http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00931.html
+ This patch is marked "mainline 2006-02-17 4356747 stack realign".
+B) I added my own patch (URL above), marked "4356747 stack realign".
+C) I had to modify my patch to work without the "i386.opt" file (I was too lazy
+to merge this non-trivial change into Apple's Curry branch).
+HTH. */
+/* APPLE LOCAL end 4356747 stack realign */
+
/* Preferred alignment for stack boundary in bits. */
unsigned int ix86_preferred_stack_boundary;
@@ -977,6 +1005,11 @@ static bool ix86_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
static void ix86_init_builtins (void);
static rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+static rtx ix86_internal_arg_pointer (void);
+static void ix86_dwarf_handle_frame_unspec (const char *, rtx, int);
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* This function is only used on Solaris. */
static void i386_solaris_elf_named_section (const char *, unsigned int, tree)
ATTRIBUTE_UNUSED;
@@ -1129,6 +1162,12 @@ static void init_ext_80387_constants (void);
#define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+#undef TARGET_INTERNAL_ARG_POINTER
+#define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
+#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
+#define TARGET_DWARF_HANDLE_FRAME_UNSPEC ix86_dwarf_handle_frame_unspec
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
@@ -1789,6 +1828,11 @@ const struct attribute_spec ix86_attribute_table[] =
{ "regparmandstackparm", 0, 0, false, true, true, ix86_handle_cconv_attribute },
{ "regparmandstackparmee", 0, 0, false, true, true, ix86_handle_cconv_attribute },
/* APPLE LOCAL end regparmandstackparm */
+ /* APPLE LOCAL begin 4356747 stack realign */
+ /* force_align_arg_pointer says this function realigns the stack at entry. */
+ { ix86_force_align_arg_pointer_string, 0, 0,
+ false, true, true, ix86_handle_cconv_attribute },
+ /* APPLE LOCAL end 4356747 stack realign */
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
{ "dllimport", 0, 0, false, false, false, handle_dll_attribute },
{ "dllexport", 0, 0, false, false, false, handle_dll_attribute },
@@ -1872,6 +1916,13 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
return false;
#endif
+ /* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+ /* If we forced aligned the stack, then sibcalling would unalign the
+ stack, which may break the called function. */
+ if (cfun->machine->force_align_arg_pointer)
+ return false;
+ /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* Otherwise okay. That also includes certain types of indirect calls. */
return true;
}
@@ -1993,6 +2044,8 @@ ix86_handle_cconv_attribute (tree *node, tree name,
}
/* Can combine sseregparm with all attributes. */
+ /* APPLE LOCAL 4356747 stack realign */
+ /* Can combine force_align_arg_pointer with all attributes. */
return NULL_TREE;
}
@@ -2039,8 +2092,9 @@ ix86_comp_type_attributes (tree type1, tree type2)
static int
ix86_function_regparm (tree type, tree decl)
{
+ /* APPLE LOCAL mainline 2006-02-17 4356747 stack realign (function body) */
tree attr;
- int regparm = ix86_regparm;
+ int local_regparm = ix86_regparm;
bool user_convention = false;
if (!TARGET_64BIT)
@@ -2048,7 +2102,7 @@ ix86_function_regparm (tree type, tree decl)
attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
if (attr)
{
- regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+ local_regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
user_convention = true;
}
@@ -2057,7 +2111,7 @@ ix86_function_regparm (tree type, tree decl)
|| lookup_attribute ("regparmandstackparmee", TYPE_ATTRIBUTES (type)))
/* APPLE LOCAL end regparmandstackparm */
{
- regparm = 2;
+ local_regparm = 2;
user_convention = true;
}
@@ -2071,13 +2125,18 @@ ix86_function_regparm (tree type, tree decl)
/* We can't use regparm(3) for nested functions as these use
static chain pointer in third argument. */
if (DECL_CONTEXT (decl) && !DECL_NO_STATIC_CHAIN (decl))
- regparm = 2;
+ local_regparm = 2;
else
- regparm = 3;
+ local_regparm = 3;
+ /* If the function realigns its stackpointer, it
+ clobbers %ecx to deref unaligned arguments. */
+ if (cfun->machine->force_align_arg_pointer)
+ local_regparm = 2;
}
}
}
- return regparm;
+ return local_regparm;
+ /* APPLE LOCAL end 4356747 stack realign (function body) */
}
/* APPLE LOCAL begin mainline 2005-09-20 4205103 */
@@ -4454,6 +4513,12 @@ ix86_save_reg (unsigned int regno, int maybe_eh_return)
}
}
+ /* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+ if (cfun->machine->force_align_arg_pointer
+ && regno == REGNO (cfun->machine->force_align_arg_pointer))
+ return 1;
+ /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
return (regs_ever_live[regno]
&& !call_used_regs[regno]
&& !fixed_regs[regno]
@@ -4669,15 +4734,17 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
static void
ix86_emit_save_regs (void)
{
- int regno;
+ /* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign (function body) */
+ unsigned int regno;
rtx insn;
- for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
+ for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0; )
if (ix86_save_reg (regno, true))
{
insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
RTX_FRAME_RELATED_P (insn) = 1;
}
+ /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign (function body) */
}
/* Emit code to save registers using MOV insns. First register
@@ -4685,7 +4752,8 @@ ix86_emit_save_regs (void)
static void
ix86_emit_save_regs_using_mov (rtx pointer, HOST_WIDE_INT offset)
{
- int regno;
+ /* APPLE LOCAL mainline 2006-02-17 4356747 stack realign */
+ unsigned int regno;
rtx insn;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
@@ -4740,6 +4808,70 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style)
#endif
/* APPLE LOCAL end fix-and-continue x86 */
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+/* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
+
+static rtx
+ix86_internal_arg_pointer (void)
+{
+ /* APPLE LOCAL begin 4356747 stack realign */
+ /* Note to merger: this function is from FSF mainline, AND it has
+ been altered with a local patch that is pending in FSF. */
+ bool has_force_align_arg_pointer =
+ (0 != lookup_attribute (ix86_force_align_arg_pointer_string,
+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))));
+ if ((FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
+ && DECL_NAME (current_function_decl)
+ && MAIN_NAME_P (DECL_NAME (current_function_decl))
+ && DECL_FILE_SCOPE_P (current_function_decl))
+ || ix86_force_align_arg_pointer
+ || has_force_align_arg_pointer)
+ {
+ /* Nested functions can't realign the stack due to a register
+ conflict. */
+ if (DECL_CONTEXT (current_function_decl)
+ && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL)
+ {
+ if (ix86_force_align_arg_pointer)
+ warning ("-mstackrealign ignored for nested functions");
+ if (has_force_align_arg_pointer)
+ error ("%s not supported for nested functions",
+ ix86_force_align_arg_pointer_string);
+ return virtual_incoming_args_rtx;
+ }
+ cfun->machine->force_align_arg_pointer = gen_rtx_REG (Pmode, 2);
+ return copy_to_reg (cfun->machine->force_align_arg_pointer);
+ }
+ else
+ return virtual_incoming_args_rtx;
+ /* APPLE LOCAL end 4356747 stack realign */
+}
+
+/* Handle the TARGET_DWARF_HANDLE_FRAME_UNSPEC hook.
+ This is called from dwarf2out.c to emit call frame instructions
+ for frame-related insns containing UNSPECs and UNSPEC_VOLATILEs. */
+static void
+ix86_dwarf_handle_frame_unspec (const char *label, rtx pattern, int index)
+{
+ rtx unspec = SET_SRC (pattern);
+ gcc_assert (GET_CODE (unspec) == UNSPEC);
+
+ switch (index)
+ {
+ case UNSPEC_REG_SAVE:
+ dwarf2out_reg_save_reg (label, XVECEXP (unspec, 0, 0),
+ SET_DEST (pattern));
+ break;
+ case UNSPEC_DEF_CFA:
+ dwarf2out_def_cfa (label, REGNO (SET_DEST (pattern)),
+ INTVAL (XVECEXP (unspec, 0, 0)));
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* Expand the prologue into a bunch of separate insns. */
void
@@ -4769,6 +4901,54 @@ ix86_expand_prologue (void)
ix86_compute_frame_layout (&frame);
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+ if (cfun->machine->force_align_arg_pointer)
+ {
+ rtx x, y;
+
+ /* Grab the argument pointer. */
+ x = plus_constant (stack_pointer_rtx, 4);
+ y = cfun->machine->force_align_arg_pointer;
+ insn = emit_insn (gen_rtx_SET (VOIDmode, y, x));
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ /* The unwind info consists of two parts: install the fafp as the cfa,
+ and record the fafp as the "save register" of the stack pointer.
+ The later is there in order that the unwinder can see where it
+ should restore the stack pointer across the and insn. */
+ x = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), UNSPEC_DEF_CFA);
+ x = gen_rtx_SET (VOIDmode, y, x);
+ RTX_FRAME_RELATED_P (x) = 1;
+ y = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, stack_pointer_rtx),
+ UNSPEC_REG_SAVE);
+ y = gen_rtx_SET (VOIDmode, cfun->machine->force_align_arg_pointer, y);
+ RTX_FRAME_RELATED_P (y) = 1;
+ x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x, y));
+ x = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, x, NULL);
+ REG_NOTES (insn) = x;
+
+ /* Align the stack. */
+ emit_insn (gen_andsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-16)));
+
+ /* And here we cheat like madmen with the unwind info. We force the
+ cfa register back to sp+4, which is exactly what it was at the
+ start of the function. Re-pushing the return address results in
+ the return at the same spot relative to the cfa, and thus is
+ correct wrt the unwind info. */
+ x = cfun->machine->force_align_arg_pointer;
+ x = gen_frame_mem (Pmode, plus_constant (x, -4));
+ insn = emit_insn (gen_push (x));
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ x = GEN_INT (4);
+ x = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, x), UNSPEC_DEF_CFA);
+ x = gen_rtx_SET (VOIDmode, stack_pointer_rtx, x);
+ x = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, x, NULL);
+ REG_NOTES (insn) = x;
+ }
+ /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* Note: AT&T enter does NOT have reversed args. Enter is probably
slower on all targets. Also sdb doesn't like it. */
@@ -5059,6 +5239,15 @@ ix86_expand_epilogue (int style)
}
}
+ /* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+ if (cfun->machine->force_align_arg_pointer)
+ {
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ cfun->machine->force_align_arg_pointer,
+ GEN_INT (-4)));
+ }
+ /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* Sibcall epilogues don't want a return instruction. */
if (style == 0)
return;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 323cf47faa5..b02a6c51f47 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -517,6 +517,11 @@ extern int x86_prefetch_sse;
N_("Use given assembler dialect"), 0}, \
{ "tls-dialect=", &ix86_tls_dialect_string, \
N_("Use given thread-local storage dialect"), 0}, \
+ /* APPLE LOCAL begin 4356747 stack realign */ \
+ { "stackrealign", \
+ &ix86_force_align_arg_pointer, \
+ N_("Realign stack in prologue"), 0}, \
+ /* APPLE LOCAL end 4356747 stack realign */ \
SUBTARGET_OPTIONS \
}
@@ -2288,9 +2293,11 @@ number as al, and ax.
#define DBX_REGISTER_NUMBER(N) \
(TARGET_64BIT ? dbx64_register_map[(N)] : dbx_register_map[(N)])
-extern int const dbx_register_map[FIRST_PSEUDO_REGISTER];
-extern int const dbx64_register_map[FIRST_PSEUDO_REGISTER];
-extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+extern int const dbx_register_map[FIRST_PSEUDO_REGISTER+1];
+extern int const dbx64_register_map[FIRST_PSEUDO_REGISTER+1];
+extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER+1];
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
/* Before the prologue, RA is at 0(%esp). */
#define INCOMING_RETURN_ADDR_RTX \
@@ -2587,6 +2594,8 @@ struct machine_function GTY(())
{
struct stack_local_entry *stack_locals;
const char *some_ld_name;
+ /* APPLE LOCAL mainline 2006-02-17 4356747 stack realign */
+ rtx force_align_arg_pointer;
int save_varrargs_registers;
int accesses_prev_frame;
int optimize_mode_switching;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index a61c80bdea7..ddedbbc375e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -66,11 +66,15 @@
(UNSPEC_STACK_ALLOC 11)
(UNSPEC_SET_GOT 12)
(UNSPEC_SSE_PROLOGUE_SAVE 13)
+ ; APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign
+ (UNSPEC_REG_SAVE 14)
+ (UNSPEC_DEF_CFA 15)
; TLS support
- (UNSPEC_TP 15)
- (UNSPEC_TLS_GD 16)
- (UNSPEC_TLS_LD_BASE 17)
+ (UNSPEC_TP 16)
+ (UNSPEC_TLS_GD 17)
+ (UNSPEC_TLS_LD_BASE 18)
+ ; APPLE LOCAL end mainline 2006-02-17 4356747 stack realign
; Other random patterns
(UNSPEC_SCAS 20)
@@ -18511,7 +18515,10 @@
[(set (match_operand:SI 0 "push_operand" "")
(match_operand:SI 1 "memory_operand" ""))
(match_scratch:SI 2 "r")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ ;; APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
+ ;; APPLE LOCAL end mainline 2006-02-17 4356747 stack realign
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
@@ -18520,7 +18527,10 @@
[(set (match_operand:DI 0 "push_operand" "")
(match_operand:DI 1 "memory_operand" ""))
(match_scratch:DI 2 "r")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ ;; APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
+ ;; APPLE LOCAL end mainline 2006-02-17 4356747 stack realign
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
@@ -18531,7 +18541,10 @@
[(set (match_operand:SF 0 "push_operand" "")
(match_operand:SF 1 "memory_operand" ""))
(match_scratch:SF 2 "r")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ ;; APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
+ ;; APPLE LOCAL end mainline 2006-02-17 4356747 stack realign
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
@@ -18540,7 +18553,10 @@
[(set (match_operand:HI 0 "push_operand" "")
(match_operand:HI 1 "memory_operand" ""))
(match_scratch:HI 2 "r")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ ;; APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
+ ;; APPLE LOCAL end mainline 2006-02-17 4356747 stack realign
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
@@ -18549,7 +18565,10 @@
[(set (match_operand:QI 0 "push_operand" "")
(match_operand:QI 1 "memory_operand" ""))
(match_scratch:QI 2 "q")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ ;; APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
+ ;; APPLE LOCAL end mainline 2006-02-17 4356747 stack realign
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index e91ca054a12..c655b8fb9d2 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2168,6 +2168,22 @@ safe since the loaders there save all registers. (Lazy binding can be
disabled with the linker or the loader if desired, to avoid the
problem.)
+@c APPLE LOCAL begin 4356747 stack realign
+@item force_align_arg_pointer
+@cindex @code{force_align_arg_pointer} attribute
+On the Intel x86, the @code{force_align_arg_pointer} attribute may be
+applied to individual function definitions, generating an alternate
+prologue and epilogue that realigns the runtime stack. This supports
+mixing legacy codes that run with a 4-byte aligned stack with modern
+codes that keep a 16-byte stack for SSE compatibility. The alternate
+prologue/epilogue is slower and bigger than the regular one, and it
+requires one dedicated register for the life of the function. This
+also lowers the number of registers available if used in conjunction
+with the @code{regparm} attribute. The @code{force_align_arg_pointer}
+attribute is incompatible with nested functions; this is considered a
+hard error.
+@c APPLE LOCAL end 4356747 stack realign
+
@item saveall
@cindex save all registers on the Blackfin, H8/300, H8/300H, and H8S
Use this attribute on the Blackfin, H8/300, H8/300H, and H8S to indicate that
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ac974df892b..618e3fd1296 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -374,6 +374,8 @@ Objective-C and Objective-C++ Dialects}.
-fno-inline -fno-math-errno -fno-peephole -fno-peephole2 @gol
-funsafe-math-optimizations -ffinite-math-only @gol
-fno-trapping-math -fno-zero-initialized-in-bss @gol
+@c APPLE LOCAL 4356747 stack realign
+-mstackrealign @gol
-fomit-frame-pointer -foptimize-register-move @gol
-foptimize-sibling-calls -fprefetch-loop-arrays @gol
-fprofile-generate -fprofile-use @gol
@@ -9468,6 +9470,22 @@ function by using the function attribute @samp{regparm}.
value, including any libraries. This includes the system libraries and
startup modules.
+@c APPLE LOCAL begin 4356747 stack realign
+@item -mstackrealign
+@opindex mstackrealign
+Realign the stack at entry. On the Intel x86, the
+@option{-mstackrealign} option will generate an alternate
+prologue/epilogue that realigns the runtime stack. This supports
+mixing legacy codes that keep a 4-byte aligned stack with modern codes
+that keep a 16-byte stack for SSE compatibility. The alternate
+prologue and epilogue are slower and bigger than the regular ones, and
+they require one dedicated register for the entire function. This
+also lowers the number of registers available if used in conjunction
+with the @code{regparm} attribute. Nested functions encountered while
+@option{-mstackrealign} is on will generate warnings, and they will
+not realign the stack when called.
+@c APPLE LOCAL end 4356747 stack realign
+
@item -mpreferred-stack-boundary=@var{num}
@opindex mpreferred-stack-boundary
Attempt to keep the stack boundary aligned to a 2 raised to @var{num}
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3d07181e1d6..255726038de 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -1258,6 +1258,32 @@ clobbers_queued_reg_save (rtx insn)
return false;
}
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+/* Entry point for saving the first register into the second. */
+
+void
+dwarf2out_reg_save_reg (const char *label, rtx reg, rtx sreg)
+{
+ size_t i;
+ unsigned int regno, sregno;
+
+ for (i = 0; i < num_regs_saved_in_regs; i++)
+ if (REGNO (regs_saved_in_regs[i].orig_reg) == REGNO (reg))
+ break;
+ if (i == num_regs_saved_in_regs)
+ {
+ gcc_assert (i != ARRAY_SIZE (regs_saved_in_regs));
+ num_regs_saved_in_regs++;
+ }
+ regs_saved_in_regs[i].orig_reg = reg;
+ regs_saved_in_regs[i].saved_in_reg = sreg;
+
+ regno = DWARF_FRAME_REGNUM (REGNO (reg));
+ sregno = DWARF_FRAME_REGNUM (REGNO (sreg));
+ reg_save (label, regno, sregno, 0);
+}
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* What register, if any, is currently saved in REG? */
static rtx
@@ -1646,7 +1672,8 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
case UNSPEC_VOLATILE:
gcc_assert (targetm.dwarf_handle_frame_unspec);
targetm.dwarf_handle_frame_unspec (label, expr, XINT (src, 1));
- break;
+ /* APPLE LOCAL mainline 2006-02-17 4356747 stack realign */
+ return;
default:
gcc_unreachable ();
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 37bd66587d8..606b76b2e0f 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -606,6 +606,33 @@ gen_const_mem (enum machine_mode mode, rtx addr)
return mem;
}
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+/* Generate a MEM referring to fixed portions of the frame, e.g., register
+ save areas. */
+
+rtx
+gen_frame_mem (enum machine_mode mode, rtx addr)
+{
+ rtx mem = gen_rtx_MEM (mode, addr);
+ MEM_NOTRAP_P (mem) = 1;
+ set_mem_alias_set (mem, get_frame_alias_set ());
+ return mem;
+}
+
+/* Generate a MEM referring to a temporary use of the stack, not part
+ of the fixed stack frame. For example, something which is pushed
+ by a target splitter. */
+rtx
+gen_tmp_stack_mem (enum machine_mode mode, rtx addr)
+{
+ rtx mem = gen_rtx_MEM (mode, addr);
+ MEM_NOTRAP_P (mem) = 1;
+ if (!current_function_calls_alloca)
+ set_mem_alias_set (mem, get_frame_alias_set ());
+ return mem;
+}
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* We want to create (subreg:OMODE (obj:IMODE) OFFSET). Return true if
this construct would be valid, and false otherwise. */
diff --git a/gcc/function.c b/gcc/function.c
index f17dd551ad5..5ea2def46d4 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -3061,24 +3061,14 @@ assign_parms (tree fndecl)
{
struct assign_parm_data_all all;
tree fnargs, parm;
- rtx internal_arg_pointer;
+ /* APPLE LOCAL deletion mainline 2006-02-17 4356747 stack realign */
/* APPLE LOCAL AltiVec */
int pass, last_pass;
- /* If the reg that the virtual arg pointer will be translated into is
- not a fixed reg or is the stack pointer, make a copy of the virtual
- arg pointer, and address parms via the copy. The frame pointer is
- considered fixed even though it is not marked as such.
-
- The second time through, simply use ap to avoid generating rtx. */
-
- if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
- || ! (fixed_regs[ARG_POINTER_REGNUM]
- || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
- internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
- else
- internal_arg_pointer = virtual_incoming_args_rtx;
- current_function_internal_arg_pointer = internal_arg_pointer;
+ /* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+ current_function_internal_arg_pointer
+ = targetm.calls.internal_arg_pointer ();
+ /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
assign_parms_initialize_all (&all);
fnargs = assign_parms_augmented_arg_list (&all);
@@ -4093,42 +4083,7 @@ init_function_for_compilation (void)
void
expand_main_function (void)
{
-#ifdef FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
- if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN)
- {
- int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
- rtx tmp, seq;
-
- start_sequence ();
- /* Forcibly align the stack. */
-#ifdef STACK_GROWS_DOWNWARD
- tmp = expand_simple_binop (Pmode, AND, stack_pointer_rtx, GEN_INT(-align),
- stack_pointer_rtx, 1, OPTAB_WIDEN);
-#else
- tmp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
- GEN_INT (align - 1), NULL_RTX, 1, OPTAB_WIDEN);
- tmp = expand_simple_binop (Pmode, AND, tmp, GEN_INT (-align),
- stack_pointer_rtx, 1, OPTAB_WIDEN);
-#endif
- if (tmp != stack_pointer_rtx)
- emit_move_insn (stack_pointer_rtx, tmp);
-
- /* Enlist allocate_dynamic_stack_space to pick up the pieces. */
- tmp = force_reg (Pmode, const0_rtx);
- allocate_dynamic_stack_space (tmp, NULL_RTX, BIGGEST_ALIGNMENT);
- seq = get_insns ();
- end_sequence ();
-
- for (tmp = get_last_insn (); tmp; tmp = PREV_INSN (tmp))
- if (NOTE_P (tmp) && NOTE_LINE_NUMBER (tmp) == NOTE_INSN_FUNCTION_BEG)
- break;
- if (tmp)
- emit_insn_before (seq, tmp);
- else
- emit_insn (seq);
- }
-#endif
-
+ /* APPLE LOCAL deletion mainline 2006-02-17 4356747 stack realign */
#ifndef HAS_INIT_SECTION
emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
#endif
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 2d45ee6a81a..f7489f5f310 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1967,6 +1967,8 @@ extern rtx delete_insn_and_edges (rtx);
extern void delete_insn_chain_and_edges (rtx, rtx);
extern rtx gen_lowpart_SUBREG (enum machine_mode, rtx);
extern rtx gen_const_mem (enum machine_mode, rtx);
+/* APPLE LOCAL mainline 2006-02-17 4356747 stack realign */
+extern rtx gen_frame_mem (enum machine_mode, rtx);
extern bool validate_subreg (enum machine_mode, enum machine_mode,
rtx, unsigned int);
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 27a48a141fc..8fbdc56bdf4 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -433,6 +433,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
#define TARGET_ARG_PARTIAL_BYTES hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+#define TARGET_INTERNAL_ARG_POINTER default_internal_arg_pointer
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* APPLE LOCAL begin mainline 2005-04-14 */
#define TARGET_CALLS { \
TARGET_PROMOTE_FUNCTION_ARGS, \
@@ -453,7 +457,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_MUST_PASS_IN_STACK, \
TARGET_CALLEE_COPIES, \
TARGET_ARG_PARTIAL_BYTES, \
- TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN \
+ /* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */ \
+ TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \
+ TARGET_INTERNAL_ARG_POINTER \
+ /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */ \
}
/* APPLE LOCAL end mainline 2005-04-14 */
diff --git a/gcc/target.h b/gcc/target.h
index 67c42fa5545..220663cd0e0 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -576,6 +576,12 @@ struct gcc_target
const char *(*invalid_arg_for_unprototyped_fn) (tree typelist,
tree funcdecl, tree val);
/* APPLE LOCAL end mainline 2005-04-14 */
+
+ /* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+ /* Return an rtx for the argument pointer incoming to the
+ current function. */
+ rtx (*internal_arg_pointer) (void);
+ /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
} calls;
/* Functions specific to the C++ frontend. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index c231e03f1e9..fc69a42510a 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -61,6 +61,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "tm_p.h"
#include "target-def.h"
+/* APPLE LOCAL mainline 2006-02-17 4356747 stack realign */
+#include "hard-reg-set.h"
void
@@ -309,3 +311,20 @@ hook_invalid_arg_for_unprototyped_fn (
return NULL;
}
/* APPLE LOCAL end mainline 2005-04-14 */
+
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+rtx
+default_internal_arg_pointer (void)
+{
+ /* If the reg that the virtual arg pointer will be translated into is
+ not a fixed reg or is the stack pointer, make a copy of the virtual
+ arg pointer, and address parms via the copy. The frame pointer is
+ considered fixed even though it is not marked as such. */
+ if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
+ || ! (fixed_regs[ARG_POINTER_REGNUM]
+ || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
+ return copy_to_reg (virtual_incoming_args_rtx);
+ else
+ return virtual_incoming_args_rtx;
+}
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index eccdf80d38e..2d3dde9c464 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -65,3 +65,6 @@ extern int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
extern const char *hook_invalid_arg_for_unprototyped_fn
(tree, tree, tree);
/* APPLE LOCAL end mainline 2005-04-14 */
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+extern rtx default_internal_arg_pointer (void);
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
diff --git a/gcc/testsuite/ChangeLog.apple-ppc b/gcc/testsuite/ChangeLog.apple-ppc
index d9d91f6cf5b..fe7416f9d70 100644
--- a/gcc/testsuite/ChangeLog.apple-ppc
+++ b/gcc/testsuite/ChangeLog.apple-ppc
@@ -19,6 +19,14 @@
2006-02-17 Stuart Hastings <stuart@apple.com>
+ Radar 4356747
+ testsuite/gcc.target/i386/20060210-1.c: New.
+ testsuite/gcc.target/i386/20060210-2.c: New.
+ testsuite/gcc.target/i386/20060210-3.c: New.
+ testsuite/gcc.target/i386/20060210-4.c: New.
+
+2006-02-17 Stuart Hastings <stuart@apple.com>
+
* gcc.dg/4176531.c: Fix target.
2006-02-16 Mike Stump <mrs@apple.com>
diff --git a/gcc/testsuite/gcc.target/i386/20060210-1.c b/gcc/testsuite/gcc.target/i386/20060210-1.c
new file mode 100644
index 00000000000..63d2ce66488
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/20060210-1.c
@@ -0,0 +1,39 @@
+/* APPLE LOCAL file 4356747 stack realign */
+/* { dg-do run { target i?86-*-darwin* i[6789]86-*-* } } */
+/* APPLE LOCAL Note: if/when this file arrives in a merge, the FSF
+ version probably won't have the -fnested-functions option, and it's
+ required on OS X. */
+/* { dg-options "-std=gnu99 -fnested-functions" } */
+#include <stdio.h>
+#include <stdlib.h>
+#include <emmintrin.h>
+
+
+__m128i __attribute__ ((__noinline__))
+vector_using_function ()
+{
+ volatile __m128i vx; /* We want to force a vector-aligned store into the stack. */
+ vx = _mm_xor_si128 (vx, vx);
+ return vx;
+}
+
+int __attribute__ ((__noinline__, __force_align_arg_pointer__))
+self_aligning_function (int x, int y)
+{
+ __m128i ignored = vector_using_function ();
+ return (x + y);
+}
+
+int g_1 = 20;
+int g_2 = 22;
+
+int
+main ()
+{
+ int result;
+ asm ("pushl %esi"); /* Disalign runtime stack. */
+ result = self_aligning_function (g_1, g_2);
+ asm ("popl %esi");
+ if (result != 42)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/20060210-2.c b/gcc/testsuite/gcc.target/i386/20060210-2.c
new file mode 100644
index 00000000000..dee3cb7ea68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/20060210-2.c
@@ -0,0 +1,19 @@
+/* APPLE LOCAL file 4356747 stack realign */
+/* { dg-do compile { target i?86-*-darwin* i[6789]86-*-* } } */
+/* APPLE LOCAL Note: if/when this file arrives in a merge, the FSF
+ version probably won't have the -fnested-functions option, and it's
+ required on OS X. */
+/* { dg-options "-std=gnu99 -fnested-functions" } */
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+outer_function (int x, int y)
+{
+ int __attribute__ ((__noinline__, __force_align_arg_pointer__))
+ nested_function (int x, int y)
+ { /* { dg-error "force_align_arg_pointer not supported for nested functions" } */
+ return (x + y);
+ }
+ return (3 + nested_function (x, y));
+}
diff --git a/gcc/testsuite/gcc.target/i386/20060210-3.c b/gcc/testsuite/gcc.target/i386/20060210-3.c
new file mode 100644
index 00000000000..efd3f50e386
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/20060210-3.c
@@ -0,0 +1,39 @@
+/* APPLE LOCAL file 4356747 stack realign */
+/* { dg-do run { target i?86-*-darwin* i[6789]86-*-* } } */
+/* APPLE LOCAL Note: if/when this file arrives in a merge, the FSF
+ version probably won't have the -fnested-functions option, and it's
+ required on OS X. */
+/* { dg-options "-std=gnu99 -fnested-functions -mstackrealign" } */
+#include <stdio.h>
+#include <stdlib.h>
+#include <emmintrin.h>
+
+
+__m128i __attribute__ ((__noinline__))
+vector_using_function ()
+{
+ volatile __m128i vx; /* We want to force a vector-aligned store into the stack. */
+ vx = _mm_xor_si128 (vx, vx);
+ return vx;
+}
+
+int __attribute__ ((__noinline__))
+self_aligning_function (int x, int y)
+{
+ __m128i ignored = vector_using_function ();
+ return (x + y);
+}
+
+int g_1 = 20;
+int g_2 = 22;
+
+int
+main ()
+{
+ int result;
+ asm ("pushl %esi"); /* Disalign runtime stack. */
+ result = self_aligning_function (g_1, g_2);
+ asm ("popl %esi");
+ if (result != 42)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/20060210-4.c b/gcc/testsuite/gcc.target/i386/20060210-4.c
new file mode 100644
index 00000000000..627cc742015
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/20060210-4.c
@@ -0,0 +1,19 @@
+/* APPLE LOCAL file 4356747 stack realign */
+/* { dg-do compile { target i?86-*-darwin* i[6789]86-*-* } } */
+/* APPLE LOCAL Note: if/when this file arrives in a merge, the FSF
+ version probably won't have the -fnested-functions option, and it's
+ required on OS X. */
+/* { dg-options "-std=gnu99 -fnested-functions -mstackrealign" } */
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+outer_function (int x, int y)
+{
+ int __attribute__ ((__noinline__))
+ nested_function (int x, int y)
+ { /* { dg-error "-mstackrealign ignored for nested functions" } */
+ return (x + y);
+ }
+ return (3 + nested_function (x, y));
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index 3ad60698252..19e133a5520 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3840,6 +3840,12 @@ extern void dwarf2out_return_save (const char *, HOST_WIDE_INT);
extern void dwarf2out_return_reg (const char *, unsigned);
+/* APPLE LOCAL begin mainline 2006-02-17 4356747 stack realign */
+/* Entry point for saving the first register into the second. */
+
+extern void dwarf2out_reg_save_reg (const char *, rtx, rtx);
+/* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign */
+
/* In tree-inline.c */
/* The type of a set of already-visited pointers. Functions for creating