1.0.41.33: ppc: Implement threaded symbol value accessors.
[sbcl.git] / src / compiler / ppc / cell.lisp
index ff16478..7a2eb8d 100644 (file)
@@ -35,7 +35,7 @@
 ;;;; Symbol hacking VOPs:
 
 ;;; The compiler likes to be able to directly SET symbols.
 ;;;; Symbol hacking VOPs:
 
 ;;; The compiler likes to be able to directly SET symbols.
-(define-vop (set cell-set)
+(define-vop (%set-symbol-global-value cell-set)
   (:variant symbol-value-slot other-pointer-lowtag))
 
 ;;; Do a cell ref with an error check for being unbound.
   (:variant symbol-value-slot other-pointer-lowtag))
 
 ;;; Do a cell ref with an error check for being unbound.
 
 ;;; With SYMBOL-VALUE, we check that the value isn't the trap object.
 ;;; So SYMBOL-VALUE of NIL is NIL.
 
 ;;; With SYMBOL-VALUE, we check that the value isn't the trap object.
 ;;; So SYMBOL-VALUE of NIL is NIL.
-(define-vop (symbol-value checked-cell-ref)
-  (:translate symbol-value)
+(define-vop (symbol-global-value checked-cell-ref)
+  (:translate symbol-global-value)
   (:generator 9
     (move obj-temp object)
     (loadw value obj-temp symbol-value-slot other-pointer-lowtag)
   (:generator 9
     (move obj-temp object)
     (loadw value obj-temp symbol-value-slot other-pointer-lowtag)
-    (let ((err-lab (generate-error-code vop unbound-symbol-error obj-temp)))
+    (let ((err-lab (generate-error-code vop 'unbound-symbol-error obj-temp)))
       (inst cmpwi value unbound-marker-widetag)
       (inst beq err-lab))))
 
       (inst cmpwi value unbound-marker-widetag)
       (inst beq err-lab))))
 
+(define-vop (fast-symbol-global-value cell-ref)
+  (:variant symbol-value-slot other-pointer-lowtag)
+  (:policy :fast)
+  (:translate symbol-global-value))
+
+#!+sb-thread
+(progn
+  (define-vop (set)
+    (:args (symbol :scs (descriptor-reg))
+           (value :scs (descriptor-reg any-reg)))
+    (:temporary (:sc any-reg) tls-slot temp)
+    (:generator 4
+      (loadw tls-slot symbol symbol-tls-index-slot other-pointer-lowtag)
+      (inst lwzx temp thread-base-tn tls-slot)
+      (inst cmpwi temp no-tls-value-marker-widetag)
+      (inst beq GLOBAL-VALUE)
+      (inst stwx value thread-base-tn tls-slot)
+      (inst b DONE)
+      GLOBAL-VALUE
+      (storew value symbol symbol-value-slot other-pointer-lowtag)
+      DONE))
+
+  ;; With Symbol-Value, we check that the value isn't the trap object. So
+  ;; Symbol-Value of NIL is NIL.
+  (define-vop (symbol-value)
+    (:translate symbol-value)
+    (:policy :fast-safe)
+    (:args (object :scs (descriptor-reg) :to (:result 1)))
+    (:results (value :scs (descriptor-reg any-reg)))
+    (:vop-var vop)
+    (:save-p :compute-only)
+    (:generator 9
+      (loadw value object symbol-tls-index-slot other-pointer-lowtag)
+      (inst lwzx value thread-base-tn value)
+      (inst cmpwi value no-tls-value-marker-widetag)
+      (inst bne CHECK-UNBOUND)
+      (loadw value object symbol-value-slot other-pointer-lowtag)
+      CHECK-UNBOUND
+      (inst cmpwi value unbound-marker-widetag)
+      (inst beq (generate-error-code vop 'unbound-symbol-error object))))
+
+  (define-vop (fast-symbol-value symbol-value)
+    ;; KLUDGE: not really fast, in fact, because we're going to have to
+    ;; do a full lookup of the thread-local area anyway.  But half of
+    ;; the meaning of FAST-SYMBOL-VALUE is "do not signal an error if
+    ;; unbound", which is used in the implementation of COPY-SYMBOL.  --
+    ;; CSR, 2003-04-22
+    (:policy :fast)
+    (:translate symbol-value)
+    (:generator 8
+      (loadw value object symbol-tls-index-slot other-pointer-lowtag)
+      (inst lwzx value thread-base-tn value)
+      (inst cmpwi value no-tls-value-marker-widetag)
+      (inst bne DONE)
+      (loadw value object symbol-value-slot other-pointer-lowtag)
+      DONE)))
+
+;;; On unithreaded builds these are just copies of the global versions.
+#!-sb-thread
+(progn
+  (define-vop (symbol-value symbol-global-value)
+    (:translate symbol-value))
+  (define-vop (fast-symbol-value fast-symbol-global-value)
+    (:translate symbol-value))
+  (define-vop (set %set-symbol-global-value)))
+
 ;;; Like CHECKED-CELL-REF, only we are a predicate to see if the cell
 ;;; is bound.
 (define-vop (boundp-frob)
 ;;; Like CHECKED-CELL-REF, only we are a predicate to see if the cell
 ;;; is bound.
 (define-vop (boundp-frob)
   (:policy :fast-safe)
   (:temporary (:scs (descriptor-reg)) value))
 
   (:policy :fast-safe)
   (:temporary (:scs (descriptor-reg)) value))
 
+#!+sb-thread
 (define-vop (boundp boundp-frob)
   (:translate boundp)
   (:generator 9
 (define-vop (boundp boundp-frob)
   (:translate boundp)
   (:generator 9
+    (loadw value object symbol-tls-index-slot other-pointer-lowtag)
+    (inst lwzx value thread-base-tn value)
+    (inst cmpwi value no-tls-value-marker-widetag)
+    (inst bne CHECK-UNBOUND)
     (loadw value object symbol-value-slot other-pointer-lowtag)
     (loadw value object symbol-value-slot other-pointer-lowtag)
+    CHECK-UNBOUND
     (inst cmpwi value unbound-marker-widetag)
     (inst b? (if not-p :eq :ne) target)))
 
     (inst cmpwi value unbound-marker-widetag)
     (inst b? (if not-p :eq :ne) target)))
 
-(define-vop (fast-symbol-value cell-ref)
-  (:variant symbol-value-slot other-pointer-lowtag)
-  (:policy :fast)
-  (:translate symbol-value))
+#!-sb-thread
+(define-vop (boundp boundp-frob)
+  (:translate boundp)
+  (:generator 9
+    (loadw value object symbol-value-slot other-pointer-lowtag)
+    (inst cmpwi value unbound-marker-widetag)
+    (inst b? (if not-p :eq :ne) target)))
 
 (define-vop (symbol-hash)
   (:policy :fast-safe)
 
 (define-vop (symbol-hash)
   (:policy :fast-safe)
     ;; 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)
     ;; 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 clrrwi res res (1- n-lowtag-bits))))
+    (inst clrrwi res res n-fixnum-tag-bits)))
 \f
 ;;;; Fdefinition (fdefn) objects.
 
 \f
 ;;;; Fdefinition (fdefn) objects.
 
     (move obj-temp object)
     (loadw value obj-temp fdefn-fun-slot other-pointer-lowtag)
     (inst cmpw value null-tn)
     (move obj-temp object)
     (loadw value obj-temp fdefn-fun-slot other-pointer-lowtag)
     (inst cmpw value null-tn)
-    (let ((err-lab (generate-error-code vop undefined-fun-error obj-temp)))
+    (let ((err-lab (generate-error-code vop 'undefined-fun-error obj-temp)))
       (inst beq err-lab))))
 
 (define-vop (set-fdefn-fun)
       (inst beq err-lab))))
 
 (define-vop (set-fdefn-fun)
     (loadw value bsp-tn (- binding-value-slot binding-size))
     (storew value symbol symbol-value-slot other-pointer-lowtag)
     (storew zero-tn bsp-tn (- binding-symbol-slot binding-size))
     (loadw value bsp-tn (- binding-value-slot binding-size))
     (storew value symbol symbol-value-slot other-pointer-lowtag)
     (storew zero-tn bsp-tn (- binding-symbol-slot binding-size))
+    (storew zero-tn bsp-tn (- binding-value-slot binding-size))
     (inst subi bsp-tn bsp-tn (* 2 n-word-bytes))))
 
 
     (inst subi bsp-tn bsp-tn (* 2 n-word-bytes))))
 
 
       (storew zero-tn bsp-tn (- binding-symbol-slot binding-size))
 
       (emit-label skip)
       (storew zero-tn bsp-tn (- binding-symbol-slot binding-size))
 
       (emit-label skip)
