1.0.17.4: support for dynamic-extent structures
[sbcl/tcr.git] / src / compiler / x86-64 / cell.lisp
blob213c90074b0e698d6d00d4950717eadafb4d18f1
1 ;;;; various primitive memory access VOPs for the x86 VM
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
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.
12 (in-package "SB!VM")
14 ;;;; data object ref/set stuff
16 (define-vop (slot)
17 (:args (object :scs (descriptor-reg)))
18 (:info name offset lowtag)
19 (:ignore name)
20 (:results (result :scs (descriptor-reg any-reg)))
21 (:generator 1
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)
29 (:ignore name)
30 (:results)
31 (:generator 1
32 (if (sc-is value immediate)
33 (let ((val (tn-value value)))
34 (move-immediate (make-ea :qword
35 :base object
36 :disp (- (* offset n-word-bytes)
37 lowtag))
38 (etypecase val
39 (integer
40 (fixnumize val))
41 (symbol
42 (+ nil-value (static-symbol-offset val)))
43 (character
44 (logior (ash (char-code val) n-widetag-bits)
45 character-widetag)))
46 temp))
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)
56 rax)
57 (:info name offset lowtag)
58 (:ignore name)
59 (:results (result :scs (descriptor-reg any-reg)))
60 (:generator 5
61 (move rax old)
62 #!+sb-thread
63 (inst lock)
64 (inst cmpxchg (make-ea :qword :base object
65 :disp (- (* offset n-word-bytes) lowtag))
66 new)
67 (move result rax)))
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)
77 #!+sb-thread
78 (:temporary (:sc descriptor-reg) tls)
79 (:results (result :scs (descriptor-reg any-reg)))
80 (:policy :fast-safe)
81 (:vop-var vop)
82 (:generator 15
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))
87 (check (gen-label)))
88 (move rax old)
89 #!+sb-thread
90 (progn
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
94 :index tls :scale 1)
95 new)
96 (inst cmp rax no-tls-value-marker-widetag)
97 (inst jmp :ne check)
98 (move rax old)
99 (inst lock))
100 (inst cmpxchg (make-ea :qword :base symbol
101 :disp (- (* symbol-value-slot n-word-bytes)
102 other-pointer-lowtag)
103 :scale 1)
104 new)
105 (emit-label check)
106 (move result rax)
107 (inst cmp result unbound-marker-widetag)
108 (inst jmp :e unbound))))
110 ;;; these next two cf the sparc version, by jrd.
111 ;;; FIXME: Deref this ^ reference.
114 ;;; The compiler likes to be able to directly SET symbols.
115 #!+sb-thread
116 (define-vop (set)
117 (:args (symbol :scs (descriptor-reg))
118 (value :scs (descriptor-reg any-reg)))
119 (:temporary (:sc descriptor-reg) tls)
120 ;;(:policy :fast-safe)
121 (:generator 4
122 (let ((global-val (gen-label))
123 (done (gen-label)))
124 (loadw tls symbol symbol-tls-index-slot other-pointer-lowtag)
125 (inst cmp (make-ea :qword :base thread-base-tn :scale 1 :index tls)
126 no-tls-value-marker-widetag)
127 (inst jmp :z global-val)
128 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls)
129 value)
130 (inst jmp done)
131 (emit-label global-val)
132 (storew value symbol symbol-value-slot other-pointer-lowtag)
133 (emit-label done))))
135 ;; unithreaded it's a lot simpler ...
136 #!-sb-thread
137 (define-vop (set cell-set)
138 (:variant symbol-value-slot other-pointer-lowtag))
140 ;;; With Symbol-Value, we check that the value isn't the trap object. So
141 ;;; Symbol-Value of NIL is NIL.
142 #!+sb-thread
143 (define-vop (symbol-value)
144 (:translate symbol-value)
145 (:policy :fast-safe)
146 (:args (object :scs (descriptor-reg) :to (:result 1)))
147 (:results (value :scs (descriptor-reg any-reg)))
148 (:vop-var vop)
149 (:save-p :compute-only)
150 (:generator 9
151 (let* ((check-unbound-label (gen-label))
152 (err-lab (generate-error-code vop 'unbound-symbol-error object))
153 (ret-lab (gen-label)))
154 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
155 (inst mov value (make-ea :qword :base thread-base-tn
156 :index value :scale 1))
157 (inst cmp value no-tls-value-marker-widetag)
158 (inst jmp :ne check-unbound-label)
159 (loadw value object symbol-value-slot other-pointer-lowtag)
160 (emit-label check-unbound-label)
161 (inst cmp value unbound-marker-widetag)
162 (inst jmp :e err-lab)
163 (emit-label ret-lab))))
165 #!+sb-thread
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. --
171 ;; CSR, 2003-04-22
172 (:policy :fast)
173 (:translate symbol-value)
174 (:generator 8
175 (let ((ret-lab (gen-label)))
176 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
177 (inst mov value
178 (make-ea :qword :base thread-base-tn :index value :scale 1))
179 (inst cmp value no-tls-value-marker-widetag)
180 (inst jmp :ne ret-lab)
181 (loadw value object symbol-value-slot other-pointer-lowtag)
182 (emit-label ret-lab))))
184 #!-sb-thread
185 (define-vop (symbol-value)
186 (:translate symbol-value)
187 (:policy :fast-safe)
188 (:args (object :scs (descriptor-reg) :to (:result 1)))
189 (:results (value :scs (descriptor-reg any-reg)))
190 (:vop-var vop)
191 (:save-p :compute-only)
192 (:generator 9
193 (let ((err-lab (generate-error-code vop 'unbound-symbol-error object)))
194 (loadw value object symbol-value-slot other-pointer-lowtag)
195 (inst cmp value unbound-marker-widetag)
196 (inst jmp :e err-lab))))
198 #!-sb-thread
199 (define-vop (fast-symbol-value cell-ref)
200 (:variant symbol-value-slot other-pointer-lowtag)
201 (:policy :fast)
202 (:translate symbol-value))
204 (defknown locked-symbol-global-value-add (symbol fixnum) fixnum ())
206 (define-vop (locked-symbol-global-value-add)
207 (:args (object :scs (descriptor-reg) :to :result)
208 (value :scs (any-reg) :target result))
209 (:arg-types * tagged-num)
210 (:results (result :scs (any-reg) :from (:argument 1)))
211 (:policy :fast)
212 (:translate locked-symbol-global-value-add)
213 (:result-types tagged-num)
214 (:policy :fast-safe)
215 (:generator 4
216 (move result value)
217 (inst lock)
218 (inst add (make-ea :qword :base object
219 :disp (- (* symbol-value-slot n-word-bytes)
220 other-pointer-lowtag))
221 value)))
223 #!+sb-thread
224 (define-vop (boundp)
225 (:translate boundp)
226 (:policy :fast-safe)
227 (:args (object :scs (descriptor-reg)))
228 (:conditional)
229 (:info target not-p)
230 (:temporary (:sc descriptor-reg #+nil(:from (:argument 0))) value)
231 (:generator 9
232 (let ((check-unbound-label (gen-label)))
233 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
234 (inst mov value
235 (make-ea :qword :base thread-base-tn :index value :scale 1))
236 (inst cmp value no-tls-value-marker-widetag)
237 (inst jmp :ne check-unbound-label)
238 (loadw value object symbol-value-slot other-pointer-lowtag)
239 (emit-label check-unbound-label)
240 (inst cmp value unbound-marker-widetag)
241 (inst jmp (if not-p :e :ne) target))))
243 #!-sb-thread
244 (define-vop (boundp)
245 (:translate boundp)
246 (:policy :fast-safe)
247 (:args (object :scs (descriptor-reg)))
248 (:conditional)
249 (:info target not-p)
250 (:generator 9
251 (inst cmp (make-ea-for-object-slot object symbol-value-slot
252 other-pointer-lowtag)
253 unbound-marker-widetag)
254 (inst jmp (if not-p :e :ne) target)))
257 (define-vop (symbol-hash)
258 (:policy :fast-safe)
259 (:translate symbol-hash)
260 (:args (symbol :scs (descriptor-reg)))
261 (:results (res :scs (any-reg)))
262 (:result-types positive-fixnum)
263 (:generator 2
264 ;; The symbol-hash slot of NIL holds NIL because it is also the
265 ;; cdr slot, so we have to strip off the three low bits to make sure
266 ;; it is a fixnum. The lowtag selection magic that is required to
267 ;; ensure this is explained in the comment in objdef.lisp
268 (loadw res symbol symbol-hash-slot other-pointer-lowtag)
269 (inst and res (lognot #b111))))
271 ;;;; fdefinition (FDEFN) objects
273 (define-vop (fdefn-fun cell-ref) ; /pfw - alpha
274 (:variant fdefn-fun-slot other-pointer-lowtag))
276 (define-vop (safe-fdefn-fun)
277 (:args (object :scs (descriptor-reg) :to (:result 1)))
278 (:results (value :scs (descriptor-reg any-reg)))
279 (:vop-var vop)
280 (:save-p :compute-only)
281 (:generator 10
282 (loadw value object fdefn-fun-slot other-pointer-lowtag)
283 (inst cmp value nil-value)
284 (let ((err-lab (generate-error-code vop 'undefined-fun-error object)))
285 (inst jmp :e err-lab))))
287 (define-vop (set-fdefn-fun)
288 (:policy :fast-safe)
289 (:translate (setf fdefn-fun))
290 (:args (function :scs (descriptor-reg) :target result)
291 (fdefn :scs (descriptor-reg)))
292 (:temporary (:sc unsigned-reg) raw)
293 (:temporary (:sc byte-reg) type)
294 (:results (result :scs (descriptor-reg)))
295 (:generator 38
296 (load-type type function (- fun-pointer-lowtag))
297 (inst lea raw
298 (make-ea :byte :base function
299 :disp (- (* simple-fun-code-offset n-word-bytes)
300 fun-pointer-lowtag)))
301 (inst cmp type simple-fun-header-widetag)
302 (inst jmp :e NORMAL-FUN)
303 (inst lea raw (make-fixup "closure_tramp" :foreign))
304 NORMAL-FUN
305 (storew function fdefn fdefn-fun-slot other-pointer-lowtag)
306 (storew raw fdefn fdefn-raw-addr-slot other-pointer-lowtag)
307 (move result function)))
309 (define-vop (fdefn-makunbound)
310 (:policy :fast-safe)
311 (:translate fdefn-makunbound)
312 (:args (fdefn :scs (descriptor-reg) :target result))
313 (:results (result :scs (descriptor-reg)))
314 (:generator 38
315 (storew nil-value fdefn fdefn-fun-slot other-pointer-lowtag)
316 (storew (make-fixup "undefined_tramp" :foreign)
317 fdefn fdefn-raw-addr-slot other-pointer-lowtag)
318 (move result fdefn)))
320 ;;;; binding and unbinding
322 ;;; BIND -- Establish VAL as a binding for SYMBOL. Save the old value and
323 ;;; the symbol on the binding stack and stuff the new value into the
324 ;;; symbol.
326 #!+sb-thread
327 (define-vop (bind)
328 (:args (val :scs (any-reg descriptor-reg))
329 (symbol :scs (descriptor-reg)))
330 (:temporary (:sc unsigned-reg) tls-index bsp)
331 (:generator 10
332 (let ((tls-index-valid (gen-label)))
333 (load-binding-stack-pointer bsp)
334 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
335 (inst add bsp (* binding-size n-word-bytes))
336 (store-binding-stack-pointer bsp)
337 (inst or tls-index tls-index)
338 (inst jmp :ne tls-index-valid)
339 (inst mov tls-index symbol)
340 (inst lea temp-reg-tn
341 (make-ea :qword :disp
342 (make-fixup (ecase (tn-offset tls-index)
343 (#.rax-offset 'alloc-tls-index-in-rax)
344 (#.rcx-offset 'alloc-tls-index-in-rcx)
345 (#.rdx-offset 'alloc-tls-index-in-rdx)
346 (#.rbx-offset 'alloc-tls-index-in-rbx)
347 (#.rsi-offset 'alloc-tls-index-in-rsi)
348 (#.rdi-offset 'alloc-tls-index-in-rdi)
349 (#.r8-offset 'alloc-tls-index-in-r8)
350 (#.r9-offset 'alloc-tls-index-in-r9)
351 (#.r10-offset 'alloc-tls-index-in-r10)
352 (#.r12-offset 'alloc-tls-index-in-r12)
353 (#.r13-offset 'alloc-tls-index-in-r13)
354 (#.r14-offset 'alloc-tls-index-in-r14)
355 (#.r15-offset 'alloc-tls-index-in-r15))
356 :assembly-routine)))
357 (inst call temp-reg-tn)
358 (emit-label tls-index-valid)
359 (inst push (make-ea :qword :base thread-base-tn :scale 1 :index tls-index))
360 (popw bsp (- binding-value-slot binding-size))
361 (storew symbol bsp (- binding-symbol-slot binding-size))
362 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
363 val))))
365 #!-sb-thread
366 (define-vop (bind)
367 (:args (val :scs (any-reg descriptor-reg))
368 (symbol :scs (descriptor-reg)))
369 (:temporary (:sc unsigned-reg) temp bsp)
370 (:generator 5
371 (load-symbol-value bsp *binding-stack-pointer*)
372 (loadw temp symbol symbol-value-slot other-pointer-lowtag)
373 (inst add bsp (* binding-size n-word-bytes))
374 (store-symbol-value bsp *binding-stack-pointer*)
375 (storew temp bsp (- binding-value-slot binding-size))
376 (storew symbol bsp (- binding-symbol-slot binding-size))
377 (storew val symbol symbol-value-slot other-pointer-lowtag)))
379 #!+sb-thread
380 (define-vop (unbind)
381 (:temporary (:sc unsigned-reg) temp bsp tls-index)
382 (:generator 0
383 (load-binding-stack-pointer bsp)
384 ;; Load SYMBOL from stack, and get the TLS-INDEX
385 (loadw temp bsp (- binding-symbol-slot binding-size))
386 (loadw tls-index temp symbol-tls-index-slot other-pointer-lowtag)
387 ;; Load VALUE from stack, the restore it to the TLS area.
388 (loadw temp bsp (- binding-value-slot binding-size))
389 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
390 temp)
391 ;; Zero out the stack.
392 (storew 0 bsp (- binding-symbol-slot binding-size))
393 (storew 0 bsp (- binding-value-slot binding-size))
394 (inst sub bsp (* binding-size n-word-bytes))
395 (store-binding-stack-pointer bsp)))
397 #!-sb-thread
398 (define-vop (unbind)
399 (:temporary (:sc unsigned-reg) symbol value bsp)
400 (:generator 0
401 (load-symbol-value bsp *binding-stack-pointer*)
402 (loadw symbol bsp (- binding-symbol-slot binding-size))
403 (loadw value bsp (- binding-value-slot binding-size))
404 (storew value symbol symbol-value-slot other-pointer-lowtag)
405 (storew 0 bsp (- binding-symbol-slot binding-size))
406 (storew 0 bsp (- binding-value-slot binding-size))
407 (inst sub bsp (* binding-size n-word-bytes))
408 (store-symbol-value bsp *binding-stack-pointer*)))
410 (define-vop (unbind-to-here)
411 (:args (where :scs (descriptor-reg any-reg)))
412 (:temporary (:sc unsigned-reg) symbol value bsp #!+sb-thread tls-index)
413 (:generator 0
414 (load-binding-stack-pointer bsp)
415 (inst cmp where bsp)
416 (inst jmp :e DONE)
418 LOOP
419 (loadw symbol bsp (- binding-symbol-slot binding-size))
420 (inst or symbol symbol)
421 (inst jmp :z SKIP)
422 ;; Bind stack debug sentinels have the unbound marker in the symbol slot
423 (inst cmp symbol unbound-marker-widetag)
424 (inst jmp :eq SKIP)
425 (loadw value bsp (- binding-value-slot binding-size))
426 #!-sb-thread
427 (storew value symbol symbol-value-slot other-pointer-lowtag)
428 #!+sb-thread
429 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
430 #!+sb-thread
431 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
432 value)
433 (storew 0 bsp (- binding-symbol-slot binding-size))
435 SKIP
436 (storew 0 bsp (- binding-value-slot binding-size))
437 (inst sub bsp (* binding-size n-word-bytes))
438 (inst cmp where bsp)
439 (inst jmp :ne LOOP)
440 (store-binding-stack-pointer bsp)
442 DONE))
444 (define-vop (bind-sentinel)
445 (:temporary (:sc unsigned-reg) bsp)
446 (:generator 1
447 (load-binding-stack-pointer bsp)
448 (inst add bsp (* binding-size n-word-bytes))
449 (storew unbound-marker-widetag bsp (- binding-symbol-slot binding-size))
450 (storew rbp-tn bsp (- binding-value-slot binding-size))
451 (store-binding-stack-pointer bsp)))
453 (define-vop (unbind-sentinel)
454 (:temporary (:sc unsigned-reg) bsp)
455 (:generator 1
456 (load-binding-stack-pointer bsp)
457 (storew 0 bsp (- binding-value-slot binding-size))
458 (storew 0 bsp (- binding-symbol-slot binding-size))
459 (inst sub bsp (* binding-size n-word-bytes))
460 (store-binding-stack-pointer bsp)))
465 ;;;; closure indexing
467 (define-full-reffer closure-index-ref *
468 closure-info-offset fun-pointer-lowtag
469 (any-reg descriptor-reg) * %closure-index-ref)
471 (define-full-setter set-funcallable-instance-info *
472 funcallable-instance-info-offset fun-pointer-lowtag
473 (any-reg descriptor-reg) * %set-funcallable-instance-info)
475 (define-full-reffer funcallable-instance-info *
476 funcallable-instance-info-offset fun-pointer-lowtag
477 (descriptor-reg any-reg) * %funcallable-instance-info)
479 (define-vop (closure-ref slot-ref)
480 (:variant closure-info-offset fun-pointer-lowtag))
482 (define-vop (closure-init slot-set)
483 (:variant closure-info-offset fun-pointer-lowtag))
485 ;;;; value cell hackery
487 (define-vop (value-cell-ref cell-ref)
488 (:variant value-cell-value-slot other-pointer-lowtag))
490 (define-vop (value-cell-set cell-set)
491 (:variant value-cell-value-slot other-pointer-lowtag))
493 ;;;; structure hackery
495 (define-vop (instance-length)
496 (:policy :fast-safe)
497 (:translate %instance-length)
498 (:args (struct :scs (descriptor-reg)))
499 (:results (res :scs (unsigned-reg)))
500 (:result-types positive-fixnum)
501 (:generator 4
502 (loadw res struct 0 instance-pointer-lowtag)
503 (inst shr res n-widetag-bits)))
505 (define-full-reffer instance-index-ref * instance-slots-offset
506 instance-pointer-lowtag (any-reg descriptor-reg) * %instance-ref)
508 (define-full-setter instance-index-set * instance-slots-offset
509 instance-pointer-lowtag (any-reg descriptor-reg) * %instance-set)
511 (define-full-compare-and-swap %compare-and-swap-instance-ref instance
512 instance-slots-offset instance-pointer-lowtag
513 (any-reg descriptor-reg) *
514 %compare-and-swap-instance-ref)
516 ;;;; code object frobbing
518 (define-full-reffer code-header-ref * 0 other-pointer-lowtag
519 (any-reg descriptor-reg) * code-header-ref)
521 (define-full-setter code-header-set * 0 other-pointer-lowtag
522 (any-reg descriptor-reg) * code-header-set)
524 ;;;; raw instance slot accessors
526 (defun make-ea-for-raw-slot (object index instance-length
527 &optional (adjustment 0))
528 (etypecase index
530 (make-ea :qword :base object :index instance-length
531 :disp (+ (* (1- instance-slots-offset) n-word-bytes)
532 (- instance-pointer-lowtag)
533 adjustment)))
534 (integer
535 (make-ea :qword :base object :index instance-length
536 :scale 8
537 :disp (+ (* (1- instance-slots-offset) n-word-bytes)
538 (- instance-pointer-lowtag)
539 adjustment
540 (- (fixnumize index)))))))
542 (define-vop (raw-instance-ref/word)
543 (:translate %raw-instance-ref/word)
544 (:policy :fast-safe)
545 (:args (object :scs (descriptor-reg)) (index :scs (any-reg)))
546 (:arg-types * tagged-num)
547 (:temporary (:sc unsigned-reg) tmp)
548 (:results (value :scs (unsigned-reg)))
549 (:result-types unsigned-num)
550 (:generator 5
551 (loadw tmp object 0 instance-pointer-lowtag)
552 (inst shr tmp n-widetag-bits)
553 (inst shl tmp 3)
554 (inst sub tmp index)
555 (inst mov value (make-ea-for-raw-slot object index tmp))))
557 (define-vop (raw-instance-ref-c/word)
558 (:translate %raw-instance-ref/word)
559 (:policy :fast-safe)
560 (:args (object :scs (descriptor-reg)))
561 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
562 #.instance-pointer-lowtag
563 #.instance-slots-offset)))
564 (:info index)
565 (:temporary (:sc unsigned-reg) tmp)
566 (:results (value :scs (unsigned-reg)))
567 (:result-types unsigned-num)
568 (:generator 4
569 (loadw tmp object 0 instance-pointer-lowtag)
570 (inst shr tmp n-widetag-bits)
571 (inst mov value (make-ea-for-raw-slot object index tmp))))
573 (define-vop (raw-instance-set/word)
574 (:translate %raw-instance-set/word)
575 (:policy :fast-safe)
576 (:args (object :scs (descriptor-reg))
577 (index :scs (any-reg))
578 (value :scs (unsigned-reg) :target result))
579 (:arg-types * tagged-num unsigned-num)
580 (:temporary (:sc unsigned-reg) tmp)
581 (:results (result :scs (unsigned-reg)))
582 (:result-types unsigned-num)
583 (:generator 5
584 (loadw tmp object 0 instance-pointer-lowtag)
585 (inst shr tmp n-widetag-bits)
586 (inst shl tmp 3)
587 (inst sub tmp index)
588 (inst mov (make-ea-for-raw-slot object index tmp) value)
589 (move result value)))
591 (define-vop (raw-instance-set-c/word)
592 (:translate %raw-instance-set/word)
593 (:policy :fast-safe)
594 (:args (object :scs (descriptor-reg))
595 (value :scs (unsigned-reg) :target result))
596 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
597 #.instance-pointer-lowtag
598 #.instance-slots-offset))
599 unsigned-num)
600 (:info index)
601 (:temporary (:sc unsigned-reg) tmp)
602 (:results (result :scs (unsigned-reg)))
603 (:result-types unsigned-num)
604 (:generator 4
605 (loadw tmp object 0 instance-pointer-lowtag)
606 (inst shr tmp n-widetag-bits)
607 (inst mov (make-ea-for-raw-slot object index tmp) value)
608 (move result value)))
610 (define-vop (raw-instance-init/word)
611 (:args (object :scs (descriptor-reg))
612 (value :scs (unsigned-reg)))
613 (:arg-types * unsigned-num)
614 (:info index)
615 (:temporary (:sc unsigned-reg) tmp)
616 (:generator 4
617 (loadw tmp object 0 instance-pointer-lowtag)
618 (inst shr tmp n-widetag-bits)
619 (inst mov (make-ea-for-raw-slot object index tmp) value)))
621 (define-vop (raw-instance-ref/single)
622 (:translate %raw-instance-ref/single)
623 (:policy :fast-safe)
624 (:args (object :scs (descriptor-reg))
625 (index :scs (any-reg)))
626 (:arg-types * positive-fixnum)
627 (:temporary (:sc unsigned-reg) tmp)
628 (:results (value :scs (single-reg)))
629 (:result-types single-float)
630 (:generator 5
631 (loadw tmp object 0 instance-pointer-lowtag)
632 (inst shr tmp n-widetag-bits)
633 (inst shl tmp 3)
634 (inst sub tmp index)
635 (inst movss value (make-ea-for-raw-slot object index tmp))))
637 (define-vop (raw-instance-ref-c/single)
638 (:translate %raw-instance-ref/single)
639 (:policy :fast-safe)
640 (:args (object :scs (descriptor-reg)))
641 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
642 #.instance-pointer-lowtag
643 #.instance-slots-offset)))
644 (:info index)
645 (:temporary (:sc unsigned-reg) tmp)
646 (:results (value :scs (single-reg)))
647 (:result-types single-float)
648 (:generator 4
649 (loadw tmp object 0 instance-pointer-lowtag)
650 (inst shr tmp n-widetag-bits)
651 (inst movss value (make-ea-for-raw-slot object index tmp))))
653 (define-vop (raw-instance-set/single)
654 (:translate %raw-instance-set/single)
655 (:policy :fast-safe)
656 (:args (object :scs (descriptor-reg))
657 (index :scs (any-reg))
658 (value :scs (single-reg) :target result))
659 (:arg-types * positive-fixnum single-float)
660 (:temporary (:sc unsigned-reg) tmp)
661 (:results (result :scs (single-reg)))
662 (:result-types single-float)
663 (:generator 5
664 (loadw tmp object 0 instance-pointer-lowtag)
665 (inst shr tmp n-widetag-bits)
666 (inst shl tmp 3)
667 (inst sub tmp index)
668 (inst movss (make-ea-for-raw-slot object index tmp) value)
669 (unless (location= result value)
670 (inst movss result value))))
672 (define-vop (raw-instance-set-c/single)
673 (:translate %raw-instance-set/single)
674 (:policy :fast-safe)
675 (:args (object :scs (descriptor-reg))
676 (value :scs (single-reg) :target result))
677 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
678 #.instance-pointer-lowtag
679 #.instance-slots-offset))
680 single-float)
681 (:info index)
682 (:temporary (:sc unsigned-reg) tmp)
683 (:results (result :scs (single-reg)))
684 (:result-types single-float)
685 (:generator 4
686 (loadw tmp object 0 instance-pointer-lowtag)
687 (inst shr tmp n-widetag-bits)
688 (inst movss (make-ea-for-raw-slot object index tmp) value)
689 (unless (location= result value)
690 (inst movss result value))))
692 (define-vop (raw-instance-init/single)
693 (:translate %raw-instance-set/single)
694 (:policy :fast-safe)
695 (:args (object :scs (descriptor-reg))
696 (value :scs (single-reg)))
697 (:arg-types * single-float)
698 (:info index)
699 (:temporary (:sc unsigned-reg) tmp)
700 (:generator 4
701 (loadw tmp object 0 instance-pointer-lowtag)
702 (inst shr tmp n-widetag-bits)
703 (inst movss (make-ea-for-raw-slot object index tmp) value)))
705 (define-vop (raw-instance-ref/double)
706 (:translate %raw-instance-ref/double)
707 (:policy :fast-safe)
708 (:args (object :scs (descriptor-reg))
709 (index :scs (any-reg)))
710 (:arg-types * positive-fixnum)
711 (:temporary (:sc unsigned-reg) tmp)
712 (:results (value :scs (double-reg)))
713 (:result-types double-float)
714 (:generator 5
715 (loadw tmp object 0 instance-pointer-lowtag)
716 (inst shr tmp n-widetag-bits)
717 (inst shl tmp 3)
718 (inst sub tmp index)
719 (inst movsd value (make-ea-for-raw-slot object index tmp))))
721 (define-vop (raw-instance-ref-c/double)
722 (:translate %raw-instance-ref/double)
723 (:policy :fast-safe)
724 (:args (object :scs (descriptor-reg)))
725 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
726 #.instance-pointer-lowtag
727 #.instance-slots-offset)))
728 (:info index)
729 (:temporary (:sc unsigned-reg) tmp)
730 (:results (value :scs (double-reg)))
731 (:result-types double-float)
732 (:generator 4
733 (loadw tmp object 0 instance-pointer-lowtag)
734 (inst shr tmp n-widetag-bits)
735 (inst movsd value (make-ea-for-raw-slot object index tmp))))
737 (define-vop (raw-instance-set/double)
738 (:translate %raw-instance-set/double)
739 (:policy :fast-safe)
740 (:args (object :scs (descriptor-reg))
741 (index :scs (any-reg))
742 (value :scs (double-reg) :target result))
743 (:arg-types * positive-fixnum double-float)
744 (:temporary (:sc unsigned-reg) tmp)
745 (:results (result :scs (double-reg)))
746 (:result-types double-float)
747 (:generator 5
748 (loadw tmp object 0 instance-pointer-lowtag)
749 (inst shr tmp n-widetag-bits)
750 (inst shl tmp 3)
751 (inst sub tmp index)
752 (inst movsd (make-ea-for-raw-slot object index tmp) value)
753 (unless (location= result value)
754 (inst movsd result value))))
756 (define-vop (raw-instance-set-c/double)
757 (:translate %raw-instance-set/double)
758 (:policy :fast-safe)
759 (:args (object :scs (descriptor-reg))
760 (value :scs (double-reg) :target result))
761 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
762 #.instance-pointer-lowtag
763 #.instance-slots-offset))
764 double-float)
765 (:info index)
766 (:temporary (:sc unsigned-reg) tmp)
767 (:results (result :scs (double-reg)))
768 (:result-types double-float)
769 (:generator 4
770 (loadw tmp object 0 instance-pointer-lowtag)
771 (inst shr tmp n-widetag-bits)
772 (inst movsd (make-ea-for-raw-slot object index tmp) value)
773 (unless (location= result value)
774 (inst movsd result value))))
776 (define-vop (raw-instance-init/double)
777 (:args (object :scs (descriptor-reg))
778 (value :scs (double-reg)))
779 (:arg-types * double-float)
780 (:info index)
781 (:temporary (:sc unsigned-reg) tmp)
782 (:generator 4
783 (loadw tmp object 0 instance-pointer-lowtag)
784 (inst shr tmp n-widetag-bits)
785 (inst movsd (make-ea-for-raw-slot object index tmp) value)))
787 (define-vop (raw-instance-ref/complex-single)
788 (:translate %raw-instance-ref/complex-single)
789 (:policy :fast-safe)
790 (:args (object :scs (descriptor-reg))
791 (index :scs (any-reg)))
792 (:arg-types * positive-fixnum)
793 (:temporary (:sc unsigned-reg) tmp)
794 (:results (value :scs (complex-single-reg)))
795 (:result-types complex-single-float)
796 (:generator 5
797 (loadw tmp object 0 instance-pointer-lowtag)
798 (inst shr tmp n-widetag-bits)
799 (inst shl tmp 3)
800 (inst sub tmp index)
801 (let ((real-tn (complex-single-reg-real-tn value)))
802 (inst movss real-tn (make-ea-for-raw-slot object index tmp)))
803 (let ((imag-tn (complex-single-reg-imag-tn value)))
804 (inst movss imag-tn (make-ea-for-raw-slot object index tmp 4)))))
806 (define-vop (raw-instance-ref-c/complex-single)
807 (:translate %raw-instance-ref/complex-single)
808 (:policy :fast-safe)
809 (:args (object :scs (descriptor-reg)))
810 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
811 #.instance-pointer-lowtag
812 #.instance-slots-offset)))
813 (:info index)
814 (:temporary (:sc unsigned-reg) tmp)
815 (:results (value :scs (complex-single-reg)))
816 (:result-types complex-single-float)
817 (:generator 4
818 (loadw tmp object 0 instance-pointer-lowtag)
819 (inst shr tmp n-widetag-bits)
820 (let ((real-tn (complex-single-reg-real-tn value)))
821 (inst movss real-tn (make-ea-for-raw-slot object index tmp)))
822 (let ((imag-tn (complex-single-reg-imag-tn value)))
823 (inst movss imag-tn (make-ea-for-raw-slot object index tmp 4)))))
825 (define-vop (raw-instance-set/complex-single)
826 (:translate %raw-instance-set/complex-single)
827 (:policy :fast-safe)
828 (:args (object :scs (descriptor-reg))
829 (index :scs (any-reg))
830 (value :scs (complex-single-reg) :target result))
831 (:arg-types * positive-fixnum complex-single-float)
832 (:temporary (:sc unsigned-reg) tmp)
833 (:results (result :scs (complex-single-reg)))
834 (:result-types complex-single-float)
835 (:generator 5
836 (loadw tmp object 0 instance-pointer-lowtag)
837 (inst shr tmp n-widetag-bits)
838 (inst shl tmp 3)
839 (inst sub tmp index)
840 (let ((value-real (complex-single-reg-real-tn value))
841 (result-real (complex-single-reg-real-tn result)))
842 (inst movss (make-ea-for-raw-slot object index tmp) value-real)
843 (unless (location= value-real result-real)
844 (inst movss result-real value-real)))
845 (let ((value-imag (complex-single-reg-imag-tn value))
846 (result-imag (complex-single-reg-imag-tn result)))
847 (inst movss (make-ea-for-raw-slot object index tmp 4) value-imag)
848 (unless (location= value-imag result-imag)
849 (inst movss result-imag value-imag)))))
851 (define-vop (raw-instance-set-c/complex-single)
852 (:translate %raw-instance-set/complex-single)
853 (:policy :fast-safe)
854 (:args (object :scs (descriptor-reg))
855 (value :scs (complex-single-reg) :target result))
856 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
857 #.instance-pointer-lowtag
858 #.instance-slots-offset))
859 complex-single-float)
860 (:info index)
861 (:temporary (:sc unsigned-reg) tmp)
862 (:results (result :scs (complex-single-reg)))
863 (:result-types complex-single-float)
864 (:generator 4
865 (loadw tmp object 0 instance-pointer-lowtag)
866 (inst shr tmp n-widetag-bits)
867 (let ((value-real (complex-single-reg-real-tn value))
868 (result-real (complex-single-reg-real-tn result)))
869 (inst movss (make-ea-for-raw-slot object index tmp) value-real)
870 (unless (location= value-real result-real)
871 (inst movss result-real value-real)))
872 (let ((value-imag (complex-single-reg-imag-tn value))
873 (result-imag (complex-single-reg-imag-tn result)))
874 (inst movss (make-ea-for-raw-slot object index tmp 4) value-imag)
875 (unless (location= value-imag result-imag)
876 (inst movss result-imag value-imag)))))
878 (define-vop (raw-instance-init/complex-single)
879 (:args (object :scs (descriptor-reg))
880 (value :scs (complex-single-reg)))
881 (:arg-types * complex-single-float)
882 (:info index)
883 (:temporary (:sc unsigned-reg) tmp)
884 (:generator 4
885 (loadw tmp object 0 instance-pointer-lowtag)
886 (inst shr tmp n-widetag-bits)
887 (let ((value-real (complex-single-reg-real-tn value)))
888 (inst movss (make-ea-for-raw-slot object index tmp) value-real))
889 (let ((value-imag (complex-single-reg-imag-tn value)))
890 (inst movss (make-ea-for-raw-slot object index tmp 4) value-imag))))
892 (define-vop (raw-instance-ref/complex-double)
893 (:translate %raw-instance-ref/complex-double)
894 (:policy :fast-safe)
895 (:args (object :scs (descriptor-reg))
896 (index :scs (any-reg)))
897 (:arg-types * positive-fixnum)
898 (:temporary (:sc unsigned-reg) tmp)
899 (:results (value :scs (complex-double-reg)))
900 (:result-types complex-double-float)
901 (:generator 5
902 (loadw tmp object 0 instance-pointer-lowtag)
903 (inst shr tmp n-widetag-bits)
904 (inst shl tmp 3)
905 (inst sub tmp index)
906 (let ((real-tn (complex-double-reg-real-tn value)))
907 (inst movsd real-tn (make-ea-for-raw-slot object index tmp -8)))
908 (let ((imag-tn (complex-double-reg-imag-tn value)))
909 (inst movsd imag-tn (make-ea-for-raw-slot object index tmp)))))
911 (define-vop (raw-instance-ref-c/complex-double)
912 (:translate %raw-instance-ref/complex-double)
913 (:policy :fast-safe)
914 (:args (object :scs (descriptor-reg)))
915 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
916 #.instance-pointer-lowtag
917 #.instance-slots-offset)))
918 (:info index)
919 (:temporary (:sc unsigned-reg) tmp)
920 (:results (value :scs (complex-double-reg)))
921 (:result-types complex-double-float)
922 (:generator 4
923 (loadw tmp object 0 instance-pointer-lowtag)
924 (inst shr tmp n-widetag-bits)
925 (let ((real-tn (complex-double-reg-real-tn value)))
926 (inst movsd real-tn (make-ea-for-raw-slot object index tmp -8)))
927 (let ((imag-tn (complex-double-reg-imag-tn value)))
928 (inst movsd imag-tn (make-ea-for-raw-slot object index tmp)))))
930 (define-vop (raw-instance-set/complex-double)
931 (:translate %raw-instance-set/complex-double)
932 (:policy :fast-safe)
933 (:args (object :scs (descriptor-reg))
934 (index :scs (any-reg))
935 (value :scs (complex-double-reg) :target result))
936 (:arg-types * positive-fixnum complex-double-float)
937 (:temporary (:sc unsigned-reg) tmp)
938 (:results (result :scs (complex-double-reg)))
939 (:result-types complex-double-float)
940 (:generator 5
941 (loadw tmp object 0 instance-pointer-lowtag)
942 (inst shr tmp n-widetag-bits)
943 (inst shl tmp 3)
944 (inst sub tmp index)
945 (let ((value-real (complex-double-reg-real-tn value))
946 (result-real (complex-double-reg-real-tn result)))
947 (inst movsd (make-ea-for-raw-slot object index tmp -8) value-real)
948 (unless (location= value-real result-real)
949 (inst movsd result-real value-real)))
950 (let ((value-imag (complex-double-reg-imag-tn value))
951 (result-imag (complex-double-reg-imag-tn result)))
952 (inst movsd (make-ea-for-raw-slot object index tmp) value-imag)
953 (unless (location= value-imag result-imag)
954 (inst movsd result-imag value-imag)))))
956 (define-vop (raw-instance-set-c/complex-double)
957 (:translate %raw-instance-set/complex-double)
958 (:policy :fast-safe)
959 (:args (object :scs (descriptor-reg))
960 (value :scs (complex-double-reg) :target result))
961 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
962 #.instance-pointer-lowtag
963 #.instance-slots-offset))
964 complex-double-float)
965 (:info index)
966 (:temporary (:sc unsigned-reg) tmp)
967 (:results (result :scs (complex-double-reg)))
968 (:result-types complex-double-float)
969 (:generator 4
970 (loadw tmp object 0 instance-pointer-lowtag)
971 (inst shr tmp n-widetag-bits)
972 (let ((value-real (complex-double-reg-real-tn value))
973 (result-real (complex-double-reg-real-tn result)))
974 (inst movsd (make-ea-for-raw-slot object index tmp -8) value-real)
975 (unless (location= value-real result-real)
976 (inst movsd result-real value-real)))
977 (let ((value-imag (complex-double-reg-imag-tn value))
978 (result-imag (complex-double-reg-imag-tn result)))
979 (inst movsd (make-ea-for-raw-slot object index tmp) value-imag)
980 (unless (location= value-imag result-imag)
981 (inst movsd result-imag value-imag)))))
983 (define-vop (raw-instance-init/complex-double)
984 (:args (object :scs (descriptor-reg))
985 (value :scs (complex-double-reg)))
986 (:arg-types * complex-double-float)
987 (:info index)
988 (:temporary (:sc unsigned-reg) tmp)
989 (:generator 4
990 (loadw tmp object 0 instance-pointer-lowtag)
991 (inst shr tmp n-widetag-bits)
992 (let ((value-real (complex-double-reg-real-tn value)))
993 (inst movsd (make-ea-for-raw-slot object index tmp -8) value-real))
994 (let ((value-imag (complex-double-reg-imag-tn value)))
995 (inst movsd (make-ea-for-raw-slot object index tmp) value-imag))))