Skip to content

Commit

Permalink
1.0.5.35: stack alignment on x86/Darwin, once more
Browse files Browse the repository at this point in the history
 * Stack alignment cannot be changed after arguments have been pushed
   on stack: ALLOCATE-NUMBER-STACK-SPACE is the place to do this, and
   nowhere else.

 * Use the RESET-STACK-POINTER logic on all x86 platforms for
   simplicity.

 * Factor out the alignment logic to ALIGN-STACK-POINTER.

 * Clear DF unconditionally when calling out, which means that Solaris
   doesn't need to switch it back and forth. (Darwin, Solaris, and Win32
   all need DF cleared for call-out.)
  • Loading branch information
nikodemus committed May 6, 2007
1 parent 7effaab commit a6c61ba
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 93 deletions.
4 changes: 3 additions & 1 deletion package-data-list.lisp-expr
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ of SBCL which maintained the CMU-CL-style split into two packages.)"

#!+x86 "SET-FPU-WORD-FOR-C"
#!+x86 "SET-FPU-WORD-FOR-LISP"
"ALIGN-STACK-POINTER"
"ALLOC-ALIEN-STACK-SPACE" "ALLOC-NUMBER-STACK-SPACE"
"ALLOCATE-CODE-OBJECT" "ALLOCATE-FRAME"
"ALLOCATE-DYNAMIC-CODE-OBJECT" "ALLOCATE-FULL-CALL-FRAME"
Expand Down Expand Up @@ -248,7 +249,8 @@ of SBCL which maintained the CMU-CL-style split into two packages.)"
"COMPONENT-INFO" "COMPONENT-LIVE-TN" "COMPUTE-FUN"
"COMPUTE-OLD-NFP" "COPY-MORE-ARG"
"CURRENT-BINDING-POINTER" "CURRENT-NFP-TN"
"CURRENT-STACK-POINTER" "DEALLOC-ALIEN-STACK-SPACE"
"CURRENT-STACK-POINTER"
"DEALLOC-ALIEN-STACK-SPACE"
"DEALLOC-NUMBER-STACK-SPACE"
"DEBUG-CATCH-TAG"
"DEF-IR1-TRANSLATOR"
Expand Down
66 changes: 37 additions & 29 deletions src/compiler/aliencomp.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -348,14 +348,16 @@
(/noshow (local-alien-info-force-to-memory-p info))
(/noshow alien-type (unparse-alien-type alien-type) (alien-type-bits alien-type))
(if (local-alien-info-force-to-memory-p info)
#!+(or x86 x86-64) `(truly-the system-area-pointer
(%primitive alloc-alien-stack-space
,(ceiling (alien-type-bits alien-type)
sb!vm:n-byte-bits)))
#!-(or x86 x86-64) `(truly-the system-area-pointer
(%primitive alloc-number-stack-space
,(ceiling (alien-type-bits alien-type)
sb!vm:n-byte-bits)))
#!+(or x86 x86-64)
`(truly-the system-area-pointer
(%primitive alloc-alien-stack-space
,(ceiling (alien-type-bits alien-type)
sb!vm:n-byte-bits)))
#!-(or x86 x86-64)
`(truly-the system-area-pointer
(%primitive alloc-number-stack-space
,(ceiling (alien-type-bits alien-type)
sb!vm:n-byte-bits)))
(let* ((alien-rep-type-spec (compute-alien-rep-type alien-type))
(alien-rep-type (specifier-type alien-rep-type-spec)))
(cond ((csubtypep (specifier-type 'system-area-pointer)
Expand Down Expand Up @@ -700,11 +702,14 @@
(error "Something is broken.")))
(lvar (node-lvar call))
(args args)
#!+(or (and x86 darwin) win32) (stack-pointer (make-stack-pointer-tn)))
#!+x86
(stack-pointer (make-stack-pointer-tn)))
(multiple-value-bind (nsp stack-frame-size arg-tns result-tns)
(make-call-out-tns type)
#!+x86 (vop set-fpu-word-for-c call block)
#!+(or (and x86 darwin) win32) (vop current-stack-pointer call block stack-pointer)
#!+x86
(progn
(vop set-fpu-word-for-c call block)
(vop current-stack-pointer call block stack-pointer))
(vop alloc-number-stack-space call block stack-frame-size nsp)
(dolist (tn arg-tns)
;; On PPC, TN might be a list. This is used to indicate
Expand All @@ -722,22 +727,22 @@
(unless (= (length move-arg-vops) 1)
(error "no unique move-arg-vop for moves in SC ~S" (sc-name sc)))
#!+(or x86 x86-64) (emit-move-arg-template call
block
(first move-arg-vops)
(lvar-tn call block arg)
nsp
first-tn)
block
(first move-arg-vops)
(lvar-tn call block arg)
nsp
first-tn)
#!-(or x86 x86-64) (progn
(emit-move call
block
(lvar-tn call block arg)
temp-tn)
(emit-move-arg-template call
block
(first move-arg-vops)
temp-tn
nsp
first-tn))
(emit-move call
block
(lvar-tn call block arg)
temp-tn)
(emit-move-arg-template call
block
(first move-arg-vops)
temp-tn
nsp
first-tn))
#!+(and ppc darwin)
(when (listp tn)
;; This means that we have a float arg that we need to
Expand All @@ -759,7 +764,10 @@
((lvar-tn call block function)
(reference-tn-list arg-tns nil))
((reference-tn-list result-tns t))))
#!-(or (and darwin x86) win32) (vop dealloc-number-stack-space call block stack-frame-size)
#!+(or (and darwin x86) win32) (vop reset-stack-pointer call block stack-pointer)
#!+x86 (vop set-fpu-word-for-lisp call block)
#!-x86
(vop dealloc-number-stack-space call block stack-frame-size)
#!+x86
(progn
(vop reset-stack-pointer call block stack-pointer)
(vop set-fpu-word-for-lisp call block))
(move-lvar-result call block result-tns lvar))))
31 changes: 6 additions & 25 deletions src/compiler/x86/c-call.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,6 @@
:from :eval :to :result) ecx)
(:temporary (:sc unsigned-reg :offset edx-offset
:from :eval :to :result) edx)
#!+darwin
(:temporary (:sc unsigned-reg :offset esi-offset) prev-esp)
(:node-var node)
(:vop-var vop)
(:save-p t)
Expand All @@ -233,32 +231,23 @@
(dotimes (i 8)
(inst fstp fr0-tn))