+      (storew zero-tn bsp-tn (- binding-value-slot binding-size))
       (inst subi bsp-tn bsp-tn (* 2 n-word-bytes))
       (inst cmpw where bsp-tn)
       (inst bne loop)
       (inst subi bsp-tn bsp-tn (* 2 n-word-bytes))
       (inst cmpw where bsp-tn)
       (inst bne loop)
   (:variant funcallable-instance-info-offset fun-pointer-lowtag)
   (:translate %set-funcallable-instance-info))
 
   (:variant funcallable-instance-info-offset fun-pointer-lowtag)
   (:translate %set-funcallable-instance-info))
 
-(define-vop (funcallable-instance-lexenv cell-ref)
-  (:variant funcallable-instance-lexenv-slot fun-pointer-lowtag))
-
-
 (define-vop (closure-ref slot-ref)
   (:variant closure-info-offset fun-pointer-lowtag))
 
 (define-vop (closure-ref slot-ref)
   (:variant closure-info-offset fun-pointer-lowtag))
 
     (loadw temp struct 0 instance-pointer-lowtag)
     (inst srwi res temp n-widetag-bits)))
 
     (loadw temp struct 0 instance-pointer-lowtag)
     (inst srwi res temp n-widetag-bits)))
 
-(define-vop (instance-ref slot-ref)
-  (:variant instance-slots-offset instance-pointer-lowtag)
-  (:policy :fast-safe)
-  (:translate %instance-ref)
-  (:arg-types * (:constant index)))
-
-#+nil
-(define-vop (instance-set slot-set)
-  (:policy :fast-safe)
-  (:translate %instance-set)
-  (:variant instance-slots-offset instance-pointer-lowtag)
-  (:arg-types instance (:constant index) *))
-
 (define-vop (instance-index-ref word-index-ref)
   (:policy :fast-safe)
   (:translate %instance-ref)
 (define-vop (instance-index-ref word-index-ref)
   (:policy :fast-safe)
   (:translate %instance-ref)
 \f
 ;;;; raw instance slot accessors
 
 \f
 ;;;; raw instance slot accessors
 
+(defun offset-for-raw-slot (instance-length index n-words)
+  (+ (* (- instance-length instance-slots-offset index (1- n-words))
+        n-word-bytes)
+     (- instance-pointer-lowtag)))
+
+(define-vop (raw-instance-init/word)
+  (:args (object :scs (descriptor-reg))
+         (value :scs (unsigned-reg)))
+  (:arg-types * unsigned-num)
+  (:info instance-length index)
+  (:generator 4
+    (inst stw value object (offset-for-raw-slot instance-length index 1))))
+
 (define-vop (raw-instance-ref/word)
   (:translate %raw-instance-ref/word)
   (:policy :fast-safe)
 (define-vop (raw-instance-ref/word)
   (:translate %raw-instance-ref/word)
   (:policy :fast-safe)
   (:result-types unsigned-num)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:result-types unsigned-num)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
   (:result-types unsigned-num)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:result-types unsigned-num)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
     (inst stwx value object offset)
     (move result value)))
 
     (inst stwx value object offset)
     (move result value)))
 
