1.0.5.6: compare-and-swap / instance-set-conditional refactoring
[sbcl.git] / src / compiler / x86 / array.lisp
index aeb4c4a..16e9aa0 100644 (file)
 ;;; out of 8, 16, or 32 bit elements.
 (macrolet ((def-full-data-vector-frobs (type element-type &rest scs)
              `(progn
-                (define-full-reffer ,(symbolicate "DATA-VECTOR-REF/" type)
+                (define-full-reffer+offset ,(symbolicate "DATA-VECTOR-REF-WITH-OFFSET/" type)
                   ,type vector-data-offset other-pointer-lowtag ,scs
-                  ,element-type data-vector-ref)
-                (define-full-setter ,(symbolicate "DATA-VECTOR-SET/" type)
+                  ,element-type data-vector-ref-with-offset)
+                (define-full-setter+offset ,(symbolicate "DATA-VECTOR-SET-WITH-OFFSET/" type)
                   ,type vector-data-offset other-pointer-lowtag ,scs
-                  ,element-type data-vector-set))))
+                  ,element-type data-vector-set-with-offset))))
   (def-full-data-vector-frobs simple-vector * descriptor-reg any-reg)
   (def-full-data-vector-frobs simple-array-unsigned-byte-32 unsigned-num
     unsigned-reg)
   (def-full-data-vector-frobs simple-array-signed-byte-32 signed-num
     signed-reg)
   (def-full-data-vector-frobs simple-array-unsigned-byte-31 unsigned-num
-    unsigned-reg))
+    unsigned-reg)
+  #!+sb-unicode
+  (def-full-data-vector-frobs simple-character-string character character-reg))
+
+(define-full-compare-and-swap simple-vector-compare-and-swap
+    simple-vector vector-data-offset other-pointer-lowtag
+    (descriptor-reg any-reg) *
+    %simple-vector-compare-and-swap)
 \f
 ;;;; integer vectors whose elements are smaller than a byte, i.e.,
 ;;;; bit, 2-bit, and 4-bit vectors
          (:generator 20
            (move ecx index)
            (inst shr ecx ,bit-shift)
-           (inst mov result
-                 (make-ea :dword :base object :index ecx :scale 4
-                          :disp (- (* vector-data-offset n-word-bytes)
-                                   other-pointer-lowtag)))
+           (inst mov result (make-ea-for-vector-data object :index ecx))
            (move ecx index)
-           (inst and ecx ,(1- elements-per-word))
-           ,@(unless (= bits 1)
-               `((inst shl ecx ,(1- (integer-length bits)))))
+           ;; We used to mask ECX for all values of ELEMENT-PER-WORD,
+           ;; but since Intel's documentation says that the chip will
+           ;; mask shift and rotate counts by 31 automatically, we can
+           ;; safely move the masking operation under the protection of
+           ;; this UNLESS in the bit-vector case.  --njf, 2006-07-14
+           ,@(unless (= elements-per-word n-word-bits)
+               `((inst and ecx ,(1- elements-per-word))
+                 (inst shl ecx ,(1- (integer-length bits)))))
            (inst shr result :cl)
            (inst and result ,(1- (ash 1 bits)))))
        (define-vop (,(symbolicate 'data-vector-ref-c/ type))
          (:note "inline array store")
          (:translate data-vector-set)
          (:policy :fast-safe)
-         (:args (object :scs (descriptor-reg) :target ptr)
+         (:args (object :scs (descriptor-reg) :to (:argument 2))
                 (index :scs (unsigned-reg) :target ecx)
                 (value :scs (unsigned-reg immediate) :target result))
          (:arg-types ,type positive-fixnum positive-fixnum)
          (:results (result :scs (unsigned-reg)))
          (:result-types positive-fixnum)
          (:temporary (:sc unsigned-reg) word-index)
-         (:temporary (:sc unsigned-reg :from (:argument 0)) ptr old)
-         (:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1))
-                     ecx)
+         (:temporary (:sc unsigned-reg) old)
+         (:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1)) ecx)
          (:generator 25
            (move word-index index)
            (inst shr word-index ,bit-shift)
-           (inst lea ptr
-                 (make-ea :dword :base object :index word-index :scale 4
-                          :disp (- (* vector-data-offset n-word-bytes)
-                                   other-pointer-lowtag)))
-           (loadw old ptr)
+           (inst mov old (make-ea-for-vector-data object :index word-index))
            (move ecx index)
-           (inst and ecx ,(1- elements-per-word))
-           ,@(unless (= bits 1)
-               `((inst shl ecx ,(1- (integer-length bits)))))
+           ;; We used to mask ECX for all values of ELEMENT-PER-WORD,
+           ;; but since Intel's documentation says that the chip will
+           ;; mask shift and rotate counts by 31 automatically, we can
+           ;; safely move the masking operation under the protection of
+           ;; this UNLESS in the bit-vector case.  --njf, 2006-07-14
+           ,@(unless (= elements-per-word n-word-bits)
+               `((inst and ecx ,(1- elements-per-word))
+                 (inst shl ecx ,(1- (integer-length bits)))))
            (inst ror old :cl)
            (unless (and (sc-is value immediate)
                         (= (tn-value value) ,(1- (ash 1 bits))))
              (unsigned-reg
               (inst or old value)))
            (inst rol old :cl)
-           (storew old ptr)
+           (inst mov (make-ea-for-vector-data object :index word-index)
+                 old)
            (sc-case value
              (immediate
               (inst mov result (tn-value value)))
          (:temporary (:sc unsigned-reg :to (:result 0)) old)
          (:generator 20
            (multiple-value-bind (word extra) (floor index ,elements-per-word)
-             (inst mov old
-                   (make-ea :dword :base object
-                            :disp (- (* (+ word vector-data-offset)
-                                        n-word-bytes)
-                                     other-pointer-lowtag)))
+             (loadw old object (+ word vector-data-offset) other-pointer-lowtag)
              (sc-case value
                (immediate
                 (let* ((value (tn-value value))
                   (inst or old value)
                   (unless (zerop shift)
                     (inst rol old shift)))))
-             (inst mov (make-ea :dword :base object
-                                :disp (- (* (+ word vector-data-offset)
-                                            n-word-bytes)
-                                         other-pointer-lowtag))
-                   old)
+             (storew old object (+ word vector-data-offset) other-pointer-lowtag)
              (sc-case value
                (immediate
                 (inst mov result (tn-value value)))
 
 ;;; And the float variants.
 
-(define-vop (data-vector-ref/simple-array-single-float)
+(defun make-ea-for-float-ref (object index offset element-size
+                              &key (scale 1) (complex-offset 0))
+  (sc-case index
+    (immediate
+     (make-ea :dword :base object
+              :disp (- (+ (* vector-data-offset n-word-bytes)
+                          (* element-size (+ offset (tn-value index)))
+                          complex-offset)
+                       other-pointer-lowtag)))
+    (t
+     (make-ea :dword :base object :index index :scale scale
+              :disp (- (+ (* vector-data-offset n-word-bytes)
+                          (* element-size offset)
+                          complex-offset)
+                       other-pointer-lowtag)))))
+
+(define-vop (data-vector-ref-with-offset/simple-array-single-float)
   (:note "inline array access")
-  (:translate data-vector-ref)
+  (:translate data-vector-ref-with-offset)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg))
-         (index :scs (any-reg)))
-  (:arg-types simple-array-single-float positive-fixnum)
+         (index :scs (any-reg immediate)))
+  (:info offset)
+  (:arg-types simple-array-single-float positive-fixnum
+              (:constant (constant-displacement other-pointer-lowtag
+                                                4 vector-data-offset)))
   (:results (value :scs (single-reg)))
   (:result-types single-float)
   (:generator 5
    (with-empty-tn@fp-top(value)
-     (inst fld (make-ea :dword :base object :index index :scale 1
-                        :disp (- (* vector-data-offset
-                                    n-word-bytes)
-                                 other-pointer-lowtag))))))
-
-(define-vop (data-vector-ref-c/simple-array-single-float)
-  (:note "inline array access")
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg)))
-  (:info index)
-  (:arg-types simple-array-single-float (:constant (signed-byte 30)))
-  (:results (value :scs (single-reg)))
-  (:result-types single-float)
-  (:generator 4
-   (with-empty-tn@fp-top(value)
-     (inst fld (make-ea :dword :base object
-                        :disp (- (+ (* vector-data-offset
-                                       n-word-bytes)
-                                    (* 4 index))
-                                 other-pointer-lowtag))))))
-
-(define-vop (data-vector-set/simple-array-single-float)
-  (:note "inline array store")
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg))
-         (index :scs (any-reg))
-         (value :scs (single-reg) :target result))
-  (:arg-types simple-array-single-float positive-fixnum single-float)
-  (:results (result :scs (single-reg)))
-  (:result-types single-float)
-  (:generator 5
-    (cond ((zerop (tn-offset value))
-           ;; Value is in ST0.
-           (inst fst (make-ea :dword :base object :index index :scale 1
-                              :disp (- (* vector-data-offset
-                                          n-word-bytes)
-                                       other-pointer-lowtag)))
-           (unless (zerop (tn-offset result))
-                   ;; Value is in ST0 but not result.
-                   (inst fst result)))
-          (t
-           ;; Value is not in ST0.
-           (inst fxch value)
-           (inst fst (make-ea :dword :base object :index index :scale 1
-                              :disp (- (* vector-data-offset
-                                          n-word-bytes)
-                                       other-pointer-lowtag)))
-           (cond ((zerop (tn-offset result))
-                  ;; The result is in ST0.
-                  (inst fst value))
-                 (t
-                  ;; Neither value or result are in ST0
-                  (unless (location= value result)
-                          (inst fst result))
-                  (inst fxch value)))))))
+     (inst fld (make-ea-for-float-ref object index offset 4)))))
 
-(define-vop (data-vector-set-c/simple-array-single-float)
+(define-vop (data-vector-set-with-offset/simple-array-single-float)
   (:note "inline array store")
-  (:translate data-vector-set)
+  (:translate data-vector-set-with-offset)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg))
+         (index :scs (any-reg immediate))
          (value :scs (single-reg) :target result))
-  (:info index)
-  (:arg-types simple-array-single-float (:constant (signed-byte 30))
+  (:info offset)
+  (:arg-types simple-array-single-float positive-fixnum
+              (:constant (constant-displacement other-pointer-lowtag
+                                                4 vector-data-offset))
               single-float)
   (:results (result :scs (single-reg)))
   (:result-types single-float)
-  (:generator 4
+  (:generator 5
     (cond ((zerop (tn-offset value))
            ;; Value is in ST0.
-           (inst fst (make-ea :dword :base object
-                              :disp (- (+ (* vector-data-offset
-                                             n-word-bytes)
-                                          (* 4 index))
-                                       other-pointer-lowtag)))
+           (inst fst (make-ea-for-float-ref object index offset 4))
            (unless (zerop (tn-offset result))
-                   ;; Value is in ST0 but not result.
-                   (inst fst result)))
+             ;; Value is in ST0 but not result.
+             (inst fst result)))
           (t
            ;; Value is not in ST0.
            (inst fxch value)
-           (inst fst (make-ea :dword :base object
-                              :disp (- (+ (* vector-data-offset
-                                             n-word-bytes)
-                                          (* 4 index))
-                                       other-pointer-lowtag)))
+           (inst fst (make-ea-for-float-ref object index offset 4))
            (cond ((zerop (tn-offset result))
                   ;; The result is in ST0.
                   (inst fst value))
                  (t
                   ;; Neither value or result are in ST0
                   (unless (location= value result)
-                          (inst fst result))
+                    (inst fst result))
                   (inst fxch value)))))))
 
-(define-vop (data-vector-ref/simple-array-double-float)
+(define-vop (data-vector-ref-with-offset/simple-array-double-float)
   (:note "inline array access")
-  (:translate data-vector-ref)
+  (:translate data-vector-ref-with-offset)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg))
-         (index :scs (any-reg)))
-  (:arg-types simple-array-double-float positive-fixnum)
+         (index :scs (any-reg immediate)))
+  (:info offset)
+  (:arg-types simple-array-double-float
+              positive-fixnum
+              (:constant (constant-displacement other-pointer-lowtag
+                                                8 vector-data-offset)))
   (:results (value :scs (double-reg)))
   (:result-types double-float)
   (:generator 7
    (with-empty-tn@fp-top(value)
-     (inst fldd (make-ea :dword :base object :index index :scale 2
-                         :disp (- (* vector-data-offset
-                                     n-word-bytes)
-                                  other-pointer-lowtag))))))
-
-(define-vop (data-vector-ref-c/simple-array-double-float)
-  (:note "inline array access")
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg)))
-  (:info index)
-  (:arg-types simple-array-double-float (:constant (signed-byte 30)))
-  (:results (value :scs (double-reg)))
-  (:result-types double-float)
-  (:generator 6
-   (with-empty-tn@fp-top(value)
-     (inst fldd (make-ea :dword :base object
-                         :disp (- (+ (* vector-data-offset
-                                        n-word-bytes)
-                                     (* 8 index))
-                                  other-pointer-lowtag))))))
-
-(define-vop (data-vector-set/simple-array-double-float)
-  (:note "inline array store")
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg))
-         (index :scs (any-reg))
-         (value :scs (double-reg) :target result))
-  (:arg-types simple-array-double-float positive-fixnum double-float)
-  (:results (result :scs (double-reg)))
-  (:result-types double-float)
-  (:generator 20
-    (cond ((zerop (tn-offset value))
-           ;; Value is in ST0.
-           (inst fstd (make-ea :dword :base object :index index :scale 2
-                               :disp (- (* vector-data-offset
-                                           n-word-bytes)
-                                        other-pointer-lowtag)))
-           (unless (zerop (tn-offset result))
-                   ;; Value is in ST0 but not result.
-                   (inst fstd result)))
-          (t
-           ;; Value is not in ST0.
-           (inst fxch value)
-           (inst fstd (make-ea :dword :base object :index index :scale 2
-                               :disp (- (* vector-data-offset
-                                           n-word-bytes)
-                                        other-pointer-lowtag)))
-           (cond ((zerop (tn-offset result))
-                  ;; The result is in ST0.
-                  (inst fstd value))
-                 (t
-                  ;; Neither value or result are in ST0
-                  (unless (location= value result)
-                          (inst fstd result))
-                  (inst fxch value)))))))
+     (inst fldd (make-ea-for-float-ref object index offset 8 :scale 2)))))
 
-(define-vop (data-vector-set-c/simple-array-double-float)
+(define-vop (data-vector-set-with-offset/simple-array-double-float)
   (:note "inline array store")
-  (:translate data-vector-set)
+  (:translate data-vector-set-with-offset)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg))
+         (index :scs (any-reg immediate))
          (value :scs (double-reg) :target result))
-  (:info index)
-  (:arg-types simple-array-double-float (:constant (signed-byte 30))
+  (:info offset)
+  (:arg-types simple-array-double-float positive-fixnum
+              (:constant (constant-displacement other-pointer-lowtag
+                                                8 vector-data-offset))
               double-float)
   (:results (result :scs (double-reg)))
   (:result-types double-float)
-  (:generator 19
+  (:generator 20
     (cond ((zerop (tn-offset value))
            ;; Value is in ST0.
-           (inst fstd (make-ea :dword :base object
-                               :disp (- (+ (* vector-data-offset
-                                              n-word-bytes)
-                                           (* 8 index))
-                                        other-pointer-lowtag)))
+           (inst fstd (make-ea-for-float-ref object index offset 8 :scale 2))
            (unless (zerop (tn-offset result))
                    ;; Value is in ST0 but not result.
                    (inst fstd result)))
           (t
            ;; Value is not in ST0.
            (inst fxch value)
-           (inst fstd (make-ea :dword :base object
-                               :disp (- (+ (* vector-data-offset
-                                              n-word-bytes)
-                                           (* 8 index))
-                                        other-pointer-lowtag)))
+           (inst fstd (make-ea-for-float-ref object index offset 8 :scale 2))
            (cond ((zerop (tn-offset result))
                   ;; The result is in ST0.
                   (inst fstd value))
                           (inst fstd result))
                   (inst fxch value)))))))
 
-
-
 ;;; complex float variants
 
-(define-vop (data-vector-ref/simple-array-complex-single-float)
+(define-vop (data-vector-ref-with-offset/simple-array-complex-single-float)
   (:note "inline array access")
-  (:translate data-vector-ref)
+  (:translate data-vector-ref-with-offset)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg))
-         (index :scs (any-reg)))
-  (:arg-types simple-array-complex-single-float positive-fixnum)
+         (index :scs (any-reg immediate)))
+  (:info offset)
+  (:arg-types simple-array-complex-single-float positive-fixnum
+              (:constant (constant-displacement other-pointer-lowtag
+                                                8 vector-data-offset)))
   (:results (value :scs (complex-single-reg)))
   (:result-types complex-single-float)
   (:generator 5
     (let ((real-tn (complex-single-reg-real-tn value)))
       (with-empty-tn@fp-top (real-tn)
-        (inst fld (make-ea :dword :base object :index index :scale 2
-                           :disp (- (* vector-data-offset
-                                       n-word-bytes)
-                                    other-pointer-lowtag)))))
-    (let ((imag-tn (complex-single-reg-imag-tn value)))
-      (with-empty-tn@fp-top (imag-tn)
-        (inst fld (make-ea :dword :base object :index index :scale 2
-                           :disp (- (* (1+ vector-data-offset)
-                                       n-word-bytes)
-                                    other-pointer-lowtag)))))))
-
-(define-vop (data-vector-ref-c/simple-array-complex-single-float)
-  (:note "inline array access")
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg)))
-  (:info index)
-  (:arg-types simple-array-complex-single-float (:constant (signed-byte 30)))
-  (:results (value :scs (complex-single-reg)))
-  (:result-types complex-single-float)
-  (:generator 4
-    (let ((real-tn (complex-single-reg-real-tn value)))
-      (with-empty-tn@fp-top (real-tn)
-        (inst fld (make-ea :dword :base object
-                           :disp (- (+ (* vector-data-offset
-                                          n-word-bytes)
-                                       (* 8 index))
-                                    other-pointer-lowtag)))))
+        (inst fld (make-ea-for-float-ref object index offset 8 :scale 2))))
     (let ((imag-tn (complex-single-reg-imag-tn value)))
       (with-empty-tn@fp-top (imag-tn)
-        (inst fld (make-ea :dword :base object
-                           :disp (- (+ (* vector-data-offset
-                                          n-word-bytes)
-                                       (* 8 index) 4)
-                                    other-pointer-lowtag)))))))
+        ;; FIXME
+        (inst fld (make-ea-for-float-ref object index offset 8
+                                         :scale 2 :complex-offset 4))))))
 
-(define-vop (data-vector-set/simple-array-complex-single-float)
+(define-vop (data-vector-set-with-offset/simple-array-complex-single-float)
   (:note "inline array store")
-  (:translate data-vector-set)
+  (:translate data-vector-set-with-offset)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg))
-         (index :scs (any-reg))
+         (index :scs (any-reg immediate))
          (value :scs (complex-single-reg) :target result))
+  (:info offset)
   (:arg-types simple-array-complex-single-float positive-fixnum
+              (:constant (constant-displacement other-pointer-lowtag
+                                                8 vector-data-offset))
               complex-single-float)
   (:results (result :scs (complex-single-reg)))
   (:result-types complex-single-float)
           (result-real (complex-single-reg-real-tn result)))
       (cond ((zerop (tn-offset value-real))
              ;; Value is in ST0.
-             (inst fst (make-ea :dword :base object :index index :scale 2
-                                :disp (- (* vector-data-offset
-                                            n-word-bytes)
-                                         other-pointer-lowtag)))
-             (unless (zerop (tn-offset result-real))
-               ;; Value is in ST0 but not result.
-               (inst fst result-real)))
-            (t
-             ;; Value is not in ST0.
-             (inst fxch value-real)
-             (inst fst (make-ea :dword :base object :index index :scale 2
-                                :disp (- (* vector-data-offset
-                                            n-word-bytes)
-                                         other-pointer-lowtag)))
-             (cond ((zerop (tn-offset result-real))
-                    ;; The result is in ST0.
-                    (inst fst value-real))
-                   (t
-                    ;; Neither value or result are in ST0
-                    (unless (location= value-real result-real)
-                      (inst fst result-real))
-                    (inst fxch value-real))))))
-    (let ((value-imag (complex-single-reg-imag-tn value))
-          (result-imag (complex-single-reg-imag-tn result)))
-      (inst fxch value-imag)
-      (inst fst (make-ea :dword :base object :index index :scale 2
-                         :disp (- (+ (* vector-data-offset
-                                        n-word-bytes)
-                                     4)
-                                  other-pointer-lowtag)))
-      (unless (location= value-imag result-imag)
-        (inst fst result-imag))
-      (inst fxch value-imag))))
-
-(define-vop (data-vector-set-c/simple-array-complex-single-float)
-  (:note "inline array store")
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg))
-         (value :scs (complex-single-reg) :target result))
-  (:info index)
-  (:arg-types simple-array-complex-single-float (:constant (signed-byte 30))
-              complex-single-float)
-  (:results (result :scs (complex-single-reg)))
-  (:result-types complex-single-float)
-  (:generator 4
-    (let ((value-real (complex-single-reg-real-tn value))
-          (result-real (complex-single-reg-real-tn result)))
-      (cond ((zerop (tn-offset value-real))
-             ;; Value is in ST0.
-             (inst fst (make-ea :dword :base object
-                                :disp (- (+ (* vector-data-offset
-                                               n-word-bytes)
-                                            (* 8 index))
-                                         other-pointer-lowtag)))
+             (inst fst (make-ea-for-float-ref object index offset 8 :scale 2))
              (unless (zerop (tn-offset result-real))
                ;; Value is in ST0 but not result.
                (inst fst result-real)))
             (t
              ;; Value is not in ST0.
              (inst fxch value-real)
-             (inst fst (make-ea :dword :base object
-                                :disp (- (+ (* vector-data-offset
-                                               n-word-bytes)
-                                            (* 8 index))
-                                         other-pointer-lowtag)))
+             (inst fst (make-ea-for-float-ref object index offset 8 :scale 2))
              (cond ((zerop (tn-offset result-real))
                     ;; The result is in ST0.
                     (inst fst value-real))
     (let ((value-imag (complex-single-reg-imag-tn value))
           (result-imag (complex-single-reg-imag-tn result)))
       (inst fxch value-imag)
-      (inst fst (make-ea :dword :base object
-                         :disp (- (+ (* vector-data-offset
-                                        n-word-bytes)
-                                     (* 8 index) 4)
-                                  other-pointer-lowtag)))
+      (inst fst (make-ea-for-float-ref object index offset 8
+                                       :scale 2 :complex-offset 4))
       (unless (location= value-imag result-imag)
         (inst fst result-imag))
       (inst fxch value-imag))))
 
-
-(define-vop (data-vector-ref/simple-array-complex-double-float)
+(define-vop (data-vector-ref-with-offset/simple-array-complex-double-float)
   (:note "inline array access")
-  (:translate data-vector-ref)
+  (:translate data-vector-ref-with-offset)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg))
-         (index :scs (any-reg)))
-  (:arg-types simple-array-complex-double-float positive-fixnum)
+         (index :scs (any-reg immediate)))
+  (:info offset)
+  (:arg-types simple-array-complex-double-float positive-fixnum
+              (:constant (constant-displacement other-pointer-lowtag
+                                                16 vector-data-offset)))
   (:results (value :scs (complex-double-reg)))
   (:result-types complex-double-float)
   (:generator 7
     (let ((real-tn (complex-double-reg-real-tn value)))
       (with-empty-tn@fp-top (real-tn)
-        (inst fldd (make-ea :dword :base object :index index :scale 4
-                            :disp (- (* vector-data-offset
-                                        n-word-bytes)
-                                     other-pointer-lowtag)))))
+        (inst fldd (make-ea-for-float-ref object index offset 16 :scale 4)))
     (let ((imag-tn (complex-double-reg-imag-tn value)))
       (with-empty-tn@fp-top (imag-tn)
-        (inst fldd (make-ea :dword :base object :index index :scale 4
-                            :disp (- (+ (* vector-data-offset
-                                           n-word-bytes)
-                                        8)
-                                     other-pointer-lowtag)))))))
+        (inst fldd (make-ea-for-float-ref object index offset 16
+                                          :scale 4 :complex-offset 8)))))))
 
-(define-vop (data-vector-ref-c/simple-array-complex-double-float)
-  (:note "inline array access")
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg)))
-  (:info index)
-  (:arg-types simple-array-complex-double-float (:constant (signed-byte 30)))
-  (:results (value :scs (complex-double-reg)))
-  (:result-types complex-double-float)
-  (:generator 6
-    (let ((real-tn (complex-double-reg-real-tn value)))
-      (with-empty-tn@fp-top (real-tn)
-        (inst fldd (make-ea :dword :base object
-                            :disp (- (+ (* vector-data-offset
-                                           n-word-bytes)
-                                        (* 16 index))
-                                     other-pointer-lowtag)))))
-    (let ((imag-tn (complex-double-reg-imag-tn value)))
-      (with-empty-tn@fp-top (imag-tn)
-        (inst fldd (make-ea :dword :base object
-                            :disp (- (+ (* vector-data-offset
-                                           n-word-bytes)
-                                        (* 16 index) 8)
-                                     other-pointer-lowtag)))))))
-
-(define-vop (data-vector-set/simple-array-complex-double-float)
+(define-vop (data-vector-set-with-offset/simple-array-complex-double-float)
   (:note "inline array store")
-  (:translate data-vector-set)
+  (:translate data-vector-set-with-offset)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg))
-         (index :scs (any-reg))
+         (index :scs (any-reg immediate))
          (value :scs (complex-double-reg) :target result))
+  (:info offset)
   (:arg-types simple-array-complex-double-float positive-fixnum
+              (:constant (constant-displacement other-pointer-lowtag
+                                                16 vector-data-offset))
               complex-double-float)
   (:results (result :scs (complex-double-reg)))
   (:result-types complex-double-float)
           (result-real (complex-double-reg-real-tn result)))
       (cond ((zerop (tn-offset value-real))
              ;; Value is in ST0.
-             (inst fstd (make-ea :dword :base object :index index :scale 4
-                                 :disp (- (* vector-data-offset
-                                             n-word-bytes)
-                                          other-pointer-lowtag)))
-             (unless (zerop (tn-offset result-real))
-               ;; Value is in ST0 but not result.
-               (inst fstd result-real)))
-            (t
-             ;; Value is not in ST0.
-             (inst fxch value-real)
-             (inst fstd (make-ea :dword :base object :index index :scale 4
-                                 :disp (- (* vector-data-offset
-                                             n-word-bytes)
-                                          other-pointer-lowtag)))
-             (cond ((zerop (tn-offset result-real))
-                    ;; The result is in ST0.
-                    (inst fstd value-real))
-                   (t
-                    ;; Neither value or result are in ST0
-                    (unless (location= value-real result-real)
-                      (inst fstd result-real))
-                    (inst fxch value-real))))))
-    (let ((value-imag (complex-double-reg-imag-tn value))
-          (result-imag (complex-double-reg-imag-tn result)))
-      (inst fxch value-imag)
-      (inst fstd (make-ea :dword :base object :index index :scale 4
-                          :disp (- (+ (* vector-data-offset
-                                         n-word-bytes)
-                                      8)
-                                   other-pointer-lowtag)))
-      (unless (location= value-imag result-imag)
-        (inst fstd result-imag))
-      (inst fxch value-imag))))
-
-(define-vop (data-vector-set-c/simple-array-complex-double-float)
-  (:note "inline array store")
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg))
-         (value :scs (complex-double-reg) :target result))
-  (:info index)
-  (:arg-types simple-array-complex-double-float (:constant (signed-byte 30))
-              complex-double-float)
-  (:results (result :scs (complex-double-reg)))
-  (:result-types complex-double-float)
-  (:generator 19
-    (let ((value-real (complex-double-reg-real-tn value))
-          (result-real (complex-double-reg-real-tn result)))
-      (cond ((zerop (tn-offset value-real))
-             ;; Value is in ST0.
-             (inst fstd (make-ea :dword :base object
-                                 :disp (- (+ (* vector-data-offset
-                                                n-word-bytes)
-                                             (* 16 index))
-                                          other-pointer-lowtag)))
+             (inst fstd (make-ea-for-float-ref object index offset 16
+                                               :scale 4))
              (unless (zerop (tn-offset result-real))
                ;; Value is in ST0 but not result.
                (inst fstd result-real)))
             (t
              ;; Value is not in ST0.
              (inst fxch value-real)
-             (inst fstd (make-ea :dword :base object
-                                 :disp (- (+ (* vector-data-offset
-                                                n-word-bytes)
-                                             (* 16 index))
-                                          other-pointer-lowtag)))
+             (inst fstd (make-ea-for-float-ref object index offset 16
+                                               :scale 4))
              (cond ((zerop (tn-offset result-real))
                     ;; The result is in ST0.
                     (inst fstd value-real))
     (let ((value-imag (complex-double-reg-imag-tn value))
           (result-imag (complex-double-reg-imag-tn result)))
       (inst fxch value-imag)
-      (inst fstd (make-ea :dword :base object
-                          :disp (- (+ (* vector-data-offset
-                                         n-word-bytes)
-                                      (* 16 index) 8)
-                                   other-pointer-lowtag)))
+      (inst fstd (make-ea-for-float-ref object index offset 16
+                                        :scale 4 :complex-offset 8))
       (unless (location= value-imag result-imag)
         (inst fstd result-imag))
       (inst fxch value-imag))))
 
-
-
 \f
-;;; unsigned-byte-8
-(macrolet ((define-data-vector-frobs (ptype)
+;;; {un,}signed-byte-8, simple-base-string
+
+(macrolet ((define-data-vector-frobs (ptype element-type ref-inst
+                                            8-bit-tns-p &rest scs)
   `(progn
-    (define-vop (,(symbolicate "DATA-VECTOR-REF/" ptype))
-      (:translate data-vector-ref)
+    (define-vop (,(symbolicate "DATA-VECTOR-REF-WITH-OFFSET/" ptype))
+      (:translate data-vector-ref-with-offset)
       (:policy :fast-safe)
       (:args (object :scs (descriptor-reg))
-             (index :scs (unsigned-reg)))
-      (:arg-types ,ptype positive-fixnum)
-      (:results (value :scs (unsigned-reg signed-reg)))
-      (:result-types positive-fixnum)
+             (index :scs (unsigned-reg immediate)))
+      (:info offset)
+      (:arg-types ,ptype positive-fixnum
+                  (:constant (constant-displacement other-pointer-lowtag
+                                                    1 vector-data-offset)))
+      (:results (value :scs ,scs))
+      (:result-types ,element-type)
       (:generator 5
-        (inst movzx value
-              (make-ea :byte :base object :index index :scale 1
-                       :disp (- (* vector-data-offset n-word-bytes)
-                                other-pointer-lowtag)))))
-    (define-vop (,(symbolicate "DATA-VECTOR-REF-C/" ptype))
-      (:translate data-vector-ref)
-      (:policy :fast-safe)
-      (:args (object :scs (descriptor-reg)))
-      (:info index)
-      (:arg-types ,ptype (:constant (signed-byte 30)))
-      (:results (value :scs (unsigned-reg signed-reg)))
-      (:result-types positive-fixnum)
-      (:generator 4
-        (inst movzx value
-              (make-ea :byte :base object
-                       :disp (- (+ (* vector-data-offset n-word-bytes) index)
-                                other-pointer-lowtag)))))
-    (define-vop (,(symbolicate "DATA-VECTOR-SET/" ptype))
-      (:translate data-vector-set)
+        (sc-case index
+          (immediate
+           (inst ,ref-inst value (make-ea-for-vector-data
+                                  object :size :byte
+                                  :offset (+ (tn-value index) offset))))
+          (t
+           (inst ,ref-inst value
+                 (make-ea-for-vector-data object :size :byte
+                                          :index index :offset offset))))))
+    (define-vop (,(symbolicate "DATA-VECTOR-SET-WITH-OFFSET/" ptype))
+      (:translate data-vector-set-with-offset)
       (:policy :fast-safe)
       (:args (object :scs (descriptor-reg) :to (:eval 0))
-             (index :scs (unsigned-reg) :to (:eval 0))
-             (value :scs (unsigned-reg signed-reg) :target eax))
-      (:arg-types ,ptype positive-fixnum positive-fixnum)
-      (:temporary (:sc unsigned-reg :offset eax-offset :target result
-                       :from (:argument 2) :to (:result 0))
-                  eax)
-      (:results (result :scs (unsigned-reg signed-reg)))
-      (:result-types positive-fixnum)
+             (index :scs (unsigned-reg immediate) :to (:eval 0))
+             (value :scs ,scs ,@(unless 8-bit-tns-p
+                                  '(:target eax))))
+      (:info offset)
+      (:arg-types ,ptype positive-fixnum
+                  (:constant (constant-displacement other-pointer-lowtag
+                                                    1 vector-data-offset))
+                  ,element-type)
+      ,@(unless 8-bit-tns-p
+         '((:temporary (:sc unsigned-reg :offset eax-offset :target result
+                        :from (:argument 2) :to (:result 0))
+            eax)))
+      (:results (result :scs ,scs))
+      (:result-types ,element-type)
       (:generator 5
-        (move eax value)
-        (inst mov (make-ea :byte :base object :index index :scale 1
-                           :disp (- (* vector-data-offset n-word-bytes)
-                                    other-pointer-lowtag))
-              al-tn)
-        (move result eax)))
-    (define-vop (,(symbolicate "DATA-VECTOR-SET-C/" ptype))
-      (:translate data-vector-set)
-      (:policy :fast-safe)
-      (:args (object :scs (descriptor-reg) :to (:eval 0))
-             (value :scs (unsigned-reg signed-reg) :target eax))
-      (:info index)
-      (:arg-types ,ptype (:constant (signed-byte 30))
-                  positive-fixnum)
-      (:temporary (:sc unsigned-reg :offset eax-offset :target result
-                       :from (:argument 1) :to (:result 0))
-                  eax)
-      (:results (result :scs (unsigned-reg signed-reg)))
-      (:result-types positive-fixnum)
-      (:generator 4
-        (move eax value)
-        (inst mov (make-ea :byte :base object
-                           :disp (- (+ (* vector-data-offset n-word-bytes) index)
-                                    other-pointer-lowtag))
-              al-tn)
-        (move result eax))))))
-  (define-data-vector-frobs simple-array-unsigned-byte-7)
-  (define-data-vector-frobs simple-array-unsigned-byte-8))
-
-;;; unsigned-byte-16
-(macrolet ((define-data-vector-frobs (ptype)
+        ,@(unless 8-bit-tns-p
+           '((move eax value)))
+        (sc-case index
+          (immediate
+           (inst mov (make-ea-for-vector-data
+                      object :size :byte :offset (+ (tn-value index) offset))
+                 ,(if 8-bit-tns-p
+                      'value
+                      'al-tn)))
+          (t
+           (inst mov (make-ea-for-vector-data object :size :byte
+                                              :index index :offset offset)
+                 ,(if 8-bit-tns-p
+                      'value
+                      'al-tn))))
+        (move result ,(if 8-bit-tns-p
+                          'value
+                          'eax)))))))
+  (define-data-vector-frobs simple-array-unsigned-byte-7 positive-fixnum
+    movzx nil unsigned-reg signed-reg)
+  (define-data-vector-frobs simple-array-unsigned-byte-8 positive-fixnum
+    movzx nil unsigned-reg signed-reg)
+  (define-data-vector-frobs simple-array-signed-byte-8 tagged-num
+    movsx nil signed-reg)
+  (define-data-vector-frobs simple-base-string character
+                            #!+sb-unicode movzx #!-sb-unicode mov
+                            #!+sb-unicode nil #!-sb-unicode t character-reg))
+
+;;; {un,}signed-byte-16
+(macrolet ((define-data-vector-frobs (ptype element-type ref-inst &rest scs)
     `(progn
-      (define-vop (,(symbolicate "DATA-VECTOR-REF/" ptype))
-        (:translate data-vector-ref)
+      (define-vop (,(symbolicate "DATA-VECTOR-REF-WITH-OFFSET/" ptype))
+        (:translate data-vector-ref-with-offset)
         (:policy :fast-safe)
         (:args (object :scs (descriptor-reg))
-               (index :scs (unsigned-reg)))
-        (:arg-types ,ptype positive-fixnum)
-        (:results (value :scs (unsigned-reg signed-reg)))
-        (:result-types positive-fixnum)
+               (index :scs (unsigned-reg immediate)))
+        (:info offset)
+        (:arg-types ,ptype positive-fixnum
+                    (:constant (constant-displacement other-pointer-lowtag
+                                                      2 vector-data-offset)))
+        (:results (value :scs ,scs))
+        (:result-types ,element-type)
         (:generator 5
-          (inst movzx value
-                (make-ea :word :base object :index index :scale 2
-                         :disp (- (* vector-data-offset n-word-bytes)
-                                  other-pointer-lowtag)))))
-      (define-vop (,(symbolicate "DATA-VECTOR-REF-C/" ptype))
-        (:translate data-vector-ref)
-        (:policy :fast-safe)
-        (:args (object :scs (descriptor-reg)))
-        (:info index)
-        (:arg-types ,ptype (:constant (signed-byte 30)))
-        (:results (value :scs (unsigned-reg signed-reg)))
-        (:result-types positive-fixnum)
-        (:generator 4
-          (inst movzx value
-                (make-ea :word :base object
-                         :disp (- (+ (* vector-data-offset n-word-bytes) (* 2 index))
-                                  other-pointer-lowtag)))))
-      (define-vop (,(symbolicate "DATA-VECTOR-SET/" ptype))
-        (:translate data-vector-set)
+          (sc-case index
+            (immediate
+             (inst ,ref-inst value
+                   (make-ea-for-vector-data object :size :word
+                                            :offset (+ (tn-value index) offset))))
+            (t
+             (inst ,ref-inst value
+                   (make-ea-for-vector-data object :size :word
+                                            :index index :offset offset))))))
+      (define-vop (,(symbolicate "DATA-VECTOR-SET-WITH-OFFSET/" ptype))
+        (:translate data-vector-set-with-offset)
         (:policy :fast-safe)
         (:args (object :scs (descriptor-reg) :to (:eval 0))
-               (index :scs (unsigned-reg) :to (:eval 0))
-               (value :scs (unsigned-reg signed-reg) :target eax))
-        (:arg-types ,ptype positive-fixnum positive-fixnum)
+               (index :scs (unsigned-reg immediate) :to (:eval 0))
+               (value :scs ,scs :target eax))
+        (:info offset)
+        (:arg-types ,ptype positive-fixnum
+                    (:constant (constant-displacement other-pointer-lowtag
+                                                      2 vector-data-offset))
+                    ,element-type)
         (:temporary (:sc unsigned-reg :offset eax-offset :target result
                          :from (:argument 2) :to (:result 0))
                     eax)
-        (:results (result :scs (unsigned-reg signed-reg)))
-        (:result-types positive-fixnum)
+        (:results (result :scs ,scs))
+        (:result-types ,element-type)
         (:generator 5
           (move eax value)
-          (inst mov (make-ea :word :base object :index index :scale 2
-                             :disp (- (* vector-data-offset n-word-bytes)
-                                      other-pointer-lowtag))
-                ax-tn)
-          (move result eax)))
-
-      (define-vop (,(symbolicate "DATA-VECTOR-SET-C/" ptype))
-        (:translate data-vector-set)
-        (:policy :fast-safe)
-        (:args (object :scs (descriptor-reg) :to (:eval 0))
-               (value :scs (unsigned-reg signed-reg) :target eax))
-        (:info index)
-        (:arg-types ,ptype (:constant (signed-byte 30))
-                    positive-fixnum)
-        (:temporary (:sc unsigned-reg :offset eax-offset :target result
-                         :from (:argument 1) :to (:result 0))
-                    eax)
-        (:results (result :scs (unsigned-reg signed-reg)))
-        (:result-types positive-fixnum)
-        (:generator 4
-          (move eax value)
-          (inst mov (make-ea :word :base object
-                             :disp (- (+ (* vector-data-offset n-word-bytes)
-                                         (* 2 index))
-                                      other-pointer-lowtag))
-                ax-tn)
+          (sc-case index
+            (immediate
+             (inst mov (make-ea-for-vector-data
+                        object :size :word :offset (+ (tn-value index) offset))
+                   ax-tn))
+            (t
+             (inst mov (make-ea-for-vector-data object :size :word
+                                                :index index :offset offset)
+                   ax-tn)))
           (move result eax))))))
-  (define-data-vector-frobs simple-array-unsigned-byte-15)
-  (define-data-vector-frobs simple-array-unsigned-byte-16))
-
-;;; simple-string
-
-#!+sb-unicode
-(progn
-(define-vop (data-vector-ref/simple-base-string)
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg))
-         (index :scs (unsigned-reg)))
-  (:arg-types simple-base-string positive-fixnum)
-  (:results (value :scs (character-reg)))
-  (:result-types character)
-  (:generator 5
-    (inst movzx value
-          (make-ea :byte :base object :index index :scale 1
-                   :disp (- (* vector-data-offset n-word-bytes)
-                            other-pointer-lowtag)))))
-
-(define-vop (data-vector-ref-c/simple-base-string)
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg)))
-  (:info index)
-  (:arg-types simple-base-string (:constant (signed-byte 30)))
-  (:results (value :scs (character-reg)))
-  (:result-types character)
-  (:generator 4
-    (inst movzx value
-          (make-ea :byte :base object
-                   :disp (- (+ (* vector-data-offset n-word-bytes) index)
-                            other-pointer-lowtag)))))
-
-(define-vop (data-vector-set/simple-base-string)
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg) :to (:eval 0))
-         (index :scs (unsigned-reg) :to (:eval 0))
-         (value :scs (character-reg) :target eax))
-  (:arg-types simple-base-string positive-fixnum character)
-  (:temporary (:sc character-reg :offset eax-offset :target result
-                   :from (:argument 2) :to (:result 0))
-              eax)
-  (:results (result :scs (character-reg)))
-  (:result-types character)
-  (:generator 5
-    (move eax value)
-    (inst mov (make-ea :byte :base object :index index :scale 1
-                       :disp (- (* vector-data-offset n-word-bytes)
-                                other-pointer-lowtag))
-          al-tn)
-    (move result eax)))
-
-(define-vop (data-vector-set-c/simple-base-string)
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg) :to (:eval 0))
-         (value :scs (character-reg)))
-  (:info index)
-  (:arg-types simple-base-string (:constant (signed-byte 30)) character)
-  (:temporary (:sc unsigned-reg :offset eax-offset :target result
-                   :from (:argument 1) :to (:result 0))
-              eax)
-  (:results (result :scs (character-reg)))
-  (:result-types character)
-  (:generator 4
-    (move eax value)
-    (inst mov (make-ea :byte :base object
-                       :disp (- (+ (* vector-data-offset n-word-bytes) index)
-                                other-pointer-lowtag))
-          al-tn)
-    (move result eax)))
-) ; PROGN
+  (define-data-vector-frobs simple-array-unsigned-byte-15 positive-fixnum
+    movzx unsigned-reg signed-reg)
+  (define-data-vector-frobs simple-array-unsigned-byte-16 positive-fixnum
+    movzx unsigned-reg signed-reg)
+  (define-data-vector-frobs simple-array-signed-byte-16 tagged-num
+    movsx signed-reg))
 
-#!-sb-unicode
-(progn
-(define-vop (data-vector-ref/simple-base-string)
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg))
-         (index :scs (unsigned-reg)))
-  (:arg-types simple-base-string positive-fixnum)
-  (:results (value :scs (character-reg)))
-  (:result-types character)
-  (:generator 5
-    (inst mov value
-          (make-ea :byte :base object :index index :scale 1
-                   :disp (- (* vector-data-offset n-word-bytes)
-                            other-pointer-lowtag)))))
-
-(define-vop (data-vector-ref-c/simple-base-string)
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg)))
-  (:info index)
-  (:arg-types simple-base-string (:constant (signed-byte 30)))
-  (:results (value :scs (character-reg)))
-  (:result-types character)
-  (:generator 4
-    (inst mov value
-          (make-ea :byte :base object
-                   :disp (- (+ (* vector-data-offset n-word-bytes) index)
-                            other-pointer-lowtag)))))
-
-(define-vop (data-vector-set/simple-base-string)
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg) :to (:eval 0))
-         (index :scs (unsigned-reg) :to (:eval 0))
-         (value :scs (character-reg) :target result))
-  (:arg-types simple-base-string positive-fixnum character)
-  (:results (result :scs (character-reg)))
-  (:result-types character)
-  (:generator 5
-    (inst mov (make-ea :byte :base object :index index :scale 1
-                       :disp (- (* vector-data-offset n-word-bytes)
-                                other-pointer-lowtag))
-          value)
-    (move result value)))
-
-(define-vop (data-vector-set-c/simple-base-string)
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg) :to (:eval 0))
-         (value :scs (character-reg)))
-  (:info index)
-  (:arg-types simple-base-string (:constant (signed-byte 30)) character)
-  (:results (result :scs (character-reg)))
-  (:result-types character)
-  (:generator 4
-   (inst mov (make-ea :byte :base object
-                      :disp (- (+ (* vector-data-offset n-word-bytes) index)
-                               other-pointer-lowtag))
-         value)
-   (move result value)))
-) ; PROGN
-
-#!+sb-unicode
-(define-full-reffer data-vector-ref/simple-character-string
-    simple-character-string vector-data-offset other-pointer-lowtag
-    (character-reg) character data-vector-ref)
-#!+sb-unicode
-(define-full-setter data-vector-set/simple-character-string
-    simple-character-string vector-data-offset other-pointer-lowtag
-    (character-reg) character data-vector-set)
-
-;;; signed-byte-8
-
-(define-vop (data-vector-ref/simple-array-signed-byte-8)
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg))
-         (index :scs (unsigned-reg)))
-  (:arg-types simple-array-signed-byte-8 positive-fixnum)
-  (:results (value :scs (signed-reg)))
-  (:result-types tagged-num)
-  (:generator 5
-    (inst movsx value
-          (make-ea :byte :base object :index index :scale 1
-                   :disp (- (* vector-data-offset n-word-bytes)
-                            other-pointer-lowtag)))))
-
-(define-vop (data-vector-ref-c/simple-array-signed-byte-8)
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg)))
-  (:info index)
-  (:arg-types simple-array-signed-byte-8 (:constant (signed-byte 30)))
-  (:results (value :scs (signed-reg)))
-  (:result-types tagged-num)
-  (:generator 4
-    (inst movsx value
-          (make-ea :byte :base object
-                   :disp (- (+ (* vector-data-offset n-word-bytes) index)
-                            other-pointer-lowtag)))))
-
-(define-vop (data-vector-set/simple-array-signed-byte-8)
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg) :to (:eval 0))
-         (index :scs (unsigned-reg) :to (:eval 0))
-         (value :scs (signed-reg) :target eax))
-  (:arg-types simple-array-signed-byte-8 positive-fixnum tagged-num)
-  (:temporary (:sc unsigned-reg :offset eax-offset :target result
-                   :from (:argument 2) :to (:result 0))
-              eax)
-  (:results (result :scs (signed-reg)))
-  (:result-types tagged-num)
-  (:generator 5
-    (move eax value)
-    (inst mov (make-ea :byte :base object :index index :scale 1
-                       :disp (- (* vector-data-offset n-word-bytes)
-                                other-pointer-lowtag))
-          al-tn)
-    (move result eax)))
-
-(define-vop (data-vector-set-c/simple-array-signed-byte-8)
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg) :to (:eval 0))
-         (value :scs (signed-reg) :target eax))
-  (:info index)
-  (:arg-types simple-array-signed-byte-8 (:constant (signed-byte 30))
-              tagged-num)
-  (:temporary (:sc unsigned-reg :offset eax-offset :target result
-                   :from (:argument 1) :to (:result 0))
-              eax)
-  (:results (result :scs (signed-reg)))
-  (:result-types tagged-num)
-  (:generator 4
-    (move eax value)
-    (inst mov (make-ea :byte :base object
-                       :disp (- (+ (* vector-data-offset n-word-bytes) index)
-                                other-pointer-lowtag))
-          al-tn)
-    (move result eax)))
-
-;;; signed-byte-16
-
-(define-vop (data-vector-ref/simple-array-signed-byte-16)
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg))
-         (index :scs (unsigned-reg)))
-  (:arg-types simple-array-signed-byte-16 positive-fixnum)
-  (:results (value :scs (signed-reg)))
-  (:result-types tagged-num)
-  (:generator 5
-    (inst movsx value
-          (make-ea :word :base object :index index :scale 2
-                   :disp (- (* vector-data-offset n-word-bytes)
-                            other-pointer-lowtag)))))
-
-(define-vop (data-vector-ref-c/simple-array-signed-byte-16)
-  (:translate data-vector-ref)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg)))
-  (:info index)
-  (:arg-types simple-array-signed-byte-16 (:constant (signed-byte 30)))
-  (:results (value :scs (signed-reg)))
-  (:result-types tagged-num)
-  (:generator 4
-    (inst movsx value
-          (make-ea :word :base object
-                   :disp (- (+ (* vector-data-offset n-word-bytes)
-                               (* 2 index))
-                            other-pointer-lowtag)))))
-
-(define-vop (data-vector-set/simple-array-signed-byte-16)
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg) :to (:eval 0))
-         (index :scs (unsigned-reg) :to (:eval 0))
-         (value :scs (signed-reg) :target eax))
-  (:arg-types simple-array-signed-byte-16 positive-fixnum tagged-num)
-  (:temporary (:sc signed-reg :offset eax-offset :target result
-                   :from (:argument 2) :to (:result 0))
-              eax)
-  (:results (result :scs (signed-reg)))
-  (:result-types tagged-num)
-  (:generator 5
-    (move eax value)
-    (inst mov (make-ea :word :base object :index index :scale 2
-                       :disp (- (* vector-data-offset n-word-bytes)
-                                other-pointer-lowtag))
-          ax-tn)
-    (move result eax)))
-
-(define-vop (data-vector-set-c/simple-array-signed-byte-16)
-  (:translate data-vector-set)
-  (:policy :fast-safe)
-  (:args (object :scs (descriptor-reg) :to (:eval 0))
-         (value :scs (signed-reg) :target eax))
-  (:info index)
-  (:arg-types simple-array-signed-byte-16 (:constant (signed-byte 30)) tagged-num)
-  (:temporary (:sc signed-reg :offset eax-offset :target result
-                   :from (:argument 1) :to (:result 0))
-              eax)
-  (:results (result :scs (signed-reg)))
-  (:result-types tagged-num)
-  (:generator 4
-    (move eax value)
-    (inst mov
-          (make-ea :word :base object
-                   :disp (- (+ (* vector-data-offset n-word-bytes)
-                               (* 2 index))
-                            other-pointer-lowtag))
-          ax-tn)
-    (move result eax)))
 \f
-;;; These VOPs are used for implementing float slots in structures (whose raw
-;;; data is an unsigned-32 vector).
-(define-vop (raw-ref-single data-vector-ref/simple-array-single-float)
-  (:translate %raw-ref-single)
-  (:arg-types sb!c::raw-vector positive-fixnum))
-(define-vop (raw-ref-single-c data-vector-ref-c/simple-array-single-float)
-  (:translate %raw-ref-single)
-  (:arg-types sb!c::raw-vector (:constant (signed-byte 30))))
-(define-vop (raw-set-single data-vector-set/simple-array-single-float)
-  (:translate %raw-set-single)
-  (:arg-types sb!c::raw-vector positive-fixnum single-float))
-(define-vop (raw-set-single-c data-vector-set-c/simple-array-single-float)
-  (:translate %raw-set-single)
-  (:arg-types sb!c::raw-vector (:constant (signed-byte 30)) single-float))
-(define-vop (raw-ref-double data-vector-ref/simple-array-double-float)
-  (:translate %raw-ref-double)
-  (:arg-types sb!c::raw-vector positive-fixnum))
-(define-vop (raw-ref-double-c data-vector-ref-c/simple-array-double-float)
-  (:translate %raw-ref-double)
-  (:arg-types sb!c::raw-vector (:constant (signed-byte 30))))
-(define-vop (raw-set-double data-vector-set/simple-array-double-float)
-  (:translate %raw-set-double)
-  (:arg-types sb!c::raw-vector positive-fixnum double-float))
-(define-vop (raw-set-double-c data-vector-set-c/simple-array-double-float)
-  (:translate %raw-set-double)
-  (:arg-types sb!c::raw-vector (:constant (signed-byte 30)) double-float))
-
-
-;;;; complex-float raw structure slot accessors
-
-(define-vop (raw-ref-complex-single
-             data-vector-ref/simple-array-complex-single-float)
-  (:translate %raw-ref-complex-single)
-  (:arg-types sb!c::raw-vector positive-fixnum))
-(define-vop (raw-ref-complex-single-c
-             data-vector-ref-c/simple-array-complex-single-float)
-  (:translate %raw-ref-complex-single)
-  (:arg-types sb!c::raw-vector (:constant (signed-byte 30))))
-(define-vop (raw-set-complex-single
-             data-vector-set/simple-array-complex-single-float)
-  (:translate %raw-set-complex-single)
-  (:arg-types sb!c::raw-vector positive-fixnum complex-single-float))
-(define-vop (raw-set-complex-single-c
-             data-vector-set-c/simple-array-complex-single-float)
-  (:translate %raw-set-complex-single)
-  (:arg-types sb!c::raw-vector (:constant (signed-byte 30))
-              complex-single-float))
-(define-vop (raw-ref-complex-double
-             data-vector-ref/simple-array-complex-double-float)
-  (:translate %raw-ref-complex-double)
-  (:arg-types sb!c::raw-vector positive-fixnum))
-(define-vop (raw-ref-complex-double-c
-             data-vector-ref-c/simple-array-complex-double-float)
-  (:translate %raw-ref-complex-double)
-  (:arg-types sb!c::raw-vector (:constant (signed-byte 30))))
-(define-vop (raw-set-complex-double
-             data-vector-set/simple-array-complex-double-float)
-  (:translate %raw-set-complex-double)
-  (:arg-types sb!c::raw-vector positive-fixnum complex-double-float))
-(define-vop (raw-set-complex-double-c
-             data-vector-set-c/simple-array-complex-double-float)
-  (:translate %raw-set-complex-double)
-  (:arg-types sb!c::raw-vector (:constant (signed-byte 30))
-              complex-double-float))
-
-
 ;;; These vops are useful for accessing the bits of a vector
 ;;; irrespective of what type of vector it is.
-(define-full-reffer raw-bits * 0 other-pointer-lowtag (unsigned-reg)
-  unsigned-num %raw-bits)
-(define-full-setter set-raw-bits * 0 other-pointer-lowtag (unsigned-reg)
-  unsigned-num %set-raw-bits)
-(define-full-reffer vector-raw-bits * vector-data-offset other-pointer-lowtag
-  (unsigned-reg) unsigned-num %vector-raw-bits)
-(define-full-setter set-vector-raw-bits * vector-data-offset other-pointer-lowtag
-  (unsigned-reg) unsigned-num %set-vector-raw-bits)
+(define-full-reffer+offset raw-bits-with-offset * 0 other-pointer-lowtag (unsigned-reg)
+  unsigned-num %raw-bits-with-offset)
+(define-full-setter+offset set-raw-bits-with-offset * 0 other-pointer-lowtag (unsigned-reg)
+  unsigned-num %set-raw-bits-with-offset)
+
 \f
 ;;;; miscellaneous array VOPs