Merged sbcl-1.0.14 with the sb-simd 1.3 patches
[sbcl/simd.git] / src / compiler / sparc / array.lisp
blob4b05ccb2d686924342e39ba06b1456bc20efa643
1 ;;;; the Sparc definitions for array operations
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
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.
12 (in-package "SB!VM")
14 ;;;; allocator for the array header.
15 (define-vop (make-array-header)
16 (:translate make-array-header)
17 (:policy :fast-safe)
18 (:args (type :scs (any-reg))
19 (rank :scs (any-reg)))
20 (:arg-types tagged-num tagged-num)
21 (:temporary (:scs (descriptor-reg) :to (:result 0) :target result) header)
22 (:temporary (:scs (non-descriptor-reg)) ndescr)
23 (:results (result :scs (descriptor-reg)))
24 (:generator 0
25 (pseudo-atomic ()
26 (inst or header alloc-tn other-pointer-lowtag)
27 (inst add ndescr rank (* (1+ array-dimensions-offset) n-word-bytes))
28 (inst andn ndescr 4)
29 (inst add alloc-tn ndescr)
30 (inst add ndescr rank (fixnumize (1- array-dimensions-offset)))
31 (inst sll ndescr ndescr n-widetag-bits)
32 (inst or ndescr ndescr type)
33 ;; Remove the extraneous fixnum tag bits because TYPE and RANK
34 ;; were fixnums
35 (inst srl ndescr ndescr n-fixnum-tag-bits)
36 (storew ndescr header 0 other-pointer-lowtag))
37 (move result header)))
39 ;;;; Additional accessors and setters for the array header.
40 (define-vop (%array-dimension word-index-ref)
41 (:translate sb!kernel:%array-dimension)
42 (:policy :fast-safe)
43 (:variant array-dimensions-offset other-pointer-lowtag))
45 (define-vop (%set-array-dimension word-index-set)
46 (:translate sb!kernel:%set-array-dimension)
47 (:policy :fast-safe)
48 (:variant array-dimensions-offset other-pointer-lowtag))
50 (define-vop (array-rank-vop)
51 (:translate sb!kernel:%array-rank)
52 (:policy :fast-safe)
53 (:args (x :scs (descriptor-reg)))
54 (:temporary (:scs (non-descriptor-reg)) temp)
55 (:results (res :scs (any-reg descriptor-reg)))
56 (:generator 6
57 (loadw temp x 0 other-pointer-lowtag)
58 (inst sra temp n-widetag-bits)
59 (inst sub temp (1- array-dimensions-offset))
60 (inst sll res temp n-fixnum-tag-bits)))
62 ;;;; Bounds checking routine.
63 (define-vop (check-bound)
64 (:translate %check-bound)
65 (:policy :fast-safe)
66 (:args (array :scs (descriptor-reg))
67 (bound :scs (any-reg descriptor-reg))
68 (index :scs (any-reg descriptor-reg) :target result))
69 (:results (result :scs (any-reg descriptor-reg)))
70 (:vop-var vop)
71 (:save-p :compute-only)
72 (:generator 5
73 (let ((error (generate-error-code vop invalid-array-index-error
74 array bound index)))
75 (inst cmp index bound)
76 (inst b :geu error)
77 (inst nop)
78 (move result index))))
80 ;;;; Accessors/Setters
82 ;;; Variants built on top of word-index-ref, etc. I.e. those vectors whos
83 ;;; elements are represented in integer registers and are built out of
84 ;;; 8, 16, or 32 bit elements.
85 (macrolet ((def-data-vector-frobs (type variant element-type &rest scs)
86 `(progn
87 (define-vop (,(symbolicate "DATA-VECTOR-REF/" (string type))
88 ,(symbolicate (string variant) "-REF"))
89 (:note "inline array access")
90 (:variant vector-data-offset other-pointer-lowtag)
91 (:translate data-vector-ref)
92 (:arg-types ,type positive-fixnum)
93 (:results (value :scs ,scs))
94 (:result-types ,element-type))
95 (define-vop (,(symbolicate "DATA-VECTOR-SET/" (string type))
96 ,(symbolicate (string variant) "-SET"))
97 (:note "inline array store")
98 (:variant vector-data-offset other-pointer-lowtag)
99 (:translate data-vector-set)
100 (:arg-types ,type positive-fixnum ,element-type)
101 (:args (object :scs (descriptor-reg))
102 (index :scs (any-reg zero immediate))
103 (value :scs ,scs))
104 (:results (result :scs ,scs))
105 (:result-types ,element-type)))))
107 (def-data-vector-frobs simple-base-string byte-index
108 character character-reg)
109 #!+sb-unicode
110 (def-data-vector-frobs simple-character-string word-index
111 character character-reg)
112 (def-data-vector-frobs simple-vector word-index
113 * descriptor-reg any-reg)
115 (def-data-vector-frobs simple-array-unsigned-byte-7 byte-index
116 positive-fixnum unsigned-reg)
117 (def-data-vector-frobs simple-array-unsigned-byte-8 byte-index
118 positive-fixnum unsigned-reg)
119 (def-data-vector-frobs simple-array-unsigned-byte-15 halfword-index
120 positive-fixnum unsigned-reg)
121 (def-data-vector-frobs simple-array-unsigned-byte-16 halfword-index
122 positive-fixnum unsigned-reg)
123 (def-data-vector-frobs simple-array-unsigned-byte-31 word-index
124 unsigned-num unsigned-reg)
125 (def-data-vector-frobs simple-array-unsigned-byte-32 word-index
126 unsigned-num unsigned-reg)
128 (def-data-vector-frobs simple-array-unsigned-byte-29 word-index
129 positive-fixnum any-reg)
130 (def-data-vector-frobs simple-array-signed-byte-30 word-index
131 tagged-num any-reg)
132 (def-data-vector-frobs simple-array-signed-byte-32 word-index
133 signed-num signed-reg))
135 ;;; Integer vectors whose elements are smaller than a byte. I.e. bit, 2-bit,
136 ;;; and 4-bit vectors.
137 (macrolet ((def-small-data-vector-frobs (type bits)
138 (let* ((elements-per-word (floor n-word-bits bits))
139 (bit-shift (1- (integer-length elements-per-word))))
140 `(progn
141 (define-vop (,(symbolicate "DATA-VECTOR-REF/" type))
142 (:note "inline array access")
143 (:translate data-vector-ref)
144 (:policy :fast-safe)
145 (:args (object :scs (descriptor-reg))
146 (index :scs (unsigned-reg)))
147 (:arg-types ,type positive-fixnum)
148 (:results (value :scs (any-reg)))
149 (:result-types positive-fixnum)
150 (:temporary (:scs (non-descriptor-reg) :to (:result 0)) temp result)
151 (:generator 20
152 (inst srl temp index ,bit-shift)
153 (inst sll temp n-fixnum-tag-bits)
154 (inst add temp (- (* vector-data-offset n-word-bytes)
155 other-pointer-lowtag))
156 (inst ld result object temp)
157 (inst and temp index ,(1- elements-per-word))
158 (inst xor temp ,(1- elements-per-word))
159 ,@(unless (= bits 1)
160 `((inst sll temp ,(1- (integer-length bits)))))
161 (inst srl result temp)
162 (inst and result ,(1- (ash 1 bits)))
163 (inst sll value result 2)))
164 (define-vop (,(symbolicate "DATA-VECTOR-REF-C/" type))
165 (:translate data-vector-ref)
166 (:policy :fast-safe)
167 (:args (object :scs (descriptor-reg)))
168 (:arg-types ,type (:constant index))
169 (:info index)
170 (:results (result :scs (unsigned-reg)))
171 (:result-types positive-fixnum)
172 (:temporary (:scs (non-descriptor-reg)) temp)
173 (:generator 15
174 (multiple-value-bind (word extra)
175 (floor index ,elements-per-word)
176 (setf extra (logxor extra (1- ,elements-per-word)))
177 (let ((offset (- (* (+ word vector-data-offset) n-word-bytes)
178 other-pointer-lowtag)))
179 (cond ((typep offset '(signed-byte 13))
180 (inst ld result object offset))
182 (inst li temp offset)
183 (inst ld result object temp))))
184 (unless (zerop extra)
185 (inst srl result (* extra ,bits)))
186 (unless (= extra ,(1- elements-per-word))
187 (inst and result ,(1- (ash 1 bits)))))))
188 (define-vop (,(symbolicate "DATA-VECTOR-SET/" type))
189 (:note "inline array store")
190 (:translate data-vector-set)
191 (:policy :fast-safe)
192 (:args (object :scs (descriptor-reg))
193 (index :scs (unsigned-reg) :target shift)
194 (value :scs (unsigned-reg zero immediate) :target result))
195 (:arg-types ,type positive-fixnum positive-fixnum)
196 (:results (result :scs (unsigned-reg)))
197 (:result-types positive-fixnum)
198 (:temporary (:scs (non-descriptor-reg)) temp old offset)
199 (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) shift)
200 (:generator 25
201 (inst srl offset index ,bit-shift)
202 (inst sll offset n-fixnum-tag-bits)
203 (inst add offset (- (* vector-data-offset n-word-bytes)
204 other-pointer-lowtag))
205 (inst ld old object offset)
206 (inst and shift index ,(1- elements-per-word))
207 (inst xor shift ,(1- elements-per-word))
208 ,@(unless (= bits 1)
209 `((inst sll shift ,(1- (integer-length bits)))))
210 (unless (and (sc-is value immediate)
211 (= (tn-value value) ,(1- (ash 1 bits))))
212 (inst li temp ,(1- (ash 1 bits)))
213 (inst sll temp shift)
214 (inst not temp)
215 (inst and old temp))
216 (unless (sc-is value zero)
217 (sc-case value
218 (immediate
219 (inst li temp (logand (tn-value value) ,(1- (ash 1 bits)))))
220 (unsigned-reg
221 (inst and temp value ,(1- (ash 1 bits)))))
222 (inst sll temp shift)
223 (inst or old temp))
224 (inst st old object offset)
225 (sc-case value
226 (immediate
227 (inst li result (tn-value value)))
229 (move result value)))))
230 (define-vop (,(symbolicate "DATA-VECTOR-SET-C/" type))
231 (:translate data-vector-set)
232 (:policy :fast-safe)
233 (:args (object :scs (descriptor-reg))
234 (value :scs (unsigned-reg zero immediate) :target result))
235 (:arg-types ,type
236 (:constant index)
237 positive-fixnum)
238 (:info index)
239 (:results (result :scs (unsigned-reg)))
240 (:result-types positive-fixnum)
241 (:temporary (:scs (non-descriptor-reg)) offset-reg temp old)
242 (:generator 20
243 (multiple-value-bind (word extra) (floor index ,elements-per-word)
244 (let ((offset (- (* (+ word vector-data-offset) n-word-bytes)
245 other-pointer-lowtag)))
246 (cond ((typep offset '(signed-byte 13))
247 (inst ld old object offset))
249 (inst li offset-reg offset)
250 (inst ld old object offset-reg)))
251 (unless (and (sc-is value immediate)
252 (= (tn-value value) ,(1- (ash 1 bits))))
253 (cond ((zerop extra)
254 (inst sll old ,bits)
255 (inst srl old ,bits))
257 (inst li temp
258 (lognot (ash ,(1- (ash 1 bits))
259 (* (logxor extra
260 ,(1- elements-per-word))
261 ,bits))))
262 (inst and old temp))))
263 (sc-case value
264 (zero)
265 (immediate
266 (let ((value (ash (logand (tn-value value)
267 ,(1- (ash 1 bits)))
268 (* (logxor extra
269 ,(1- elements-per-word))
270 ,bits))))
271 (cond ((typep value '(signed-byte 13))
272 (inst or old value))
274 (inst li temp value)
275 (inst or old temp)))))
276 (unsigned-reg
277 (inst sll temp value
278 (* (logxor extra ,(1- elements-per-word)) ,bits))
279 (inst or old temp)))
280 (if (typep offset '(signed-byte 13))
281 (inst st old object offset)
282 (inst st old object offset-reg)))
283 (sc-case value
284 (immediate
285 (inst li result (tn-value value)))
287 (move result value))))))))))
289 (def-small-data-vector-frobs simple-bit-vector 1)
290 (def-small-data-vector-frobs simple-array-unsigned-byte-2 2)
291 (def-small-data-vector-frobs simple-array-unsigned-byte-4 4))
293 ;;; And the float variants.
294 (define-vop (data-vector-ref/simple-array-single-float)
295 (:note "inline array access")
296 (:translate data-vector-ref)
297 (:policy :fast-safe)
298 (:args (object :scs (descriptor-reg))
299 (index :scs (any-reg)))
300 (:arg-types simple-array-single-float positive-fixnum)
301 (:results (value :scs (single-reg)))
302 (:temporary (:scs (non-descriptor-reg)) offset)
303 (:result-types single-float)
304 (:generator 5
305 (inst add offset index (- (* vector-data-offset n-word-bytes)
306 other-pointer-lowtag))
307 (inst ldf value object offset)))
310 (define-vop (data-vector-set/simple-array-single-float)
311 (:note "inline array store")
312 (:translate data-vector-set)
313 (:policy :fast-safe)
314 (:args (object :scs (descriptor-reg))
315 (index :scs (any-reg))
316 (value :scs (single-reg) :target result))
317 (:arg-types simple-array-single-float positive-fixnum single-float)
318 (:results (result :scs (single-reg)))
319 (:result-types single-float)
320 (:temporary (:scs (non-descriptor-reg)) offset)
321 (:generator 5
322 (inst add offset index
323 (- (* vector-data-offset n-word-bytes)
324 other-pointer-lowtag))
325 (inst stf value object offset)
326 (unless (location= result value)
327 (inst fmovs result value))))
329 (define-vop (data-vector-ref/simple-array-double-float)
330 (:note "inline array access")
331 (:translate data-vector-ref)
332 (:policy :fast-safe)
333 (:args (object :scs (descriptor-reg))
334 (index :scs (any-reg)))
335 (:arg-types simple-array-double-float positive-fixnum)
336 (:results (value :scs (double-reg)))
337 (:result-types double-float)
338 (:temporary (:scs (non-descriptor-reg)) offset)
339 (:generator 7
340 (inst sll offset index 1)
341 (inst add offset (- (* vector-data-offset n-word-bytes)
342 other-pointer-lowtag))
343 (inst lddf value object offset)))
345 (define-vop (data-vector-set/simple-array-double-float)
346 (:note "inline array store")
347 (:translate data-vector-set)
348 (:policy :fast-safe)
349 (:args (object :scs (descriptor-reg))
350 (index :scs (any-reg))
351 (value :scs (double-reg) :target result))
352 (:arg-types simple-array-double-float positive-fixnum double-float)
353 (:results (result :scs (double-reg)))
354 (:result-types double-float)
355 (:temporary (:scs (non-descriptor-reg)) offset)
356 (:generator 20
357 (inst sll offset index 1)
358 (inst add offset (- (* vector-data-offset n-word-bytes)
359 other-pointer-lowtag))
360 (inst stdf value object offset)
361 (unless (location= result value)
362 (move-double-reg result value))))
364 #!+long-float
365 (define-vop (data-vector-ref/simple-array-long-float)
366 (:note "inline array access")
367 (:translate data-vector-ref)
368 (:policy :fast-safe)
369 (:args (object :scs (descriptor-reg))
370 (index :scs (any-reg)))
371 (:arg-types simple-array-long-float positive-fixnum)
372 (:results (value :scs (long-reg)))
373 (:result-types long-float)
374 (:temporary (:scs (non-descriptor-reg)) offset)
375 (:generator 7
376 (inst sll offset index 2)
377 (inst add offset (- (* vector-data-offset n-word-bytes)
378 other-pointer-lowtag))
379 (load-long-reg value object offset nil)))
381 #!+long-float
382 (define-vop (data-vector-set/simple-array-long-float)
383 (:note "inline array store")
384 (:translate data-vector-set)
385 (:policy :fast-safe)
386 (:args (object :scs (descriptor-reg))
387 (index :scs (any-reg))
388 (value :scs (long-reg) :target result))
389 (:arg-types simple-array-long-float positive-fixnum long-float)
390 (:results (result :scs (long-reg)))
391 (:result-types long-float)
392 (:temporary (:scs (non-descriptor-reg)) offset)
393 (:generator 20
394 (inst sll offset index 2)
395 (inst add offset (- (* vector-data-offset n-word-bytes)
396 other-pointer-lowtag))
397 (store-long-reg value object offset nil)
398 (unless (location= result value)
399 (move-long-reg result value))))
402 ;;;; Misc. Array VOPs.
405 #+nil
406 (define-vop (vector-word-length)
407 (:args (vec :scs (descriptor-reg)))
408 (:results (res :scs (any-reg descriptor-reg)))
409 (:generator 6
410 (loadw res vec clc::g-vector-header-words)
411 (inst niuo res res clc::g-vector-words-mask-16)))
413 (define-vop (get-vector-subtype get-header-data))
414 (define-vop (set-vector-subtype set-header-data))
417 ;;; XXX FIXME: Don't we have these above, in DEF-DATA-VECTOR-FROBS?
418 (define-vop (data-vector-ref/simple-array-signed-byte-8 signed-byte-index-ref)
419 (:note "inline array access")
420 (:variant vector-data-offset other-pointer-lowtag)
421 (:translate data-vector-ref)
422 (:arg-types simple-array-signed-byte-8 positive-fixnum)
423 (:results (value :scs (signed-reg)))
424 (:result-types tagged-num))
426 (define-vop (data-vector-set/simple-array-signed-byte-8 byte-index-set)
427 (:note "inline array store")
428 (:variant vector-data-offset other-pointer-lowtag)
429 (:translate data-vector-set)
430 (:arg-types simple-array-signed-byte-8 positive-fixnum tagged-num)
431 (:args (object :scs (descriptor-reg))
432 (index :scs (any-reg zero immediate))
433 (value :scs (signed-reg)))
434 (:results (result :scs (signed-reg)))
435 (:result-types tagged-num))
438 (define-vop (data-vector-ref/simple-array-signed-byte-16
439 signed-halfword-index-ref)
440 (:note "inline array access")
441 (:variant vector-data-offset other-pointer-lowtag)
442 (:translate data-vector-ref)
443 (:arg-types simple-array-signed-byte-16 positive-fixnum)
444 (:results (value :scs (signed-reg)))
445 (:result-types tagged-num))
447 (define-vop (data-vector-set/simple-array-signed-byte-16 halfword-index-set)
448 (:note "inline array store")
449 (:variant vector-data-offset other-pointer-lowtag)
450 (:translate data-vector-set)
451 (:arg-types simple-array-signed-byte-16 positive-fixnum tagged-num)
452 (:args (object :scs (descriptor-reg))
453 (index :scs (any-reg zero immediate))
454 (value :scs (signed-reg)))
455 (:results (result :scs (signed-reg)))
456 (:result-types tagged-num))
459 ;;; Complex float arrays.
461 (define-vop (data-vector-ref/simple-array-complex-single-float)
462 (:note "inline array access")
463 (:translate data-vector-ref)
464 (:policy :fast-safe)
465 (:args (object :scs (descriptor-reg) :to :result)
466 (index :scs (any-reg)))
467 (:arg-types simple-array-complex-single-float positive-fixnum)
468 (:results (value :scs (complex-single-reg)))
469 (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) offset)
470 (:result-types complex-single-float)
471 (:generator 5
472 (let ((real-tn (complex-single-reg-real-tn value)))
473 (inst sll offset index 1)
474 (inst add offset (- (* vector-data-offset n-word-bytes)
475 other-pointer-lowtag))
476 (inst ldf real-tn object offset))
477 (let ((imag-tn (complex-single-reg-imag-tn value)))
478 (inst add offset n-word-bytes)
479 (inst ldf imag-tn object offset))))
481 (define-vop (data-vector-set/simple-array-complex-single-float)
482 (:note "inline array store")
483 (:translate data-vector-set)
484 (:policy :fast-safe)
485 (:args (object :scs (descriptor-reg) :to :result)
486 (index :scs (any-reg))
487 (value :scs (complex-single-reg) :target result))
488 (:arg-types simple-array-complex-single-float positive-fixnum
489 complex-single-float)
490 (:results (result :scs (complex-single-reg)))
491 (:result-types complex-single-float)
492 (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) offset)
493 (:generator 5
494 (let ((value-real (complex-single-reg-real-tn value))
495 (result-real (complex-single-reg-real-tn result)))
496 (inst sll offset index 1)
497 (inst add offset (- (* vector-data-offset n-word-bytes)
498 other-pointer-lowtag))
499 (inst stf value-real object offset)
500 (unless (location= result-real value-real)
501 (inst fmovs result-real value-real)))
502 (let ((value-imag (complex-single-reg-imag-tn value))
503 (result-imag (complex-single-reg-imag-tn result)))
504 (inst add offset n-word-bytes)
505 (inst stf value-imag object offset)
506 (unless (location= result-imag value-imag)
507 (inst fmovs result-imag value-imag)))))
509 (define-vop (data-vector-ref/simple-array-complex-double-float)
510 (:note "inline array access")
511 (:translate data-vector-ref)
512 (:policy :fast-safe)
513 (:args (object :scs (descriptor-reg) :to :result)
514 (index :scs (any-reg)))
515 (:arg-types simple-array-complex-double-float positive-fixnum)
516 (:results (value :scs (complex-double-reg)))
517 (:result-types complex-double-float)
518 (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) offset)
519 (:generator 7
520 (let ((real-tn (complex-double-reg-real-tn value)))
521 (inst sll offset index 2)
522 (inst add offset (- (* vector-data-offset n-word-bytes)
523 other-pointer-lowtag))
524 (inst lddf real-tn object offset))
525 (let ((imag-tn (complex-double-reg-imag-tn value)))
526 (inst add offset (* 2 n-word-bytes))
527 (inst lddf imag-tn object offset))))
529 (define-vop (data-vector-set/simple-array-complex-double-float)
530 (:note "inline array store")
531 (:translate data-vector-set)
532 (:policy :fast-safe)
533 (:args (object :scs (descriptor-reg) :to :result)
534 (index :scs (any-reg))
535 (value :scs (complex-double-reg) :target result))
536 (:arg-types simple-array-complex-double-float positive-fixnum
537 complex-double-float)
538 (:results (result :scs (complex-double-reg)))
539 (:result-types complex-double-float)
540 (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) offset)
541 (:generator 20
542 (let ((value-real (complex-double-reg-real-tn value))
543 (result-real (complex-double-reg-real-tn result)))
544 (inst sll offset index 2)
545 (inst add offset (- (* vector-data-offset n-word-bytes)
546 other-pointer-lowtag))
547 (inst stdf value-real object offset)
548 (unless (location= result-real value-real)
549 (move-double-reg result-real value-real)))
550 (let ((value-imag (complex-double-reg-imag-tn value))
551 (result-imag (complex-double-reg-imag-tn result)))
552 (inst add offset (* 2 n-word-bytes))
553 (inst stdf value-imag object offset)
554 (unless (location= result-imag value-imag)
555 (move-double-reg result-imag value-imag)))))
557 #!+long-float
558 (define-vop (data-vector-ref/simple-array-complex-long-float)
559 (:note "inline array access")
560 (:translate data-vector-ref)
561 (:policy :fast-safe)
562 (:args (object :scs (descriptor-reg) :to :result)
563 (index :scs (any-reg)))
564 (:arg-types simple-array-complex-long-float positive-fixnum)
565 (:results (value :scs (complex-long-reg)))
566 (:result-types complex-long-float)
567 (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) offset)
568 (:generator 7
569 (let ((real-tn (complex-long-reg-real-tn value)))
570 (inst sll offset index 3)
571 (inst add offset (- (* vector-data-offset n-word-bytes)
572 other-pointer-lowtag))
573 (load-long-reg real-tn object offset nil))
574 (let ((imag-tn (complex-long-reg-imag-tn value)))
575 (inst add offset (* 4 n-word-bytes))
576 (load-long-reg imag-tn object offset nil))))
578 #!+long-float
579 (define-vop (data-vector-set/simple-array-complex-long-float)
580 (:note "inline array store")
581 (:translate data-vector-set)
582 (:policy :fast-safe)
583 (:args (object :scs (descriptor-reg) :to :result)
584 (index :scs (any-reg))
585 (value :scs (complex-long-reg) :target result))
586 (:arg-types simple-array-complex-long-float positive-fixnum
587 complex-long-float)
588 (:results (result :scs (complex-long-reg)))
589 (:result-types complex-long-float)
590 (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) offset)
591 (:generator 20
592 (let ((value-real (complex-long-reg-real-tn value))
593 (result-real (complex-long-reg-real-tn result)))
594 (inst sll offset index 3)
595 (inst add offset (- (* vector-data-offset n-word-bytes)
596 other-pointer-lowtag))
597 (store-long-reg value-real object offset nil)
598 (unless (location= result-real value-real)
599 (move-long-reg result-real value-real)))
600 (let ((value-imag (complex-long-reg-imag-tn value))
601 (result-imag (complex-long-reg-imag-tn result)))
602 (inst add offset (* 4 n-word-bytes))
603 (store-long-reg value-imag object offset nil)
604 (unless (location= result-imag value-imag)
605 (move-long-reg result-imag value-imag)))))
608 ;;; These vops are useful for accessing the bits of a vector irrespective of
609 ;;; what type of vector it is.
610 (define-vop (raw-bits word-index-ref)
611 (:note "raw-bits VOP")
612 (:translate %raw-bits)
613 (:results (value :scs (unsigned-reg)))
614 (:result-types unsigned-num)
615 (:variant 0 other-pointer-lowtag))
617 (define-vop (set-raw-bits word-index-set)
618 (:note "setf raw-bits VOP")
619 (:translate %set-raw-bits)
620 (:args (object :scs (descriptor-reg))
621 (index :scs (any-reg zero immediate))
622 (value :scs (unsigned-reg)))
623 (:arg-types * tagged-num unsigned-num)
624 (:results (result :scs (unsigned-reg)))
625 (:result-types unsigned-num)
626 (:variant 0 other-pointer-lowtag))
628 (define-vop (vector-raw-bits word-index-ref)
629 (:note "vector-raw-bits VOP")
630 (:translate %vector-raw-bits)
631 (:results (value :scs (unsigned-reg)))
632 (:result-types unsigned-num)
633 (:variant vector-data-offset other-pointer-lowtag))
635 (define-vop (set-vector-raw-bits word-index-set)
636 (:note "setf vector-raw-bits VOP")
637 (:translate %set-vector-raw-bits)
638 (:args (object :scs (descriptor-reg))
639 (index :scs (any-reg zero immediate))
640 (value :scs (unsigned-reg)))
641 (:arg-types * tagged-num unsigned-num)
642 (:results (result :scs (unsigned-reg)))
643 (:result-types unsigned-num)
644 (:variant vector-data-offset other-pointer-lowtag))