+(define-vop (raw-instance-init/single)
+  (:args (object :scs (descriptor-reg))
+         (value :scs (single-reg)))
+  (:arg-types * single-float)
+  (:info instance-length index)
+  (:generator 4
+    (inst stfs value object (offset-for-raw-slot instance-length index 1))))
+
 (define-vop (raw-instance-ref/single)
   (:translate %raw-instance-ref/single)
   (:policy :fast-safe)
 (define-vop (raw-instance-ref/single)
   (:translate %raw-instance-ref/single)
   (:policy :fast-safe)
   (:result-types single-float)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:result-types single-float)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
   (:temporary (:scs (non-descriptor-reg)) offset)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:temporary (:scs (non-descriptor-reg)) offset)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
     (unless (location= result value)
       (inst frsp result value))))
 
     (unless (location= result value)
       (inst frsp result value))))
 
+(define-vop (raw-instance-init/double)
+  (:args (object :scs (descriptor-reg))
+         (value :scs (double-reg)))
+  (:arg-types * double-float)
+  (:info instance-length index)
+  (:generator 4
+    (inst stfd value object (offset-for-raw-slot instance-length index 2))))
+
 (define-vop (raw-instance-ref/double)
   (:translate %raw-instance-ref/double)
   (:policy :fast-safe)
 (define-vop (raw-instance-ref/double)
   (:translate %raw-instance-ref/double)
   (:policy :fast-safe)
   (:result-types double-float)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:result-types double-float)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
   (:temporary (:scs (non-descriptor-reg)) offset)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:temporary (:scs (non-descriptor-reg)) offset)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
     (unless (location= result value)
       (inst fmr result value))))
 
     (unless (location= result value)
       (inst fmr result value))))
 
