UPGRADED-ARRAY-ELEMENT-TYPE: more thoroughly signal errors on unknown types.
[sbcl.git] / src / compiler / x86-64 / cell.lisp
index 0857ff6..f20d3fb 100644 (file)
     ;; it is a fixnum.  The lowtag selection magic that is required to
     ;; ensure this is explained in the comment in objdef.lisp
     (loadw res symbol symbol-hash-slot other-pointer-lowtag)
-    (inst and res (lognot #b111))))
+    (inst and res (lognot fixnum-tag-mask))))
 \f
 ;;;; fdefinition (FDEFN) objects
 
   (:args (function :scs (descriptor-reg) :target result)
          (fdefn :scs (descriptor-reg)))
   (:temporary (:sc unsigned-reg) raw)
-  (:temporary (:sc byte-reg) type)
+  (:temporary (:sc unsigned-reg) type)
   (:results (result :scs (descriptor-reg)))
   (:generator 38
     (load-type type function (- fun-pointer-lowtag))
           (make-ea :byte :base function
                    :disp (- (* simple-fun-code-offset n-word-bytes)
                             fun-pointer-lowtag)))
-    (inst cmp type simple-fun-header-widetag)
+    (inst cmp (reg-in-size type :byte) simple-fun-header-widetag)
     (inst jmp :e NORMAL-FUN)
-    (inst lea raw (make-fixup "closure_tramp" :foreign))
+    (inst mov raw (make-fixup "closure_tramp" :foreign))
     NORMAL-FUN
     (storew function fdefn fdefn-fun-slot other-pointer-lowtag)
     (storew raw fdefn fdefn-raw-addr-slot other-pointer-lowtag)
 ;;; 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.
 
 #!+sb-thread
 (define-vop (bind)
   (:args (val :scs (any-reg descriptor-reg))
-         (symbol :scs (descriptor-reg)))
-  (:temporary (:sc unsigned-reg) tls-index bsp)
+         (symbol :scs (descriptor-reg) :target tmp
+                 :to :load))
+  (:temporary (:sc unsigned-reg) tls-index bsp tmp)
   (: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 or tls-index tls-index)
