1 ;;;; array operations for the x86 VM
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
14 ;;;; allocator for the array header
16 (define-vop (make-array-header)
17 (:translate make-array-header
)
19 (:args
(type :scs
(any-reg))
20 (rank :scs
(any-reg)))
21 (:arg-types positive-fixnum positive-fixnum
)
22 (:temporary
(:sc any-reg
:to
:eval
) bytes
)
23 (:temporary
(:sc any-reg
:to
:result
) header
)
24 (:results
(result :scs
(descriptor-reg) :from
:eval
))
28 (make-ea :dword
:base rank
29 :disp
(+ (* (1+ array-dimensions-offset
) n-word-bytes
)
31 (inst and bytes
(lognot lowtag-mask
))
32 (inst lea header
(make-ea :dword
:base rank
33 :disp
(fixnumize (1- array-dimensions-offset
))))
34 (inst shl header n-widetag-bits
)
38 (allocation result bytes node
)
39 (inst lea result
(make-ea :dword
:base result
:disp other-pointer-lowtag
))
40 (storew header result
0 other-pointer-lowtag
))))
42 ;;;; additional accessors and setters for the array header
43 (define-full-reffer %array-dimension
*
44 array-dimensions-offset other-pointer-lowtag
45 (any-reg) positive-fixnum sb
!kernel
:%array-dimension
)
47 (define-full-setter %set-array-dimension
*
48 array-dimensions-offset other-pointer-lowtag
49 (any-reg) positive-fixnum sb
!kernel
:%set-array-dimension
)
51 (define-vop (array-rank-vop)
52 (:translate sb
!kernel
:%array-rank
)
54 (:args
(x :scs
(descriptor-reg)))
55 (:results
(res :scs
(unsigned-reg)))
56 (:result-types positive-fixnum
)
58 (loadw res x
0 other-pointer-lowtag
)
59 (inst shr res n-widetag-bits
)
60 (inst sub res
(1- array-dimensions-offset
))))
62 ;;;; bounds checking routine
64 ;;; Note that the immediate SC for the index argument is disabled
65 ;;; because it is not possible to generate a valid error code SC for
66 ;;; an immediate value.
68 ;;; FIXME: As per the KLUDGE note explaining the :IGNORE-FAILURE-P
69 ;;; flag in build-order.lisp-expr, compiling this file causes warnings
70 ;;; Argument FOO to VOP CHECK-BOUND has SC restriction
71 ;;; DESCRIPTOR-REG which is not allowed by the operand type:
72 ;;; (:OR POSITIVE-FIXNUM)
73 ;;; CSR's message "format ~/ /" on sbcl-devel 2002-03-12 contained
74 ;;; a possible patch, described as
75 ;;; Another patch is included more for information than anything --
76 ;;; removing the descriptor-reg SCs from the CHECK-BOUND vop in
77 ;;; x86/array.lisp seems to allow that file to compile without error[*],
78 ;;; and build; I haven't tested rebuilding capability, but I'd be
79 ;;; surprised if there were a problem. I'm not certain that this is the
80 ;;; correct fix, though, as the restrictions on the arguments to the VOP
81 ;;; aren't the same as in the sparc and alpha ports, where, incidentally,
82 ;;; the corresponding file builds without error currently.
83 ;;; Since neither of us (CSR or WHN) was quite sure that this is the
84 ;;; right thing, I've just recorded the patch here in hopes it might
85 ;;; help when someone attacks this problem again:
86 ;;; diff -u -r1.7 array.lisp
87 ;;; --- src/compiler/x86/array.lisp 11 Oct 2001 14:05:26 -0000 1.7
88 ;;; +++ src/compiler/x86/array.lisp 12 Mar 2002 12:23:37 -0000
89 ;;; @@ -76,10 +76,10 @@
90 ;;; (:translate %check-bound)
91 ;;; (:policy :fast-safe)
92 ;;; (:args (array :scs (descriptor-reg))
93 ;;; - (bound :scs (any-reg descriptor-reg))
94 ;;; - (index :scs (any-reg descriptor-reg #+nil immediate) :target result))
95 ;;; + (bound :scs (any-reg))
96 ;;; + (index :scs (any-reg #+nil immediate) :target result))
97 ;;; (:arg-types * positive-fixnum tagged-num)
98 ;;; - (:results (result :scs (any-reg descriptor-reg)))
99 ;;; + (:results (result :scs (any-reg)))
100 ;;; (:result-types positive-fixnum)
102 ;;; (:save-p :compute-only)
103 (define-vop (check-bound)
104 (:translate %check-bound
)
106 (:args
(array :scs
(descriptor-reg))
107 (bound :scs
(any-reg))
108 (index :scs
(any-reg #+nil immediate
) :target result
))
109 (:arg-types
* positive-fixnum tagged-num
)
110 (:results
(result :scs
(any-reg)))
111 (:result-types positive-fixnum
)
113 (:save-p
:compute-only
)
115 (let ((error (generate-error-code vop invalid-array-index-error
117 (index (if (sc-is index immediate
)
118 (fixnumize (tn-value index
))
120 (inst cmp bound index
)
121 ;; We use below-or-equal even though it's an unsigned test,
122 ;; because negative indexes appear as large unsigned numbers.
123 ;; Therefore, we get the <0 and >=bound test all rolled into one.
125 (unless (and (tn-p index
) (location= result index
))
126 (inst mov result index
)))))
128 ;;;; accessors/setters
130 ;;; variants built on top of WORD-INDEX-REF, etc. I.e., those vectors
131 ;;; whose elements are represented in integer registers and are built
132 ;;; out of 8, 16, or 32 bit elements.
133 (macrolet ((def-full-data-vector-frobs (type element-type
&rest scs
)
135 (define-full-reffer ,(symbolicate "DATA-VECTOR-REF/" type
)
136 ,type vector-data-offset other-pointer-lowtag
,scs
137 ,element-type data-vector-ref
)
138 (define-full-setter ,(symbolicate "DATA-VECTOR-SET/" type
)
139 ,type vector-data-offset other-pointer-lowtag
,scs
140 ,element-type data-vector-set
))))
141 (def-full-data-vector-frobs simple-vector
* descriptor-reg any-reg
)
142 (def-full-data-vector-frobs simple-array-unsigned-byte-32 unsigned-num
144 (def-full-data-vector-frobs simple-array-signed-byte-30 tagged-num any-reg
)
145 (def-full-data-vector-frobs simple-array-unsigned-byte-29 positive-fixnum any-reg
)
146 (def-full-data-vector-frobs simple-array-signed-byte-32 signed-num
148 (def-full-data-vector-frobs simple-array-unsigned-byte-31 unsigned-num
151 ;;;; integer vectors whose elements are smaller than a byte, i.e.,
152 ;;;; bit, 2-bit, and 4-bit vectors
154 (macrolet ((def-small-data-vector-frobs (type bits
)
155 (let* ((elements-per-word (floor n-word-bits bits
))
156 (bit-shift (1- (integer-length elements-per-word
))))
158 (define-vop (,(symbolicate 'data-vector-ref
/ type
))
159 (:note
"inline array access")
160 (:translate data-vector-ref
)
162 (:args
(object :scs
(descriptor-reg))
163 (index :scs
(unsigned-reg)))
164 (:arg-types
,type positive-fixnum
)
165 (:results
(result :scs
(unsigned-reg) :from
(:argument
0)))
166 (:result-types positive-fixnum
)
167 (:temporary
(:sc unsigned-reg
:offset ecx-offset
) ecx
)
170 (inst shr ecx
,bit-shift
)
172 (make-ea :dword
:base object
:index ecx
:scale
4
173 :disp
(- (* vector-data-offset n-word-bytes
)
174 other-pointer-lowtag
)))
176 (inst and ecx
,(1- elements-per-word
))
178 `((inst shl ecx
,(1- (integer-length bits
)))))
179 (inst shr result
:cl
)
180 (inst and result
,(1- (ash 1 bits
)))))
181 (define-vop (,(symbolicate 'data-vector-ref-c
/ type
))
182 (:translate data-vector-ref
)
184 (:args
(object :scs
(descriptor-reg)))
185 (:arg-types
,type
(:constant index
))
187 (:results
(result :scs
(unsigned-reg)))
188 (:result-types positive-fixnum
)
190 (multiple-value-bind (word extra
) (floor index
,elements-per-word
)
191 (loadw result object
(+ word vector-data-offset
)
192 other-pointer-lowtag
)
193 (unless (zerop extra
)
194 (inst shr result
(* extra
,bits
)))
195 (unless (= extra
,(1- elements-per-word
))
196 (inst and result
,(1- (ash 1 bits
)))))))
197 (define-vop (,(symbolicate 'data-vector-set
/ type
))
198 (:note
"inline array store")
199 (:translate data-vector-set
)
201 (:args
(object :scs
(descriptor-reg) :target ptr
)
202 (index :scs
(unsigned-reg) :target ecx
)
203 (value :scs
(unsigned-reg immediate
) :target result
))
204 (:arg-types
,type positive-fixnum positive-fixnum
)
205 (:results
(result :scs
(unsigned-reg)))
206 (:result-types positive-fixnum
)
207 (:temporary
(:sc unsigned-reg
) word-index
)
208 (:temporary
(:sc unsigned-reg
:from
(:argument
0)) ptr old
)
209 (:temporary
(:sc unsigned-reg
:offset ecx-offset
:from
(:argument
1))
212 (move word-index index
)
213 (inst shr word-index
,bit-shift
)
215 (make-ea :dword
:base object
:index word-index
:scale
4
216 :disp
(- (* vector-data-offset n-word-bytes
)
217 other-pointer-lowtag
)))
220 (inst and ecx
,(1- elements-per-word
))
222 `((inst shl ecx
,(1- (integer-length bits
)))))
224 (unless (and (sc-is value immediate
)
225 (= (tn-value value
) ,(1- (ash 1 bits
))))
226 (inst and old
,(lognot (1- (ash 1 bits
)))))
229 (unless (zerop (tn-value value
))
230 (inst or old
(logand (tn-value value
) ,(1- (ash 1 bits
))))))
232 (inst or old value
)))
237 (inst mov result
(tn-value value
)))
239 (move result value
)))))
240 (define-vop (,(symbolicate 'data-vector-set-c
/ type
))
241 (:translate data-vector-set
)
243 (:args
(object :scs
(descriptor-reg))
244 (value :scs
(unsigned-reg immediate
) :target result
))
245 (:arg-types
,type
(:constant index
) positive-fixnum
)
247 (:results
(result :scs
(unsigned-reg)))
248 (:result-types positive-fixnum
)
249 (:temporary
(:sc unsigned-reg
:to
(:result
0)) old
)
251 (multiple-value-bind (word extra
) (floor index
,elements-per-word
)
253 (make-ea :dword
:base object
254 :disp
(- (* (+ word vector-data-offset
)
256 other-pointer-lowtag
)))
259 (let* ((value (tn-value value
))
260 (mask ,(1- (ash 1 bits
)))
261 (shift (* extra
,bits
)))
262 (unless (= value mask
)
263 (inst and old
(lognot (ash mask shift
))))
264 (unless (zerop value
)
265 (inst or old
(ash value shift
)))))
267 (let ((shift (* extra
,bits
)))
268 (unless (zerop shift
)
269 (inst ror old shift
))
270 (inst and old
(lognot ,(1- (ash 1 bits
))))
272 (unless (zerop shift
)
273 (inst rol old shift
)))))
274 (inst mov
(make-ea :dword
:base object
275 :disp
(- (* (+ word vector-data-offset
)
277 other-pointer-lowtag
))
281 (inst mov result
(tn-value value
)))
283 (move result value
))))))))))
284 (def-small-data-vector-frobs simple-bit-vector
1)
285 (def-small-data-vector-frobs simple-array-unsigned-byte-2
2)
286 (def-small-data-vector-frobs simple-array-unsigned-byte-4
4))
288 ;;; And the float variants.
290 (define-vop (data-vector-ref/simple-array-single-float
)
291 (:note
"inline array access")
292 (:translate data-vector-ref
)
294 (:args
(object :scs
(descriptor-reg))
295 (index :scs
(any-reg)))
296 (:arg-types simple-array-single-float positive-fixnum
)
297 (:results
(value :scs
(single-reg)))
298 (:result-types single-float
)
300 (with-empty-tn@fp-top
(value)
301 (inst fld
(make-ea :dword
:base object
:index index
:scale
1
302 :disp
(- (* vector-data-offset
304 other-pointer-lowtag
))))))
306 (define-vop (data-vector-ref-c/simple-array-single-float
)
307 (:note
"inline array access")
308 (:translate data-vector-ref
)
310 (:args
(object :scs
(descriptor-reg)))
312 (:arg-types simple-array-single-float
(:constant
(signed-byte 30)))
313 (:results
(value :scs
(single-reg)))
314 (:result-types single-float
)
316 (with-empty-tn@fp-top
(value)
317 (inst fld
(make-ea :dword
:base object
318 :disp
(- (+ (* vector-data-offset
321 other-pointer-lowtag
))))))
323 (define-vop (data-vector-set/simple-array-single-float
)
324 (:note
"inline array store")
325 (:translate data-vector-set
)
327 (:args
(object :scs
(descriptor-reg))
328 (index :scs
(any-reg))
329 (value :scs
(single-reg) :target result
))
330 (:arg-types simple-array-single-float positive-fixnum single-float
)
331 (:results
(result :scs
(single-reg)))
332 (:result-types single-float
)
334 (cond ((zerop (tn-offset value
))
336 (inst fst
(make-ea :dword
:base object
:index index
:scale
1
337 :disp
(- (* vector-data-offset
339 other-pointer-lowtag
)))
340 (unless (zerop (tn-offset result
))
341 ;; Value is in ST0 but not result.
344 ;; Value is not in ST0.
346 (inst fst
(make-ea :dword
:base object
:index index
:scale
1
347 :disp
(- (* vector-data-offset
349 other-pointer-lowtag
)))
350 (cond ((zerop (tn-offset result
))
351 ;; The result is in ST0.
354 ;; Neither value or result are in ST0
355 (unless (location= value result
)
357 (inst fxch value
)))))))
359 (define-vop (data-vector-set-c/simple-array-single-float
)
360 (:note
"inline array store")
361 (:translate data-vector-set
)
363 (:args
(object :scs
(descriptor-reg))
364 (value :scs
(single-reg) :target result
))
366 (:arg-types simple-array-single-float
(:constant
(signed-byte 30))
368 (:results
(result :scs
(single-reg)))
369 (:result-types single-float
)
371 (cond ((zerop (tn-offset value
))
373 (inst fst
(make-ea :dword
:base object
374 :disp
(- (+ (* vector-data-offset
377 other-pointer-lowtag
)))
378 (unless (zerop (tn-offset result
))
379 ;; Value is in ST0 but not result.
382 ;; Value is not in ST0.
384 (inst fst
(make-ea :dword
:base object
385 :disp
(- (+ (* vector-data-offset
388 other-pointer-lowtag
)))
389 (cond ((zerop (tn-offset result
))
390 ;; The result is in ST0.
393 ;; Neither value or result are in ST0
394 (unless (location= value result
)
396 (inst fxch value
)))))))
398 (define-vop (data-vector-ref/simple-array-double-float
)
399 (:note
"inline array access")
400 (:translate data-vector-ref
)
402 (:args
(object :scs
(descriptor-reg))
403 (index :scs
(any-reg)))
404 (:arg-types simple-array-double-float positive-fixnum
)
405 (:results
(value :scs
(double-reg)))
406 (:result-types double-float
)
408 (with-empty-tn@fp-top
(value)
409 (inst fldd
(make-ea :dword
:base object
:index index
:scale
2
410 :disp
(- (* vector-data-offset
412 other-pointer-lowtag
))))))
414 (define-vop (data-vector-ref-c/simple-array-double-float
)
415 (:note
"inline array access")
416 (:translate data-vector-ref
)
418 (:args
(object :scs
(descriptor-reg)))
420 (:arg-types simple-array-double-float
(:constant
(signed-byte 30)))
421 (:results
(value :scs
(double-reg)))
422 (:result-types double-float
)
424 (with-empty-tn@fp-top
(value)
425 (inst fldd
(make-ea :dword
:base object
426 :disp
(- (+ (* vector-data-offset
429 other-pointer-lowtag
))))))
431 (define-vop (data-vector-set/simple-array-double-float
)
432 (:note
"inline array store")
433 (:translate data-vector-set
)
435 (:args
(object :scs
(descriptor-reg))
436 (index :scs
(any-reg))
437 (value :scs
(double-reg) :target result
))
438 (:arg-types simple-array-double-float positive-fixnum double-float
)
439 (:results
(result :scs
(double-reg)))
440 (:result-types double-float
)
442 (cond ((zerop (tn-offset value
))
444 (inst fstd
(make-ea :dword
:base object
:index index
:scale
2
445 :disp
(- (* vector-data-offset
447 other-pointer-lowtag
)))
448 (unless (zerop (tn-offset result
))
449 ;; Value is in ST0 but not result.
452 ;; Value is not in ST0.
454 (inst fstd
(make-ea :dword
:base object
:index index
:scale
2
455 :disp
(- (* vector-data-offset
457 other-pointer-lowtag
)))
458 (cond ((zerop (tn-offset result
))
459 ;; The result is in ST0.
462 ;; Neither value or result are in ST0
463 (unless (location= value result
)
465 (inst fxch value
)))))))
467 (define-vop (data-vector-set-c/simple-array-double-float
)
468 (:note
"inline array store")
469 (:translate data-vector-set
)
471 (:args
(object :scs
(descriptor-reg))
472 (value :scs
(double-reg) :target result
))
474 (:arg-types simple-array-double-float
(:constant
(signed-byte 30))
476 (:results
(result :scs
(double-reg)))
477 (:result-types double-float
)
479 (cond ((zerop (tn-offset value
))
481 (inst fstd
(make-ea :dword
:base object
482 :disp
(- (+ (* vector-data-offset
485 other-pointer-lowtag
)))
486 (unless (zerop (tn-offset result
))
487 ;; Value is in ST0 but not result.
490 ;; Value is not in ST0.
492 (inst fstd
(make-ea :dword
:base object
493 :disp
(- (+ (* vector-data-offset
496 other-pointer-lowtag
)))
497 (cond ((zerop (tn-offset result
))
498 ;; The result is in ST0.
501 ;; Neither value or result are in ST0
502 (unless (location= value result
)
504 (inst fxch value
)))))))
507 (define-vop (data-vector-ref/simple-array-long-float
)
508 (:note
"inline array access")
509 (:translate data-vector-ref
)
511 (:args
(object :scs
(descriptor-reg) :to
:result
)
512 (index :scs
(any-reg)))
513 (:arg-types simple-array-long-float positive-fixnum
)
514 (:temporary
(:sc any-reg
:from
:eval
:to
:result
) temp
)
515 (:results
(value :scs
(long-reg)))
516 (:result-types long-float
)
519 (inst lea temp
(make-ea :dword
:base index
:index index
:scale
2))
520 (with-empty-tn@fp-top
(value)
521 (inst fldl
(make-ea :dword
:base object
:index temp
:scale
1
522 :disp
(- (* vector-data-offset
524 other-pointer-lowtag
))))))
527 (define-vop (data-vector-ref-c/simple-array-long-float
)
528 (:note
"inline array access")
529 (:translate data-vector-ref
)
531 (:args
(object :scs
(descriptor-reg)))
533 (:arg-types simple-array-long-float
(:constant
(signed-byte 30)))
534 (:results
(value :scs
(long-reg)))
535 (:result-types long-float
)
537 (with-empty-tn@fp-top
(value)
538 (inst fldl
(make-ea :dword
:base object
539 :disp
(- (+ (* vector-data-offset
542 other-pointer-lowtag
))))))
545 (define-vop (data-vector-set/simple-array-long-float
)
546 (:note
"inline array store")
547 (:translate data-vector-set
)
549 (:args
(object :scs
(descriptor-reg) :to
:result
)
550 (index :scs
(any-reg))
551 (value :scs
(long-reg) :target result
))
552 (:arg-types simple-array-long-float positive-fixnum long-float
)
553 (:temporary
(:sc any-reg
:from
(:argument
1) :to
:result
) temp
)
554 (:results
(result :scs
(long-reg)))
555 (:result-types long-float
)
558 (inst lea temp
(make-ea :dword
:base index
:index index
:scale
2))
559 (cond ((zerop (tn-offset value
))
562 (make-ea :dword
:base object
:index temp
:scale
1
563 :disp
(- (* vector-data-offset n-word-bytes
)
564 other-pointer-lowtag
)))
565 (unless (zerop (tn-offset result
))
566 ;; Value is in ST0 but not result.
569 ;; Value is not in ST0.
572 (make-ea :dword
:base object
:index temp
:scale
1
573 :disp
(- (* vector-data-offset n-word-bytes
)
574 other-pointer-lowtag
)))
575 (cond ((zerop (tn-offset result
))
576 ;; The result is in ST0.
579 ;; Neither value or result are in ST0
580 (unless (location= value result
)
582 (inst fxch value
)))))))
585 (define-vop (data-vector-set-c/simple-array-long-float
)
586 (:note
"inline array store")
587 (:translate data-vector-set
)
589 (:args
(object :scs
(descriptor-reg))
590 (value :scs
(long-reg) :target result
))
592 (:arg-types simple-array-long-float
(:constant
(signed-byte 30)) long-float
)
593 (:results
(result :scs
(long-reg)))
594 (:result-types long-float
)
596 (cond ((zerop (tn-offset value
))
598 (store-long-float (make-ea :dword
:base object
599 :disp
(- (+ (* vector-data-offset
602 other-pointer-lowtag
)))
603 (unless (zerop (tn-offset result
))
604 ;; Value is in ST0 but not result.
607 ;; Value is not in ST0.
609 (store-long-float (make-ea :dword
:base object
610 :disp
(- (+ (* vector-data-offset
613 other-pointer-lowtag
)))
614 (cond ((zerop (tn-offset result
))
615 ;; The result is in ST0.
618 ;; Neither value or result are in ST0
619 (unless (location= value result
)
621 (inst fxch value
)))))))
623 ;;; complex float variants
625 (define-vop (data-vector-ref/simple-array-complex-single-float
)
626 (:note
"inline array access")
627 (:translate data-vector-ref
)
629 (:args
(object :scs
(descriptor-reg))
630 (index :scs
(any-reg)))
631 (:arg-types simple-array-complex-single-float positive-fixnum
)
632 (:results
(value :scs
(complex-single-reg)))
633 (:result-types complex-single-float
)
635 (let ((real-tn (complex-single-reg-real-tn value
)))
636 (with-empty-tn@fp-top
(real-tn)
637 (inst fld
(make-ea :dword
:base object
:index index
:scale
2
638 :disp
(- (* vector-data-offset
640 other-pointer-lowtag
)))))
641 (let ((imag-tn (complex-single-reg-imag-tn value
)))
642 (with-empty-tn@fp-top
(imag-tn)
643 (inst fld
(make-ea :dword
:base object
:index index
:scale
2
644 :disp
(- (* (1+ vector-data-offset
)
646 other-pointer-lowtag
)))))))
648 (define-vop (data-vector-ref-c/simple-array-complex-single-float
)
649 (:note
"inline array access")
650 (:translate data-vector-ref
)
652 (:args
(object :scs
(descriptor-reg)))
654 (:arg-types simple-array-complex-single-float
(:constant
(signed-byte 30)))
655 (:results
(value :scs
(complex-single-reg)))
656 (:result-types complex-single-float
)
658 (let ((real-tn (complex-single-reg-real-tn value
)))
659 (with-empty-tn@fp-top
(real-tn)
660 (inst fld
(make-ea :dword
:base object
661 :disp
(- (+ (* vector-data-offset
664 other-pointer-lowtag
)))))
665 (let ((imag-tn (complex-single-reg-imag-tn value
)))
666 (with-empty-tn@fp-top
(imag-tn)
667 (inst fld
(make-ea :dword
:base object
668 :disp
(- (+ (* vector-data-offset
671 other-pointer-lowtag
)))))))
673 (define-vop (data-vector-set/simple-array-complex-single-float
)
674 (:note
"inline array store")
675 (:translate data-vector-set
)
677 (:args
(object :scs
(descriptor-reg))
678 (index :scs
(any-reg))
679 (value :scs
(complex-single-reg) :target result
))
680 (:arg-types simple-array-complex-single-float positive-fixnum
681 complex-single-float
)
682 (:results
(result :scs
(complex-single-reg)))
683 (:result-types complex-single-float
)
685 (let ((value-real (complex-single-reg-real-tn value
))
686 (result-real (complex-single-reg-real-tn result
)))
687 (cond ((zerop (tn-offset value-real
))
689 (inst fst
(make-ea :dword
:base object
:index index
:scale
2
690 :disp
(- (* vector-data-offset
692 other-pointer-lowtag
)))
693 (unless (zerop (tn-offset result-real
))
694 ;; Value is in ST0 but not result.
695 (inst fst result-real
)))
697 ;; Value is not in ST0.
698 (inst fxch value-real
)
699 (inst fst
(make-ea :dword
:base object
:index index
:scale
2
700 :disp
(- (* vector-data-offset
702 other-pointer-lowtag
)))
703 (cond ((zerop (tn-offset result-real
))
704 ;; The result is in ST0.
705 (inst fst value-real
))
707 ;; Neither value or result are in ST0
708 (unless (location= value-real result-real
)
709 (inst fst result-real
))
710 (inst fxch value-real
))))))
711 (let ((value-imag (complex-single-reg-imag-tn value
))
712 (result-imag (complex-single-reg-imag-tn result
)))
713 (inst fxch value-imag
)
714 (inst fst
(make-ea :dword
:base object
:index index
:scale
2
715 :disp
(- (+ (* vector-data-offset
718 other-pointer-lowtag
)))
719 (unless (location= value-imag result-imag
)
720 (inst fst result-imag
))
721 (inst fxch value-imag
))))
723 (define-vop (data-vector-set-c/simple-array-complex-single-float
)
724 (:note
"inline array store")
725 (:translate data-vector-set
)
727 (:args
(object :scs
(descriptor-reg))
728 (value :scs
(complex-single-reg) :target result
))
730 (:arg-types simple-array-complex-single-float
(:constant
(signed-byte 30))
731 complex-single-float
)
732 (:results
(result :scs
(complex-single-reg)))
733 (:result-types complex-single-float
)
735 (let ((value-real (complex-single-reg-real-tn value
))
736 (result-real (complex-single-reg-real-tn result
)))
737 (cond ((zerop (tn-offset value-real
))
739 (inst fst
(make-ea :dword
:base object
740 :disp
(- (+ (* vector-data-offset
743 other-pointer-lowtag
)))
744 (unless (zerop (tn-offset result-real
))
745 ;; Value is in ST0 but not result.
746 (inst fst result-real
)))
748 ;; Value is not in ST0.
749 (inst fxch value-real
)
750 (inst fst
(make-ea :dword
:base object
751 :disp
(- (+ (* vector-data-offset
754 other-pointer-lowtag
)))
755 (cond ((zerop (tn-offset result-real
))
756 ;; The result is in ST0.
757 (inst fst value-real
))
759 ;; Neither value or result are in ST0
760 (unless (location= value-real result-real
)
761 (inst fst result-real
))
762 (inst fxch value-real
))))))
763 (let ((value-imag (complex-single-reg-imag-tn value
))
764 (result-imag (complex-single-reg-imag-tn result
)))
765 (inst fxch value-imag
)
766 (inst fst
(make-ea :dword
:base object
767 :disp
(- (+ (* vector-data-offset
770 other-pointer-lowtag
)))
771 (unless (location= value-imag result-imag
)
772 (inst fst result-imag
))
773 (inst fxch value-imag
))))
776 (define-vop (data-vector-ref/simple-array-complex-double-float
)
777 (:note
"inline array access")
778 (:translate data-vector-ref
)
780 (:args
(object :scs
(descriptor-reg))
781 (index :scs
(any-reg)))
782 (:arg-types simple-array-complex-double-float positive-fixnum
)
783 (:results
(value :scs
(complex-double-reg)))
784 (:result-types complex-double-float
)
786 (let ((real-tn (complex-double-reg-real-tn value
)))
787 (with-empty-tn@fp-top
(real-tn)
788 (inst fldd
(make-ea :dword
:base object
:index index
:scale
4
789 :disp
(- (* vector-data-offset
791 other-pointer-lowtag
)))))
792 (let ((imag-tn (complex-double-reg-imag-tn value
)))
793 (with-empty-tn@fp-top
(imag-tn)
794 (inst fldd
(make-ea :dword
:base object
:index index
:scale
4
795 :disp
(- (+ (* vector-data-offset
798 other-pointer-lowtag
)))))))
800 (define-vop (data-vector-ref-c/simple-array-complex-double-float
)
801 (:note
"inline array access")
802 (:translate data-vector-ref
)
804 (:args
(object :scs
(descriptor-reg)))
806 (:arg-types simple-array-complex-double-float
(:constant
(signed-byte 30)))
807 (:results
(value :scs
(complex-double-reg)))
808 (:result-types complex-double-float
)
810 (let ((real-tn (complex-double-reg-real-tn value
)))
811 (with-empty-tn@fp-top
(real-tn)
812 (inst fldd
(make-ea :dword
:base object
813 :disp
(- (+ (* vector-data-offset
816 other-pointer-lowtag
)))))
817 (let ((imag-tn (complex-double-reg-imag-tn value
)))
818 (with-empty-tn@fp-top
(imag-tn)
819 (inst fldd
(make-ea :dword
:base object
820 :disp
(- (+ (* vector-data-offset
823 other-pointer-lowtag
)))))))
825 (define-vop (data-vector-set/simple-array-complex-double-float
)
826 (:note
"inline array store")
827 (:translate data-vector-set
)
829 (:args
(object :scs
(descriptor-reg))
830 (index :scs
(any-reg))
831 (value :scs
(complex-double-reg) :target result
))
832 (:arg-types simple-array-complex-double-float positive-fixnum
833 complex-double-float
)
834 (:results
(result :scs
(complex-double-reg)))
835 (:result-types complex-double-float
)
837 (let ((value-real (complex-double-reg-real-tn value
))
838 (result-real (complex-double-reg-real-tn result
)))
839 (cond ((zerop (tn-offset value-real
))
841 (inst fstd
(make-ea :dword
:base object
:index index
:scale
4
842 :disp
(- (* vector-data-offset
844 other-pointer-lowtag
)))
845 (unless (zerop (tn-offset result-real
))
846 ;; Value is in ST0 but not result.
847 (inst fstd result-real
)))
849 ;; Value is not in ST0.
850 (inst fxch value-real
)
851 (inst fstd
(make-ea :dword
:base object
:index index
:scale
4
852 :disp
(- (* vector-data-offset
854 other-pointer-lowtag
)))
855 (cond ((zerop (tn-offset result-real
))
856 ;; The result is in ST0.
857 (inst fstd value-real
))
859 ;; Neither value or result are in ST0
860 (unless (location= value-real result-real
)
861 (inst fstd result-real
))
862 (inst fxch value-real
))))))
863 (let ((value-imag (complex-double-reg-imag-tn value
))
864 (result-imag (complex-double-reg-imag-tn result
)))
865 (inst fxch value-imag
)
866 (inst fstd
(make-ea :dword
:base object
:index index
:scale
4
867 :disp
(- (+ (* vector-data-offset
870 other-pointer-lowtag
)))
871 (unless (location= value-imag result-imag
)
872 (inst fstd result-imag
))
873 (inst fxch value-imag
))))
875 (define-vop (data-vector-set-c/simple-array-complex-double-float
)
876 (:note
"inline array store")
877 (:translate data-vector-set
)
879 (:args
(object :scs
(descriptor-reg))
880 (value :scs
(complex-double-reg) :target result
))
882 (:arg-types simple-array-complex-double-float
(:constant
(signed-byte 30))
883 complex-double-float
)
884 (:results
(result :scs
(complex-double-reg)))
885 (:result-types complex-double-float
)
887 (let ((value-real (complex-double-reg-real-tn value
))
888 (result-real (complex-double-reg-real-tn result
)))
889 (cond ((zerop (tn-offset value-real
))
891 (inst fstd
(make-ea :dword
:base object
892 :disp
(- (+ (* vector-data-offset
895 other-pointer-lowtag
)))
896 (unless (zerop (tn-offset result-real
))
897 ;; Value is in ST0 but not result.
898 (inst fstd result-real
)))
900 ;; Value is not in ST0.
901 (inst fxch value-real
)
902 (inst fstd
(make-ea :dword
:base object
903 :disp
(- (+ (* vector-data-offset
906 other-pointer-lowtag
)))
907 (cond ((zerop (tn-offset result-real
))
908 ;; The result is in ST0.
909 (inst fstd value-real
))
911 ;; Neither value or result are in ST0
912 (unless (location= value-real result-real
)
913 (inst fstd result-real
))
914 (inst fxch value-real
))))))
915 (let ((value-imag (complex-double-reg-imag-tn value
))
916 (result-imag (complex-double-reg-imag-tn result
)))
917 (inst fxch value-imag
)
918 (inst fstd
(make-ea :dword
:base object
919 :disp
(- (+ (* vector-data-offset
922 other-pointer-lowtag
)))
923 (unless (location= value-imag result-imag
)
924 (inst fstd result-imag
))
925 (inst fxch value-imag
))))
929 (define-vop (data-vector-ref/simple-array-complex-long-float
)
930 (:note
"inline array access")
931 (:translate data-vector-ref
)
933 (:args
(object :scs
(descriptor-reg) :to
:result
)
934 (index :scs
(any-reg)))
935 (:arg-types simple-array-complex-long-float positive-fixnum
)
936 (:temporary
(:sc any-reg
:from
:eval
:to
:result
) temp
)
937 (:results
(value :scs
(complex-long-reg)))
938 (:result-types complex-long-float
)
941 (inst lea temp
(make-ea :dword
:base index
:index index
:scale
2))
942 (let ((real-tn (complex-long-reg-real-tn value
)))
943 (with-empty-tn@fp-top
(real-tn)
944 (inst fldl
(make-ea :dword
:base object
:index temp
:scale
2
945 :disp
(- (* vector-data-offset
947 other-pointer-lowtag
)))))
948 (let ((imag-tn (complex-long-reg-imag-tn value
)))
949 (with-empty-tn@fp-top
(imag-tn)
950 (inst fldl
(make-ea :dword
:base object
:index temp
:scale
2
951 :disp
(- (+ (* vector-data-offset
954 other-pointer-lowtag
)))))))
957 (define-vop (data-vector-ref-c/simple-array-complex-long-float
)
958 (:note
"inline array access")
959 (:translate data-vector-ref
)
961 (:args
(object :scs
(descriptor-reg)))
963 (:arg-types simple-array-complex-long-float
(:constant
(signed-byte 30)))
964 (:results
(value :scs
(complex-long-reg)))
965 (:result-types complex-long-float
)
967 (let ((real-tn (complex-long-reg-real-tn value
)))
968 (with-empty-tn@fp-top
(real-tn)
969 (inst fldl
(make-ea :dword
:base object
970 :disp
(- (+ (* vector-data-offset
973 other-pointer-lowtag
)))))
974 (let ((imag-tn (complex-long-reg-imag-tn value
)))
975 (with-empty-tn@fp-top
(imag-tn)
976 (inst fldl
(make-ea :dword
:base object
977 :disp
(- (+ (* vector-data-offset
980 other-pointer-lowtag
)))))))
983 (define-vop (data-vector-set/simple-array-complex-long-float
)
984 (:note
"inline array store")
985 (:translate data-vector-set
)
987 (:args
(object :scs
(descriptor-reg) :to
:result
)
988 (index :scs
(any-reg))
989 (value :scs
(complex-long-reg) :target result
))
990 (:arg-types simple-array-complex-long-float positive-fixnum
992 (:temporary
(:sc any-reg
:from
(:argument
1) :to
:result
) temp
)
993 (:results
(result :scs
(complex-long-reg)))
994 (:result-types complex-long-float
)
997 (inst lea temp
(make-ea :dword
:base index
:index index
:scale
2))
998 (let ((value-real (complex-long-reg-real-tn value
))
999 (result-real (complex-long-reg-real-tn result
)))
1000 (cond ((zerop (tn-offset value-real
))
1003 (make-ea :dword
:base object
:index temp
:scale
2
1004 :disp
(- (* vector-data-offset n-word-bytes
)
1005 other-pointer-lowtag
)))
1006 (unless (zerop (tn-offset result-real
))
1007 ;; Value is in ST0 but not result.
1008 (inst fstd result-real
)))
1010 ;; Value is not in ST0.
1011 (inst fxch value-real
)
1013 (make-ea :dword
:base object
:index temp
:scale
2
1014 :disp
(- (* vector-data-offset n-word-bytes
)
1015 other-pointer-lowtag
)))
1016 (cond ((zerop (tn-offset result-real
))
1017 ;; The result is in ST0.
1018 (inst fstd value-real
))
1020 ;; Neither value or result are in ST0
1021 (unless (location= value-real result-real
)
1022 (inst fstd result-real
))
1023 (inst fxch value-real
))))))
1024 (let ((value-imag (complex-long-reg-imag-tn value
))
1025 (result-imag (complex-long-reg-imag-tn result
)))
1026 (inst fxch value-imag
)
1028 (make-ea :dword
:base object
:index temp
:scale
2
1029 :disp
(- (+ (* vector-data-offset n-word-bytes
) 12)
1030 other-pointer-lowtag
)))
1031 (unless (location= value-imag result-imag
)
1032 (inst fstd result-imag
))
1033 (inst fxch value-imag
))))
1036 (define-vop (data-vector-set-c/simple-array-complex-long-float
)
1037 (:note
"inline array store")
1038 (:translate data-vector-set
)
1039 (:policy
:fast-safe
)
1040 (:args
(object :scs
(descriptor-reg))
1041 (value :scs
(complex-long-reg) :target result
))
1043 (:arg-types simple-array-complex-long-float
(:constant
(signed-byte 30))
1045 (:results
(result :scs
(complex-long-reg)))
1046 (:result-types complex-long-float
)
1048 (let ((value-real (complex-long-reg-real-tn value
))
1049 (result-real (complex-long-reg-real-tn result
)))
1050 (cond ((zerop (tn-offset value-real
))
1053 (make-ea :dword
:base object
1054 :disp
(- (+ (* vector-data-offset
1057 other-pointer-lowtag
)))
1058 (unless (zerop (tn-offset result-real
))
1059 ;; Value is in ST0 but not result.
1060 (inst fstd result-real
)))
1062 ;; Value is not in ST0.
1063 (inst fxch value-real
)
1065 (make-ea :dword
:base object
1066 :disp
(- (+ (* vector-data-offset
1069 other-pointer-lowtag
)))
1070 (cond ((zerop (tn-offset result-real
))
1071 ;; The result is in ST0.
1072 (inst fstd value-real
))
1074 ;; Neither value or result are in ST0
1075 (unless (location= value-real result-real
)
1076 (inst fstd result-real
))
1077 (inst fxch value-real
))))))
1078 (let ((value-imag (complex-long-reg-imag-tn value
))
1079 (result-imag (complex-long-reg-imag-tn result
)))
1080 (inst fxch value-imag
)
1082 (make-ea :dword
:base object
1083 :disp
(- (+ (* vector-data-offset
1085 ;; FIXME: There are so many of these bare constants
1086 ;; (24, 12..) in the LONG-FLOAT code that it's
1087 ;; ridiculous. I should probably just delete it all
1088 ;; instead of appearing to flirt with supporting
1089 ;; this maintenance nightmare.
1091 other-pointer-lowtag
)))
1092 (unless (location= value-imag result-imag
)
1093 (inst fstd result-imag
))
1094 (inst fxch value-imag
))))
1097 (macrolet ((define-data-vector-frobs (ptype)
1099 (define-vop (,(symbolicate "DATA-VECTOR-REF/" ptype
))
1100 (:translate data-vector-ref
)
1101 (:policy
:fast-safe
)
1102 (:args
(object :scs
(descriptor-reg))
1103 (index :scs
(unsigned-reg)))
1104 (:arg-types
,ptype positive-fixnum
)
1105 (:results
(value :scs
(unsigned-reg signed-reg
)))
1106 (:result-types positive-fixnum
)
1109 (make-ea :byte
:base object
:index index
:scale
1
1110 :disp
(- (* vector-data-offset n-word-bytes
)
1111 other-pointer-lowtag
)))))
1112 (define-vop (,(symbolicate "DATA-VECTOR-REF-C/" ptype
))
1113 (:translate data-vector-ref
)
1114 (:policy
:fast-safe
)
1115 (:args
(object :scs
(descriptor-reg)))
1117 (:arg-types
,ptype
(:constant
(signed-byte 30)))
1118 (:results
(value :scs
(unsigned-reg signed-reg
)))
1119 (:result-types positive-fixnum
)
1122 (make-ea :byte
:base object
1123 :disp
(- (+ (* vector-data-offset n-word-bytes
) index
)
1124 other-pointer-lowtag
)))))
1125 (define-vop (,(symbolicate "DATA-VECTOR-SET/" ptype
))
1126 (:translate data-vector-set
)
1127 (:policy
:fast-safe
)
1128 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1129 (index :scs
(unsigned-reg) :to
(:eval
0))
1130 (value :scs
(unsigned-reg signed-reg
) :target eax
))
1131 (:arg-types
,ptype positive-fixnum positive-fixnum
)
1132 (:temporary
(:sc unsigned-reg
:offset eax-offset
:target result
1133 :from
(:argument
2) :to
(:result
0))
1135 (:results
(result :scs
(unsigned-reg signed-reg
)))
1136 (:result-types positive-fixnum
)
1139 (inst mov
(make-ea :byte
:base object
:index index
:scale
1
1140 :disp
(- (* vector-data-offset n-word-bytes
)
1141 other-pointer-lowtag
))
1144 (define-vop (,(symbolicate "DATA-VECTOR-SET-C/" ptype
))
1145 (:translate data-vector-set
)
1146 (:policy
:fast-safe
)
1147 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1148 (value :scs
(unsigned-reg signed-reg
) :target eax
))
1150 (:arg-types
,ptype
(:constant
(signed-byte 30))
1152 (:temporary
(:sc unsigned-reg
:offset eax-offset
:target result
1153 :from
(:argument
1) :to
(:result
0))
1155 (:results
(result :scs
(unsigned-reg signed-reg
)))
1156 (:result-types positive-fixnum
)
1159 (inst mov
(make-ea :byte
:base object
1160 :disp
(- (+ (* vector-data-offset n-word-bytes
) index
)
1161 other-pointer-lowtag
))
1163 (move result eax
))))))
1164 (define-data-vector-frobs simple-array-unsigned-byte-7
)
1165 (define-data-vector-frobs simple-array-unsigned-byte-8
))
1167 ;;; unsigned-byte-16
1168 (macrolet ((define-data-vector-frobs (ptype)
1170 (define-vop (,(symbolicate "DATA-VECTOR-REF/" ptype
))
1171 (:translate data-vector-ref
)
1172 (:policy
:fast-safe
)
1173 (:args
(object :scs
(descriptor-reg))
1174 (index :scs
(unsigned-reg)))
1175 (:arg-types
,ptype positive-fixnum
)
1176 (:results
(value :scs
(unsigned-reg signed-reg
)))
1177 (:result-types positive-fixnum
)
1180 (make-ea :word
:base object
:index index
:scale
2
1181 :disp
(- (* vector-data-offset n-word-bytes
)
1182 other-pointer-lowtag
)))))
1183 (define-vop (,(symbolicate "DATA-VECTOR-REF-C/" ptype
))
1184 (:translate data-vector-ref
)
1185 (:policy
:fast-safe
)
1186 (:args
(object :scs
(descriptor-reg)))
1188 (:arg-types
,ptype
(:constant
(signed-byte 30)))
1189 (:results
(value :scs
(unsigned-reg signed-reg
)))
1190 (:result-types positive-fixnum
)
1193 (make-ea :word
:base object
1194 :disp
(- (+ (* vector-data-offset n-word-bytes
) (* 2 index
))
1195 other-pointer-lowtag
)))))
1196 (define-vop (,(symbolicate "DATA-VECTOR-SET/" ptype
))
1197 (:translate data-vector-set
)
1198 (:policy
:fast-safe
)
1199 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1200 (index :scs
(unsigned-reg) :to
(:eval
0))
1201 (value :scs
(unsigned-reg signed-reg
) :target eax
))
1202 (:arg-types
,ptype positive-fixnum positive-fixnum
)
1203 (:temporary
(:sc unsigned-reg
:offset eax-offset
:target result
1204 :from
(:argument
2) :to
(:result
0))
1206 (:results
(result :scs
(unsigned-reg signed-reg
)))
1207 (:result-types positive-fixnum
)
1210 (inst mov
(make-ea :word
:base object
:index index
:scale
2
1211 :disp
(- (* vector-data-offset n-word-bytes
)
1212 other-pointer-lowtag
))
1216 (define-vop (,(symbolicate "DATA-VECTOR-SET-C/" ptype
))
1217 (:translate data-vector-set
)
1218 (:policy
:fast-safe
)
1219 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1220 (value :scs
(unsigned-reg signed-reg
) :target eax
))
1222 (:arg-types
,ptype
(:constant
(signed-byte 30))
1224 (:temporary
(:sc unsigned-reg
:offset eax-offset
:target result
1225 :from
(:argument
1) :to
(:result
0))
1227 (:results
(result :scs
(unsigned-reg signed-reg
)))
1228 (:result-types positive-fixnum
)
1231 (inst mov
(make-ea :word
:base object
1232 :disp
(- (+ (* vector-data-offset n-word-bytes
)
1234 other-pointer-lowtag
))
1236 (move result eax
))))))
1237 (define-data-vector-frobs simple-array-unsigned-byte-15
)
1238 (define-data-vector-frobs simple-array-unsigned-byte-16
))
1242 (define-vop (data-vector-ref/simple-base-string
)
1243 (:translate data-vector-ref
)
1244 (:policy
:fast-safe
)
1245 (:args
(object :scs
(descriptor-reg))
1246 (index :scs
(unsigned-reg)))
1247 (:arg-types simple-base-string positive-fixnum
)
1248 (:results
(value :scs
(base-char-reg)))
1249 (:result-types base-char
)
1252 (make-ea :byte
:base object
:index index
:scale
1
1253 :disp
(- (* vector-data-offset n-word-bytes
)
1254 other-pointer-lowtag
)))))
1256 (define-vop (data-vector-ref-c/simple-base-string
)
1257 (:translate data-vector-ref
)
1258 (:policy
:fast-safe
)
1259 (:args
(object :scs
(descriptor-reg)))
1261 (:arg-types simple-base-string
(:constant
(signed-byte 30)))
1262 (:results
(value :scs
(base-char-reg)))
1263 (:result-types base-char
)
1266 (make-ea :byte
:base object
1267 :disp
(- (+ (* vector-data-offset n-word-bytes
) index
)
1268 other-pointer-lowtag
)))))
1270 (define-vop (data-vector-set/simple-base-string
)
1271 (:translate data-vector-set
)
1272 (:policy
:fast-safe
)
1273 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1274 (index :scs
(unsigned-reg) :to
(:eval
0))
1275 (value :scs
(base-char-reg) :target result
))
1276 (:arg-types simple-base-string positive-fixnum base-char
)
1277 (:results
(result :scs
(base-char-reg)))
1278 (:result-types base-char
)
1280 (inst mov
(make-ea :byte
:base object
:index index
:scale
1
1281 :disp
(- (* vector-data-offset n-word-bytes
)
1282 other-pointer-lowtag
))
1284 (move result value
)))
1286 (define-vop (data-vector-set/simple-base-string-c
)
1287 (:translate data-vector-set
)
1288 (:policy
:fast-safe
)
1289 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1290 (value :scs
(base-char-reg)))
1292 (:arg-types simple-base-string
(:constant
(signed-byte 30)) base-char
)
1293 (:results
(result :scs
(base-char-reg)))
1294 (:result-types base-char
)
1296 (inst mov
(make-ea :byte
:base object
1297 :disp
(- (+ (* vector-data-offset n-word-bytes
) index
)
1298 other-pointer-lowtag
))
1300 (move result value
)))
1304 (define-vop (data-vector-ref/simple-array-signed-byte-8
)
1305 (:translate data-vector-ref
)
1306 (:policy
:fast-safe
)
1307 (:args
(object :scs
(descriptor-reg))
1308 (index :scs
(unsigned-reg)))
1309 (:arg-types simple-array-signed-byte-8 positive-fixnum
)
1310 (:results
(value :scs
(signed-reg)))
1311 (:result-types tagged-num
)
1314 (make-ea :byte
:base object
:index index
:scale
1
1315 :disp
(- (* vector-data-offset n-word-bytes
)
1316 other-pointer-lowtag
)))))
1318 (define-vop (data-vector-ref-c/simple-array-signed-byte-8
)
1319 (:translate data-vector-ref
)
1320 (:policy
:fast-safe
)
1321 (:args
(object :scs
(descriptor-reg)))
1323 (:arg-types simple-array-signed-byte-8
(:constant
(signed-byte 30)))
1324 (:results
(value :scs
(signed-reg)))
1325 (:result-types tagged-num
)
1328 (make-ea :byte
:base object
1329 :disp
(- (+ (* vector-data-offset n-word-bytes
) index
)
1330 other-pointer-lowtag
)))))
1332 (define-vop (data-vector-set/simple-array-signed-byte-8
)
1333 (:translate data-vector-set
)
1334 (:policy
:fast-safe
)
1335 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1336 (index :scs
(unsigned-reg) :to
(:eval
0))
1337 (value :scs
(signed-reg) :target eax
))
1338 (:arg-types simple-array-signed-byte-8 positive-fixnum tagged-num
)
1339 (:temporary
(:sc unsigned-reg
:offset eax-offset
:target result
1340 :from
(:argument
2) :to
(:result
0))
1342 (:results
(result :scs
(signed-reg)))
1343 (:result-types tagged-num
)
1346 (inst mov
(make-ea :byte
:base object
:index index
:scale
1
1347 :disp
(- (* vector-data-offset n-word-bytes
)
1348 other-pointer-lowtag
))
1352 (define-vop (data-vector-set-c/simple-array-signed-byte-8
)
1353 (:translate data-vector-set
)
1354 (:policy
:fast-safe
)
1355 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1356 (value :scs
(signed-reg) :target eax
))
1358 (:arg-types simple-array-signed-byte-8
(:constant
(signed-byte 30))
1360 (:temporary
(:sc unsigned-reg
:offset eax-offset
:target result
1361 :from
(:argument
1) :to
(:result
0))
1363 (:results
(result :scs
(signed-reg)))
1364 (:result-types tagged-num
)
1367 (inst mov
(make-ea :byte
:base object
1368 :disp
(- (+ (* vector-data-offset n-word-bytes
) index
)
1369 other-pointer-lowtag
))
1375 (define-vop (data-vector-ref/simple-array-signed-byte-16
)
1376 (:translate data-vector-ref
)
1377 (:policy
:fast-safe
)
1378 (:args
(object :scs
(descriptor-reg))
1379 (index :scs
(unsigned-reg)))
1380 (:arg-types simple-array-signed-byte-16 positive-fixnum
)
1381 (:results
(value :scs
(signed-reg)))
1382 (:result-types tagged-num
)
1385 (make-ea :word
:base object
:index index
:scale
2
1386 :disp
(- (* vector-data-offset n-word-bytes
)
1387 other-pointer-lowtag
)))))
1389 (define-vop (data-vector-ref-c/simple-array-signed-byte-16
)
1390 (:translate data-vector-ref
)
1391 (:policy
:fast-safe
)
1392 (:args
(object :scs
(descriptor-reg)))
1394 (:arg-types simple-array-signed-byte-16
(:constant
(signed-byte 30)))
1395 (:results
(value :scs
(signed-reg)))
1396 (:result-types tagged-num
)
1399 (make-ea :word
:base object
1400 :disp
(- (+ (* vector-data-offset n-word-bytes
)
1402 other-pointer-lowtag
)))))
1404 (define-vop (data-vector-set/simple-array-signed-byte-16
)
1405 (:translate data-vector-set
)
1406 (:policy
:fast-safe
)
1407 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1408 (index :scs
(unsigned-reg) :to
(:eval
0))
1409 (value :scs
(signed-reg) :target eax
))
1410 (:arg-types simple-array-signed-byte-16 positive-fixnum tagged-num
)
1411 (:temporary
(:sc signed-reg
:offset eax-offset
:target result
1412 :from
(:argument
2) :to
(:result
0))
1414 (:results
(result :scs
(signed-reg)))
1415 (:result-types tagged-num
)
1418 (inst mov
(make-ea :word
:base object
:index index
:scale
2
1419 :disp
(- (* vector-data-offset n-word-bytes
)
1420 other-pointer-lowtag
))
1424 (define-vop (data-vector-set-c/simple-array-signed-byte-16
)
1425 (:translate data-vector-set
)
1426 (:policy
:fast-safe
)
1427 (:args
(object :scs
(descriptor-reg) :to
(:eval
0))
1428 (value :scs
(signed-reg) :target eax
))
1430 (:arg-types simple-array-signed-byte-16
(:constant
(signed-byte 30)) tagged-num
)
1431 (:temporary
(:sc signed-reg
:offset eax-offset
:target result
1432 :from
(:argument
1) :to
(:result
0))
1434 (:results
(result :scs
(signed-reg)))
1435 (:result-types tagged-num
)
1439 (make-ea :word
:base object
1440 :disp
(- (+ (* vector-data-offset n-word-bytes
)
1442 other-pointer-lowtag
))
1446 ;;; These VOPs are used for implementing float slots in structures (whose raw
1447 ;;; data is an unsigned-32 vector).
1448 (define-vop (raw-ref-single data-vector-ref
/simple-array-single-float
)
1449 (:translate %raw-ref-single
)
1450 (:arg-types sb
!c
::raw-vector positive-fixnum
))
1451 (define-vop (raw-ref-single-c data-vector-ref-c
/simple-array-single-float
)
1452 (:translate %raw-ref-single
)
1453 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))))
1454 (define-vop (raw-set-single data-vector-set
/simple-array-single-float
)
1455 (:translate %raw-set-single
)
1456 (:arg-types sb
!c
::raw-vector positive-fixnum single-float
))
1457 (define-vop (raw-set-single-c data-vector-set-c
/simple-array-single-float
)
1458 (:translate %raw-set-single
)
1459 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30)) single-float
))
1460 (define-vop (raw-ref-double data-vector-ref
/simple-array-double-float
)
1461 (:translate %raw-ref-double
)
1462 (:arg-types sb
!c
::raw-vector positive-fixnum
))
1463 (define-vop (raw-ref-double-c data-vector-ref-c
/simple-array-double-float
)
1464 (:translate %raw-ref-double
)
1465 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))))
1466 (define-vop (raw-set-double data-vector-set
/simple-array-double-float
)
1467 (:translate %raw-set-double
)
1468 (:arg-types sb
!c
::raw-vector positive-fixnum double-float
))
1469 (define-vop (raw-set-double-c data-vector-set-c
/simple-array-double-float
)
1470 (:translate %raw-set-double
)
1471 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30)) double-float
))
1473 (define-vop (raw-ref-long data-vector-ref
/simple-array-long-float
)
1474 (:translate %raw-ref-long
)
1475 (:arg-types sb
!c
::raw-vector positive-fixnum
))
1477 (define-vop (raw-ref-long-c data-vector-ref-c
/simple-array-long-float
)
1478 (:translate %raw-ref-long
)
1479 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))))
1481 (define-vop (raw-set-double data-vector-set
/simple-array-long-float
)
1482 (:translate %raw-set-long
)
1483 (:arg-types sb
!c
::raw-vector positive-fixnum long-float
))
1485 (define-vop (raw-set-long-c data-vector-set-c
/simple-array-long-float
)
1486 (:translate %raw-set-long
)
1487 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30)) long-float
))
1489 ;;;; complex-float raw structure slot accessors
1491 (define-vop (raw-ref-complex-single
1492 data-vector-ref
/simple-array-complex-single-float
)
1493 (:translate %raw-ref-complex-single
)
1494 (:arg-types sb
!c
::raw-vector positive-fixnum
))
1495 (define-vop (raw-ref-complex-single-c
1496 data-vector-ref-c
/simple-array-complex-single-float
)
1497 (:translate %raw-ref-complex-single
)
1498 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))))
1499 (define-vop (raw-set-complex-single
1500 data-vector-set
/simple-array-complex-single-float
)
1501 (:translate %raw-set-complex-single
)
1502 (:arg-types sb
!c
::raw-vector positive-fixnum complex-single-float
))
1503 (define-vop (raw-set-complex-single-c
1504 data-vector-set-c
/simple-array-complex-single-float
)
1505 (:translate %raw-set-complex-single
)
1506 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))
1507 complex-single-float
))
1508 (define-vop (raw-ref-complex-double
1509 data-vector-ref
/simple-array-complex-double-float
)
1510 (:translate %raw-ref-complex-double
)
1511 (:arg-types sb
!c
::raw-vector positive-fixnum
))
1512 (define-vop (raw-ref-complex-double-c
1513 data-vector-ref-c
/simple-array-complex-double-float
)
1514 (:translate %raw-ref-complex-double
)
1515 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))))
1516 (define-vop (raw-set-complex-double
1517 data-vector-set
/simple-array-complex-double-float
)
1518 (:translate %raw-set-complex-double
)
1519 (:arg-types sb
!c
::raw-vector positive-fixnum complex-double-float
))
1520 (define-vop (raw-set-complex-double-c
1521 data-vector-set-c
/simple-array-complex-double-float
)
1522 (:translate %raw-set-complex-double
)
1523 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))
1524 complex-double-float
))
1526 (define-vop (raw-ref-complex-long
1527 data-vector-ref
/simple-array-complex-long-float
)
1528 (:translate %raw-ref-complex-long
)
1529 (:arg-types sb
!c
::raw-vector positive-fixnum
))
1531 (define-vop (raw-ref-complex-long-c
1532 data-vector-ref-c
/simple-array-complex-long-float
)
1533 (:translate %raw-ref-complex-long
)
1534 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))))
1536 (define-vop (raw-set-complex-long
1537 data-vector-set
/simple-array-complex-long-float
)
1538 (:translate %raw-set-complex-long
)
1539 (:arg-types sb
!c
::raw-vector positive-fixnum complex-long-float
))
1541 (define-vop (raw-set-complex-long-c
1542 data-vector-set-c
/simple-array-complex-long-float
)
1543 (:translate %raw-set-complex-long
)
1544 (:arg-types sb
!c
::raw-vector
(:constant
(signed-byte 30))
1545 complex-long-float
))
1547 ;;; These vops are useful for accessing the bits of a vector
1548 ;;; irrespective of what type of vector it is.
1549 (define-full-reffer raw-bits
* 0 other-pointer-lowtag
(unsigned-reg)
1550 unsigned-num %raw-bits
)
1551 (define-full-setter set-raw-bits
* 0 other-pointer-lowtag
(unsigned-reg)
1552 unsigned-num %set-raw-bits
)
1554 ;;;; miscellaneous array VOPs
1556 (define-vop (get-vector-subtype get-header-data
))
1557 (define-vop (set-vector-subtype set-header-data
))