#!+win32
;; Clear out DF: Darwin, Windows, and Solaris at least require
;; this, and it should not hurt others either.
(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?
;; To give the debugger a clue. FIXME: 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))

(if (and results
(location= (tn-ref-tn results) fr0-tn))
;; The return result is in fr0.
(inst fxch fr7-tn) ; move the result back to fr0
(inst fldz)) ; insure no regs are empty
(inst fxch fr7-tn) ; move the result back to fr0
(inst fldz)) ; insure no regs are empty
))))

;;; While SBCL uses the FPU in 53-bit mode, most C libraries assume that
Expand Down Expand Up @@ -295,17 +284,9 @@
(unless (zerop amount)
(let ((delta (logandc2 (+ amount 3) 3)))
(inst sub esp-tn delta)))
;; C stack should probably be 16 byte aligned on Darwin
#!+darwin (inst and esp-tn -16)
(align-stack-pointer esp-tn)
(move result esp-tn)))

(define-vop (dealloc-number-stack-space)
(:info amount)
(:generator 0
(unless (zerop amount)
(let ((delta (logandc2 (+ amount 3) 3)))
(inst add esp-tn delta)))))

(define-vop (alloc-alien-stack-space)
(:info amount)
#!+sb-thread (:temporary (:sc unsigned-reg) temp)
Expand Down
10 changes: 1 addition & 9 deletions src/compiler/x86/call.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,6 @@
(inst mov eax-tn nil-value)
(inst std)
(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)

Expand Down Expand Up @@ -348,8 +346,6 @@
(inst std)
(inst rep)
(inst movs :dword)
;; solaris requires DF being zero.
#!+sunos (inst cld)
;; Restore ESI.
(loadw esi-tn ebx-tn (frame-word-offset 2))
;; Now we have to default the remaining args. Find out how many.
Expand All @@ -365,8 +361,6 @@
(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 (frame-word-offset 1))
Expand Down Expand Up @@ -1383,9 +1377,7 @@
(inst jmp :nz loop)
;; NIL out the last cons.
(storew nil-value dst 1 list-pointer-lowtag))
(emit-label done)
;; solaris requires DF being zero.
#!+sunos (inst cld))))
(emit-label done))))