-      (inst jmp :ne tls-index-valid)
-      (inst mov tls-index symbol)
-      (inst lea temp-reg-tn
-            (make-ea :qword :disp
-                     (make-fixup (ecase (tn-offset tls-index)
-                                   (#.rax-offset 'alloc-tls-index-in-rax)
-                                   (#.rcx-offset 'alloc-tls-index-in-rcx)
-                                   (#.rdx-offset 'alloc-tls-index-in-rdx)
-                                   (#.rbx-offset 'alloc-tls-index-in-rbx)
-                                   (#.rsi-offset 'alloc-tls-index-in-rsi)
-                                   (#.rdi-offset 'alloc-tls-index-in-rdi)
-                                   (#.r8-offset  'alloc-tls-index-in-r8)
-                                   (#.r9-offset  'alloc-tls-index-in-r9)
-                                   (#.r10-offset 'alloc-tls-index-in-r10)
-                                   (#.r12-offset 'alloc-tls-index-in-r12)
-                                   (#.r13-offset 'alloc-tls-index-in-r13)
-                                   (#.r14-offset 'alloc-tls-index-in-r14)
-                                   (#.r15-offset 'alloc-tls-index-in-r15))
-                                 :assembly-routine)))
-      (inst call temp-reg-tn)
-      (emit-label tls-index-valid)
-      (inst push (make-ea :qword :base thread-base-tn :scale 1 :index tls-index))
-      (popw bsp (- binding-value-slot binding-size))
-      (storew symbol bsp (- binding-symbol-slot binding-size))
-      (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
-            val))))
+    (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 mov tmp
+          (make-fixup (ecase (tn-offset tls-index)
+                        (#.rax-offset 'alloc-tls-index-in-rax)
+                        (#.rcx-offset 'alloc-tls-index-in-rcx)
+                        (#.rdx-offset 'alloc-tls-index-in-rdx)
+                        (#.rbx-offset 'alloc-tls-index-in-rbx)
+                        (#.rsi-offset 'alloc-tls-index-in-rsi)
+                        (#.rdi-offset 'alloc-tls-index-in-rdi)
+                        (#.r8-offset  'alloc-tls-index-in-r8)
+                        (#.r9-offset  'alloc-tls-index-in-r9)
+                        (#.r10-offset 'alloc-tls-index-in-r10)
+                        (#.r12-offset 'alloc-tls-index-in-r12)
+                        (#.r13-offset 'alloc-tls-index-in-r13)
+                        (#.r14-offset 'alloc-tls-index-in-r14)
+                        (#.r15-offset 'alloc-tls-index-in-r15))
+                      :assembly-routine))
+    (inst call tmp)
+    TLS-INDEX-VALID
+    (inst mov tmp (make-ea :qword :base thread-base-tn :index tls-index))
+    (storew tmp bsp (- binding-value-slot binding-size))
+    (storew tls-index bsp (- binding-symbol-slot binding-size))
+    (inst mov (make-ea :qword :base thread-base-tn :index tls-index) val)))
 
 #!-sb-thread
 (define-vop (bind)
   (:temporary (:sc unsigned-reg) temp bsp tls-index)
   (: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)
-    ;; Load VALUE from stack, the restore it to the TLS area.
-    (loadw temp bsp (- binding-value-slot binding-size))
-    (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
+    (inst sub bsp (* binding-size n-word-bytes))
+    ;; Load TLS-INDEX of the SYMBOL from stack
+    (loadw tls-index bsp binding-symbol-slot)
+    ;; Load VALUE from stack, then restore it to the TLS area.
+    (loadw temp bsp binding-value-slot)
+    (inst mov (make-ea :qword :base thread-base-tn :index tls-index)
           temp)
     ;; 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))
+    (zeroize temp)
+
+    (storew temp bsp binding-symbol-slot)
+    (storew temp bsp binding-value-slot)
     (store-binding-stack-pointer bsp)))
 
 #!-sb-thread
 
 (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 zero)
   (:generator 0
     (load-binding-stack-pointer bsp)
     (inst cmp where bsp)
     (inst jmp :e DONE)
-
+    (zeroize zero)
     LOOP
-    (loadw symbol bsp (- binding-symbol-slot binding-size))
-    (inst or symbol symbol)
+    (inst sub bsp (* binding-size n-word-bytes))
+    ;; on sb-thread symbol is actually a tls-index
+    (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
-    (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
+    (inst mov (make-ea :qword :base thread-base-tn :index symbol)
           value)
-    (storew 0 bsp (- binding-symbol-slot binding-size))
+    (storew zero bsp binding-symbol-slot)
 
     SKIP
-    (storew 0 bsp (- binding-value-slot binding-size))
-    (inst sub bsp (* binding-size n-word-bytes))
+    (storew zero bsp binding-value-slot)
+
     (inst cmp where bsp)
     (inst jmp :ne LOOP)
     (store-binding-stack-pointer bsp)
 \f
 ;;;; raw instance slot accessors
 
-(defun make-ea-for-raw-slot (object index instance-length
-                             &optional (adjustment 0))
+(defun make-ea-for-raw-slot (object instance-length
+                             &key (index nil) (adjustment 0) (scale 1))
   (if (integerp instance-length)
       ;; For RAW-INSTANCE-INIT/* VOPs, which know the exact instance length
       ;; at compile time.
                         (- instance-pointer-lowtag)
                         adjustment))
       (etypecase index
-        (tn
-         (make-ea :qword :base object :index instance-length
+        (null
+         (make-ea :qword :base object :index instance-length :scale scale
                   :disp (+ (* (1- instance-slots-offset) n-word-bytes)
                            (- instance-pointer-lowtag)
                            adjustment)))
     (inst shr tmp n-widetag-bits)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
-    (inst mov value (make-ea-for-raw-slot object index tmp))))
+    (inst mov value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))))))
 
 (define-vop (raw-instance-ref-c/word)
   (:translate %raw-instance-ref/word)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst mov value (make-ea-for-raw-slot object index tmp))))
+    (inst mov value (make-ea-for-raw-slot object tmp :index index))))
 
 (define-vop (raw-instance-set/word)
   (:translate %raw-instance-set/word)
     (inst shr tmp n-widetag-bits)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
-    (inst mov (make-ea-for-raw-slot object index tmp) value)
+    (inst mov (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))) value)
     (move result value)))
 
 (define-vop (raw-instance-set-c/word)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst mov (make-ea-for-raw-slot object index tmp) value)
+    (inst mov (make-ea-for-raw-slot object tmp :index index) value)
     (move result value)))
 
 (define-vop (raw-instance-init/word)
   (:arg-types * unsigned-num)
   (:info instance-length index)
   (:generator 4
-    (inst mov (make-ea-for-raw-slot object index instance-length) value)))
+    (inst mov (make-ea-for-raw-slot object instance-length :index index) value)))
 
 (define-vop (raw-instance-atomic-incf-c/word)
   (:translate %raw-instance-atomic-incf/word)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst xadd (make-ea-for-raw-slot object index tmp) diff :lock)
+    (inst xadd (make-ea-for-raw-slot object tmp :index index) diff :lock)
     (move result diff)))
 
 (define-vop (raw-instance-ref/single)
     (inst shr tmp n-widetag-bits)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
-    (inst movss value (make-ea-for-raw-slot object index tmp))))
+    (inst movss value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))))))
 
 (define-vop (raw-instance-ref-c/single)
   (:translate %raw-instance-ref/single)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst movss value (make-ea-for-raw-slot object index tmp))))
+    (inst movss value (make-ea-for-raw-slot object tmp :index index))))
 
 (define-vop (raw-instance-set/single)
   (:translate %raw-instance-set/single)
     (inst shr tmp n-widetag-bits)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
-    (inst movss (make-ea-for-raw-slot object index tmp) value)
+    (inst movss (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))) value)
     (move result value)))
 
 (define-vop (raw-instance-set-c/single)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst movss (make-ea-for-raw-slot object index tmp) value)
+    (inst movss (make-ea-for-raw-slot object tmp :index index) value)
     (move result value)))
 
 (define-vop (raw-instance-init/single)
   (:arg-types * single-float)
   (:info instance-length index)
   (:generator 4
-    (inst movss (make-ea-for-raw-slot object index instance-length) value)))
+    (inst movss (make-ea-for-raw-slot object instance-length :index index) value)))
 
 (define-vop (raw-instance-ref/double)
   (:translate %raw-instance-ref/double)
     (inst shr tmp n-widetag-bits)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
-    (inst movsd value (make-ea-for-raw-slot object index tmp))))
+    (inst movsd value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))))))
 
 (define-vop (raw-instance-ref-c/double)
   (:translate %raw-instance-ref/double)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst movsd value (make-ea-for-raw-slot object index tmp))))
+    (inst movsd value (make-ea-for-raw-slot object tmp :index index))))
 
 (define-vop (raw-instance-set/double)
   (:translate %raw-instance-set/double)
     (inst shr tmp n-widetag-bits)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
-    (inst movsd (make-ea-for-raw-slot object index tmp) value)
+    (inst movsd (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))) value)
     (move result value)))
 
 (define-vop (raw-instance-set-c/double)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst movsd (make-ea-for-raw-slot object index tmp) value)
+    (inst movsd (make-ea-for-raw-slot object tmp :index index) value)
     (move result value)))
 
 (define-vop (raw-instance-init/double)
   (:arg-types * double-float)
   (:info instance-length index)
   (:generator 4
-    (inst movsd (make-ea-for-raw-slot object index instance-length) value)))
+    (inst movsd (make-ea-for-raw-slot object instance-length :index index) value)))
 
 (define-vop (raw-instance-ref/complex-single)
   (:translate %raw-instance-ref/complex-single)
     (inst shr tmp n-widetag-bits)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
-    (inst movq value (make-ea-for-raw-slot object index tmp))))
+    (inst movq value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))))))
 
 (define-vop (raw-instance-ref-c/complex-single)
   (:translate %raw-instance-ref/complex-single)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst movq value (make-ea-for-raw-slot object index tmp))))
+    (inst movq value (make-ea-for-raw-slot object tmp :index index))))
 
 (define-vop (raw-instance-set/complex-single)
   (:translate %raw-instance-set/complex-single)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
     (move result value)
-    (inst movq (make-ea-for-raw-slot object index tmp) value)))
+    (inst movq (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))) value)))
 
 (define-vop (raw-instance-set-c/complex-single)
   (:translate %raw-instance-set/complex-single)
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
     (move result value)
-    (inst movq (make-ea-for-raw-slot object index tmp) value)))
+    (inst movq (make-ea-for-raw-slot object tmp :index index) value)))
 
 (define-vop (raw-instance-init/complex-single)
   (:args (object :scs (descriptor-reg))
   (:arg-types * complex-single-float)
   (:info instance-length index)
   (:generator 4
-    (inst movq (make-ea-for-raw-slot object index instance-length) value)))
+    (inst movq (make-ea-for-raw-slot object instance-length :index index) value)))
 
 (define-vop (raw-instance-ref/complex-double)
   (:translate %raw-instance-ref/complex-double)
     (inst shr tmp n-widetag-bits)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
-    (inst movdqu value (make-ea-for-raw-slot object index tmp -8))))
+    (inst movdqu value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits)) :adjustment -8))))
 
 (define-vop (raw-instance-ref-c/complex-double)
   (:translate %raw-instance-ref/complex-double)
   (:generator 4
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
-    (inst movdqu value (make-ea-for-raw-slot object index tmp -8))))
+    (inst movdqu value (make-ea-for-raw-slot object tmp :index index :adjustment -8))))
 
 (define-vop (raw-instance-set/complex-double)
   (:translate %raw-instance-set/complex-double)
     (inst shl tmp n-fixnum-tag-bits)
     (inst sub tmp index)
     (move result value)
-    (inst movdqu (make-ea-for-raw-slot object index tmp -8) value)))
+    (inst movdqu (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits)) :adjustment -8) value)))
 
 (define-vop (raw-instance-set-c/complex-double)
   (:translate %raw-instance-set/complex-double)
     (loadw tmp object 0 instance-pointer-lowtag)
     (inst shr tmp n-widetag-bits)
     (move result value)
-    (inst movdqu (make-ea-for-raw-slot object index tmp -8) value)))
+    (inst movdqu (make-ea-for-raw-slot object tmp :index index :adjustment -8) value)))
 
 (define-vop (raw-instance-init/complex-double)
   (:args (object :scs (descriptor-reg))
   (:arg-types * complex-double-float)
   (:info instance-length index)
   (:generator 4
-    (inst movdqu (make-ea-for-raw-slot object index instance-length -8) value)))
+    (inst movdqu (make-ea-for-raw-slot object instance-length :index index :adjustment -8) value)))