+(define-vop (raw-instance-init/complex-single)
+  (:args (object :scs (descriptor-reg))
+         (value :scs (complex-single-reg)))
+  (:arg-types * complex-single-float)
+  (:info instance-length index)
+  (:generator 4
+    (inst stfs (complex-single-reg-real-tn value)
+          object (offset-for-raw-slot instance-length index 2))
+    (inst stfs (complex-single-reg-imag-tn value)
+          object (offset-for-raw-slot instance-length index 1))))
+
 (define-vop (raw-instance-ref/complex-single)
   (:translate %raw-instance-ref/complex-single)
   (:policy :fast-safe)
 (define-vop (raw-instance-ref/complex-single)
   (:translate %raw-instance-ref/complex-single)
   (:policy :fast-safe)
   (:result-types complex-single-float)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:result-types complex-single-float)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
   (:temporary (:scs (non-descriptor-reg)) offset)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:temporary (:scs (non-descriptor-reg)) offset)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
       (unless (location= result-imag value-imag)
         (inst frsp result-imag value-imag)))))
 
       (unless (location= result-imag value-imag)
         (inst frsp result-imag value-imag)))))
 
+(define-vop (raw-instance-init/complex-double)
+  (:args (object :scs (descriptor-reg))
+         (value :scs (complex-double-reg)))
+  (:arg-types * complex-double-float)
+  (:info instance-length index)
+  (:generator 4
+    (inst stfd (complex-single-reg-real-tn value)
+          object (offset-for-raw-slot instance-length index 4))
+    (inst stfd (complex-double-reg-imag-tn value)
+          object (offset-for-raw-slot instance-length index 2))))
+
 (define-vop (raw-instance-ref/complex-double)
   (:translate %raw-instance-ref/complex-double)
   (:policy :fast-safe)
 (define-vop (raw-instance-ref/complex-double)
   (:translate %raw-instance-ref/complex-double)
   (:policy :fast-safe)
   (:result-types complex-double-float)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:result-types complex-double-float)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset
   (:temporary (:scs (non-descriptor-reg)) offset)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
   (:temporary (:scs (non-descriptor-reg)) offset)
   (:generator 5
     (loadw offset object 0 instance-pointer-lowtag)
-    (inst srwi offset offset n-widetag-bits)
-    (inst slwi offset offset 2)
+    ;; offset = (offset >> n-widetag-bits) << 2
+    (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
     (inst subf offset index offset)
     (inst addi
           offset
     (inst subf offset index offset)
     (inst addi
           offset