1 ;;;; the Sparc definitions for array operations
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.
15 (define-vop (make-array-header)
16 (:translate make-array-header
)
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 (:temporary
(:scs
(non-descriptor-reg)) gencgc-temp
)
24 (:results
(result :scs
(descriptor-reg)))
27 (inst add ndescr rank
(+ (* array-dimensions-offset n-word-bytes
)
29 (inst andn ndescr lowtag-mask
)
30 (allocation header ndescr other-pointer-lowtag
:temp-tn gencgc-temp
)
31 (inst add ndescr rank
(fixnumize (1- array-dimensions-offset
)))
32 (inst sll ndescr ndescr n-widetag-bits
)
33 (inst or ndescr ndescr type
)
34 ;; Remove the extraneous fixnum tag bits because TYPE and RANK
36 (inst srl ndescr ndescr n-fixnum-tag-bits
)
37 (storew ndescr header
0 other-pointer-lowtag
))
38 (move result header
)))
40 ;;;; Additional accessors and setters for the array header.
41 (define-vop (%array-dimension word-index-ref
)
42 (:translate %array-dimension
)
44 (:variant array-dimensions-offset other-pointer-lowtag
))
46 (define-vop (%set-array-dimension word-index-set
)
47 (:translate %set-array-dimension
)
49 (:variant array-dimensions-offset other-pointer-lowtag
))
51 (define-vop (array-rank-vop)
52 (:translate %array-rank
)
54 (:args
(x :scs
(descriptor-reg)))
55 (:temporary
(:scs
(non-descriptor-reg)) temp
)
56 (:results
(res :scs
(any-reg descriptor-reg
)))
58 (loadw temp x
0 other-pointer-lowtag
)
59 (inst sra temp n-widetag-bits
)
60 (inst sub temp
(1- array-dimensions-offset
))
61 (inst sll res temp n-fixnum-tag-bits
)))
63 ;;;; Bounds checking routine.
64 (define-vop (check-bound)
65 (:translate %check-bound
)
67 (:args
(array :scs
(descriptor-reg))
68 (bound :scs
(any-reg descriptor-reg
))
69 (index :scs
(any-reg descriptor-reg
)))
71 (:save-p
:compute-only
)
73 (let ((error (generate-error-code vop
'invalid-array-index-error
75 (%test-fixnum index error t
)
76 (inst cmp index bound
)
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
)
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
))
104 (:results
(result :scs
,scs
))
105 (:result-types
,element-type
)))))
107 (def-data-vector-frobs simple-base-string byte-index
108 character character-reg
)
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-fixnum word-index
129 positive-fixnum any-reg
)
130 (def-data-vector-frobs simple-array-fixnum word-index
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
))))
141 (define-vop (,(symbolicate "DATA-VECTOR-REF/" type
))
142 (:note
"inline array access")
143 (:translate data-vector-ref
)
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
)
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
))
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
)
167 (:args
(object :scs
(descriptor-reg)))
168 (:arg-types
,type
(:constant index
))
170 (:results
(result :scs
(unsigned-reg)))
171 (:result-types positive-fixnum
)
172 (:temporary
(:scs
(non-descriptor-reg)) temp
)
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
)
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
)
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
))
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
)
216 (unless (sc-is value zero
)
219 (inst li temp
(logand (tn-value value
) ,(1- (ash 1 bits
)))))
221 (inst and temp value
,(1- (ash 1 bits
)))))
222 (inst sll temp shift
)
224 (inst st old object offset
)
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
)
233 (:args
(object :scs
(descriptor-reg))
234 (value :scs
(unsigned-reg zero immediate
) :target result
))
239 (:results
(result :scs
(unsigned-reg)))
240 (:result-types positive-fixnum
)
241 (:temporary
(:scs
(non-descriptor-reg)) offset-reg temp old
)
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
))))
255 (inst srl old
,bits
))
258 (lognot (ash ,(1- (ash 1 bits
))
260 ,(1- elements-per-word
))
262 (inst and old temp
))))
266 (let ((value (ash (logand (tn-value value
)
269 ,(1- elements-per-word
))
271 (cond ((typep value
'(signed-byte 13))
275 (inst or old temp
)))))
278 (* (logxor extra
,(1- elements-per-word
)) ,bits
))
280 (if (typep offset
'(signed-byte 13))
281 (inst st old object offset
)
282 (inst st old object offset-reg
)))
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
))))
365 (define-vop (data-vector-ref/simple-array-long-float
)
366 (:note
"inline array access")
367 (:translate data-vector-ref
)
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
)
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
)))
382 (define-vop (data-vector-set/simple-array-long-float
)
383 (:note
"inline array store")
384 (:translate data-vector-set
)
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
)
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 ;;; XXX FIXME: Don't we have these above, in DEF-DATA-VECTOR-FROBS?
403 (define-vop (data-vector-ref/simple-array-signed-byte-8 signed-byte-index-ref
)
404 (:note
"inline array access")
405 (:variant vector-data-offset other-pointer-lowtag
)
406 (:translate data-vector-ref
)
407 (:arg-types simple-array-signed-byte-8 positive-fixnum
)
408 (:results
(value :scs
(signed-reg)))
409 (:result-types tagged-num
))
411 (define-vop (data-vector-set/simple-array-signed-byte-8 byte-index-set
)
412 (:note
"inline array store")
413 (:variant vector-data-offset other-pointer-lowtag
)
414 (:translate data-vector-set
)
415 (:arg-types simple-array-signed-byte-8 positive-fixnum tagged-num
)
416 (:args
(object :scs
(descriptor-reg))
417 (index :scs
(any-reg zero immediate
))
418 (value :scs
(signed-reg)))
419 (:results
(result :scs
(signed-reg)))
420 (:result-types tagged-num
))
423 (define-vop (data-vector-ref/simple-array-signed-byte-16
424 signed-halfword-index-ref
)
425 (:note
"inline array access")
426 (:variant vector-data-offset other-pointer-lowtag
)
427 (:translate data-vector-ref
)
428 (:arg-types simple-array-signed-byte-16 positive-fixnum
)
429 (:results
(value :scs
(signed-reg)))
430 (:result-types tagged-num
))
432 (define-vop (data-vector-set/simple-array-signed-byte-16 halfword-index-set
)
433 (:note
"inline array store")
434 (:variant vector-data-offset other-pointer-lowtag
)
435 (:translate data-vector-set
)
436 (:arg-types simple-array-signed-byte-16 positive-fixnum tagged-num
)
437 (:args
(object :scs
(descriptor-reg))
438 (index :scs
(any-reg zero immediate
))
439 (value :scs
(signed-reg)))
440 (:results
(result :scs
(signed-reg)))
441 (:result-types tagged-num
))
444 ;;; Complex float arrays.
446 (define-vop (data-vector-ref/simple-array-complex-single-float
)
447 (:note
"inline array access")
448 (:translate data-vector-ref
)
450 (:args
(object :scs
(descriptor-reg) :to
:result
)
451 (index :scs
(any-reg)))
452 (:arg-types simple-array-complex-single-float positive-fixnum
)
453 (:results
(value :scs
(complex-single-reg)))
454 (:temporary
(:scs
(non-descriptor-reg) :from
(:argument
1)) offset
)
455 (:result-types complex-single-float
)
457 (let ((real-tn (complex-single-reg-real-tn value
)))
458 (inst sll offset index
1)
459 (inst add offset
(- (* vector-data-offset n-word-bytes
)
460 other-pointer-lowtag
))
461 (inst ldf real-tn object offset
))
462 (let ((imag-tn (complex-single-reg-imag-tn value
)))
463 (inst add offset n-word-bytes
)
464 (inst ldf imag-tn object offset
))))
466 (define-vop (data-vector-set/simple-array-complex-single-float
)
467 (:note
"inline array store")
468 (:translate data-vector-set
)
470 (:args
(object :scs
(descriptor-reg) :to
:result
)
471 (index :scs
(any-reg))
472 (value :scs
(complex-single-reg) :target result
))
473 (:arg-types simple-array-complex-single-float positive-fixnum
474 complex-single-float
)
475 (:results
(result :scs
(complex-single-reg)))
476 (:result-types complex-single-float
)
477 (:temporary
(:scs
(non-descriptor-reg) :from
(:argument
1)) offset
)
479 (let ((value-real (complex-single-reg-real-tn value
))
480 (result-real (complex-single-reg-real-tn result
)))
481 (inst sll offset index
1)
482 (inst add offset
(- (* vector-data-offset n-word-bytes
)
483 other-pointer-lowtag
))
484 (inst stf value-real object offset
)
485 (unless (location= result-real value-real
)
486 (inst fmovs result-real value-real
)))
487 (let ((value-imag (complex-single-reg-imag-tn value
))
488 (result-imag (complex-single-reg-imag-tn result
)))
489 (inst add offset n-word-bytes
)
490 (inst stf value-imag object offset
)
491 (unless (location= result-imag value-imag
)
492 (inst fmovs result-imag value-imag
)))))
494 (define-vop (data-vector-ref/simple-array-complex-double-float
)
495 (:note
"inline array access")
496 (:translate data-vector-ref
)
498 (:args
(object :scs
(descriptor-reg) :to
:result
)
499 (index :scs
(any-reg)))
500 (:arg-types simple-array-complex-double-float positive-fixnum
)
501 (:results
(value :scs
(complex-double-reg)))
502 (:result-types complex-double-float
)
503 (:temporary
(:scs
(non-descriptor-reg) :from
(:argument
1)) offset
)
505 (let ((real-tn (complex-double-reg-real-tn value
)))
506 (inst sll offset index
2)
507 (inst add offset
(- (* vector-data-offset n-word-bytes
)
508 other-pointer-lowtag
))
509 (inst lddf real-tn object offset
))
510 (let ((imag-tn (complex-double-reg-imag-tn value
)))
511 (inst add offset
(* 2 n-word-bytes
))
512 (inst lddf imag-tn object offset
))))
514 (define-vop (data-vector-set/simple-array-complex-double-float
)
515 (:note
"inline array store")
516 (:translate data-vector-set
)
518 (:args
(object :scs
(descriptor-reg) :to
:result
)
519 (index :scs
(any-reg))
520 (value :scs
(complex-double-reg) :target result
))
521 (:arg-types simple-array-complex-double-float positive-fixnum
522 complex-double-float
)
523 (:results
(result :scs
(complex-double-reg)))
524 (:result-types complex-double-float
)
525 (:temporary
(:scs
(non-descriptor-reg) :from
(:argument
1)) offset
)
527 (let ((value-real (complex-double-reg-real-tn value
))
528 (result-real (complex-double-reg-real-tn result
)))
529 (inst sll offset index
2)
530 (inst add offset
(- (* vector-data-offset n-word-bytes
)
531 other-pointer-lowtag
))
532 (inst stdf value-real object offset
)
533 (unless (location= result-real value-real
)
534 (move-double-reg result-real value-real
)))
535 (let ((value-imag (complex-double-reg-imag-tn value
))
536 (result-imag (complex-double-reg-imag-tn result
)))
537 (inst add offset
(* 2 n-word-bytes
))
538 (inst stdf value-imag object offset
)
539 (unless (location= result-imag value-imag
)
540 (move-double-reg result-imag value-imag
)))))
543 (define-vop (data-vector-ref/simple-array-complex-long-float
)
544 (:note
"inline array access")
545 (:translate data-vector-ref
)
547 (:args
(object :scs
(descriptor-reg) :to
:result
)
548 (index :scs
(any-reg)))
549 (:arg-types simple-array-complex-long-float positive-fixnum
)
550 (:results
(value :scs
(complex-long-reg)))
551 (:result-types complex-long-float
)
552 (:temporary
(:scs
(non-descriptor-reg) :from
(:argument
1)) offset
)
554 (let ((real-tn (complex-long-reg-real-tn value
)))
555 (inst sll offset index
3)
556 (inst add offset
(- (* vector-data-offset n-word-bytes
)
557 other-pointer-lowtag
))
558 (load-long-reg real-tn object offset nil
))
559 (let ((imag-tn (complex-long-reg-imag-tn value
)))
560 (inst add offset
(* 4 n-word-bytes
))
561 (load-long-reg imag-tn object offset nil
))))
564 (define-vop (data-vector-set/simple-array-complex-long-float
)
565 (:note
"inline array store")
566 (:translate data-vector-set
)
568 (:args
(object :scs
(descriptor-reg) :to
:result
)
569 (index :scs
(any-reg))
570 (value :scs
(complex-long-reg) :target result
))
571 (:arg-types simple-array-complex-long-float positive-fixnum
573 (:results
(result :scs
(complex-long-reg)))
574 (:result-types complex-long-float
)
575 (:temporary
(:scs
(non-descriptor-reg) :from
(:argument
1)) offset
)
577 (let ((value-real (complex-long-reg-real-tn value
))
578 (result-real (complex-long-reg-real-tn result
)))
579 (inst sll offset index
3)
580 (inst add offset
(- (* vector-data-offset n-word-bytes
)
581 other-pointer-lowtag
))
582 (store-long-reg value-real object offset nil
)
583 (unless (location= result-real value-real
)
584 (move-long-reg result-real value-real
)))
585 (let ((value-imag (complex-long-reg-imag-tn value
))
586 (result-imag (complex-long-reg-imag-tn result
)))
587 (inst add offset
(* 4 n-word-bytes
))
588 (store-long-reg value-imag object offset nil
)
589 (unless (location= result-imag value-imag
)
590 (move-long-reg result-imag value-imag
)))))
593 ;;; These vops are useful for accessing the bits of a vector irrespective of
594 ;;; what type of vector it is.
595 (define-vop (vector-raw-bits word-index-ref
)
596 (:note
"vector-raw-bits VOP")
597 (:translate %vector-raw-bits
)
598 (:results
(value :scs
(unsigned-reg)))
599 (:result-types unsigned-num
)
600 (:variant vector-data-offset other-pointer-lowtag
))
602 (define-vop (set-vector-raw-bits word-index-set
)
603 (:note
"setf vector-raw-bits VOP")
604 (:translate %set-vector-raw-bits
)
605 (:args
(object :scs
(descriptor-reg))
606 (index :scs
(any-reg zero immediate
))
607 (value :scs
(unsigned-reg)))
608 (:arg-types
* tagged-num unsigned-num
)
609 (:results
(result :scs
(unsigned-reg)))
610 (:result-types unsigned-num
)
611 (:variant vector-data-offset other-pointer-lowtag
))