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
)))
34 (define-vop (init-slot set-slot
)
35 (:info name dx-p offset lowtag
)
38 #!+compare-and-swap-vops
39 (define-vop (compare-and-swap-slot)
40 (:args
(object :scs
(descriptor-reg))
41 (old :scs
(descriptor-reg any-reg
))
42 (new :scs
(descriptor-reg any-reg
)))
43 (:temporary
(:sc non-descriptor-reg
) temp
)
44 (:info name offset lowtag
)
46 (:results
(result :scs
(descriptor-reg) :from
:load
))
49 (inst li temp
(- (* offset n-word-bytes
) lowtag
))
51 (inst lwarx result temp object
)
52 (inst cmpw result old
)
54 (inst stwcx. new temp object
)
60 ;;;; Symbol hacking VOPs:
62 #!+compare-and-swap-vops
63 (define-vop (%compare-and-swap-symbol-value
)
64 (:translate %compare-and-swap-symbol-value
)
65 (:args
(symbol :scs
(descriptor-reg))
66 (old :scs
(descriptor-reg any-reg
))
67 (new :scs
(descriptor-reg any-reg
)))
68 (:temporary
(:sc non-descriptor-reg
) temp
)
69 (:results
(result :scs
(descriptor-reg any-reg
) :from
:load
))
76 (loadw temp symbol symbol-tls-index-slot other-pointer-lowtag
)
77 ;; Thread-local area, no synchronization needed.
78 (inst lwzx result thread-base-tn temp
)
79 (inst cmpw result old
)
80 (inst bne DONT-STORE-TLS
)
81 (inst stwx new thread-base-tn temp
)
84 (inst cmpwi result no-tls-value-marker-widetag
)
85 (inst bne CHECK-UNBOUND
))
87 (inst li temp
(- (* symbol-value-slot n-word-bytes
)
88 other-pointer-lowtag
))
90 (inst lwarx result symbol temp
)
91 (inst cmpw result old
)
92 (inst bne CHECK-UNBOUND
)
93 (inst stwcx. new symbol temp
)
98 (inst cmpwi result unbound-marker-widetag
)
99 (inst beq
(generate-error-code vop
'unbound-symbol-error symbol
))))
101 ;;; The compiler likes to be able to directly SET symbols.
102 (define-vop (%set-symbol-global-value cell-set
)
103 (:variant symbol-value-slot other-pointer-lowtag
))
105 ;;; Do a cell ref with an error check for being unbound.
106 (define-vop (checked-cell-ref)
107 (:args
(object :scs
(descriptor-reg) :target obj-temp
))
108 (:results
(value :scs
(descriptor-reg any-reg
)))
111 (:save-p
:compute-only
)
112 (:temporary
(:scs
(descriptor-reg) :from
(:argument
0)) obj-temp
))
114 ;;; With SYMBOL-VALUE, we check that the value isn't the trap object.
115 ;;; So SYMBOL-VALUE of NIL is NIL.
116 (define-vop (symbol-global-value checked-cell-ref
)
117 (:translate sym-global-val
)
119 (move obj-temp object
)
120 (loadw value obj-temp symbol-value-slot other-pointer-lowtag
)
121 (let ((err-lab (generate-error-code vop
'unbound-symbol-error obj-temp
)))
122 (inst cmpwi value unbound-marker-widetag
)
123 (inst beq err-lab
))))
125 (define-vop (fast-symbol-global-value cell-ref
)
126 (:variant symbol-value-slot other-pointer-lowtag
)
128 (:translate sym-global-val
))
133 (:args
(symbol :scs
(descriptor-reg))
134 (value :scs
(descriptor-reg any-reg
)))
135 (:temporary
(:sc any-reg
) tls-slot temp
)
137 (loadw tls-slot symbol symbol-tls-index-slot other-pointer-lowtag
)
138 (inst lwzx temp thread-base-tn tls-slot
)
139 (inst cmpwi temp no-tls-value-marker-widetag
)
140 (inst beq GLOBAL-VALUE
)
141 (inst stwx value thread-base-tn tls-slot
)
144 (storew value symbol symbol-value-slot other-pointer-lowtag
)
147 ;; With Symbol-Value, we check that the value isn't the trap object. So
148 ;; Symbol-Value of NIL is NIL.
149 (define-vop (symbol-value)
152 (:args
(object :scs
(descriptor-reg) :to
(:result
1)))
153 (:results
(value :scs
(descriptor-reg any-reg
)))
155 (:save-p
:compute-only
)
157 (loadw value object symbol-tls-index-slot other-pointer-lowtag
)
158 (inst lwzx value thread-base-tn value
)
159 (inst cmpwi value no-tls-value-marker-widetag
)
160 (inst bne CHECK-UNBOUND
)
161 (loadw value object symbol-value-slot other-pointer-lowtag
)
163 (inst cmpwi value unbound-marker-widetag
)
164 (inst beq
(generate-error-code vop
'unbound-symbol-error object
))))
166 (define-vop (fast-symbol-value symbol-value
)
167 ;; KLUDGE: not really fast, in fact, because we're going to have to
168 ;; do a full lookup of the thread-local area anyway. But half of
169 ;; the meaning of FAST-SYMBOL-VALUE is "do not signal an error if
170 ;; unbound", which is used in the implementation of COPY-SYMBOL. --
175 (loadw value object symbol-tls-index-slot other-pointer-lowtag
)
176 (inst lwzx value thread-base-tn value
)
177 (inst cmpwi value no-tls-value-marker-widetag
)
179 (loadw value object symbol-value-slot other-pointer-lowtag
)
182 ;;; On unithreaded builds these are just copies of the global versions.
185 (define-vop (symbol-value symbol-global-value
)
186 (:translate symeval
))
187 (define-vop (fast-symbol-value fast-symbol-global-value
)
188 (:translate symeval
))
189 (define-vop (set %set-symbol-global-value
)))
191 ;;; Like CHECKED-CELL-REF, only we are a predicate to see if the cell
193 (define-vop (boundp-frob)
194 (:args
(object :scs
(descriptor-reg)))
198 (:temporary
(:scs
(descriptor-reg)) value
))
201 (define-vop (boundp boundp-frob
)
204 (loadw value object symbol-tls-index-slot other-pointer-lowtag
)
205 (inst lwzx value thread-base-tn value
)
206 (inst cmpwi value no-tls-value-marker-widetag
)
207 (inst bne CHECK-UNBOUND
)
208 (loadw value object symbol-value-slot other-pointer-lowtag
)
210 (inst cmpwi value unbound-marker-widetag
)
211 (inst b?
(if not-p
:eq
:ne
) target
)))
214 (define-vop (boundp boundp-frob
)
217 (loadw value object symbol-value-slot other-pointer-lowtag
)
218 (inst cmpwi value unbound-marker-widetag
)
219 (inst b?
(if not-p
:eq
:ne
) target
)))
221 (define-vop (symbol-hash)
223 (:translate symbol-hash
)
224 (:args
(symbol :scs
(descriptor-reg)))
225 (:results
(res :scs
(any-reg)))
226 (:result-types positive-fixnum
)
228 ;; The symbol-hash slot of NIL holds NIL because it is also the
229 ;; cdr slot, so we have to strip off the two low bits to make sure
230 ;; it is a fixnum. The lowtag selection magic that is required to
231 ;; ensure this is explained in the comment in objdef.lisp
232 (loadw res symbol symbol-hash-slot other-pointer-lowtag
)
233 (inst clrrwi res res n-fixnum-tag-bits
)))
235 ;;;; Fdefinition (fdefn) objects.
237 (define-vop (fdefn-fun cell-ref
)
238 (:variant fdefn-fun-slot other-pointer-lowtag
))
240 (define-vop (safe-fdefn-fun)
241 (:translate safe-fdefn-fun
)
243 (:args
(object :scs
(descriptor-reg) :target obj-temp
))
244 (:results
(value :scs
(descriptor-reg any-reg
)))
246 (:save-p
:compute-only
)
247 (:temporary
(:scs
(descriptor-reg) :from
(:argument
0)) obj-temp
)
249 (move obj-temp object
)
250 (loadw value obj-temp fdefn-fun-slot other-pointer-lowtag
)
251 (inst cmpw value null-tn
)
252 (let ((err-lab (generate-error-code vop
'undefined-fun-error obj-temp
)))
253 (inst beq err-lab
))))
255 (define-vop (set-fdefn-fun)
257 (:translate
(setf fdefn-fun
))
258 (:args
(function :scs
(descriptor-reg) :target result
)
259 (fdefn :scs
(descriptor-reg)))
260 (:temporary
(:scs
(interior-reg)) lip
)
261 (:temporary
(:scs
(non-descriptor-reg)) type
)
262 (:results
(result :scs
(descriptor-reg)))
264 (let ((normal-fn (gen-label)))
265 (load-type type function
(- fun-pointer-lowtag
))
266 (inst cmpwi type simple-fun-widetag
)
267 ;;(inst mr lip function)
268 (inst addi lip function
269 (- (ash simple-fun-code-offset word-shift
) fun-pointer-lowtag
))
271 (inst lr lip
(make-fixup 'closure-tramp
:assembly-routine
))
272 (emit-label normal-fn
)
273 (storew lip fdefn fdefn-raw-addr-slot other-pointer-lowtag
)
274 (storew function fdefn fdefn-fun-slot other-pointer-lowtag
)
275 (move result function
))))
277 (define-vop (fdefn-makunbound)
279 (:translate fdefn-makunbound
)
280 (:args
(fdefn :scs
(descriptor-reg) :target result
))
281 (:temporary
(:scs
(non-descriptor-reg)) temp
)
282 (:results
(result :scs
(descriptor-reg)))
284 (storew null-tn fdefn fdefn-fun-slot other-pointer-lowtag
)
285 (inst lr temp
(make-fixup 'undefined-tramp
:assembly-routine
))
286 (storew temp fdefn fdefn-raw-addr-slot other-pointer-lowtag
)
287 (move result fdefn
)))
291 ;;;; Binding and Unbinding.
293 ;;; BIND -- Establish VAL as a binding for SYMBOL. Save the old value and
294 ;;; the symbol on the binding stack and stuff the new value into the
296 ;;; See the "Chapter 9: Specials" of the SBCL Internals Manual.
298 (define-vop (dynbind)
299 (:args
(val :scs
(any-reg descriptor-reg
))
300 (symbol :scs
(descriptor-reg)))
301 (:temporary
(:sc non-descriptor-reg
:offset nl3-offset
) pa-flag
)
302 (:temporary
(:scs
(descriptor-reg)) temp tls-index
)
304 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag
)
305 (inst cmpwi tls-index
0)
308 ;; No TLS slot allocated, so allocate one.
309 ;; FIXME: this is a ridiculous number of instructions to emit inline.
310 (pseudo-atomic (pa-flag)
311 (without-scheduling ()
313 (inst li temp
(+ (static-symbol-offset '*tls-index-lock
*)
314 (ash symbol-value-slot word-shift
)
315 (- other-pointer-lowtag
)))
317 (inst lwarx tls-index null-tn temp
)
318 (inst cmpwi tls-index
0)
319 (inst bne OBTAIN-LOCK
)
320 (inst stwcx. thread-base-tn null-tn temp
)
321 (inst bne OBTAIN-LOCK
)
324 ;; Check to see if the TLS index was set while we were waiting.
325 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag
)
326 (inst cmpwi tls-index
0)
327 (inst bne RELEASE-LOCK
)
329 (load-symbol-value tls-index
*free-tls-index
*)
330 ;; FIXME: Check for TLS index overflow.
331 (inst addi tls-index tls-index n-word-bytes
)
332 (store-symbol-value tls-index
*free-tls-index
*)
333 (inst addi tls-index tls-index
(- n-word-bytes
))
334 (storew tls-index symbol symbol-tls-index-slot other-pointer-lowtag
)
336 ;; The sync instruction doesn't need to happen if we branch
337 ;; directly to RELEASE-LOCK as we didn't do any stores in that
341 (inst stwx zero-tn null-tn temp
)
343 ;; temp is a boxed register, but we've been storing crap in it.
344 ;; fix it before we leave pseudo-atomic.
348 (inst lwzx temp thread-base-tn tls-index
)
349 (inst addi bsp-tn bsp-tn
(* binding-size n-word-bytes
))
350 (storew temp bsp-tn
(- binding-value-slot binding-size
))
351 (storew tls-index bsp-tn
(- binding-symbol-slot binding-size
))
352 (inst stwx val thread-base-tn tls-index
)))
355 (define-vop (dynbind)
356 (:args
(val :scs
(any-reg descriptor-reg
))
357 (symbol :scs
(descriptor-reg)))
358 (:temporary
(:scs
(descriptor-reg)) temp
)
360 (loadw temp symbol symbol-value-slot other-pointer-lowtag
)
361 (inst addi bsp-tn bsp-tn
(* binding-size n-word-bytes
))
362 (storew temp bsp-tn
(- binding-value-slot binding-size
))
363 (storew symbol bsp-tn
(- binding-symbol-slot binding-size
))
364 (storew val symbol symbol-value-slot other-pointer-lowtag
)))
368 (:temporary
(:scs
(descriptor-reg)) tls-index value
)
370 (loadw tls-index bsp-tn
(- binding-symbol-slot binding-size
))
371 (loadw value bsp-tn
(- binding-value-slot binding-size
))
372 (inst stwx value thread-base-tn tls-index
)
373 (storew zero-tn bsp-tn
(- binding-symbol-slot binding-size
))
374 (storew zero-tn bsp-tn
(- binding-value-slot binding-size
))
375 (inst subi bsp-tn bsp-tn
(* binding-size n-word-bytes
))))
379 (:temporary
(:scs
(descriptor-reg)) symbol value
)
381 (loadw symbol bsp-tn
(- binding-symbol-slot binding-size
))
382 (loadw value bsp-tn
(- binding-value-slot binding-size
))
383 (storew value symbol symbol-value-slot other-pointer-lowtag
)
384 (storew zero-tn bsp-tn
(- binding-symbol-slot binding-size
))
385 (storew zero-tn bsp-tn
(- binding-value-slot binding-size
))
386 (inst subi bsp-tn bsp-tn
(* binding-size n-word-bytes
))))
389 (define-vop (unbind-to-here)
390 (:args
(arg :scs
(descriptor-reg any-reg
) :target where
))
391 (:temporary
(:scs
(any-reg) :from
(:argument
0)) where
)
392 (:temporary
(:scs
(descriptor-reg)) symbol value
)
394 (let ((loop (gen-label))
398 (inst cmpw where bsp-tn
)
402 (loadw symbol bsp-tn
(- binding-symbol-slot binding-size
))
403 (inst cmpwi symbol
0)
405 (loadw value bsp-tn
(- binding-value-slot binding-size
))
407 (inst stwx value thread-base-tn symbol
)
409 (storew value symbol symbol-value-slot other-pointer-lowtag
)
410 (storew zero-tn bsp-tn
(- binding-symbol-slot binding-size
))
413 (storew zero-tn bsp-tn
(- binding-value-slot binding-size
))
414 (inst subi bsp-tn bsp-tn
(* binding-size n-word-bytes
))
415 (inst cmpw where bsp-tn
)
422 ;;;; Closure indexing.
424 (define-vop (closure-index-ref word-index-ref
)
425 (:variant closure-info-offset fun-pointer-lowtag
)
426 (:translate %closure-index-ref
))
428 (define-vop (funcallable-instance-info word-index-ref
)
429 (:variant funcallable-instance-info-offset fun-pointer-lowtag
)
430 (:translate %funcallable-instance-info
))
432 (define-vop (set-funcallable-instance-info word-index-set
)
433 (:variant funcallable-instance-info-offset fun-pointer-lowtag
)
434 (:translate %set-funcallable-instance-info
))
436 (define-vop (closure-ref slot-ref
)
437 (:variant closure-info-offset fun-pointer-lowtag
))
439 (define-vop (closure-init slot-set
)
440 (:variant closure-info-offset fun-pointer-lowtag
))
442 (define-vop (closure-init-from-fp)
443 (:args
(object :scs
(descriptor-reg)))
446 (storew cfp-tn object
(+ closure-info-offset offset
) fun-pointer-lowtag
)))
448 ;;;; Value Cell hackery.
450 (define-vop (value-cell-ref cell-ref
)
451 (:variant value-cell-value-slot other-pointer-lowtag
))
453 (define-vop (value-cell-set cell-set
)
454 (:variant value-cell-value-slot other-pointer-lowtag
))
458 ;;;; Instance hackery:
460 (define-vop (instance-length)
462 (:translate %instance-length
)
463 (:args
(struct :scs
(descriptor-reg)))
464 (:temporary
(:scs
(non-descriptor-reg)) temp
)
465 (:results
(res :scs
(unsigned-reg)))
466 (:result-types positive-fixnum
)
468 (loadw temp struct
0 instance-pointer-lowtag
)
469 (inst srwi res temp n-widetag-bits
)))
471 (define-vop (instance-index-ref word-index-ref
)
473 (:translate %instance-ref
)
474 (:variant instance-slots-offset instance-pointer-lowtag
)
475 (:arg-types instance positive-fixnum
))
477 (define-vop (instance-index-set word-index-set
)
479 (:translate %instance-set
)
480 (:variant instance-slots-offset instance-pointer-lowtag
)
481 (:arg-types instance positive-fixnum
*))
483 #!+compare-and-swap-vops
484 (define-vop (%instance-cas word-index-cas
)
486 (:translate %instance-cas
)
487 (:variant instance-slots-offset instance-pointer-lowtag
)
488 (:arg-types instance tagged-num
* *))
491 ;;;; Code object frobbing.
493 (define-vop (code-header-ref word-index-ref
)
494 (:translate code-header-ref
)
496 (:variant
0 other-pointer-lowtag
))
498 (define-vop (code-header-set word-index-set
)
499 (:translate code-header-set
)
501 (:variant
0 other-pointer-lowtag
))
505 ;;;; raw instance slot accessors
507 (defun offset-for-raw-slot (index &optional
(displacement 0))
508 (- (ash (+ index displacement instance-slots-offset
) word-shift
)
509 instance-pointer-lowtag
))
511 (define-vop (raw-instance-init/word
)
512 (:args
(object :scs
(descriptor-reg))
513 (value :scs
(unsigned-reg)))
514 (:arg-types
* unsigned-num
)
517 (inst stw value object
(offset-for-raw-slot index
))))
519 (define-vop (raw-instance-atomic-incf/word
)
520 (:translate %raw-instance-atomic-incf
/word
)
522 (:args
(object :scs
(descriptor-reg))
523 (index :scs
(any-reg)) ; FIXME: allow immediate
524 (diff :scs
(unsigned-reg)))
525 (:arg-types
* positive-fixnum unsigned-num
)
526 (:temporary
(:sc unsigned-reg
) offset
)
527 (:temporary
(:sc non-descriptor-reg
) sum
)
528 (:results
(result :scs
(unsigned-reg) :from
:load
))
529 (:result-types unsigned-num
)
531 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
532 instance-pointer-lowtag
))
533 ;; load the slot value, add DIFF, write the sum back, and return
534 ;; the original slot value, atomically, and include a memory
538 (inst lwarx result offset object
)
539 (inst add sum result diff
)
540 (inst stwcx. sum offset object
)
544 (define-vop (raw-instance-ref/word word-index-ref
)
546 (:translate %raw-instance-ref
/word
)
547 (:variant instance-slots-offset instance-pointer-lowtag
)
548 (:arg-types instance positive-fixnum
)
549 (:results
(value :scs
(unsigned-reg)))
550 (:result-types unsigned-num
))
552 (define-vop (raw-instance-set/word word-index-set
)
554 (:translate %raw-instance-set
/word
)
555 (:variant instance-slots-offset instance-pointer-lowtag
)
556 (:arg-types instance positive-fixnum unsigned-num
)
557 (:args
(object) (index) (value :scs
(unsigned-reg)))
558 (:results
(result :scs
(unsigned-reg)))
559 (:result-types unsigned-num
))
561 (define-vop (raw-instance-init/single
)
562 (:args
(object :scs
(descriptor-reg))
563 (value :scs
(single-reg)))
564 (:arg-types
* single-float
)
567 (inst stfs value object
(offset-for-raw-slot index
))))
569 (define-vop (raw-instance-ref/single
)
570 (:translate %raw-instance-ref
/single
)
572 (:args
(object :scs
(descriptor-reg))
573 (index :scs
(any-reg)))
574 (:arg-types
* positive-fixnum
)
575 (:results
(value :scs
(single-reg)))
576 (:temporary
(:scs
(non-descriptor-reg)) offset
)
577 (:result-types single-float
)
579 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
580 instance-pointer-lowtag
))
581 (inst lfsx value object offset
)))
583 (define-vop (raw-instance-set/single
)
584 (:translate %raw-instance-set
/single
)
586 (:args
(object :scs
(descriptor-reg))
587 (index :scs
(any-reg))
588 (value :scs
(single-reg) :target result
))
589 (:arg-types
* positive-fixnum single-float
)
590 (:results
(result :scs
(single-reg)))
591 (:result-types single-float
)
592 (:temporary
(:scs
(non-descriptor-reg)) offset
)
594 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
595 instance-pointer-lowtag
))
596 (inst stfsx value object offset
)
597 (unless (location= result value
)
598 (inst frsp result value
))))
600 (define-vop (raw-instance-init/double
)
601 (:args
(object :scs
(descriptor-reg))
602 (value :scs
(double-reg)))
603 (:arg-types
* double-float
)
606 (inst stfd value object
(offset-for-raw-slot index
))))
608 (define-vop (raw-instance-ref/double
)
609 (:translate %raw-instance-ref
/double
)
611 (:args
(object :scs
(descriptor-reg))
612 (index :scs
(any-reg)))
613 (:arg-types
* positive-fixnum
)
614 (:results
(value :scs
(double-reg)))
615 (:temporary
(:scs
(non-descriptor-reg)) offset
)
616 (:result-types double-float
)
618 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
619 instance-pointer-lowtag
))
620 (inst lfdx value object offset
)))
622 (define-vop (raw-instance-set/double
)
623 (:translate %raw-instance-set
/double
)
625 (:args
(object :scs
(descriptor-reg))
626 (index :scs
(any-reg))
627 (value :scs
(double-reg) :target result
))
628 (:arg-types
* positive-fixnum double-float
)
629 (:results
(result :scs
(double-reg)))
630 (:result-types double-float
)
631 (:temporary
(:scs
(non-descriptor-reg)) offset
)
633 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
634 instance-pointer-lowtag
))
635 (inst stfdx value object offset
)
636 (unless (location= result value
)
637 (inst fmr result value
))))
639 (define-vop (raw-instance-init/complex-single
)
640 (:args
(object :scs
(descriptor-reg))
641 (value :scs
(complex-single-reg)))
642 (:arg-types
* complex-single-float
)
645 (inst stfs
(complex-single-reg-real-tn value
)
646 object
(offset-for-raw-slot index
))
647 (inst stfs
(complex-single-reg-imag-tn value
)
648 object
(offset-for-raw-slot index
1))))
650 (define-vop (raw-instance-ref/complex-single
)
651 (:translate %raw-instance-ref
/complex-single
)
653 (:args
(object :scs
(descriptor-reg))
654 (index :scs
(any-reg)))
655 (:arg-types
* positive-fixnum
)
656 (:results
(value :scs
(complex-single-reg)))
657 (:temporary
(:scs
(non-descriptor-reg)) offset
)
658 (:result-types complex-single-float
)
660 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
661 instance-pointer-lowtag
))
662 (inst lfsx
(complex-single-reg-real-tn value
) object offset
)
663 (inst addi offset offset n-word-bytes
)
664 (inst lfsx
(complex-single-reg-imag-tn value
) object offset
)))
666 (define-vop (raw-instance-set/complex-single
)
667 (:translate %raw-instance-set
/complex-single
)
669 (:args
(object :scs
(descriptor-reg))
670 (index :scs
(any-reg))
671 (value :scs
(complex-single-reg) :target result
))
672 (:arg-types
* positive-fixnum complex-single-float
)
673 (:results
(result :scs
(complex-single-reg)))
674 (:result-types complex-single-float
)
675 (:temporary
(:scs
(non-descriptor-reg)) offset
)
677 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
678 instance-pointer-lowtag
))
679 (let ((value-real (complex-single-reg-real-tn value
))
680 (result-real (complex-single-reg-real-tn result
)))
681 (inst stfsx value-real object offset
)
682 (unless (location= result-real value-real
)
683 (inst frsp result-real value-real
)))
684 (inst addi offset offset n-word-bytes
)
685 (let ((value-imag (complex-single-reg-imag-tn value
))
686 (result-imag (complex-single-reg-imag-tn result
)))
687 (inst stfsx value-imag object offset
)
688 (unless (location= result-imag value-imag
)
689 (inst frsp result-imag value-imag
)))))
691 (define-vop (raw-instance-init/complex-double
)
692 (:args
(object :scs
(descriptor-reg))
693 (value :scs
(complex-double-reg)))
694 (:arg-types
* complex-double-float
)
697 (inst stfd
(complex-single-reg-real-tn value
)
698 object
(offset-for-raw-slot index
))
699 (inst stfd
(complex-double-reg-imag-tn value
)
700 object
(offset-for-raw-slot index
2))))
702 (define-vop (raw-instance-ref/complex-double
)
703 (:translate %raw-instance-ref
/complex-double
)
705 (:args
(object :scs
(descriptor-reg))
706 (index :scs
(any-reg)))
707 (:arg-types
* positive-fixnum
)
708 (:results
(value :scs
(complex-double-reg)))
709 (:temporary
(:scs
(non-descriptor-reg)) offset
)
710 (:result-types complex-double-float
)
712 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
713 instance-pointer-lowtag
))
714 (inst lfdx
(complex-double-reg-real-tn value
) object offset
)
715 (inst addi offset offset
(* 2 n-word-bytes
))
716 (inst lfdx
(complex-double-reg-imag-tn value
) object offset
)))
718 (define-vop (raw-instance-set/complex-double
)
719 (:translate %raw-instance-set
/complex-double
)
721 (:args
(object :scs
(descriptor-reg))
722 (index :scs
(any-reg))
723 (value :scs
(complex-double-reg) :target result
))
724 (:arg-types
* positive-fixnum complex-double-float
)
725 (:results
(result :scs
(complex-double-reg)))
726 (:result-types complex-double-float
)
727 (:temporary
(:scs
(non-descriptor-reg)) offset
)
729 (inst addi offset index
(- (ash instance-slots-offset word-shift
)
730 instance-pointer-lowtag
))
731 (let ((value-real (complex-double-reg-real-tn value
))
732 (result-real (complex-double-reg-real-tn result
)))
733 (inst stfdx value-real object offset
)
734 (unless (location= result-real value-real
)
735 (inst fmr result-real value-real
)))
736 (inst addi offset offset
(* 2 n-word-bytes
))
737 (let ((value-imag (complex-double-reg-imag-tn value
))
738 (result-imag (complex-double-reg-imag-tn result
)))
739 (inst stfdx value-imag object offset
)
740 (unless (location= result-imag value-imag
)
741 (inst fmr result-imag value-imag
)))))