1 ;;;; various primitive memory access VOPs for the x86 VM
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
14 ;;;; data object ref/set stuff
17 (:args (object :scs (descriptor-reg)))
18 (:info name offset lowtag)
20 (:results (result :scs (descriptor-reg any-reg)))
22 (loadw result object offset lowtag)))
24 (define-vop (set-slot)
25 (:args (object :scs (descriptor-reg))
26 (value :scs (descriptor-reg any-reg immediate)))
27 (:temporary (:sc descriptor-reg) temp)
28 (:info name offset lowtag)
32 (if (sc-is value immediate)
33 (let ((val (tn-value value)))
34 (move-immediate (make-ea :qword
36 :disp (- (* offset n-word-bytes)
42 (+ nil-value (static-symbol-offset val)))
44 (logior (ash (char-code val) n-widetag-bits)
47 ;; Else, value not immediate.
48 (storew value object offset lowtag))))
50 (define-vop (compare-and-swap-slot)
51 (:args (object :scs (descriptor-reg) :to :eval)
52 (old :scs (descriptor-reg any-reg) :target rax)
53 (new :scs (descriptor-reg any-reg)))
54 (:temporary (:sc descriptor-reg :offset rax-offset
55 :from (:argument 1) :to :result :target result)
57 (:info name offset lowtag)
59 (:results (result :scs (descriptor-reg any-reg)))
62 (inst cmpxchg (make-ea :qword :base object
63 :disp (- (* offset n-word-bytes) lowtag))
67 ;;;; symbol hacking VOPs
69 (define-vop (%compare-and-swap-symbol-value)
70 (:translate %compare-and-swap-symbol-value)
71 (:args (symbol :scs (descriptor-reg) :to (:result 1))
72 (old :scs (descriptor-reg any-reg) :target rax)
73 (new :scs (descriptor-reg any-reg)))
74 (:temporary (:sc descriptor-reg :offset rax-offset) rax)
76 (:temporary (:sc descriptor-reg) tls)
77 (:results (result :scs (descriptor-reg any-reg)))
81 ;; This code has two pathological cases: NO-TLS-VALUE-MARKER
82 ;; or UNBOUND-MARKER as NEW: in either case we would end up
83 ;; doing possible damage with CMPXCHG -- so don't do that!
84 (let ((unbound (generate-error-code vop 'unbound-symbol-error symbol))
89 (loadw tls symbol symbol-tls-index-slot other-pointer-lowtag)
90 ;; Thread-local area, no LOCK needed.
91 (inst cmpxchg (make-ea :qword :base thread-base-tn
94 (inst cmp rax no-tls-value-marker-widetag)
97 (inst cmpxchg (make-ea :qword :base symbol
98 :disp (- (* symbol-value-slot n-word-bytes)
104 (inst cmp result unbound-marker-widetag)
105 (inst jmp :e unbound))))
107 ;;; these next two cf the sparc version, by jrd.
108 ;;; FIXME: Deref this ^ reference.
111 ;;; The compiler likes to be able to directly SET symbols.
114 (:args (symbol :scs (descriptor-reg))
115 (value :scs (descriptor-reg any-reg)))
116 (:temporary (:sc descriptor-reg) tls)
117 ;;(:policy :fast-safe)
119 (let ((global-val (gen-label))
121 (loadw tls symbol symbol-tls-index-slot other-pointer-lowtag)
122 (inst cmp (make-ea :qword :base thread-base-tn :scale 1 :index tls)
123 no-tls-value-marker-widetag)
124 (inst jmp :z global-val)
125 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls)
128 (emit-label global-val)
129 (storew value symbol symbol-value-slot other-pointer-lowtag)
132 ;; unithreaded it's a lot simpler ...
134 (define-vop (set cell-set)
135 (:variant symbol-value-slot other-pointer-lowtag))
137 ;;; With Symbol-Value, we check that the value isn't the trap object. So
138 ;;; Symbol-Value of NIL is NIL.
140 (define-vop (symbol-value)
141 (:translate symbol-value)
143 (:args (object :scs (descriptor-reg) :to (:result 1)))
144 (:results (value :scs (descriptor-reg any-reg)))
146 (:save-p :compute-only)
148 (let* ((check-unbound-label (gen-label))
149 (err-lab (generate-error-code vop 'unbound-symbol-error object))
150 (ret-lab (gen-label)))
151 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
152 (inst mov value (make-ea :qword :base thread-base-tn
153 :index value :scale 1))
154 (inst cmp value no-tls-value-marker-widetag)
155 (inst jmp :ne check-unbound-label)
156 (loadw value object symbol-value-slot other-pointer-lowtag)
157 (emit-label check-unbound-label)
158 (inst cmp value unbound-marker-widetag)
159 (inst jmp :e err-lab)
160 (emit-label ret-lab))))
163 (define-vop (fast-symbol-value symbol-value)
164 ;; KLUDGE: not really fast, in fact, because we're going to have to
165 ;; do a full lookup of the thread-local area anyway. But half of
166 ;; the meaning of FAST-SYMBOL-VALUE is "do not signal an error if
167 ;; unbound", which is used in the implementation of COPY-SYMBOL. --
170 (:translate symbol-value)
172 (let ((ret-lab (gen-label)))
173 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
175 (make-ea :qword :base thread-base-tn :index value :scale 1))
176 (inst cmp value no-tls-value-marker-widetag)
177 (inst jmp :ne ret-lab)
178 (loadw value object symbol-value-slot other-pointer-lowtag)
179 (emit-label ret-lab))))
182 (define-vop (symbol-value)
183 (:translate symbol-value)
185 (:args (object :scs (descriptor-reg) :to (:result 1)))
186 (:results (value :scs (descriptor-reg any-reg)))
188 (:save-p :compute-only)
190 (let ((err-lab (generate-error-code vop 'unbound-symbol-error object)))
191 (loadw value object symbol-value-slot other-pointer-lowtag)
192 (inst cmp value unbound-marker-widetag)
193 (inst jmp :e err-lab))))
196 (define-vop (fast-symbol-value cell-ref)
197 (:variant symbol-value-slot other-pointer-lowtag)
199 (:translate symbol-value))
205 (:args (object :scs (descriptor-reg)))
207 (:temporary (:sc descriptor-reg #+nil(:from (:argument 0))) value)
209 (let ((check-unbound-label (gen-label)))
210 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
212 (make-ea :qword :base thread-base-tn :index value :scale 1))
213 (inst cmp value no-tls-value-marker-widetag)
214 (inst jmp :ne check-unbound-label)
215 (loadw value object symbol-value-slot other-pointer-lowtag)
216 (emit-label check-unbound-label)
217 (inst cmp value unbound-marker-widetag))))
223 (:args (object :scs (descriptor-reg)))
226 (inst cmp (make-ea-for-object-slot object symbol-value-slot
227 other-pointer-lowtag)
228 unbound-marker-widetag)))
231 (define-vop (symbol-hash)
233 (:translate symbol-hash)
234 (:args (symbol :scs (descriptor-reg)))
235 (:results (res :scs (any-reg)))
236 (:result-types positive-fixnum)
238 ;; The symbol-hash slot of NIL holds NIL because it is also the
239 ;; cdr slot, so we have to strip off the three low bits to make sure
240 ;; it is a fixnum. The lowtag selection magic that is required to
241 ;; ensure this is explained in the comment in objdef.lisp
242 (loadw res symbol symbol-hash-slot other-pointer-lowtag)
243 (inst and res (lognot #b111))))
245 ;;;; fdefinition (FDEFN) objects
247 (define-vop (fdefn-fun cell-ref) ; /pfw - alpha
248 (:variant fdefn-fun-slot other-pointer-lowtag))
250 (define-vop (safe-fdefn-fun)
251 (:args (object :scs (descriptor-reg) :to (:result 1)))
252 (:results (value :scs (descriptor-reg any-reg)))
254 (:save-p :compute-only)
256 (loadw value object fdefn-fun-slot other-pointer-lowtag)
257 (inst cmp value nil-value)
258 (let ((err-lab (generate-error-code vop 'undefined-fun-error object)))
259 (inst jmp :e err-lab))))
261 (define-vop (set-fdefn-fun)
263 (:translate (setf fdefn-fun))
264 (:args (function :scs (descriptor-reg) :target result)
265 (fdefn :scs (descriptor-reg)))
266 (:temporary (:sc unsigned-reg) raw)
267 (:temporary (:sc byte-reg) type)
268 (:results (result :scs (descriptor-reg)))
270 (load-type type function (- fun-pointer-lowtag))
272 (make-ea :byte :base function
273 :disp (- (* simple-fun-code-offset n-word-bytes)
274 fun-pointer-lowtag)))
275 (inst cmp type simple-fun-header-widetag)
276 (inst jmp :e NORMAL-FUN)
277 (inst lea raw (make-fixup "closure_tramp" :foreign))
279 (storew function fdefn fdefn-fun-slot other-pointer-lowtag)
280 (storew raw fdefn fdefn-raw-addr-slot other-pointer-lowtag)
281 (move result function)))
283 (define-vop (fdefn-makunbound)
285 (:translate fdefn-makunbound)
286 (:args (fdefn :scs (descriptor-reg) :target result))
287 (:results (result :scs (descriptor-reg)))
289 (storew nil-value fdefn fdefn-fun-slot other-pointer-lowtag)
290 (storew (make-fixup "undefined_tramp" :foreign)
291 fdefn fdefn-raw-addr-slot other-pointer-lowtag)
292 (move result fdefn)))
294 ;;;; binding and unbinding
296 ;;; BIND -- Establish VAL as a binding for SYMBOL. Save the old value and
297 ;;; the symbol on the binding stack and stuff the new value into the
302 (:args (val :scs (any-reg descriptor-reg))
303 (symbol :scs (descriptor-reg)))
304 (:temporary (:sc unsigned-reg) tls-index bsp)
306 (let ((tls-index-valid (gen-label)))
307 (load-binding-stack-pointer bsp)
308 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
309 (inst add bsp (* binding-size n-word-bytes))
310 (store-binding-stack-pointer bsp)
311 (inst or tls-index tls-index)
312 (inst jmp :ne tls-index-valid)
313 (inst mov tls-index symbol)
314 (inst lea temp-reg-tn
315 (make-ea :qword :disp
316 (make-fixup (ecase (tn-offset tls-index)
317 (#.rax-offset 'alloc-tls-index-in-rax)
318 (#.rcx-offset 'alloc-tls-index-in-rcx)
319 (#.rdx-offset 'alloc-tls-index-in-rdx)
320 (#.rbx-offset 'alloc-tls-index-in-rbx)
321 (#.rsi-offset 'alloc-tls-index-in-rsi)
322 (#.rdi-offset 'alloc-tls-index-in-rdi)
323 (#.r8-offset 'alloc-tls-index-in-r8)
324 (#.r9-offset 'alloc-tls-index-in-r9)
325 (#.r10-offset 'alloc-tls-index-in-r10)
326 (#.r12-offset 'alloc-tls-index-in-r12)
327 (#.r13-offset 'alloc-tls-index-in-r13)
328 (#.r14-offset 'alloc-tls-index-in-r14)
329 (#.r15-offset 'alloc-tls-index-in-r15))
331 (inst call temp-reg-tn)
332 (emit-label tls-index-valid)
333 (inst push (make-ea :qword :base thread-base-tn :scale 1 :index tls-index))
334 (popw bsp (- binding-value-slot binding-size))
335 (storew symbol bsp (- binding-symbol-slot binding-size))
336 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
341 (:args (val :scs (any-reg descriptor-reg))
342 (symbol :scs (descriptor-reg)))
343 (:temporary (:sc unsigned-reg) temp bsp)
345 (load-symbol-value bsp *binding-stack-pointer*)
346 (loadw temp symbol symbol-value-slot other-pointer-lowtag)
347 (inst add bsp (* binding-size n-word-bytes))
348 (store-symbol-value bsp *binding-stack-pointer*)
349 (storew temp bsp (- binding-value-slot binding-size))
350 (storew symbol bsp (- binding-symbol-slot binding-size))
351 (storew val symbol symbol-value-slot other-pointer-lowtag)))
355 (:temporary (:sc unsigned-reg) temp bsp tls-index)
357 (load-binding-stack-pointer bsp)
358 ;; Load SYMBOL from stack, and get the TLS-INDEX
359 (loadw temp bsp (- binding-symbol-slot binding-size))
360 (loadw tls-index temp symbol-tls-index-slot other-pointer-lowtag)
361 ;; Load VALUE from stack, the restore it to the TLS area.
362 (loadw temp bsp (- binding-value-slot binding-size))
363 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
365 ;; Zero out the stack.
366 (storew 0 bsp (- binding-symbol-slot binding-size))
367 (storew 0 bsp (- binding-value-slot binding-size))
368 (inst sub bsp (* binding-size n-word-bytes))
369 (store-binding-stack-pointer bsp)))
373 (:temporary (:sc unsigned-reg) symbol value bsp)
375 (load-symbol-value bsp *binding-stack-pointer*)
376 (loadw symbol bsp (- binding-symbol-slot binding-size))
377 (loadw value bsp (- binding-value-slot binding-size))
378 (storew value symbol symbol-value-slot other-pointer-lowtag)
379 (storew 0 bsp (- binding-symbol-slot binding-size))
380 (storew 0 bsp (- binding-value-slot binding-size))
381 (inst sub bsp (* binding-size n-word-bytes))
382 (store-symbol-value bsp *binding-stack-pointer*)))
384 (define-vop (unbind-to-here)
385 (:args (where :scs (descriptor-reg any-reg)))
386 (:temporary (:sc unsigned-reg) symbol value bsp #!+sb-thread tls-index)
388 (load-binding-stack-pointer bsp)
393 (loadw symbol bsp (- binding-symbol-slot binding-size))
394 (inst or symbol symbol)
396 ;; Bind stack debug sentinels have the unbound marker in the symbol slot
397 (inst cmp symbol unbound-marker-widetag)
399 (loadw value bsp (- binding-value-slot binding-size))
401 (storew value symbol symbol-value-slot other-pointer-lowtag)
403 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
405 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
407 (storew 0 bsp (- binding-symbol-slot binding-size))
410 (storew 0 bsp (- binding-value-slot binding-size))
411 (inst sub bsp (* binding-size n-word-bytes))
414 (store-binding-stack-pointer bsp)
418 (define-vop (bind-sentinel)
419 (:temporary (:sc unsigned-reg) bsp)
421 (load-binding-stack-pointer bsp)
422 (inst add bsp (* binding-size n-word-bytes))
423 (storew unbound-marker-widetag bsp (- binding-symbol-slot binding-size))
424 (storew rbp-tn bsp (- binding-value-slot binding-size))
425 (store-binding-stack-pointer bsp)))
427 (define-vop (unbind-sentinel)
428 (:temporary (:sc unsigned-reg) bsp)
430 (load-binding-stack-pointer bsp)
431 (storew 0 bsp (- binding-value-slot binding-size))
432 (storew 0 bsp (- binding-symbol-slot binding-size))
433 (inst sub bsp (* binding-size n-word-bytes))
434 (store-binding-stack-pointer bsp)))
439 ;;;; closure indexing
441 (define-full-reffer closure-index-ref *
442 closure-info-offset fun-pointer-lowtag
443 (any-reg descriptor-reg) * %closure-index-ref)
445 (define-full-setter set-funcallable-instance-info *
446 funcallable-instance-info-offset fun-pointer-lowtag
447 (any-reg descriptor-reg) * %set-funcallable-instance-info)
449 (define-full-reffer funcallable-instance-info *
450 funcallable-instance-info-offset fun-pointer-lowtag
451 (descriptor-reg any-reg) * %funcallable-instance-info)
453 (define-vop (closure-ref slot-ref)
454 (:variant closure-info-offset fun-pointer-lowtag))
456 (define-vop (closure-init slot-set)
457 (:variant closure-info-offset fun-pointer-lowtag))
459 ;;;; value cell hackery
461 (define-vop (value-cell-ref cell-ref)
462 (:variant value-cell-value-slot other-pointer-lowtag))
464 (define-vop (value-cell-set cell-set)
465 (:variant value-cell-value-slot other-pointer-lowtag))
467 ;;;; structure hackery
469 (define-vop (instance-length)
471 (:translate %instance-length)
472 (:args (struct :scs (descriptor-reg)))
473 (:results (res :scs (unsigned-reg)))
474 (:result-types positive-fixnum)
476 (loadw res struct 0 instance-pointer-lowtag)
477 (inst shr res n-widetag-bits)))
479 (define-full-reffer instance-index-ref * instance-slots-offset
480 instance-pointer-lowtag (any-reg descriptor-reg) * %instance-ref)
482 (define-full-setter instance-index-set * instance-slots-offset
483 instance-pointer-lowtag (any-reg descriptor-reg) * %instance-set)
485 (define-full-compare-and-swap %compare-and-swap-instance-ref instance
486 instance-slots-offset instance-pointer-lowtag
487 (any-reg descriptor-reg) *
488 %compare-and-swap-instance-ref)
490 ;;;; code object frobbing
492 (define-full-reffer code-header-ref * 0 other-pointer-lowtag
493 (any-reg descriptor-reg) * code-header-ref)
495 (define-full-setter code-header-set * 0 other-pointer-lowtag
496 (any-reg descriptor-reg) * code-header-set)
498 ;;;; raw instance slot accessors
500 (defun make-ea-for-raw-slot (object index instance-length
501 &optional (adjustment 0))
502 (if (integerp instance-length)
503 ;; For RAW-INSTANCE-INIT/* VOPs, which know the exact instance length
507 :disp (+ (* (- instance-length instance-slots-offset index)
509 (- instance-pointer-lowtag)
513 (make-ea :qword :base object :index instance-length
514 :disp (+ (* (1- instance-slots-offset) n-word-bytes)
515 (- instance-pointer-lowtag)
518 (make-ea :qword :base object :index instance-length
520 :disp (+ (* (1- instance-slots-offset) n-word-bytes)
521 (- instance-pointer-lowtag)
523 (* index (- n-word-bytes))))))))
525 (define-vop (raw-instance-ref/word)
526 (:translate %raw-instance-ref/word)
528 (:args (object :scs (descriptor-reg)) (index :scs (any-reg)))
529 (:arg-types * tagged-num)
530 (:temporary (:sc unsigned-reg) tmp)
531 (:results (value :scs (unsigned-reg)))
532 (:result-types unsigned-num)
534 (loadw tmp object 0 instance-pointer-lowtag)
535 (inst shr tmp n-widetag-bits)
538 (inst mov value (make-ea-for-raw-slot object index tmp))))
540 (define-vop (raw-instance-ref-c/word)
541 (:translate %raw-instance-ref/word)
543 (:args (object :scs (descriptor-reg)))
544 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
545 #.instance-pointer-lowtag
546 #.instance-slots-offset)))
548 (:temporary (:sc unsigned-reg) tmp)
549 (:results (value :scs (unsigned-reg)))
550 (:result-types unsigned-num)
552 (loadw tmp object 0 instance-pointer-lowtag)
553 (inst shr tmp n-widetag-bits)
554 (inst mov value (make-ea-for-raw-slot object index tmp))))
556 (define-vop (raw-instance-set/word)
557 (:translate %raw-instance-set/word)
559 (:args (object :scs (descriptor-reg))
560 (index :scs (any-reg))
561 (value :scs (unsigned-reg) :target result))
562 (:arg-types * tagged-num unsigned-num)
563 (:temporary (:sc unsigned-reg) tmp)
564 (:results (result :scs (unsigned-reg)))
565 (:result-types unsigned-num)
567 (loadw tmp object 0 instance-pointer-lowtag)
568 (inst shr tmp n-widetag-bits)
571 (inst mov (make-ea-for-raw-slot object index tmp) value)
572 (move result value)))
574 (define-vop (raw-instance-set-c/word)
575 (:translate %raw-instance-set/word)
577 (:args (object :scs (descriptor-reg))
578 (value :scs (unsigned-reg) :target result))
579 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
580 #.instance-pointer-lowtag
581 #.instance-slots-offset))
584 (:temporary (:sc unsigned-reg) tmp)
585 (:results (result :scs (unsigned-reg)))
586 (:result-types unsigned-num)
588 (loadw tmp object 0 instance-pointer-lowtag)
589 (inst shr tmp n-widetag-bits)
590 (inst mov (make-ea-for-raw-slot object index tmp) value)
591 (move result value)))
593 (define-vop (raw-instance-init/word)
594 (:args (object :scs (descriptor-reg))
595 (value :scs (unsigned-reg)))
596 (:arg-types * unsigned-num)
597 (:info instance-length index)
599 (inst mov (make-ea-for-raw-slot object index instance-length) value)))
601 (define-vop (raw-instance-atomic-incf-c/word)
602 (:translate %raw-instance-atomic-incf/word)
604 (:args (object :scs (descriptor-reg))
605 (diff :scs (signed-reg) :target result))
606 (:arg-types * (:constant (load/store-index #.n-word-bytes
607 #.instance-pointer-lowtag
608 #.instance-slots-offset))
611 (:temporary (:sc unsigned-reg) tmp)
612 (:results (result :scs (unsigned-reg)))
613 (:result-types unsigned-num)
615 (loadw tmp object 0 instance-pointer-lowtag)
616 (inst shr tmp n-widetag-bits)
617 (inst xadd (make-ea-for-raw-slot object index tmp) diff :lock)
620 (define-vop (raw-instance-ref/single)
621 (:translate %raw-instance-ref/single)
623 (:args (object :scs (descriptor-reg))
624 (index :scs (any-reg)))
625 (:arg-types * positive-fixnum)
626 (:temporary (:sc unsigned-reg) tmp)
627 (:results (value :scs (single-reg)))
628 (:result-types single-float)
630 (loadw tmp object 0 instance-pointer-lowtag)
631 (inst shr tmp n-widetag-bits)
634 (inst movss value (make-ea-for-raw-slot object index tmp))))
636 (define-vop (raw-instance-ref-c/single)
637 (:translate %raw-instance-ref/single)
639 (:args (object :scs (descriptor-reg)))
640 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
641 #.instance-pointer-lowtag
642 #.instance-slots-offset)))
644 (:temporary (:sc unsigned-reg) tmp)
645 (:results (value :scs (single-reg)))
646 (:result-types single-float)
648 (loadw tmp object 0 instance-pointer-lowtag)
649 (inst shr tmp n-widetag-bits)
650 (inst movss value (make-ea-for-raw-slot object index tmp))))
652 (define-vop (raw-instance-set/single)
653 (:translate %raw-instance-set/single)
655 (:args (object :scs (descriptor-reg))
656 (index :scs (any-reg))
657 (value :scs (single-reg) :target result))
658 (:arg-types * positive-fixnum single-float)
659 (:temporary (:sc unsigned-reg) tmp)
660 (:results (result :scs (single-reg)))
661 (:result-types single-float)
663 (loadw tmp object 0 instance-pointer-lowtag)
664 (inst shr tmp n-widetag-bits)
667 (inst movss (make-ea-for-raw-slot object index tmp) value)
668 (unless (location= result value)
669 (inst movss result value))))
671 (define-vop (raw-instance-set-c/single)
672 (:translate %raw-instance-set/single)
674 (:args (object :scs (descriptor-reg))
675 (value :scs (single-reg) :target result))
676 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
677 #.instance-pointer-lowtag
678 #.instance-slots-offset))
681 (:temporary (:sc unsigned-reg) tmp)
682 (:results (result :scs (single-reg)))
683 (:result-types single-float)
685 (loadw tmp object 0 instance-pointer-lowtag)
686 (inst shr tmp n-widetag-bits)
687 (inst movss (make-ea-for-raw-slot object index tmp) value)
688 (unless (location= result value)
689 (inst movss result value))))
691 (define-vop (raw-instance-init/single)
692 (:args (object :scs (descriptor-reg))
693 (value :scs (single-reg)))
694 (:arg-types * single-float)
695 (:info instance-length index)
697 (inst movss (make-ea-for-raw-slot object index instance-length) value)))
699 (define-vop (raw-instance-ref/double)
700 (:translate %raw-instance-ref/double)
702 (:args (object :scs (descriptor-reg))
703 (index :scs (any-reg)))
704 (:arg-types * positive-fixnum)
705 (:temporary (:sc unsigned-reg) tmp)
706 (:results (value :scs (double-reg)))
707 (:result-types double-float)
709 (loadw tmp object 0 instance-pointer-lowtag)
710 (inst shr tmp n-widetag-bits)
713 (inst movsd value (make-ea-for-raw-slot object index tmp))))
715 (define-vop (raw-instance-ref-c/double)
716 (:translate %raw-instance-ref/double)
718 (:args (object :scs (descriptor-reg)))
719 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
720 #.instance-pointer-lowtag
721 #.instance-slots-offset)))
723 (:temporary (:sc unsigned-reg) tmp)
724 (:results (value :scs (double-reg)))
725 (:result-types double-float)
727 (loadw tmp object 0 instance-pointer-lowtag)
728 (inst shr tmp n-widetag-bits)
729 (inst movsd value (make-ea-for-raw-slot object index tmp))))
731 (define-vop (raw-instance-set/double)
732 (:translate %raw-instance-set/double)
734 (:args (object :scs (descriptor-reg))
735 (index :scs (any-reg))
736 (value :scs (double-reg) :target result))
737 (:arg-types * positive-fixnum double-float)
738 (:temporary (:sc unsigned-reg) tmp)
739 (:results (result :scs (double-reg)))
740 (:result-types double-float)
742 (loadw tmp object 0 instance-pointer-lowtag)
743 (inst shr tmp n-widetag-bits)
746 (inst movsd (make-ea-for-raw-slot object index tmp) value)
747 (unless (location= result value)
748 (inst movsd result value))))
750 (define-vop (raw-instance-set-c/double)
751 (:translate %raw-instance-set/double)
753 (:args (object :scs (descriptor-reg))
754 (value :scs (double-reg) :target result))
755 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
756 #.instance-pointer-lowtag
757 #.instance-slots-offset))
760 (:temporary (:sc unsigned-reg) tmp)
761 (:results (result :scs (double-reg)))
762 (:result-types double-float)
764 (loadw tmp object 0 instance-pointer-lowtag)
765 (inst shr tmp n-widetag-bits)
766 (inst movsd (make-ea-for-raw-slot object index tmp) value)
767 (unless (location= result value)
768 (inst movsd result value))))
770 (define-vop (raw-instance-init/double)
771 (:args (object :scs (descriptor-reg))
772 (value :scs (double-reg)))
773 (:arg-types * double-float)
774 (:info instance-length index)
776 (inst movsd (make-ea-for-raw-slot object index instance-length) value)))
778 (define-vop (raw-instance-ref/complex-single)
779 (:translate %raw-instance-ref/complex-single)
781 (:args (object :scs (descriptor-reg))
782 (index :scs (any-reg)))
783 (:arg-types * positive-fixnum)
784 (:temporary (:sc unsigned-reg) tmp)
785 (:results (value :scs (complex-single-reg)))
786 (:result-types complex-single-float)
788 (loadw tmp object 0 instance-pointer-lowtag)
789 (inst shr tmp n-widetag-bits)
792 (let ((real-tn (complex-single-reg-real-tn value)))
793 (inst movss real-tn (make-ea-for-raw-slot object index tmp)))
794 (let ((imag-tn (complex-single-reg-imag-tn value)))
795 (inst movss imag-tn (make-ea-for-raw-slot object index tmp 4)))))
797 (define-vop (raw-instance-ref-c/complex-single)
798 (:translate %raw-instance-ref/complex-single)
800 (:args (object :scs (descriptor-reg)))
801 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
802 #.instance-pointer-lowtag
803 #.instance-slots-offset)))
805 (:temporary (:sc unsigned-reg) tmp)
806 (:results (value :scs (complex-single-reg)))
807 (:result-types complex-single-float)
809 (loadw tmp object 0 instance-pointer-lowtag)
810 (inst shr tmp n-widetag-bits)
811 (let ((real-tn (complex-single-reg-real-tn value)))
812 (inst movss real-tn (make-ea-for-raw-slot object index tmp)))
813 (let ((imag-tn (complex-single-reg-imag-tn value)))
814 (inst movss imag-tn (make-ea-for-raw-slot object index tmp 4)))))
816 (define-vop (raw-instance-set/complex-single)
817 (:translate %raw-instance-set/complex-single)
819 (:args (object :scs (descriptor-reg))
820 (index :scs (any-reg))
821 (value :scs (complex-single-reg) :target result))
822 (:arg-types * positive-fixnum complex-single-float)
823 (:temporary (:sc unsigned-reg) tmp)
824 (:results (result :scs (complex-single-reg)))
825 (:result-types complex-single-float)
827 (loadw tmp object 0 instance-pointer-lowtag)
828 (inst shr tmp n-widetag-bits)
831 (let ((value-real (complex-single-reg-real-tn value))
832 (result-real (complex-single-reg-real-tn result)))
833 (inst movss (make-ea-for-raw-slot object index tmp) value-real)
834 (unless (location= value-real result-real)
835 (inst movss result-real value-real)))
836 (let ((value-imag (complex-single-reg-imag-tn value))
837 (result-imag (complex-single-reg-imag-tn result)))
838 (inst movss (make-ea-for-raw-slot object index tmp 4) value-imag)
839 (unless (location= value-imag result-imag)
840 (inst movss result-imag value-imag)))))
842 (define-vop (raw-instance-set-c/complex-single)
843 (:translate %raw-instance-set/complex-single)
845 (:args (object :scs (descriptor-reg))
846 (value :scs (complex-single-reg) :target result))
847 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
848 #.instance-pointer-lowtag
849 #.instance-slots-offset))
850 complex-single-float)
852 (:temporary (:sc unsigned-reg) tmp)
853 (:results (result :scs (complex-single-reg)))
854 (:result-types complex-single-float)
856 (loadw tmp object 0 instance-pointer-lowtag)
857 (inst shr tmp n-widetag-bits)
858 (let ((value-real (complex-single-reg-real-tn value))
859 (result-real (complex-single-reg-real-tn result)))
860 (inst movss (make-ea-for-raw-slot object index tmp) value-real)
861 (unless (location= value-real result-real)
862 (inst movss result-real value-real)))
863 (let ((value-imag (complex-single-reg-imag-tn value))
864 (result-imag (complex-single-reg-imag-tn result)))
865 (inst movss (make-ea-for-raw-slot object index tmp 4) value-imag)
866 (unless (location= value-imag result-imag)
867 (inst movss result-imag value-imag)))))
869 (define-vop (raw-instance-init/complex-single)
870 (:args (object :scs (descriptor-reg))
871 (value :scs (complex-single-reg)))
872 (:arg-types * complex-single-float)
873 (:info instance-length index)
875 (let ((value-real (complex-single-reg-real-tn value)))
876 (inst movss (make-ea-for-raw-slot object index instance-length) value-real))
877 (let ((value-imag (complex-single-reg-imag-tn value)))
878 (inst movss (make-ea-for-raw-slot object index instance-length 4) value-imag))))
880 (define-vop (raw-instance-ref/complex-double)
881 (:translate %raw-instance-ref/complex-double)
883 (:args (object :scs (descriptor-reg))
884 (index :scs (any-reg)))
885 (:arg-types * positive-fixnum)
886 (:temporary (:sc unsigned-reg) tmp)
887 (:results (value :scs (complex-double-reg)))
888 (:result-types complex-double-float)
890 (loadw tmp object 0 instance-pointer-lowtag)
891 (inst shr tmp n-widetag-bits)
894 (let ((real-tn (complex-double-reg-real-tn value)))
895 (inst movsd real-tn (make-ea-for-raw-slot object index tmp -8)))
896 (let ((imag-tn (complex-double-reg-imag-tn value)))
897 (inst movsd imag-tn (make-ea-for-raw-slot object index tmp)))))
899 (define-vop (raw-instance-ref-c/complex-double)
900 (:translate %raw-instance-ref/complex-double)
902 (:args (object :scs (descriptor-reg)))
903 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
904 #.instance-pointer-lowtag
905 #.instance-slots-offset)))
907 (:temporary (:sc unsigned-reg) tmp)
908 (:results (value :scs (complex-double-reg)))
909 (:result-types complex-double-float)
911 (loadw tmp object 0 instance-pointer-lowtag)
912 (inst shr tmp n-widetag-bits)
913 (let ((real-tn (complex-double-reg-real-tn value)))
914 (inst movsd real-tn (make-ea-for-raw-slot object index tmp -8)))
915 (let ((imag-tn (complex-double-reg-imag-tn value)))
916 (inst movsd imag-tn (make-ea-for-raw-slot object index tmp)))))
918 (define-vop (raw-instance-set/complex-double)
919 (:translate %raw-instance-set/complex-double)
921 (:args (object :scs (descriptor-reg))
922 (index :scs (any-reg))
923 (value :scs (complex-double-reg) :target result))
924 (:arg-types * positive-fixnum complex-double-float)
925 (:temporary (:sc unsigned-reg) tmp)
926 (:results (result :scs (complex-double-reg)))
927 (:result-types complex-double-float)
929 (loadw tmp object 0 instance-pointer-lowtag)
930 (inst shr tmp n-widetag-bits)
933 (let ((value-real (complex-double-reg-real-tn value))
934 (result-real (complex-double-reg-real-tn result)))
935 (inst movsd (make-ea-for-raw-slot object index tmp -8) value-real)
936 (unless (location= value-real result-real)
937 (inst movsd result-real value-real)))
938 (let ((value-imag (complex-double-reg-imag-tn value))
939 (result-imag (complex-double-reg-imag-tn result)))
940 (inst movsd (make-ea-for-raw-slot object index tmp) value-imag)
941 (unless (location= value-imag result-imag)
942 (inst movsd result-imag value-imag)))))
944 (define-vop (raw-instance-set-c/complex-double)
945 (:translate %raw-instance-set/complex-double)
947 (:args (object :scs (descriptor-reg))
948 (value :scs (complex-double-reg) :target result))
949 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
950 #.instance-pointer-lowtag
951 #.instance-slots-offset))
952 complex-double-float)
954 (:temporary (:sc unsigned-reg) tmp)
955 (:results (result :scs (complex-double-reg)))
956 (:result-types complex-double-float)
958 (loadw tmp object 0 instance-pointer-lowtag)
959 (inst shr tmp n-widetag-bits)
960 (let ((value-real (complex-double-reg-real-tn value))
961 (result-real (complex-double-reg-real-tn result)))
962 (inst movsd (make-ea-for-raw-slot object index tmp -8) value-real)
963 (unless (location= value-real result-real)
964 (inst movsd result-real value-real)))
965 (let ((value-imag (complex-double-reg-imag-tn value))
966 (result-imag (complex-double-reg-imag-tn result)))
967 (inst movsd (make-ea-for-raw-slot object index tmp) value-imag)
968 (unless (location= value-imag result-imag)
969 (inst movsd result-imag value-imag)))))
971 (define-vop (raw-instance-init/complex-double)
972 (:args (object :scs (descriptor-reg))
973 (value :scs (complex-double-reg)))
974 (:arg-types * complex-double-float)
975 (:info instance-length index)
977 (let ((value-real (complex-double-reg-real-tn value)))
978 (inst movsd (make-ea-for-raw-slot object index instance-length -8) value-real))
979 (let ((value-imag (complex-double-reg-imag-tn value)))
980 (inst movsd (make-ea-for-raw-slot object index instance-length) value-imag))))