1 ;;;; the VM definition of various primitive memory access VOPs for the
4 ;;;; This software is part of the SBCL system. See the README file for
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
15 ;;;; Data object ref/set stuff.
18 (:args (object :scs (descriptor-reg)))
19 (:info name offset lowtag)
21 (:results (result :scs (descriptor-reg any-reg)))
23 (loadw result object offset lowtag)))
25 (define-vop (set-slot)
26 (:args (object :scs (descriptor-reg))
27 (value :scs (descriptor-reg any-reg)))
28 (:info name offset lowtag)
32 (storew value object offset lowtag)))
35 ;;;; Symbol hacking VOPs:
37 ;;; The compiler likes to be able to directly SET symbols.
38 (define-vop (%set-symbol-global-value cell-set)
39 (:variant symbol-value-slot other-pointer-lowtag))
41 ;;; Do a cell ref with an error check for being unbound.
42 (define-vop (checked-cell-ref)
43 (:args (object :scs (descriptor-reg) :target obj-temp))
44 (:results (value :scs (descriptor-reg any-reg)))
47 (:save-p :compute-only)
48 (:temporary (:scs (descriptor-reg) :from (:argument 0)) obj-temp))
50 ;;; With SYMBOL-VALUE, we check that the value isn't the trap object.
51 ;;; So SYMBOL-VALUE of NIL is NIL.
52 (define-vop (symbol-global-value checked-cell-ref)
53 (:translate symbol-global-value)
55 (move obj-temp object)
56 (loadw value obj-temp symbol-value-slot other-pointer-lowtag)
57 (let ((err-lab (generate-error-code vop 'unbound-symbol-error obj-temp)))
58 (inst cmpwi value unbound-marker-widetag)
61 (define-vop (fast-symbol-global-value cell-ref)
62 (:variant symbol-value-slot other-pointer-lowtag)
64 (:translate symbol-global-value))
69 (:args (symbol :scs (descriptor-reg))
70 (value :scs (descriptor-reg any-reg)))
71 (:temporary (:sc any-reg) tls-slot temp)
73 (loadw tls-slot symbol symbol-tls-index-slot other-pointer-lowtag)
74 (inst lwzx temp thread-base-tn tls-slot)
75 (inst cmpwi temp no-tls-value-marker-widetag)
76 (inst beq GLOBAL-VALUE)
77 (inst stwx value thread-base-tn tls-slot)
80 (storew value symbol symbol-value-slot other-pointer-lowtag)
83 ;; With Symbol-Value, we check that the value isn't the trap object. So
84 ;; Symbol-Value of NIL is NIL.
85 (define-vop (symbol-value)
86 (:translate symbol-value)
88 (:args (object :scs (descriptor-reg) :to (:result 1)))
89 (:results (value :scs (descriptor-reg any-reg)))
91 (:save-p :compute-only)
93 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
94 (inst lwzx value thread-base-tn value)
95 (inst cmpwi value no-tls-value-marker-widetag)
96 (inst bne CHECK-UNBOUND)
97 (loadw value object symbol-value-slot other-pointer-lowtag)
99 (inst cmpwi value unbound-marker-widetag)
100 (inst beq (generate-error-code vop 'unbound-symbol-error object))))
102 (define-vop (fast-symbol-value symbol-value)
103 ;; KLUDGE: not really fast, in fact, because we're going to have to
104 ;; do a full lookup of the thread-local area anyway. But half of
105 ;; the meaning of FAST-SYMBOL-VALUE is "do not signal an error if
106 ;; unbound", which is used in the implementation of COPY-SYMBOL. --
109 (:translate symbol-value)
111 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
112 (inst lwzx value thread-base-tn value)
113 (inst cmpwi value no-tls-value-marker-widetag)
115 (loadw value object symbol-value-slot other-pointer-lowtag)
118 ;;; On unithreaded builds these are just copies of the global versions.
121 (define-vop (symbol-value symbol-global-value)
122 (:translate symbol-value))
123 (define-vop (fast-symbol-value fast-symbol-global-value)
124 (:translate symbol-value))
125 (define-vop (set %set-symbol-global-value)))
127 ;;; Like CHECKED-CELL-REF, only we are a predicate to see if the cell
129 (define-vop (boundp-frob)
130 (:args (object :scs (descriptor-reg)))
134 (:temporary (:scs (descriptor-reg)) value))
137 (define-vop (boundp boundp-frob)
140 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
141 (inst lwzx value thread-base-tn value)
142 (inst cmpwi value no-tls-value-marker-widetag)
143 (inst bne CHECK-UNBOUND)
144 (loadw value object symbol-value-slot other-pointer-lowtag)
146 (inst cmpwi value unbound-marker-widetag)
147 (inst b? (if not-p :eq :ne) target)))
150 (define-vop (boundp boundp-frob)
153 (loadw value object symbol-value-slot other-pointer-lowtag)
154 (inst cmpwi value unbound-marker-widetag)
155 (inst b? (if not-p :eq :ne) target)))
157 (define-vop (symbol-hash)
159 (:translate symbol-hash)
160 (:args (symbol :scs (descriptor-reg)))
161 (:results (res :scs (any-reg)))
162 (:result-types positive-fixnum)
164 ;; The symbol-hash slot of NIL holds NIL because it is also the
165 ;; cdr slot, so we have to strip off the two low bits to make sure
166 ;; it is a fixnum. The lowtag selection magic that is required to
167 ;; ensure this is explained in the comment in objdef.lisp
168 (loadw res symbol symbol-hash-slot other-pointer-lowtag)
169 (inst clrrwi res res n-fixnum-tag-bits)))
171 ;;;; Fdefinition (fdefn) objects.
173 (define-vop (fdefn-fun cell-ref)
174 (:variant fdefn-fun-slot other-pointer-lowtag))
176 (define-vop (safe-fdefn-fun)
177 (:args (object :scs (descriptor-reg) :target obj-temp))
178 (:results (value :scs (descriptor-reg any-reg)))
180 (:save-p :compute-only)
181 (:temporary (:scs (descriptor-reg) :from (:argument 0)) obj-temp)
183 (move obj-temp object)
184 (loadw value obj-temp fdefn-fun-slot other-pointer-lowtag)
185 (inst cmpw value null-tn)
186 (let ((err-lab (generate-error-code vop 'undefined-fun-error obj-temp)))
187 (inst beq err-lab))))
189 (define-vop (set-fdefn-fun)
191 (:translate (setf fdefn-fun))
192 (:args (function :scs (descriptor-reg) :target result)
193 (fdefn :scs (descriptor-reg)))
194 (:temporary (:scs (interior-reg)) lip)
195 (:temporary (:scs (non-descriptor-reg)) type)
196 (:results (result :scs (descriptor-reg)))
198 (let ((normal-fn (gen-label)))
199 (load-type type function (- fun-pointer-lowtag))
200 (inst cmpwi type simple-fun-header-widetag)
201 ;;(inst mr lip function)
202 (inst addi lip function
203 (- (ash simple-fun-code-offset word-shift) fun-pointer-lowtag))
205 (inst lr lip (make-fixup "closure_tramp" :foreign))
206 (emit-label normal-fn)
207 (storew lip fdefn fdefn-raw-addr-slot other-pointer-lowtag)
208 (storew function fdefn fdefn-fun-slot other-pointer-lowtag)
209 (move result function))))
211 (define-vop (fdefn-makunbound)
213 (:translate fdefn-makunbound)
214 (:args (fdefn :scs (descriptor-reg) :target result))
215 (:temporary (:scs (non-descriptor-reg)) temp)
216 (:results (result :scs (descriptor-reg)))
218 (storew null-tn fdefn fdefn-fun-slot other-pointer-lowtag)
219 (inst lr temp (make-fixup "undefined_tramp" :foreign))
220 (storew temp fdefn fdefn-raw-addr-slot other-pointer-lowtag)
221 (move result fdefn)))
225 ;;;; Binding and Unbinding.
227 ;;; BIND -- Establish VAL as a binding for SYMBOL. Save the old value and
228 ;;; the symbol on the binding stack and stuff the new value into the
233 (:args (val :scs (any-reg descriptor-reg))
234 (symbol :scs (descriptor-reg)))
235 (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
236 (:temporary (:scs (descriptor-reg)) temp tls-index)
238 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
239 (inst cmpwi tls-index 0)
242 ;; No TLS slot allocated, so allocate one.
243 (pseudo-atomic (pa-flag)
244 (without-scheduling ()
246 (inst li temp (+ (static-symbol-offset '*tls-index-lock*)
247 (ash symbol-value-slot word-shift)
248 (- other-pointer-lowtag)))
250 (inst lwarx tls-index null-tn temp)
251 (inst cmpwi tls-index 0)
252 (inst bne OBTAIN-LOCK)
253 (inst stwcx. thread-base-tn null-tn temp)
254 (inst bne OBTAIN-LOCK)
257 ;; Check to see if the TLS index was set while we were waiting.
258 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
259 (inst cmpwi tls-index 0)
260 (inst bne RELEASE-LOCK)
262 (load-symbol-value tls-index *free-tls-index*)
263 ;; FIXME: Check for TLS index overflow.
264 (inst addi tls-index tls-index n-word-bytes)
265 (store-symbol-value tls-index *free-tls-index*)
266 (inst addi tls-index tls-index (- n-word-bytes))
267 (storew tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
269 ;; The sync instruction doesn't need to happen if we branch
270 ;; directly to RELEASE-LOCK as we didn't do any stores in that
274 (inst stwx zero-tn null-tn temp)
276 ;; temp is a boxed register, but we've been storing crap in it.
277 ;; fix it before we leave pseudo-atomic.
281 (inst lwzx temp thread-base-tn tls-index)
282 (inst addi bsp-tn bsp-tn (* 2 n-word-bytes))
283 (storew temp bsp-tn (- binding-value-slot binding-size))
284 (storew symbol bsp-tn (- binding-symbol-slot binding-size))
285 (inst stwx val thread-base-tn tls-index)))
289 (:args (val :scs (any-reg descriptor-reg))
290 (symbol :scs (descriptor-reg)))
291 (:temporary (:scs (descriptor-reg)) temp)
293 (loadw temp symbol symbol-value-slot other-pointer-lowtag)
294 (inst addi bsp-tn bsp-tn (* 2 n-word-bytes))
295 (storew temp bsp-tn (- binding-value-slot binding-size))
296 (storew symbol bsp-tn (- binding-symbol-slot binding-size))
297 (storew val symbol symbol-value-slot other-pointer-lowtag)))
301 (:temporary (:scs (descriptor-reg)) tls-index value)
303 (loadw tls-index bsp-tn (- binding-symbol-slot binding-size))
304 (loadw tls-index tls-index symbol-tls-index-slot other-pointer-lowtag)
305 (loadw value bsp-tn (- binding-value-slot binding-size))
306 (inst stwx value thread-base-tn tls-index)
307 (storew zero-tn bsp-tn (- binding-symbol-slot binding-size))
308 (storew zero-tn bsp-tn (- binding-value-slot binding-size))
309 (inst subi bsp-tn bsp-tn (* 2 n-word-bytes))))
313 (:temporary (:scs (descriptor-reg)) symbol value)
315 (loadw symbol bsp-tn (- binding-symbol-slot binding-size))
316 (loadw value bsp-tn (- binding-value-slot binding-size))
317 (storew value symbol symbol-value-slot other-pointer-lowtag)
318 (storew zero-tn bsp-tn (- binding-symbol-slot binding-size))
319 (storew zero-tn bsp-tn (- binding-value-slot binding-size))
320 (inst subi bsp-tn bsp-tn (* 2 n-word-bytes))))
323 (define-vop (unbind-to-here)
324 (:args (arg :scs (descriptor-reg any-reg) :target where))
325 (:temporary (:scs (any-reg) :from (:argument 0)) where)
326 (:temporary (:scs (descriptor-reg)) symbol value)
328 (let ((loop (gen-label))
332 (inst cmpw where bsp-tn)
336 (loadw symbol bsp-tn (- binding-symbol-slot binding-size))
337 (inst cmpwi symbol 0)
339 (loadw value bsp-tn (- binding-value-slot binding-size))
341 (loadw symbol symbol symbol-tls-index-slot other-pointer-lowtag)
343 (inst stwx value thread-base-tn symbol)
345 (storew value symbol symbol-value-slot other-pointer-lowtag)
346 (storew zero-tn bsp-tn (- binding-symbol-slot binding-size))
349 (storew zero-tn bsp-tn (- binding-value-slot binding-size))
350 (inst subi bsp-tn bsp-tn (* 2 n-word-bytes))
351 (inst cmpw where bsp-tn)
358 ;;;; Closure indexing.
360 (define-vop (closure-index-ref word-index-ref)
361 (:variant closure-info-offset fun-pointer-lowtag)
362 (:translate %closure-index-ref))
364 (define-vop (funcallable-instance-info word-index-ref)
365 (:variant funcallable-instance-info-offset fun-pointer-lowtag)
366 (:translate %funcallable-instance-info))
368 (define-vop (set-funcallable-instance-info word-index-set)
369 (:variant funcallable-instance-info-offset fun-pointer-lowtag)
370 (:translate %set-funcallable-instance-info))
372 (define-vop (closure-ref slot-ref)
373 (:variant closure-info-offset fun-pointer-lowtag))
375 (define-vop (closure-init slot-set)
376 (:variant closure-info-offset fun-pointer-lowtag))
379 ;;;; Value Cell hackery.
381 (define-vop (value-cell-ref cell-ref)
382 (:variant value-cell-value-slot other-pointer-lowtag))
384 (define-vop (value-cell-set cell-set)
385 (:variant value-cell-value-slot other-pointer-lowtag))
389 ;;;; Instance hackery:
391 (define-vop (instance-length)
393 (:translate %instance-length)
394 (:args (struct :scs (descriptor-reg)))
395 (:temporary (:scs (non-descriptor-reg)) temp)
396 (:results (res :scs (unsigned-reg)))
397 (:result-types positive-fixnum)
399 (loadw temp struct 0 instance-pointer-lowtag)
400 (inst srwi res temp n-widetag-bits)))
402 (define-vop (instance-index-ref word-index-ref)
404 (:translate %instance-ref)
405 (:variant instance-slots-offset instance-pointer-lowtag)
406 (:arg-types instance positive-fixnum))
408 (define-vop (instance-index-set word-index-set)
410 (:translate %instance-set)
411 (:variant instance-slots-offset instance-pointer-lowtag)
412 (:arg-types instance positive-fixnum *))
417 ;;;; Code object frobbing.
419 (define-vop (code-header-ref word-index-ref)
420 (:translate code-header-ref)
422 (:variant 0 other-pointer-lowtag))
424 (define-vop (code-header-set word-index-set)
425 (:translate code-header-set)
427 (:variant 0 other-pointer-lowtag))
431 ;;;; raw instance slot accessors
433 (defun offset-for-raw-slot (instance-length index n-words)
434 (+ (* (- instance-length instance-slots-offset index (1- n-words))
436 (- instance-pointer-lowtag)))
438 (define-vop (raw-instance-init/word)
439 (:args (object :scs (descriptor-reg))
440 (value :scs (unsigned-reg)))
441 (:arg-types * unsigned-num)
442 (:info instance-length index)
444 (inst stw value object (offset-for-raw-slot instance-length index 1))))
446 (define-vop (raw-instance-ref/word)
447 (:translate %raw-instance-ref/word)
449 (:args (object :scs (descriptor-reg))
450 (index :scs (any-reg)))
451 (:arg-types * positive-fixnum)
452 (:results (value :scs (unsigned-reg)))
453 (:temporary (:scs (non-descriptor-reg)) offset)
454 (:result-types unsigned-num)
456 (loadw offset object 0 instance-pointer-lowtag)
457 ;; offset = (offset >> n-widetag-bits) << 2
458 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
459 (inst subf offset index offset)
463 (- (* (1- instance-slots-offset) n-word-bytes)
464 instance-pointer-lowtag))
465 (inst lwzx value object offset)))
467 (define-vop (raw-instance-set/word)
468 (:translate %raw-instance-set/word)
470 (:args (object :scs (descriptor-reg))
471 (index :scs (any-reg))
472 (value :scs (unsigned-reg)))
473 (:arg-types * positive-fixnum unsigned-num)
474 (:results (result :scs (unsigned-reg)))
475 (:temporary (:scs (non-descriptor-reg)) offset)
476 (:result-types unsigned-num)
478 (loadw offset object 0 instance-pointer-lowtag)
479 ;; offset = (offset >> n-widetag-bits) << 2
480 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
481 (inst subf offset index offset)
485 (- (* (1- instance-slots-offset) n-word-bytes)
486 instance-pointer-lowtag))
487 (inst stwx value object offset)
488 (move result value)))
490 (define-vop (raw-instance-init/single)
491 (:args (object :scs (descriptor-reg))
492 (value :scs (single-reg)))
493 (:arg-types * single-float)
494 (:info instance-length index)
496 (inst stfs value object (offset-for-raw-slot instance-length index 1))))
498 (define-vop (raw-instance-ref/single)
499 (:translate %raw-instance-ref/single)
501 (:args (object :scs (descriptor-reg))
502 (index :scs (any-reg)))
503 (:arg-types * positive-fixnum)
504 (:results (value :scs (single-reg)))
505 (:temporary (:scs (non-descriptor-reg)) offset)
506 (:result-types single-float)
508 (loadw offset object 0 instance-pointer-lowtag)
509 ;; offset = (offset >> n-widetag-bits) << 2
510 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
511 (inst subf offset index offset)
515 (- (* (1- instance-slots-offset) n-word-bytes)
516 instance-pointer-lowtag))
517 (inst lfsx value object offset)))
519 (define-vop (raw-instance-set/single)
520 (:translate %raw-instance-set/single)
522 (:args (object :scs (descriptor-reg))
523 (index :scs (any-reg))
524 (value :scs (single-reg) :target result))
525 (:arg-types * positive-fixnum single-float)
526 (:results (result :scs (single-reg)))
527 (:result-types single-float)
528 (:temporary (:scs (non-descriptor-reg)) offset)
530 (loadw offset object 0 instance-pointer-lowtag)
531 ;; offset = (offset >> n-widetag-bits) << 2
532 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
533 (inst subf offset index offset)
537 (- (* (1- instance-slots-offset) n-word-bytes)
538 instance-pointer-lowtag))
539 (inst stfsx value object offset)
540 (unless (location= result value)
541 (inst frsp result value))))
543 (define-vop (raw-instance-init/double)
544 (:args (object :scs (descriptor-reg))
545 (value :scs (double-reg)))
546 (:arg-types * double-float)
547 (:info instance-length index)
549 (inst stfd value object (offset-for-raw-slot instance-length index 2))))
551 (define-vop (raw-instance-ref/double)
552 (:translate %raw-instance-ref/double)
554 (:args (object :scs (descriptor-reg))
555 (index :scs (any-reg)))
556 (:arg-types * positive-fixnum)
557 (:results (value :scs (double-reg)))
558 (:temporary (:scs (non-descriptor-reg)) offset)
559 (:result-types double-float)
561 (loadw offset object 0 instance-pointer-lowtag)
562 ;; offset = (offset >> n-widetag-bits) << 2
563 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
564 (inst subf offset index offset)
568 (- (* (- instance-slots-offset 2) n-word-bytes)
569 instance-pointer-lowtag))
570 (inst lfdx value object offset)))
572 (define-vop (raw-instance-set/double)
573 (:translate %raw-instance-set/double)
575 (:args (object :scs (descriptor-reg))
576 (index :scs (any-reg))
577 (value :scs (double-reg) :target result))
578 (:arg-types * positive-fixnum double-float)
579 (:results (result :scs (double-reg)))
580 (:result-types double-float)
581 (:temporary (:scs (non-descriptor-reg)) offset)
583 (loadw offset object 0 instance-pointer-lowtag)
584 ;; offset = (offset >> n-widetag-bits) << 2
585 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
586 (inst subf offset index offset)
590 (- (* (- instance-slots-offset 2) n-word-bytes)
591 instance-pointer-lowtag))
592 (inst stfdx value object offset)
593 (unless (location= result value)
594 (inst fmr result value))))
596 (define-vop (raw-instance-init/complex-single)
597 (:args (object :scs (descriptor-reg))
598 (value :scs (complex-single-reg)))
599 (:arg-types * complex-single-float)
600 (:info instance-length index)
602 (inst stfs (complex-single-reg-real-tn value)
603 object (offset-for-raw-slot instance-length index 2))
604 (inst stfs (complex-single-reg-imag-tn value)
605 object (offset-for-raw-slot instance-length index 1))))
607 (define-vop (raw-instance-ref/complex-single)
608 (:translate %raw-instance-ref/complex-single)
610 (:args (object :scs (descriptor-reg))
611 (index :scs (any-reg)))
612 (:arg-types * positive-fixnum)
613 (:results (value :scs (complex-single-reg)))
614 (:temporary (:scs (non-descriptor-reg)) offset)
615 (:result-types complex-single-float)
617 (loadw offset object 0 instance-pointer-lowtag)
618 ;; offset = (offset >> n-widetag-bits) << 2
619 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
620 (inst subf offset index offset)
624 (- (* (- instance-slots-offset 2) n-word-bytes)
625 instance-pointer-lowtag))
626 (inst lfsx (complex-single-reg-real-tn value) object offset)
627 (inst addi offset offset n-word-bytes)
628 (inst lfsx (complex-single-reg-imag-tn value) object offset)))
630 (define-vop (raw-instance-set/complex-single)
631 (:translate %raw-instance-set/complex-single)
633 (:args (object :scs (descriptor-reg))
634 (index :scs (any-reg))
635 (value :scs (complex-single-reg) :target result))
636 (:arg-types * positive-fixnum complex-single-float)
637 (:results (result :scs (complex-single-reg)))
638 (:result-types complex-single-float)
639 (:temporary (:scs (non-descriptor-reg)) offset)
641 (loadw offset object 0 instance-pointer-lowtag)
642 ;; offset = (offset >> n-widetag-bits) << 2
643 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
644 (inst subf offset index offset)
648 (- (* (- instance-slots-offset 2) n-word-bytes)
649 instance-pointer-lowtag))
650 (let ((value-real (complex-single-reg-real-tn value))
651 (result-real (complex-single-reg-real-tn result)))
652 (inst stfsx value-real object offset)
653 (unless (location= result-real value-real)
654 (inst frsp result-real value-real)))
655 (inst addi offset offset n-word-bytes)
656 (let ((value-imag (complex-single-reg-imag-tn value))
657 (result-imag (complex-single-reg-imag-tn result)))
658 (inst stfsx value-imag object offset)
659 (unless (location= result-imag value-imag)
660 (inst frsp result-imag value-imag)))))
662 (define-vop (raw-instance-init/complex-double)
663 (:args (object :scs (descriptor-reg))
664 (value :scs (complex-double-reg)))
665 (:arg-types * complex-double-float)
666 (:info instance-length index)
668 (inst stfd (complex-single-reg-real-tn value)
669 object (offset-for-raw-slot instance-length index 4))
670 (inst stfd (complex-double-reg-imag-tn value)
671 object (offset-for-raw-slot instance-length index 2))))
673 (define-vop (raw-instance-ref/complex-double)
674 (:translate %raw-instance-ref/complex-double)
676 (:args (object :scs (descriptor-reg))
677 (index :scs (any-reg)))
678 (:arg-types * positive-fixnum)
679 (:results (value :scs (complex-double-reg)))
680 (:temporary (:scs (non-descriptor-reg)) offset)
681 (:result-types complex-double-float)
683 (loadw offset object 0 instance-pointer-lowtag)
684 ;; offset = (offset >> n-widetag-bits) << 2
685 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
686 (inst subf offset index offset)
690 (- (* (- instance-slots-offset 4) n-word-bytes)
691 instance-pointer-lowtag))
692 (inst lfdx (complex-double-reg-real-tn value) object offset)
693 (inst addi offset offset (* 2 n-word-bytes))
694 (inst lfdx (complex-double-reg-imag-tn value) object offset)))
696 (define-vop (raw-instance-set/complex-double)
697 (:translate %raw-instance-set/complex-double)
699 (:args (object :scs (descriptor-reg))
700 (index :scs (any-reg))
701 (value :scs (complex-double-reg) :target result))
702 (:arg-types * positive-fixnum complex-double-float)
703 (:results (result :scs (complex-double-reg)))
704 (:result-types complex-double-float)
705 (:temporary (:scs (non-descriptor-reg)) offset)
707 (loadw offset object 0 instance-pointer-lowtag)
708 ;; offset = (offset >> n-widetag-bits) << 2
709 (inst rlwinm offset offset (- 32 (- n-widetag-bits 2)) (- n-widetag-bits 2) 29)
710 (inst subf offset index offset)
714 (- (* (- instance-slots-offset 4) n-word-bytes)
715 instance-pointer-lowtag))
716 (let ((value-real (complex-double-reg-real-tn value))
717 (result-real (complex-double-reg-real-tn result)))
718 (inst stfdx value-real object offset)
719 (unless (location= result-real value-real)
720 (inst fmr result-real value-real)))
721 (inst addi offset offset (* 2 n-word-bytes))
722 (let ((value-imag (complex-double-reg-imag-tn value))
723 (result-imag (complex-double-reg-imag-tn result)))
724 (inst stfdx value-imag object offset)
725 (unless (location= result-imag value-imag)
726 (inst fmr result-imag value-imag)))))