--- old/gcc/common.opt	2012-10-28 20:56:06.805131746 -0400
+++ new/gcc/common.opt	2012-10-28 20:56:06.816974393 -0400
@@ -1108,6 +1108,10 @@
 Common Report Var(flag_strict_aliasing) Optimization
 Assume strict aliasing rules apply
 
+fstrict-calling-conventions
+Common Report Var(flag_strict_calling_conventions) Init(1)
+Use strict ABI calling conventions even for static functions
+
 fstrict-overflow
 Common Report Var(flag_strict_overflow)
 Treat signed overflow as undefined
--- old/gcc/config/i386/i386.c	2012-10-28 20:56:07.266758790 -0400
+++ new/gcc/config/i386/i386.c	2012-10-28 20:56:07.282330524 -0400
@@ -4403,6 +4403,7 @@
   if (decl
       && TREE_CODE (decl) == FUNCTION_DECL
       && optimize
+      && (TARGET_64BIT || !flag_strict_calling_conventions)
       && !profile_flag)
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
@@ -4487,7 +4488,8 @@
 
   /* For local functions, pass up to SSE_REGPARM_MAX SFmode
      (and DFmode for SSE2) arguments in SSE registers.  */
-  if (decl && TARGET_SSE_MATH && optimize && !profile_flag)
+  if (decl && TARGET_SSE_MATH && optimize && !profile_flag &&
+    (TARGET_64BIT || !flag_strict_calling_conventions))
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
       struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
--- old/gcc/doc/invoke.texi	2012-10-28 20:56:09.527531469 -0400
+++ new/gcc/doc/invoke.texi	2012-10-28 20:56:09.542581083 -0400
@@ -6586,6 +6586,12 @@
 The @option{-fstrict-aliasing} option is enabled at levels
 @option{-O2}, @option{-O3}, @option{-Os}.
 
+@item -fstrict-calling-conventions
+@opindex mstrict-calling-conventions
+Use strict ABI calling conventions even with local functions.
+This disable certain optimizations that may cause GCC to call local
+functions in a manner other than that described by the ABI.
+
 @item -fstrict-overflow
 @opindex fstrict-overflow
 Allow the compiler to assume strict signed overflow rules, depending
--- old/gcc/testsuite/gcc.dg/save-args-1.c	2012-10-28 20:56:10.900976665 -0400
+++ /dev/null	2012-10-28 20:56:10.000000000 -0400
@@ -1,10 +0,0 @@
-/* Test -msave-args */
-/* { dg-do compile { target i?86-*-solaris2.* } } */
-/* { dg-options "-m64 -msave-args" } */
-/* { dg-final { scan-assembler "movq\t%rsi, -32\\(%rbp\\)" } } */
-
-int
-foo(int argc, char **argv)
-{
-    return (1);
-}
--- old/gcc/testsuite/gcc.target/i386/local.c	2012-10-28 20:56:11.052240726 -0400
+++ new/gcc/testsuite/gcc.target/i386/local.c	2012-10-28 20:56:11.063692484 -0400
@@ -1,5 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -funit-at-a-time" } */
+/* { dg-options "-O2 -funit-at-a-time -fno-strict-calling-conventions" { target ilp32 } } */
+/* { dg-options "-O2 -funit-at-a-time" { target lp64 } } */
 /* { dg-final { scan-assembler "magic\[^\\n\]*eax" { target ilp32 } } } */
 /* { dg-final { scan-assembler "magic\[^\\n\]*edi" { target lp64 } } } */
 
--- /dev/null	2012-10-28 20:56:11.000000000 -0400
+++ new/gcc/testsuite/gcc.target/i386/save-args-1.c	2012-10-28 20:56:11.421550614 -0400
@@ -0,0 +1,12 @@
+/* Test -msave-args */
+/* { dg-do compile { target { { i?86-*-solaris2.* } && lp64 } } } */
+/* { dg-options "-msave-args" } */
+/* { dg-final { scan-assembler "movq\t%rsi, -32\\(%rbp\\)" } } */
+/* { dg-final { scan-assembler "movq\t%rsi, -16\\(%rbp\\)" } } */
+/* { dg-final { scan-assembler "movq\t%rdi, -8\\(%rbp\\)" } } */
+
+int
+foo(int argc, char **argv)
+{
+    return (1);
+}
--- /dev/null	2012-10-28 20:56:11.000000000 -0400
+++ new/gcc/testsuite/gcc.target/i386/strict-cc.c	2012-10-28 20:56:11.601382102 -0400
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { ilp32 } } } */
+/* { dg-options "-O2 -funit-at-a-time -fstrict-calling-conventions"  } */
+/* { dg-final { scan-assembler "pushl.*\\\$1" } } */
+
+#include <stdio.h>
+
+/* Verify that local calling convention is not used if strict conventions.  */
+static t(int) __attribute__ ((noinline));
+m()
+{
+	t(1);
+}
+
+static t(int a)
+{
+    printf("%d\n", a);
+}
--- old/libiberty/testsuite/test-demangle.c	2012-10-28 20:56:11.778034670 -0400
+++ new/libiberty/testsuite/test-demangle.c	2012-10-28 20:56:11.789578420 -0400
@@ -46,7 +46,7 @@
 #define LINELEN 80
 
 static void
-getline(buf)
+_getline(buf)
      struct line *buf;
 {
   char *data = buf->data;
@@ -196,12 +196,12 @@
     {
       const char *inp;
       
-      getline (&format);
+      _getline (&format);
       if (feof (stdin))
 	break;
 
-      getline (&input);
-      getline (&expect);
+      _getline (&input);
+      _getline (&expect);
 
       inp = protect_end (input.data);
 
@@ -322,7 +322,7 @@
 
       if (no_params)
 	{
-	  getline (&expect);
+	  _getline (&expect);
 	  result = cplus_demangle (inp, DMGL_ANSI|DMGL_TYPES);
 
 	  if (result
