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-reserve-ebx-2/src/compiler/x86/call.lisp sbcl-1.0.18-reserve-ebx-3/src/compiler/x86/call.lisp
--- sbcl-1.0.18-reserve-ebx-2/src/compiler/x86/call.lisp	2008-07-01 10:56:22.889312280 -0400
+++ sbcl-1.0.18-reserve-ebx-3/src/compiler/x86/call.lisp	2008-07-01 18:06:57.630878840 -0400
@@ -287,46 +287,48 @@
                  (trace-table-entry trace-table-normal)))))))
       (t
        ;; 91 bytes for this branch.
-       (let ((regs-defaulted (gen-label))
-             (restore-edi (gen-label))
-             (no-stack-args (gen-label))
-             (default-stack-vals (gen-label))
-             (count-okay (gen-label)))
+       (assemble ()
          (note-this-location vop :unknown-return)
 
-         ;; Hack so we can test the rest.
-         #!+x86-reserve-ebx
-         (inst mov ebx-tn esi-tn)
+         ;; All code paths here use string instructions, and need to
+         ;; move down.
+         (inst std)
 
          ;; Branch off to the MV case.
          (inst jmp :c regs-defaulted)
 
          ;; Default the register args, and set up the stack as if we
          ;; entered the MV return point.
-         (inst mov ebx-tn esp-tn)
+         (inst mov values-start esp-tn)
          (inst push edx-tn)
-         (inst mov edi-tn nil-value)
-         (inst push edi-tn)
+         #!+x86-reserve-ebx
+         (inst push nil-value)
+         #!-x86-reserve-ebx
+         (progn
+           (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)
+         NO-STACK-ARGS
          (inst lea edi-tn
                (make-ea :dword :base ebp-tn
                         :disp (frame-byte-offset register-arg-count)))
-         ;; Load EAX with NIL so we can quickly store it, and set up
-         ;; stuff for the loop.
-         (inst mov eax-tn nil-value)
-         (inst std)
+
+         ;; Set up loop count.
          (inst mov ecx-tn (- nvals register-arg-count))
+
          ;; Jump into the default loop.
          (inst jmp default-stack-vals)
 
          ;; The regs are defaulted. We need to copy any stack arguments,
          ;; and then default the remaining stack arguments.
-         (emit-label regs-defaulted)
+         REGS-DEFAULTED
+
          ;; Save EDI.
-         (storew edi-tn ebx-tn (frame-word-offset 1))
+         (storew edi-tn values-start (frame-word-offset 1))
+
          ;; Compute the number of stack arguments, and if it's zero or
          ;; less, don't copy any stack arguments.
          (inst sub ecx-tn (fixnumize register-arg-count))
@@ -336,44 +338,61 @@
          (inst cmp ecx-tn (fixnumize (- nvals register-arg-count)))
          (inst jmp :be count-okay)
          (inst mov ecx-tn (fixnumize (- nvals register-arg-count)))
-         (emit-label count-okay)
+         COUNT-OKAY
+
          ;; Save the number of stack values.
          (inst mov eax-tn ecx-tn)
          ;; Compute a pointer to where the stack args go.
          (inst lea edi-tn
                (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.
+
+         ;; Save ESI.
          #!-x86-two-arg-passing-regs
          (storew esi-tn ebx-tn (frame-word-offset 2))
+         #!+x86-reserve-ebx
+         (inst push values-start)
+
+         ;; Compute a pointer to where the args come from
          (inst lea esi-tn
-               (make-ea :dword :base ebx-tn
+               (make-ea :dword :base values-start
                         :disp (frame-byte-offset register-arg-count)))
+
          ;; Do the copy.
          (inst shr ecx-tn word-shift)   ; make word count
-         (inst std)
          (inst rep)
          (inst movs :dword)
+
          ;; Restore ESI.
          #!-x86-two-arg-passing-regs
          (loadw esi-tn ebx-tn (frame-word-offset 2))
+         #!+x86-reserve-ebx
+         (inst pop values-start)
+
          ;; Now we have to default the remaining args. Find out how many.
          (inst sub eax-tn (fixnumize (- nvals register-arg-count)))
          (inst neg eax-tn)
+
          ;; If none, then just blow out of here.
          (inst jmp :le restore-edi)
          (inst mov ecx-tn eax-tn)
          (inst shr ecx-tn word-shift)   ; word count
+
+         DEFAULT-STACK-VALS
+
          ;; Load EAX with NIL for fast storing.
          (inst mov eax-tn nil-value)
+
          ;; Do the store.
-         (emit-label default-stack-vals)
          (inst rep)
          (inst stos eax-tn)
+
          ;; Restore EDI, and reset the stack.
-         (emit-label restore-edi)
-         (loadw edi-tn ebx-tn (frame-word-offset 1))
-         (inst mov esp-tn ebx-tn)
+         RESTORE-EDI
+         (loadw edi-tn values-start (frame-word-offset 1))
+         (inst mov esp-tn values-start)
+
+         ;; Restore D flag to its normal state.
          (inst cld)))))
   (values))
 
@@ -1209,18 +1228,19 @@
 
     ;; Allocate the space on the stack.
     ;; stack = ebp - (max 3 frame-size) - (nargs - fixed)
-    (inst lea ebx-tn
+    (inst neg ecx-tn)
+    (inst lea esp-tn
           (make-ea :dword :base ebp-tn
+                   :index ecx-tn
                    :disp (- (fixnumize fixed)
                             (* n-word-bytes
                                (max 3 (sb-allocated-size 'stack))))))
-    (inst sub ebx-tn ecx-tn)  ; Got the new stack in ebx
-    (inst mov esp-tn ebx-tn)
+    (inst neg ecx-tn)
 
     ;; Now: nargs>=1 && nargs>fixed
 
     ;; Save the original count of args.
-    (inst mov ebx-tn ecx-tn)
+    (inst push ecx-tn)
 
     (cond ((< fixed register-arg-count)
            ;; We must stop when we run out of stack args, not when we
@@ -1242,7 +1262,7 @@
 
     ;; Initialize src to be end of args.
     (inst mov esi-tn ebp-tn)
-    (inst sub esi-tn ebx-tn)
+    (inst sub esi-tn (make-ea :dword :base esp-tn :disp (* 3 n-word-bytes)))
 
     ;; We need to copy from downwards up to avoid overwriting some of
     ;; the yet uncopied args. So we need to use EBX as the copy index
@@ -1254,7 +1274,7 @@
     COPY-LOOP
     (inst mov edi-tn (make-ea :dword :base esi-tn :index ebx-tn))
     ;; The :DISP is to account for the registers saved on the stack
-    (inst mov (make-ea :dword :base esp-tn :disp (* 3 n-word-bytes)
+    (inst mov (make-ea :dword :base esp-tn :disp (* 4 n-word-bytes)
                        :index ebx-tn)
           edi-tn)
     (inst add ebx-tn n-word-bytes)
@@ -1269,7 +1289,7 @@
     DO-REGS
 
     ;; Restore ECX
-    (inst mov ecx-tn ebx-tn)
+    (inst pop ecx-tn)
 
     ;; Here: nargs>=1 && nargs>fixed
     (when (< fixed register-arg-count)
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-reserve-ebx-2/src/compiler/x86/static-fn.lisp sbcl-1.0.18-reserve-ebx-3/src/compiler/x86/static-fn.lisp
--- sbcl-1.0.18-reserve-ebx-2/src/compiler/x86/static-fn.lisp	2008-06-29 17:56:13.000000000 -0400
+++ sbcl-1.0.18-reserve-ebx-3/src/compiler/x86/static-fn.lisp	2008-07-01 11:33:37.369930320 -0400
@@ -17,6 +17,7 @@
   (:variant-vars function)
   (:vop-var vop)
   (:node-var node)
+  #!-x86-reserve-ebx
   (:temporary (:sc unsigned-reg :offset ebx-offset
                    :from (:eval 0) :to (:eval 2)) ebx)
   (:temporary (:sc unsigned-reg :offset ecx-offset
@@ -78,7 +79,8 @@
          ;; If speed not more important than size, duplicate the
          ;; effect of the ENTER with discrete instructions. Takes
          ;; 2+1+3+2=8 bytes as opposed to 4+3=7 bytes.
-         (cond ((policy node (>= speed space))
+         (cond #!-x86-reserve-ebx
+               ((policy node (>= speed space))
                 (inst mov ebx esp-tn)
                 ;; Save the old-fp
                 (inst push ebp-tn)
@@ -86,6 +88,17 @@
                 ;; above, two more needed.
                 (inst sub esp-tn (fixnumize 2))
                 (inst mov ebp-tn ebx))
+               #!+x86-reserve-ebx
+               ((policy node (>= speed space))
+                ;; 1+1+1+4=7 bytes. Not sure the policy makes sense anymore.
+                ;; Save the old-fp
+                (inst push ebp-tn)
+                ;; Ensure that at least three slots are available; one
+                ;; above, two more needed.
+                (inst push ebp-tn)
+                (inst push ebp-tn)
+                ;; And compute our new fp.
+                (inst lea ebp-tn (make-ea :dword :base esp-tn :disp 12)))
                (t
                 (inst enter (fixnumize 2))
                 ;; The enter instruction pushes EBP and then copies
