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 (init-slot set-slot))
52 (define-vop (compare-and-swap-slot)
53 (:args (object :scs (descriptor-reg) :to :eval)
54 (old :scs (descriptor-reg any-reg) :target rax)
55 (new :scs (descriptor-reg any-reg)))
56 (:temporary (:sc descriptor-reg :offset rax-offset
57 :from (:argument 1) :to :result :target result)
59 (:info name offset lowtag)
61 (:results (result :scs (descriptor-reg any-reg)))
64 (inst cmpxchg (make-ea :qword :base object
65 :disp (- (* offset n-word-bytes) lowtag))
69 ;;;; symbol hacking VOPs
71 (define-vop (%compare-and-swap-symbol-value)
72 (:translate %compare-and-swap-symbol-value)
73 (:args (symbol :scs (descriptor-reg) :to (:result 1))
74 (old :scs (descriptor-reg any-reg) :target rax)
75 (new :scs (descriptor-reg any-reg)))
76 (:temporary (:sc descriptor-reg :offset rax-offset) rax)
78 (:temporary (:sc descriptor-reg) tls)
79 (:results (result :scs (descriptor-reg any-reg)))
83 ;; This code has two pathological cases: NO-TLS-VALUE-MARKER
84 ;; or UNBOUND-MARKER as NEW: in either case we would end up
85 ;; doing possible damage with CMPXCHG -- so don't do that!
86 (let ((unbound (generate-error-code vop 'unbound-symbol-error symbol))
91 (loadw tls symbol symbol-tls-index-slot other-pointer-lowtag)
92 ;; Thread-local area, no LOCK needed.
93 (inst cmpxchg (make-ea :qword :base thread-base-tn
96 (inst cmp rax no-tls-value-marker-widetag)
99 (inst cmpxchg (make-ea :qword :base symbol
100 :disp (- (* symbol-value-slot n-word-bytes)
101 other-pointer-lowtag)
106 (inst cmp result unbound-marker-widetag)
107 (inst jmp :e unbound))))
109 (define-vop (%set-symbol-global-value cell-set)
110 (:variant symbol-value-slot other-pointer-lowtag))
112 (define-vop (fast-symbol-global-value cell-ref)
113 (:variant symbol-value-slot other-pointer-lowtag)
115 (:translate symbol-global-value))
117 (define-vop (symbol-global-value)
119 (:translate symbol-global-value)
120 (:args (object :scs (descriptor-reg) :to (:result 1)))
121 (:results (value :scs (descriptor-reg any-reg)))
123 (:save-p :compute-only)
125 (let ((err-lab (generate-error-code vop 'unbound-symbol-error object)))
126 (loadw value object symbol-value-slot other-pointer-lowtag)
127 (inst cmp value unbound-marker-widetag)
128 (inst jmp :e err-lab))))
133 (:args (symbol :scs (descriptor-reg))
134 (value :scs (descriptor-reg any-reg)))
135 (:temporary (:sc descriptor-reg) tls)
137 (let ((global-val (gen-label))
139 (loadw tls symbol symbol-tls-index-slot other-pointer-lowtag)
140 (inst cmp (make-ea :qword :base thread-base-tn :scale 1 :index tls)
141 no-tls-value-marker-widetag)
142 (inst jmp :z global-val)
143 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls)
146 (emit-label global-val)
147 (storew value symbol symbol-value-slot other-pointer-lowtag)
150 ;; With Symbol-Value, we check that the value isn't the trap object. So
151 ;; Symbol-Value of NIL is NIL.
152 (define-vop (symbol-value)
153 (:translate symbol-value)
155 (:args (object :scs (descriptor-reg) :to (:result 1)))
156 (:results (value :scs (descriptor-reg any-reg)))
158 (:save-p :compute-only)
160 (let* ((check-unbound-label (gen-label))
161 (err-lab (generate-error-code vop 'unbound-symbol-error object))
162 (ret-lab (gen-label)))
163 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
164 (inst mov value (make-ea :qword :base thread-base-tn
165 :index value :scale 1))
166 (inst cmp value no-tls-value-marker-widetag)
167 (inst jmp :ne check-unbound-label)
168 (loadw value object symbol-value-slot other-pointer-lowtag)
169 (emit-label check-unbound-label)
170 (inst cmp value unbound-marker-widetag)
171 (inst jmp :e err-lab)
172 (emit-label ret-lab))))
174 (define-vop (fast-symbol-value symbol-value)
175 ;; KLUDGE: not really fast, in fact, because we're going to have to
176 ;; do a full lookup of the thread-local area anyway. But half of
177 ;; the meaning of FAST-SYMBOL-VALUE is "do not signal an error if
178 ;; unbound", which is used in the implementation of COPY-SYMBOL. --
181 (:translate symbol-value)
183 (let ((ret-lab (gen-label)))
184 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
186 (make-ea :qword :base thread-base-tn :index value :scale 1))
187 (inst cmp value no-tls-value-marker-widetag)
188 (inst jmp :ne ret-lab)
189 (loadw value object symbol-value-slot other-pointer-lowtag)
190 (emit-label ret-lab)))))
194 (define-vop (symbol-value symbol-global-value)
195 (:translate symbol-value))
196 (define-vop (fast-symbol-value fast-symbol-global-value)
197 (:translate symbol-value))
198 (define-vop (set %set-symbol-global-value)))
204 (:args (object :scs (descriptor-reg)))
206 (:temporary (:sc descriptor-reg #+nil(:from (:argument 0))) value)
208 (let ((check-unbound-label (gen-label)))
209 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
211 (make-ea :qword :base thread-base-tn :index value :scale 1))
212 (inst cmp value no-tls-value-marker-widetag)
213 (inst jmp :ne check-unbound-label)
214 (loadw value object symbol-value-slot other-pointer-lowtag)
215 (emit-label check-unbound-label)
216 (inst cmp value unbound-marker-widetag))))
222 (:args (object :scs (descriptor-reg)))
225 (inst cmp (make-ea-for-object-slot object symbol-value-slot
226 other-pointer-lowtag)
227 unbound-marker-widetag)))
230 (define-vop (symbol-hash)
232 (:translate symbol-hash)
233 (:args (symbol :scs (descriptor-reg)))
234 (:results (res :scs (any-reg)))
235 (:result-types positive-fixnum)
237 ;; The symbol-hash slot of NIL holds NIL because it is also the
238 ;; cdr slot, so we have to strip off the three low bits to make sure
239 ;; it is a fixnum. The lowtag selection magic that is required to
240 ;; ensure this is explained in the comment in objdef.lisp
241 (loadw res symbol symbol-hash-slot other-pointer-lowtag)
242 (inst and res (lognot fixnum-tag-mask))))
244 ;;;; fdefinition (FDEFN) objects
246 (define-vop (fdefn-fun cell-ref) ; /pfw - alpha
247 (:variant fdefn-fun-slot other-pointer-lowtag))
249 (define-vop (safe-fdefn-fun)
250 (:args (object :scs (descriptor-reg) :to (:result 1)))
251 (:results (value :scs (descriptor-reg any-reg)))
253 (:save-p :compute-only)
255 (loadw value object fdefn-fun-slot other-pointer-lowtag)
256 (inst cmp value nil-value)
257 (let ((err-lab (generate-error-code vop 'undefined-fun-error object)))
258 (inst jmp :e err-lab))))
260 (define-vop (set-fdefn-fun)
262 (:translate (setf fdefn-fun))
263 (:args (function :scs (descriptor-reg) :target result)
264 (fdefn :scs (descriptor-reg)))
265 (:temporary (:sc unsigned-reg) raw)
266 (:temporary (:sc unsigned-reg) type)
267 (:results (result :scs (descriptor-reg)))
269 (load-type type function (- fun-pointer-lowtag))
271 (make-ea :byte :base function
272 :disp (- (* simple-fun-code-offset n-word-bytes)
273 fun-pointer-lowtag)))
274 (inst cmp (reg-in-size type :byte) simple-fun-header-widetag)
275 (inst jmp :e NORMAL-FUN)
276 (inst lea raw (make-fixup "closure_tramp" :foreign))
278 (storew function fdefn fdefn-fun-slot other-pointer-lowtag)
279 (storew raw fdefn fdefn-raw-addr-slot other-pointer-lowtag)
280 (move result function)))
282 (define-vop (fdefn-makunbound)
284 (:translate fdefn-makunbound)
285 (:args (fdefn :scs (descriptor-reg) :target result))
286 (:results (result :scs (descriptor-reg)))
288 (storew nil-value fdefn fdefn-fun-slot other-pointer-lowtag)
289 (storew (make-fixup "undefined_tramp" :foreign)
290 fdefn fdefn-raw-addr-slot other-pointer-lowtag)
291 (move result fdefn)))
293 ;;;; binding and unbinding
295 ;;; BIND -- Establish VAL as a binding for SYMBOL. Save the old value and
296 ;;; the symbol on the binding stack and stuff the new value into the
301 (:args (val :scs (any-reg descriptor-reg))
302 (symbol :scs (descriptor-reg)))
303 (:temporary (:sc unsigned-reg) tls-index bsp)
305 (let ((tls-index-valid (gen-label)))
306 (load-binding-stack-pointer bsp)
307 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
308 (inst add bsp (* binding-size n-word-bytes))
309 (store-binding-stack-pointer bsp)
310 (inst test tls-index tls-index)
311 (inst jmp :ne tls-index-valid)
312 (inst mov tls-index symbol)
313 (inst lea temp-reg-tn
314 (make-ea :qword :disp
315 (make-fixup (ecase (tn-offset tls-index)
316 (#.rax-offset 'alloc-tls-index-in-rax)
317 (#.rcx-offset 'alloc-tls-index-in-rcx)
318 (#.rdx-offset 'alloc-tls-index-in-rdx)
319 (#.rbx-offset 'alloc-tls-index-in-rbx)
320 (#.rsi-offset 'alloc-tls-index-in-rsi)
321 (#.rdi-offset 'alloc-tls-index-in-rdi)
322 (#.r8-offset 'alloc-tls-index-in-r8)
323 (#.r9-offset 'alloc-tls-index-in-r9)
324 (#.r10-offset 'alloc-tls-index-in-r10)
325 (#.r12-offset 'alloc-tls-index-in-r12)
326 (#.r13-offset 'alloc-tls-index-in-r13)
327 (#.r14-offset 'alloc-tls-index-in-r14)
328 (#.r15-offset 'alloc-tls-index-in-r15))
330 (inst call temp-reg-tn)
331 (emit-label tls-index-valid)
332 (inst push (make-ea :qword :base thread-base-tn :scale 1 :index tls-index))
333 (popw bsp (- binding-value-slot binding-size))
334 (storew symbol bsp (- binding-symbol-slot binding-size))
335 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
340 (:args (val :scs (any-reg descriptor-reg))
341 (symbol :scs (descriptor-reg)))
342 (:temporary (:sc unsigned-reg) temp bsp)
344 (load-symbol-value bsp *binding-stack-pointer*)
345 (loadw temp symbol symbol-value-slot other-pointer-lowtag)
346 (inst add bsp (* binding-size n-word-bytes))
347 (store-symbol-value bsp *binding-stack-pointer*)
348 (storew temp bsp (- binding-value-slot binding-size))
349 (storew symbol bsp (- binding-symbol-slot binding-size))
350 (storew val symbol symbol-value-slot other-pointer-lowtag)))
354 (:temporary (:sc unsigned-reg) temp bsp tls-index)
356 (load-binding-stack-pointer bsp)
357 ;; Load SYMBOL from stack, and get the TLS-INDEX
358 (loadw temp bsp (- binding-symbol-slot binding-size))
359 (loadw tls-index temp symbol-tls-index-slot other-pointer-lowtag)
360 ;; Load VALUE from stack, the restore it to the TLS area.
361 (loadw temp bsp (- binding-value-slot binding-size))
362 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
364 ;; Zero out the stack.
365 (storew 0 bsp (- binding-symbol-slot binding-size))
366 (storew 0 bsp (- binding-value-slot binding-size))
367 (inst sub bsp (* binding-size n-word-bytes))
368 (store-binding-stack-pointer bsp)))
372 (:temporary (:sc unsigned-reg) symbol value bsp)
374 (load-symbol-value bsp *binding-stack-pointer*)
375 (loadw symbol bsp (- binding-symbol-slot binding-size))
376 (loadw value bsp (- binding-value-slot binding-size))
377 (storew value symbol symbol-value-slot other-pointer-lowtag)
378 (storew 0 bsp (- binding-symbol-slot binding-size))
379 (storew 0 bsp (- binding-value-slot binding-size))
380 (inst sub bsp (* binding-size n-word-bytes))
381 (store-symbol-value bsp *binding-stack-pointer*)))
383 (define-vop (unbind-to-here)
384 (:args (where :scs (descriptor-reg any-reg)))
385 (:temporary (:sc unsigned-reg) symbol value bsp #!+sb-thread tls-index)
387 (load-binding-stack-pointer bsp)
392 (loadw symbol bsp (- binding-symbol-slot binding-size))
393 (inst test symbol symbol)
395 ;; Bind stack debug sentinels have the unbound marker in the symbol slot
396 (inst cmp symbol unbound-marker-widetag)
398 (loadw value bsp (- binding-value-slot binding-size))
400 (storew value symbol symbol-value-slot other-pointer-lowtag)
402 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
404 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
406 (storew 0 bsp (- binding-symbol-slot binding-size))
409 (storew 0 bsp (- binding-value-slot binding-size))
410 (inst sub bsp (* binding-size n-word-bytes))
413 (store-binding-stack-pointer bsp)
417 (define-vop (bind-sentinel)
418 (:temporary (:sc unsigned-reg) bsp)
420 (load-binding-stack-pointer bsp)
421 (inst add bsp (* binding-size n-word-bytes))
422 (storew unbound-marker-widetag bsp (- binding-symbol-slot binding-size))
423 (storew rbp-tn bsp (- binding-value-slot binding-size))
424 (store-binding-stack-pointer bsp)))
426 (define-vop (unbind-sentinel)
427 (:temporary (:sc unsigned-reg) bsp)
429 (load-binding-stack-pointer bsp)
430 (storew 0 bsp (- binding-value-slot binding-size))
431 (storew 0 bsp (- binding-symbol-slot binding-size))
432 (inst sub bsp (* binding-size n-word-bytes))
433 (store-binding-stack-pointer bsp)))
438 ;;;; closure indexing
440 (define-full-reffer closure-index-ref *
441 closure-info-offset fun-pointer-lowtag
442 (any-reg descriptor-reg) * %closure-index-ref)
444 (define-full-setter set-funcallable-instance-info *
445 funcallable-instance-info-offset fun-pointer-lowtag
446 (any-reg descriptor-reg) * %set-funcallable-instance-info)
448 (define-full-reffer funcallable-instance-info *
449 funcallable-instance-info-offset fun-pointer-lowtag
450 (descriptor-reg any-reg) * %funcallable-instance-info)
452 (define-vop (closure-ref slot-ref)
453 (:variant closure-info-offset fun-pointer-lowtag))
455 (define-vop (closure-init slot-set)
456 (:variant closure-info-offset fun-pointer-lowtag))
458 (define-vop (closure-init-from-fp)
459 (:args (object :scs (descriptor-reg)))
462 (storew rbp-tn object (+ closure-info-offset offset) fun-pointer-lowtag)))
464 ;;;; value cell hackery
466 (define-vop (value-cell-ref cell-ref)
467 (:variant value-cell-value-slot other-pointer-lowtag))
469 (define-vop (value-cell-set cell-set)
470 (:variant value-cell-value-slot other-pointer-lowtag))
472 ;;;; structure hackery
474 (define-vop (instance-length)
476 (:translate %instance-length)
477 (:args (struct :scs (descriptor-reg)))
478 (:results (res :scs (unsigned-reg)))
479 (:result-types positive-fixnum)
481 (loadw res struct 0 instance-pointer-lowtag)
482 (inst shr res n-widetag-bits)))
484 (define-full-reffer instance-index-ref * instance-slots-offset
485 instance-pointer-lowtag (any-reg descriptor-reg) * %instance-ref)
487 (define-full-setter instance-index-set * instance-slots-offset
488 instance-pointer-lowtag (any-reg descriptor-reg) * %instance-set)
490 (define-full-compare-and-swap %compare-and-swap-instance-ref instance
491 instance-slots-offset instance-pointer-lowtag
492 (any-reg descriptor-reg) *
493 %compare-and-swap-instance-ref)
495 ;;;; code object frobbing
497 (define-full-reffer code-header-ref * 0 other-pointer-lowtag
498 (any-reg descriptor-reg) * code-header-ref)
500 (define-full-setter code-header-set * 0 other-pointer-lowtag
501 (any-reg descriptor-reg) * code-header-set)
503 ;;;; raw instance slot accessors
505 (defun make-ea-for-raw-slot (object instance-length
506 &key (index nil) (adjustment 0) (scale 1))
507 (if (integerp instance-length)
508 ;; For RAW-INSTANCE-INIT/* VOPs, which know the exact instance length
512 :disp (+ (* (- instance-length instance-slots-offset index)
514 (- instance-pointer-lowtag)
518 (make-ea :qword :base object :index instance-length :scale scale
519 :disp (+ (* (1- instance-slots-offset) n-word-bytes)
520 (- instance-pointer-lowtag)
523 (make-ea :qword :base object :index instance-length
525 :disp (+ (* (1- instance-slots-offset) n-word-bytes)
526 (- instance-pointer-lowtag)
528 (* index (- n-word-bytes))))))))
530 (define-vop (raw-instance-ref/word)
531 (:translate %raw-instance-ref/word)
533 (:args (object :scs (descriptor-reg)) (index :scs (any-reg)))
534 (:arg-types * tagged-num)
535 (:temporary (:sc unsigned-reg) tmp)
536 (:results (value :scs (unsigned-reg)))
537 (:result-types unsigned-num)
539 (loadw tmp object 0 instance-pointer-lowtag)
540 (inst shr tmp n-widetag-bits)
541 (inst shl tmp n-fixnum-tag-bits)
543 (inst mov value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))))))
545 (define-vop (raw-instance-ref-c/word)
546 (:translate %raw-instance-ref/word)
548 (:args (object :scs (descriptor-reg)))
549 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
550 #.instance-pointer-lowtag
551 #.instance-slots-offset)))
553 (:temporary (:sc unsigned-reg) tmp)
554 (:results (value :scs (unsigned-reg)))
555 (:result-types unsigned-num)
557 (loadw tmp object 0 instance-pointer-lowtag)
558 (inst shr tmp n-widetag-bits)
559 (inst mov value (make-ea-for-raw-slot object tmp :index index))))
561 (define-vop (raw-instance-set/word)
562 (:translate %raw-instance-set/word)
564 (:args (object :scs (descriptor-reg))
565 (index :scs (any-reg))
566 (value :scs (unsigned-reg) :target result))
567 (:arg-types * tagged-num unsigned-num)
568 (:temporary (:sc unsigned-reg) tmp)
569 (:results (result :scs (unsigned-reg)))
570 (:result-types unsigned-num)
572 (loadw tmp object 0 instance-pointer-lowtag)
573 (inst shr tmp n-widetag-bits)
574 (inst shl tmp n-fixnum-tag-bits)
576 (inst mov (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))) value)
577 (move result value)))
579 (define-vop (raw-instance-set-c/word)
580 (:translate %raw-instance-set/word)
582 (:args (object :scs (descriptor-reg))
583 (value :scs (unsigned-reg) :target result))
584 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
585 #.instance-pointer-lowtag
586 #.instance-slots-offset))
589 (:temporary (:sc unsigned-reg) tmp)
590 (:results (result :scs (unsigned-reg)))
591 (:result-types unsigned-num)
593 (loadw tmp object 0 instance-pointer-lowtag)
594 (inst shr tmp n-widetag-bits)
595 (inst mov (make-ea-for-raw-slot object tmp :index index) value)
596 (move result value)))
598 (define-vop (raw-instance-init/word)
599 (:args (object :scs (descriptor-reg))
600 (value :scs (unsigned-reg)))
601 (:arg-types * unsigned-num)
602 (:info instance-length index)
604 (inst mov (make-ea-for-raw-slot object instance-length :index index) value)))
606 (define-vop (raw-instance-atomic-incf-c/word)
607 (:translate %raw-instance-atomic-incf/word)
609 (:args (object :scs (descriptor-reg))
610 (diff :scs (unsigned-reg) :target result))
611 (:arg-types * (:constant (load/store-index #.n-word-bytes
612 #.instance-pointer-lowtag
613 #.instance-slots-offset))
616 (:temporary (:sc unsigned-reg) tmp)
617 (:results (result :scs (unsigned-reg)))
618 (:result-types unsigned-num)
620 (loadw tmp object 0 instance-pointer-lowtag)
621 (inst shr tmp n-widetag-bits)
622 (inst xadd (make-ea-for-raw-slot object tmp :index index) diff :lock)
625 (define-vop (raw-instance-ref/single)
626 (:translate %raw-instance-ref/single)
628 (:args (object :scs (descriptor-reg))
629 (index :scs (any-reg)))
630 (:arg-types * positive-fixnum)
631 (:temporary (:sc unsigned-reg) tmp)
632 (:results (value :scs (single-reg)))
633 (:result-types single-float)
635 (loadw tmp object 0 instance-pointer-lowtag)
636 (inst shr tmp n-widetag-bits)
637 (inst shl tmp n-fixnum-tag-bits)
639 (inst movss value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))))))
641 (define-vop (raw-instance-ref-c/single)
642 (:translate %raw-instance-ref/single)
644 (:args (object :scs (descriptor-reg)))
645 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
646 #.instance-pointer-lowtag
647 #.instance-slots-offset)))
649 (:temporary (:sc unsigned-reg) tmp)
650 (:results (value :scs (single-reg)))
651 (:result-types single-float)
653 (loadw tmp object 0 instance-pointer-lowtag)
654 (inst shr tmp n-widetag-bits)
655 (inst movss value (make-ea-for-raw-slot object tmp :index index))))
657 (define-vop (raw-instance-set/single)
658 (:translate %raw-instance-set/single)
660 (:args (object :scs (descriptor-reg))
661 (index :scs (any-reg))
662 (value :scs (single-reg) :target result))
663 (:arg-types * positive-fixnum single-float)
664 (:temporary (:sc unsigned-reg) tmp)
665 (:results (result :scs (single-reg)))
666 (:result-types single-float)
668 (loadw tmp object 0 instance-pointer-lowtag)
669 (inst shr tmp n-widetag-bits)
670 (inst shl tmp n-fixnum-tag-bits)
672 (inst movss (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))) value)
673 (move result value)))
675 (define-vop (raw-instance-set-c/single)
676 (:translate %raw-instance-set/single)
678 (:args (object :scs (descriptor-reg))
679 (value :scs (single-reg) :target result))
680 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
681 #.instance-pointer-lowtag
682 #.instance-slots-offset))
685 (:temporary (:sc unsigned-reg) tmp)
686 (:results (result :scs (single-reg)))
687 (:result-types single-float)
689 (loadw tmp object 0 instance-pointer-lowtag)
690 (inst shr tmp n-widetag-bits)
691 (inst movss (make-ea-for-raw-slot object tmp :index index) value)
692 (move result value)))
694 (define-vop (raw-instance-init/single)
695 (:args (object :scs (descriptor-reg))
696 (value :scs (single-reg)))
697 (:arg-types * single-float)
698 (:info instance-length index)
700 (inst movss (make-ea-for-raw-slot object instance-length :index index) value)))
702 (define-vop (raw-instance-ref/double)
703 (:translate %raw-instance-ref/double)
705 (:args (object :scs (descriptor-reg))
706 (index :scs (any-reg)))
707 (:arg-types * positive-fixnum)
708 (:temporary (:sc unsigned-reg) tmp)
709 (:results (value :scs (double-reg)))
710 (:result-types double-float)
712 (loadw tmp object 0 instance-pointer-lowtag)
713 (inst shr tmp n-widetag-bits)
714 (inst shl tmp n-fixnum-tag-bits)
716 (inst movsd value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))))))
718 (define-vop (raw-instance-ref-c/double)
719 (:translate %raw-instance-ref/double)
721 (:args (object :scs (descriptor-reg)))
722 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
723 #.instance-pointer-lowtag
724 #.instance-slots-offset)))
726 (:temporary (:sc unsigned-reg) tmp)
727 (:results (value :scs (double-reg)))
728 (:result-types double-float)
730 (loadw tmp object 0 instance-pointer-lowtag)
731 (inst shr tmp n-widetag-bits)
732 (inst movsd value (make-ea-for-raw-slot object tmp :index index))))
734 (define-vop (raw-instance-set/double)
735 (:translate %raw-instance-set/double)
737 (:args (object :scs (descriptor-reg))
738 (index :scs (any-reg))
739 (value :scs (double-reg) :target result))
740 (:arg-types * positive-fixnum double-float)
741 (:temporary (:sc unsigned-reg) tmp)
742 (:results (result :scs (double-reg)))
743 (:result-types double-float)
745 (loadw tmp object 0 instance-pointer-lowtag)
746 (inst shr tmp n-widetag-bits)
747 (inst shl tmp n-fixnum-tag-bits)
749 (inst movsd (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))) value)
750 (move result value)))
752 (define-vop (raw-instance-set-c/double)
753 (:translate %raw-instance-set/double)
755 (:args (object :scs (descriptor-reg))
756 (value :scs (double-reg) :target result))
757 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
758 #.instance-pointer-lowtag
759 #.instance-slots-offset))
762 (:temporary (:sc unsigned-reg) tmp)
763 (:results (result :scs (double-reg)))
764 (:result-types double-float)
766 (loadw tmp object 0 instance-pointer-lowtag)
767 (inst shr tmp n-widetag-bits)
768 (inst movsd (make-ea-for-raw-slot object tmp :index index) value)
769 (move result value)))
771 (define-vop (raw-instance-init/double)
772 (:args (object :scs (descriptor-reg))
773 (value :scs (double-reg)))
774 (:arg-types * double-float)
775 (:info instance-length index)
777 (inst movsd (make-ea-for-raw-slot object instance-length :index index) value)))
779 (define-vop (raw-instance-ref/complex-single)
780 (:translate %raw-instance-ref/complex-single)
782 (:args (object :scs (descriptor-reg))
783 (index :scs (any-reg)))
784 (:arg-types * positive-fixnum)
785 (:temporary (:sc unsigned-reg) tmp)
786 (:results (value :scs (complex-single-reg)))
787 (:result-types complex-single-float)
789 (loadw tmp object 0 instance-pointer-lowtag)
790 (inst shr tmp n-widetag-bits)
791 (inst shl tmp n-fixnum-tag-bits)
793 (inst movq value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))))))
795 (define-vop (raw-instance-ref-c/complex-single)
796 (:translate %raw-instance-ref/complex-single)
798 (:args (object :scs (descriptor-reg)))
799 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
800 #.instance-pointer-lowtag
801 #.instance-slots-offset)))
803 (:temporary (:sc unsigned-reg) tmp)
804 (:results (value :scs (complex-single-reg)))
805 (:result-types complex-single-float)
807 (loadw tmp object 0 instance-pointer-lowtag)
808 (inst shr tmp n-widetag-bits)
809 (inst movq value (make-ea-for-raw-slot object tmp :index index))))
811 (define-vop (raw-instance-set/complex-single)
812 (:translate %raw-instance-set/complex-single)
814 (:args (object :scs (descriptor-reg))
815 (index :scs (any-reg))
816 (value :scs (complex-single-reg) :target result))
817 (:arg-types * positive-fixnum complex-single-float)
818 (:temporary (:sc unsigned-reg) tmp)
819 (:results (result :scs (complex-single-reg)))
820 (:result-types complex-single-float)
822 (loadw tmp object 0 instance-pointer-lowtag)
823 (inst shr tmp n-widetag-bits)
824 (inst shl tmp n-fixnum-tag-bits)
827 (inst movq (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits))) value)))
829 (define-vop (raw-instance-set-c/complex-single)
830 (:translate %raw-instance-set/complex-single)
832 (:args (object :scs (descriptor-reg))
833 (value :scs (complex-single-reg) :target result))
834 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
835 #.instance-pointer-lowtag
836 #.instance-slots-offset))
837 complex-single-float)
839 (:temporary (:sc unsigned-reg) tmp)
840 (:results (result :scs (complex-single-reg)))
841 (:result-types complex-single-float)
843 (loadw tmp object 0 instance-pointer-lowtag)
844 (inst shr tmp n-widetag-bits)
846 (inst movq (make-ea-for-raw-slot object tmp :index index) value)))
848 (define-vop (raw-instance-init/complex-single)
849 (:args (object :scs (descriptor-reg))
850 (value :scs (complex-single-reg)))
851 (:arg-types * complex-single-float)
852 (:info instance-length index)
854 (inst movq (make-ea-for-raw-slot object instance-length :index index) value)))
856 (define-vop (raw-instance-ref/complex-double)
857 (:translate %raw-instance-ref/complex-double)
859 (:args (object :scs (descriptor-reg))
860 (index :scs (any-reg)))
861 (:arg-types * positive-fixnum)
862 (:temporary (:sc unsigned-reg) tmp)
863 (:results (value :scs (complex-double-reg)))
864 (:result-types complex-double-float)
866 (loadw tmp object 0 instance-pointer-lowtag)
867 (inst shr tmp n-widetag-bits)
868 (inst shl tmp n-fixnum-tag-bits)
870 (inst movdqu value (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits)) :adjustment -8))))
872 (define-vop (raw-instance-ref-c/complex-double)
873 (:translate %raw-instance-ref/complex-double)
875 (:args (object :scs (descriptor-reg)))
876 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
877 #.instance-pointer-lowtag
878 #.instance-slots-offset)))
880 (:temporary (:sc unsigned-reg) tmp)
881 (:results (value :scs (complex-double-reg)))
882 (:result-types complex-double-float)
884 (loadw tmp object 0 instance-pointer-lowtag)
885 (inst shr tmp n-widetag-bits)
886 (inst movdqu value (make-ea-for-raw-slot object tmp :index index :adjustment -8))))
888 (define-vop (raw-instance-set/complex-double)
889 (:translate %raw-instance-set/complex-double)
891 (:args (object :scs (descriptor-reg))
892 (index :scs (any-reg))
893 (value :scs (complex-double-reg) :target result))
894 (:arg-types * positive-fixnum complex-double-float)
895 (:temporary (:sc unsigned-reg) tmp)
896 (:results (result :scs (complex-double-reg)))
897 (:result-types complex-double-float)
899 (loadw tmp object 0 instance-pointer-lowtag)
900 (inst shr tmp n-widetag-bits)
901 (inst shl tmp n-fixnum-tag-bits)
904 (inst movdqu (make-ea-for-raw-slot object tmp :scale (ash 1 (- word-shift n-fixnum-tag-bits)) :adjustment -8) value)))
906 (define-vop (raw-instance-set-c/complex-double)
907 (:translate %raw-instance-set/complex-double)
909 (:args (object :scs (descriptor-reg))
910 (value :scs (complex-double-reg) :target result))
911 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
912 #.instance-pointer-lowtag
913 #.instance-slots-offset))
914 complex-double-float)
916 (:temporary (:sc unsigned-reg) tmp)
917 (:results (result :scs (complex-double-reg)))
918 (:result-types complex-double-float)
920 (loadw tmp object 0 instance-pointer-lowtag)
921 (inst shr tmp n-widetag-bits)
923 (inst movdqu (make-ea-for-raw-slot object tmp :index index :adjustment -8) value)))
925 (define-vop (raw-instance-init/complex-double)
926 (:args (object :scs (descriptor-reg))
927 (value :scs (complex-double-reg)))
928 (:arg-types * complex-double-float)
929 (:info instance-length index)
931 (inst movdqu (make-ea-for-raw-slot object instance-length :index index :adjustment -8) value)))