diff -Nur -x '*.trace' -x '*.rej' -x '*.orig' -x sbcl.h -x ldso-stubs.S -x Config -x target -x CVS -x 'target-*.h' -x output -x genesis -x '*.o' -x '*.nm' -x '*.core' -x '*.map' -x '*.d' -x '*~' -x '*.lisp-obj' -x '*.fasl' -x '*.lisp-temp' -x systems -x '*.tmp' -x local-target-features.lisp-expr -x a.out -x '*.so' -x foo.c -x sbcl -x grovel-headers -x customize-target-features.lisp -x external-format-test.txt -x test-status.lisp-expr sbcl-1.0.18-pristine/src/assembly/x86/assem-rtns.lisp sbcl-1.0.18-two-arg-passing-regs/src/assembly/x86/assem-rtns.lisp
--- sbcl-1.0.18-pristine/src/assembly/x86/assem-rtns.lisp	2008-04-26 11:28:57.000000000 -0400
+++ sbcl-1.0.18-two-arg-passing-regs/src/assembly/x86/assem-rtns.lisp	2008-06-29 17:56:13.000000000 -0400
@@ -36,8 +36,10 @@
   (inst jmp :e one-value)
   (inst cmp ecx (fixnumize 2))
   (inst jmp :e two-values)
-  (inst cmp ecx (fixnumize 3))
-  (inst jmp :e three-values)
+  #!-x86-two-arg-passing-regs
+  (progn
+    (inst cmp ecx (fixnumize 3))
+    (inst jmp :e three-values))
 
   ;; Save the count, because the loop is going to destroy it.
   (inst mov edx ecx)
@@ -65,6 +67,7 @@
   ;; Load the register args.
   (loadw edx ebx -1)
   (loadw edi ebx -2)
+  #!-x86-two-arg-passing-regs
   (loadw esi ebx -3)
 
   ;; And back we go.
@@ -76,6 +79,7 @@
   (move esp-tn ebx)
   (inst mov edx nil-value)
   (inst mov edi edx)
+  #!-x86-two-arg-passing-regs
   (inst mov esi edx)
   (inst stc)
   (inst jmp eax)
@@ -90,18 +94,21 @@
   TWO-VALUES
   (loadw edx esi -1)
   (loadw edi esi -2)
+  #!-x86-two-arg-passing-regs
   (inst mov esi nil-value)
   (inst lea esp-tn (make-ea :dword :base ebx :disp (* -2 n-word-bytes)))
   (inst stc)
   (inst jmp eax)
 
   THREE-VALUES
-  (loadw edx esi -1)
-  (loadw edi esi -2)
-  (loadw esi esi -3)
-  (inst lea esp-tn (make-ea :dword :base ebx :disp (* -3 n-word-bytes)))
-  (inst stc)
-  (inst jmp eax))
+  #!-x86-two-arg-passing-regs
+  (progn
+    (loadw edx esi -1)
+    (loadw edi esi -2)
+    (loadw esi esi -3)
+    (inst lea esp-tn (make-ea :dword :base ebx :disp (* -3 n-word-bytes)))
+    (inst stc)
+    (inst jmp eax)))
 
 ;;;; TAIL-CALL-VARIABLE
 
@@ -132,7 +139,7 @@
   (inst sub ecx esp-tn)
 
   ;; Check for all the args fitting the registers.
-  (inst cmp ecx (fixnumize 3))
+  (inst cmp ecx (fixnumize register-arg-count))
   (inst jmp :le REGISTER-ARGS)
 
   ;; Save the OLD-FP and RETURN-PC because the blit it going to trash
@@ -165,6 +172,7 @@
 
   ;; remaining register args
   (loadw edi ebp-tn -2)
+  #!-x86-two-arg-passing-regs
   (loadw esi ebp-tn -3)
 
   ;; Push the (saved) return-pc so it looks like we just called.
@@ -177,6 +185,7 @@
   REGISTER-ARGS
   (loadw edx esi -1)
   (loadw edi esi -2)
