diff -uNr gcc-5363/build_gcc gcc-5363-patched/build_gcc
--- gcc-5363/build_gcc	2006-06-27 17:29:34.000000000 +1000
+++ gcc-5363-patched/build_gcc	2006-12-14 10:20:22.000000000 +1100
@@ -128,7 +128,9 @@
 fi
 
 # The $LOCAL_MAKEFLAGS variable can be used to override $MAKEFLAGS.
-MAKEFLAGS=${LOCAL_MAKEFLAGS-"-j $SYSCTL"}
+# BS:
+#MAKEFLAGS=${LOCAL_MAKEFLAGS-"-j $SYSCTL"}
+MAKEFLAGS=${LOCAL_MAKEFLAGS-""}
 
 # Build the native GCC.  Do this even if the user didn't ask for it
 # because it'll be needed for the bootstrap.
diff -uNr gcc-5363/build_it gcc-5363-patched/build_it
--- gcc-5363/build_it	1970-01-01 10:00:00.000000000 +1000
+++ gcc-5363-patched/build_it	2006-12-14 00:10:15.000000000 +1100
@@ -0,0 +1,3 @@
+#!/bin/bash
+mkdir -p build/sym build/dst build/obj
+gnumake install RC_OS=macos RC_ARCHS="i386 ppc" TARGETS="i386 ppc" SRCROOT=`pwd` DSTROOT=`pwd`/build/dst SYMROOT=`pwd`/build/sym OBJROOT=`pwd`/build/obj
diff -uNr gcc-5363/gcc/ChangeLog gcc-5363-patched/gcc/ChangeLog
--- gcc-5363/gcc/ChangeLog	2006-06-12 17:31:24.000000000 +1000
+++ gcc-5363-patched/gcc/ChangeLog	2006-12-13 19:41:10.000000000 +1100
@@ -1,3 +1,11 @@
+2005-09-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/22362
+	* config/i386/i386.c (ix86_function_regparm): Make sure automatic regparm
+	for internal functions doesn't use registers used by global registers
+	variables.  Use fewer register parameters if there are global register
+	variables.
+
 2006-06-11  Eric Christopher  <echristo@apple.com>
 
 	Radar 4581948
diff -uNr gcc-5363/gcc/config/i386/i386.c gcc-5363-patched/gcc/config/i386/i386.c
--- gcc-5363/gcc/config/i386/i386.c	2006-06-24 12:06:59.000000000 +1000
+++ gcc-5363-patched/gcc/config/i386/i386.c	2006-12-14 11:58:51.000000000 +1100
@@ -2395,7 +2395,7 @@
 ix86_function_regparm (tree type, tree decl)
 {
   tree attr;
-  int local_regparm = ix86_regparm;
+  int regparm = ix86_regparm;
   bool user_convention = false;
 
   if (!TARGET_64BIT)
@@ -2403,7 +2403,7 @@
       attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
       if (attr)
 	{
-	  local_regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+	  regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
 	  user_convention = true;
 	}
 
@@ -2412,7 +2412,7 @@
 	  || lookup_attribute ("regparmandstackparmee", TYPE_ATTRIBUTES (type)))
       /* APPLE LOCAL end regparmandstackparm */
 	{
-	  local_regparm = 2;
+	  regparm = 2;
 	  user_convention = true;
 	}
 
@@ -2423,29 +2423,47 @@
 	  struct cgraph_local_info *i = cgraph_local_info (decl);
 	  if (i && i->local)
 	    {
+	      int local_regparm, globals = 0, regno;
+
+	      /* Make sure no regparm register is taken by a global register
+		 variable.  */
+	      for (local_regparm = 0; local_regparm < 3; local_regparm++)
+		if (global_regs[local_regparm])
+		  break;
 	      /* 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))
+	      if (local_regparm == 3
+		  && DECL_CONTEXT (decl) && !DECL_NO_STATIC_CHAIN (decl))
 		local_regparm = 2;
-	      else
-		local_regparm = 3;
 	      /* If the function realigns its stackpointer, it
 		 clobbers %ecx to deref unaligned arguments.  If we've
 		 already generated code for the callee, the callee
 		 DECL_STRUCT_FUNCTION is gone, so we fall back to
 		 scanning the attributes for the self-realigning
 		 property.  */
-	      if ((DECL_STRUCT_FUNCTION (decl)
+	      if (local_regparm == 3
+		 && ((DECL_STRUCT_FUNCTION (decl)
 		   && DECL_STRUCT_FUNCTION (decl)->machine
 		   && DECL_STRUCT_FUNCTION (decl)->machine->force_align_arg_pointer)
 		  || (!DECL_STRUCT_FUNCTION (decl)
 		      && lookup_attribute (ix86_force_align_arg_pointer_string,
-					   TYPE_ATTRIBUTES (TREE_TYPE (decl)))))
+					   TYPE_ATTRIBUTES (TREE_TYPE (decl))))))
 		local_regparm = 2;
+	      /* Each global register variable increases register preassure,
+		 so the more global reg vars there are, the smaller regparm
+		 optimization use, unless requested by the user explicitly.  */
+	      for (regno = 0; regno < 6; regno++)
+		if (global_regs[regno])
+		  globals++;
+	      local_regparm
+		= globals < local_regparm ? local_regparm - globals : 0;
+
+	      if (local_regparm > regparm)
+		regparm = local_regparm;
 	    }
 	}
     }
-  return local_regparm;
+  return regparm;
 }
 /* APPLE LOCAL end mainline 2006-02-17 4356747 stack realign (function body) */
 
diff -uNr gcc-5363/gcc/testsuite/ChangeLog gcc-5363-patched/gcc/testsuite/ChangeLog
--- gcc-5363/gcc/testsuite/ChangeLog	2006-05-16 01:33:10.000000000 +1000
+++ gcc-5363-patched/gcc/testsuite/ChangeLog	2006-12-13 19:42:27.000000000 +1100
@@ -1,3 +1,8 @@
+2005-09-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/22362
+	* gcc.target/i386/pr22362.c: New test.
+
 2005-10-28  Andrew Pinski  <pinskia@physics.uc.edu>
 
 	PR C++/23229
diff -uNr gcc-5363/gcc/testsuite/gcc.target/i386/pr22362.c gcc-5363-patched/gcc/testsuite/gcc.target/i386/pr22362.c
--- gcc-5363/gcc/testsuite/gcc.target/i386/pr22362.c	1970-01-01 10:00:00.000000000 +1000
+++ gcc-5363-patched/gcc/testsuite/gcc.target/i386/pr22362.c	2006-12-13 19:55:47.000000000 +1100
@@ -0,0 +1,25 @@
+/* PR target/22362 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target ilp32 } */
+
+register unsigned int reg0 __asm__ ("esi");
+register unsigned int reg1 __asm__ ("edi");
+register unsigned int reg2 __asm__ ("ebx");
+
+static unsigned int
+__attribute__((noinline))
+foo (unsigned long *x, void *y, void *z)
+{
+  int i;
+
+  for (i = 5; i > 0; i--)
+    x[i] = (unsigned long) foo ((unsigned long *) x[i], y, z);
+  return 0;
+}
+
+unsigned int
+bar (void)
+{
+  return foo (0, 0, 0);
+}
