X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86%2Fcell.lisp;h=8a93d7be3d0ddc795281c6e853cc689745844806;hb=b83353d9f998e5c0e34604b5593df70c66d2c510;hp=44d276087d22a3b6798b5e15ec9f0d0cfa9571a2;hpb=baf305daad8902018301fad1900369c0008fc745;p=sbcl.git diff --git a/src/compiler/x86/cell.lisp b/src/compiler/x86/cell.lisp index 44d2760..8a93d7b 100644 --- a/src/compiler/x86/cell.lisp +++ b/src/compiler/x86/cell.lisp @@ -274,7 +274,8 @@ ;;; BIND -- Establish VAL as a binding for SYMBOL. Save the old value and ;;; the symbol on the binding stack and stuff the new value into the ;;; symbol. - +;;; See the "Chapter 9: Specials" of the SBCL Internals Manual. +;; ;;; FIXME: Split into DYNBIND and BIND: DYNBIND needs to ensure ;;; TLS-INDEX, whereas BIND should assume it is already in place. Make ;;; LET &co compile into BIND, and PROGV into DYNBIND, plus ensure @@ -284,31 +285,36 @@ (define-vop (bind) (:args (val :scs (any-reg descriptor-reg)) (symbol :scs (descriptor-reg))) - (:temporary (:sc unsigned-reg) tls-index bsp) + (:temporary (:sc unsigned-reg) tls-index bsp + #!+win32 temp) (:generator 10 - (let ((tls-index-valid (gen-label))) - (load-binding-stack-pointer bsp) - (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag) - (inst add bsp (* binding-size n-word-bytes)) - (store-binding-stack-pointer bsp) - (inst test tls-index tls-index) - (inst jmp :ne tls-index-valid) - (inst mov tls-index symbol) - (inst call (make-fixup - (ecase (tn-offset tls-index) - (#.eax-offset 'alloc-tls-index-in-eax) - (#.ebx-offset 'alloc-tls-index-in-ebx) - (#.ecx-offset 'alloc-tls-index-in-ecx) - (#.edx-offset 'alloc-tls-index-in-edx) - (#.edi-offset 'alloc-tls-index-in-edi) - (#.esi-offset 'alloc-tls-index-in-esi)) - :assembly-routine)) - (emit-label tls-index-valid) - (with-tls-ea (EA :base tls-index :base-already-live-p t) - (inst push EA :maybe-fs) - (popw bsp (- binding-value-slot binding-size)) - (storew symbol bsp (- binding-symbol-slot binding-size)) - (inst mov EA val :maybe-fs))))) + (load-binding-stack-pointer bsp) + (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag) + (inst add bsp (* binding-size n-word-bytes)) + (store-binding-stack-pointer bsp) + (inst test tls-index tls-index) + (inst jmp :ne tls-index-valid) + (inst mov tls-index symbol) + (inst call (make-fixup + (ecase (tn-offset tls-index) + (#.eax-offset 'alloc-tls-index-in-eax) + (#.ebx-offset 'alloc-tls-index-in-ebx) + (#.ecx-offset 'alloc-tls-index-in-ecx) + (#.edx-offset 'alloc-tls-index-in-edx) + (#.edi-offset 'alloc-tls-index-in-edi) + (#.esi-offset 'alloc-tls-index-in-esi)) + :assembly-routine)) + TLS-INDEX-VALID + ;; with-tls-ea on win32 causes tls-index to be an absolute address + ;; which is problematic when UNBIND uses with-tls-ea too. + #!+win32(move temp tls-index) + (with-tls-ea (EA :base tls-index :base-already-live-p t) + (inst push EA :maybe-fs) + (popw bsp (- binding-value-slot binding-size)) + (storew #!-win32 tls-index + #!+win32 temp + bsp (- binding-symbol-slot binding-size)) + (inst mov EA val :maybe-fs)))) #!-sb-thread (define-vop (bind) @@ -330,16 +336,15 @@ (:generator 0 (load-binding-stack-pointer bsp) ;; Load SYMBOL from stack, and get the TLS-INDEX. - (loadw temp bsp (- binding-symbol-slot binding-size)) - (loadw tls-index temp symbol-tls-index-slot other-pointer-lowtag) + (loadw tls-index bsp (- binding-symbol-slot binding-size)) ;; Load VALUE from stack, then restore it to the TLS area. (loadw temp bsp (- binding-value-slot binding-size)) (with-tls-ea (EA :base tls-index :base-already-live-p t) (inst mov EA temp :maybe-fs)) ;; Zero out the stack. - (storew 0 bsp (- binding-symbol-slot binding-size)) - (storew 0 bsp (- binding-value-slot binding-size)) (inst sub bsp (* binding-size n-word-bytes)) + (storew 0 bsp binding-symbol-slot) + (storew 0 bsp binding-value-slot) (store-binding-stack-pointer bsp))) #!-sb-thread @@ -358,31 +363,28 @@ (define-vop (unbind-to-here) (:args (where :scs (descriptor-reg any-reg))) - (:temporary (:sc unsigned-reg) symbol value bsp #!+sb-thread tls-index) + (:temporary (:sc unsigned-reg) symbol value bsp) (:generator 0 (load-binding-stack-pointer bsp) (inst cmp where bsp) (inst jmp :e done) LOOP - (loadw symbol bsp (- binding-symbol-slot binding-size)) + (inst sub bsp (* binding-size n-word-bytes)) + (loadw symbol bsp binding-symbol-slot) (inst test symbol symbol) (inst jmp :z skip) ;; Bind stack debug sentinels have the unbound marker in the symbol slot (inst cmp symbol unbound-marker-widetag) (inst jmp :eq skip) - (loadw value bsp (- binding-value-slot binding-size)) + (loadw value bsp binding-value-slot) #!-sb-thread (storew value symbol symbol-value-slot other-pointer-lowtag) - - #!+sb-thread (loadw - tls-index symbol symbol-tls-index-slot other-pointer-lowtag) - #!+sb-thread (with-tls-ea (EA :base tls-index :base-already-live-p t) + #!+sb-thread (with-tls-ea (EA :base symbol :base-already-live-p t) (inst mov EA value :maybe-fs)) - (storew 0 bsp (- binding-symbol-slot binding-size)) + (storew 0 bsp binding-symbol-slot) SKIP - (storew 0 bsp (- binding-value-slot binding-size)) - (inst sub bsp (* binding-size n-word-bytes)) + (storew 0 bsp binding-value-slot) (inst cmp where bsp) (inst jmp :ne loop) (store-binding-stack-pointer bsp)