+  #!-x86-two-arg-passing-regs
   (loadw esi esi -3)
 
   ;; Clear most of the stack.
diff -Nur -x '*.trace' -x '*.rej' -x '*.orig' -x sbcl.h -x ldso-stubs.S -x Config -x target -x CVS -x 'target-*.h' -x output -x genesis -x '*.o' -x '*.nm' -x '*.core' -x '*.map' -x '*.d' -x '*~' -x '*.lisp-obj' -x '*.fasl' -x '*.lisp-temp' -x systems -x '*.tmp' -x local-target-features.lisp-expr -x a.out -x '*.so' -x foo.c -x sbcl -x grovel-headers -x customize-target-features.lisp -x external-format-test.txt -x test-status.lisp-expr sbcl-1.0.18-pristine/src/compiler/assembly/alpha/alloc.lisp sbcl-1.0.18-two-arg-passing-regs/src/compiler/assembly/alpha/alloc.lisp
--- sbcl-1.0.18-pristine/src/compiler/x86/call.lisp	2008-04-26 11:29:10.000000000 -0400
+++ sbcl-1.0.18-two-arg-passing-regs/src/compiler/x86/call.lisp	2008-06-29 18:01:15.000000000 -0400
@@ -301,6 +301,7 @@
       (inst push edx-tn)
       (inst mov edi-tn nil-value)
       (inst push edi-tn)
+      #!-x86-two-arg-passing-regs
       (inst mov esi-tn edi-tn)
       ;; Compute a pointer to where to put the [defaulted] stack values.
       (emit-label no-stack-args)
@@ -337,6 +338,7 @@
             (make-ea :dword :base ebp-tn
                      :disp (frame-byte-offset register-arg-count)))
       ;; Save ESI, and compute a pointer to where the args come from.
+      #!-x86-two-arg-passing-regs
       (storew esi-tn ebx-tn (frame-word-offset 2))
       (inst lea esi-tn
             (make-ea :dword :base ebx-tn
@@ -347,6 +349,7 @@
       (inst rep)
       (inst movs :dword)
       ;; Restore ESI.
+      #!-x86-two-arg-passing-regs
       (loadw esi-tn ebx-tn (frame-word-offset 2))
       ;; Now we have to default the remaining args. Find out how many.
       (inst sub eax-tn (fixnumize (- nvals register-arg-count)))
@@ -1049,6 +1052,7 @@
                    :from :eval) a0)
   (:temporary (:sc unsigned-reg :offset (second *register-arg-offsets*)
                    :from :eval) a1)
+  #!-x86-two-arg-passing-regs
   (:temporary (:sc unsigned-reg :offset (third *register-arg-offsets*)
                    :from :eval) a2)
 