;;; Return the location and size of the &MORE arg glob created by
;;; COPY-MORE-ARG. SUPPLIED is the total number of arguments supplied
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/x86/macros.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
`(unless (location= ,n-dst ,n-src)
(inst mov ,n-dst ,n-src))))

(defmacro align-stack-pointer (tn)
#!-darwin (declare (ignore tn))
#!+darwin
;; 16 byte alignment.
`(inst and ,tn #xfffffff0))

(defmacro make-ea-for-object-slot (ptr slot lowtag &optional (size :dword))
`(make-ea ,size :base ,ptr :disp (- (* ,slot n-word-bytes) ,lowtag)))

Expand Down
2 changes: 0 additions & 2 deletions src/compiler/x86/nlx.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,6 @@
(inst movs :dword)

DONE
;; solaris requires DF being zero.
#!+sunos (inst cld)
;; Reset the CSP at last moved arg.
(inst lea esp-tn (make-ea :dword :base edi :disp n-word-bytes))))

Expand Down
28 changes: 17 additions & 11 deletions src/compiler/x86/show.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,26 @@
:from :eval
:to (:result 0))
eax)
#!+darwin (:temporary (:sc unsigned-reg
:offset esi-offset)
prev-stack-pointer)
#!+darwin
(:temporary (:sc unsigned-reg
:offset esi-offset)
prev-stack-pointer)
(:results (result :scs (descriptor-reg)))
(:save-p t)
(:generator 100
;; the stack should be 16-byte aligned on Darwin
#!-darwin (inst push object)
#!+darwin (progn (inst mov prev-stack-pointer esp-tn)
(inst sub esp-tn n-word-bytes)
(inst and esp-tn -16)
(storew object esp-tn))
#!-darwin
(inst push object)
#!+darwin
(progn
;; the stack should be 16-byte aligned on Darwin
(inst mov prev-stack-pointer esp-tn)
(inst sub esp-tn n-word-bytes)
(align-stack-pointer esp-tn)
(storew object esp-tn))
(inst lea eax (make-fixup "debug_print" :foreign))
(inst call (make-fixup "call_into_c" :foreign))
#!-darwin (inst add esp-tn n-word-bytes)
#!+darwin (inst mov esp-tn prev-stack-pointer)
#!-darwin
(inst add esp-tn n-word-bytes)
#!+darwin
(inst mov esp-tn prev-stack-pointer)
(move result eax)))
5 changes: 1 addition & 4 deletions src/compiler/x86/values.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
(inst cmp esp-tn esi)
(inst jmp :be loop)
DONE
;; solaris requires DF being zero.
#!+sunos (inst cld)
(inst lea esp-tn (make-ea :dword :base edi :disp n-word-bytes))
(inst sub edi esi)
(loop for moved = moved-ptrs then (tn-ref-across moved)
Expand Down Expand Up @@ -151,6 +149,5 @@
(inst jmp :nz LOOP)

DONE
;; solaris requires DF being zero.
#!+sunos (inst cld)))
))

15 changes: 5 additions & 10 deletions src/runtime/x86-assem.S
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,11 @@ GNAME(call_into_c):
fstp %st(0)
fstp %st(0)

#ifdef LISP_FEATURE_WIN32
cld
#endif

#ifdef LISP_FEATURE_DARWIN
andl $0xfffffff0,%esp # align stack to 16-byte boundary before calling C
#endif
call *%eax # normal callout using Lisp stack

movl %eax,%ecx # remember integer return value
cld # clear out DF: Darwin, Solaris and Win32 at
# least need this, and it should not hurt others

call *%eax # normal callout using Lisp stack
movl %eax,%ecx # remember integer return value

/* Check for a return FP value. */
fxam
Expand Down
3 changes: 2 additions & 1 deletion tests/foreign-stack-alignment.impure.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
#+(and ppc linux) 8
#+x86-64 16
#+mips 8
#+x86 4
#+(and x86 (not darwin)) 4
#+(and x86 darwin) 16
#-(or x86 x86-64 mips (and ppc (or darwin linux))) (error "Unknown platform"))

;;;; Build the offset-tool as regular excutable, and run it with
Expand Down
2 changes: 1 addition & 1 deletion version.lisp-expr
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
"1.0.5.34"
"1.0.5.35"

0 comments on commit a6c61ba

Please sign in to comment.