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 sbcl-0.9.12-x86-reserve-ebx-2/src/compiler/x86/call.lisp sbcl-0.9.12-x86-reserve-ebx-3/src/compiler/x86/call.lisp
--- sbcl-0.9.12-x86-reserve-ebx-2/src/compiler/x86/call.lisp	2006-05-01 17:20:50.000000000 -0400
+++ sbcl-0.9.12-x86-reserve-ebx-3/src/compiler/x86/call.lisp	2006-05-06 17:34:04.000000000 -0400
@@ -287,48 +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 (* (- (1+ register-arg-count)) n-word-bytes)))
-         ;; 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))
-         ;; solaris requires DF being zero.
-         #!+sunos (inst cld)
+
          ;; 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 (- (1+ 1)))
+         (storew edi-tn values-start (- (1+ 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))
@@ -338,48 +338,63 @@
          (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 (* (- (1+ register-arg-count)) n-word-bytes)))
-         ;; Save ESI, and compute a pointer to where the args come from.
+
+         ;; Save ESI
          #!-x86-two-arg-passing-regs
          (storew esi-tn ebx-tn (- (1+ 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 (* (- (1+ register-arg-count)) n-word-bytes)))
+
          ;; Do the copy.
          (inst shr ecx-tn word-shift)   ; make word count
-         (inst std)
          (inst rep)
          (inst movs :dword)
-         ;; solaris requires DF being zero.
-         #!+sunos (inst cld)
+
          ;; Restore ESI.
          #!-x86-two-arg-passing-regs
          (loadw esi-tn ebx-tn (- (1+ 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)
-         ;; solaris requires DF being zero.
-         #!+sunos (inst cld)
+
          ;; Restore EDI, and reset the stack.
-         (emit-label restore-edi)
-         (loadw edi-tn ebx-tn (- (1+ 1)))
-         (inst mov esp-tn ebx-tn)))))
+         RESTORE-EDI
+         (loadw edi-tn values-start (- (1+ 1)))
+         (inst mov esp-tn values-start)
+
+         ;; solaris requires DF being zero.
+         #!+sunos (inst cld)))))
   (values))
 
 ;;;; unknown values receiving
@@ -1213,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
@@ -1245,11 +1261,11 @@
 
     ;; Initialize dst to be end of stack; skiping the values pushed
     ;; above.
-    (inst lea edi-tn (make-ea :dword :base esp-tn :disp 8))
+    (inst lea edi-tn (make-ea :dword :base esp-tn :disp 12))
 
     ;; 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 8))
 
     (inst shr ecx-tn word-shift)        ; make word count
     ;; And copy the args.
@@ -1264,7 +1280,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 sbcl-0.9.12-x86-reserve-ebx-2/src/compiler/x86/static-fn.lisp sbcl-0.9.12-x86-reserve-ebx-3/src/compiler/x86/static-fn.lisp
--- sbcl-0.9.12-x86-reserve-ebx-2/src/compiler/x86/static-fn.lisp	2006-04-28 07:36:34.000000000 -0400
+++ sbcl-0.9.12-x86-reserve-ebx-3/src/compiler/x86/static-fn.lisp	2006-05-06 19:08:57.000000000 -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
