1.0.4.64: more stack-alignment x86/Darwin
[sbcl.git] / src / compiler / x86 / c-call.lisp
index c52ce27..27ebe1e 100644 (file)
                    :from :eval :to :result) ecx)
   (:temporary (:sc unsigned-reg :offset edx-offset
                    :from :eval :to :result) edx)
+  (:temporary (:sc unsigned-reg :offset esi-offset) prev-esp)
   (:node-var node)
   (:vop-var vop)
   (:save-p t)
   (:ignore args ecx edx)
   (:generator 0
+    ;; FIXME & OAOOM: This is brittle and error-prone to maintain two
+    ;; instances of the same logic, on in arch-assem.S, and one in
+    ;; c-call.lisp. If you modify this, modify that one too...
     (cond ((policy node (> space speed))
            (move eax function)
            (inst call (make-fixup "call_into_c" :foreign)))
            (dotimes (i 8)
              (inst fstp fr0-tn))
 
-           #!+win32 (inst cld)
+           #!+win32
+           (inst cld)
+
+           #!+darwin
+           ;; Align stack for C.
+           (progn
+             (move prev-esp esp-tn)
+             (inst and esp-tn -16))
 
            (inst call function)
            ;; To give the debugger a clue. XX not really internal-error?
            (note-this-location vop :internal-error)
 
+           #!+darwin
+           ;; Restore
+           (move esp-tn prev-esp)
+
            ;; Restore the NPX for lisp; ensure no regs are empty
            (dotimes (i 7)
              (inst fldz))
                                 (ash symbol-tls-index-slot word-shift)
                                 (- other-pointer-lowtag))))
         (inst fs-segment-prefix)
-        (inst sub (make-ea :dword :scale 1 :index temp) delta)))
+        (inst sub (make-ea :dword :base temp) delta)))
     (load-tl-symbol-value result *alien-stack*))
   #!-sb-thread
   (:generator 0
       (let ((delta (logandc2 (+ amount 3) 3)))
         (inst mov temp
               (make-ea :dword
-                           :disp (+ nil-value
-                                    (static-symbol-offset '*alien-stack*)
+                       :disp (+ nil-value
+                                (static-symbol-offset '*alien-stack*)
                                 (ash symbol-tls-index-slot word-shift)
                                 (- other-pointer-lowtag))))
         (inst fs-segment-prefix)
-        (inst add (make-ea :dword :scale 1 :index temp) delta))))
+        (inst add (make-ea :dword :base temp) delta))))
   #!-sb-thread
   (:generator 0
     (unless (zerop amount)