@@ -1067,7 +1071,8 @@
                               :disp (- (* (max nvals 2) n-word-bytes))))
     ;; Pre-default any argument register that need it.
     (when (< nvals register-arg-count)
-      (let* ((arg-tns (nthcdr nvals (list a0 a1 a2)))
+      (let* ((arg-tns (nthcdr nvals (list a0 a1
+                                          #!-x86-two-arg-passing-regs a2)))
              (first (first arg-tns)))
         (inst mov first nil-value)
         (dolist (tn (cdr arg-tns))
diff -Nur -x '*.trace' -x '*.rej' -x '*.orig' -x sbcl.h -x ldso-stubs.S -x Config -x target -x CVS -x 'target-*.h' -x output -x genesis -x '*.o' -x '*.nm' -x '*.core' -x '*.map' -x '*.d' -x '*~' -x '*.lisp-obj' -x '*.fasl' -x '*.lisp-temp' -x systems -x '*.tmp' -x local-target-features.lisp-expr -x a.out -x '*.so' -x foo.c -x sbcl -x grovel-headers -x customize-target-features.lisp -x external-format-test.txt -x test-status.lisp-expr sbcl-1.0.18-pristine/src/compiler/x86/static-fn.lisp sbcl-1.0.18-two-arg-passing-regs/src/compiler/x86/static-fn.lisp
--- sbcl-1.0.18-pristine/src/compiler/x86/static-fn.lisp	2005-07-14 15:13:48.000000000 -0400
+++ sbcl-1.0.18-two-arg-passing-regs/src/compiler/x86/static-fn.lisp	2008-06-29 17:56:13.000000000 -0400
@@ -139,6 +139,8 @@
   (frob 0 1)
   (frob 1 1)
   (frob 2 1)
+  ;; We don't actually -use- this next static fun template.
+  #!-x86-two-arg-passing-regs
   (frob 3 1))
 
 (defmacro define-static-fun (name args &key (results '(x)) translate
diff -Nur -x '*.trace' -x '*.rej' -x '*.orig' -x sbcl.h -x ldso-stubs.S -x Config -x target -x CVS -x 'target-*.h' -x output -x genesis -x '*.o' -x '*.nm' -x '*.core' -x '*.map' -x '*.d' -x '*~' -x '*.lisp-obj' -x '*.fasl' -x '*.lisp-temp' -x systems -x '*.tmp' -x local-target-features.lisp-expr -x a.out -x '*.so' -x foo.c -x sbcl -x grovel-headers -x customize-target-features.lisp -x external-format-test.txt -x test-status.lisp-expr sbcl-1.0.18-pristine/src/compiler/x86/vm.lisp sbcl-1.0.18-two-arg-passing-regs/src/compiler/x86/vm.lisp
--- sbcl-1.0.18-pristine/src/compiler/x86/vm.lisp	2007-04-12 12:16:33.000000000 -0400
+++ sbcl-1.0.18-two-arg-passing-regs/src/compiler/x86/vm.lisp	2008-06-29 17:56:13.000000000 -0400
@@ -94,11 +94,13 @@
   ;; registers used to pass arguments
   ;;
   ;; the number of arguments/return values passed in registers
-  (def!constant  register-arg-count 3)
+  (def!constant  register-arg-count
+      #!-x86-two-arg-passing-regs 3
+      #!+x86-two-arg-passing-regs 2)
   ;; names and offsets for registers used to pass arguments
   (eval-when (:compile-toplevel :load-toplevel :execute)
-    (defparameter *register-arg-names* '(edx edi esi)))
-  (defregset    *register-arg-offsets* edx edi esi))
+    (defparameter *register-arg-names* '(edx edi #!-x86-two-arg-passing-regs esi)))
+  (defregset    *register-arg-offsets* edx edi #!-x86-two-arg-passing-regs esi))
 
 ;;;; SB definitions
 
diff -Nur -x '*.trace' -x '*.rej' -x '*.orig' -x sbcl.h -x ldso-stubs.S -x Config -x target -x CVS -x 'target-*.h' -x output -x genesis -x '*.o' -x '*.nm' -x '*.core' -x '*.map' -x '*.d' -x '*~' -x '*.lisp-obj' -x '*.fasl' -x '*.lisp-temp' -x systems -x '*.tmp' -x local-target-features.lisp-expr -x a.out -x '*.so' -x foo.c -x sbcl -x grovel-headers -x customize-target-features.lisp -x external-format-test.txt -x test-status.lisp-expr sbcl-1.0.18-pristine/src/runtime/x86-assem.S sbcl-1.0.18-two-arg-passing-regs/src/runtime/x86-assem.S
--- sbcl-1.0.18-pristine/src/runtime/x86-assem.S	2008-06-26 22:15:02.000000000 -0400
+++ sbcl-1.0.18-two-arg-passing-regs/src/runtime/x86-assem.S	2008-06-29 17:56:13.000000000 -0400
@@ -279,6 +279,10 @@
 	sub	$8,%esp		# Ensure 3 slots are allocated, one above.
 	mov	%ebx,%ebp	# Switch to new frame.
 
+#ifdef LISP_FEATURE_X86_TWO_ARG_PASSING_REGS
+	mov	%esi,-12(%ebp)	# Write third arg back down.
+#endif
+
 	call	*CLOSURE_FUN_OFFSET(%eax)
 	
 	/* If the function returned multiple values, it will return to
