1.0.37.8: add ATOMIC-DECF, fix WAIT-ON-SEMAPHORE-BUGLET
[sbcl/nikodemus.git] / src / compiler / x86-64 / cell.lisp
blobf282900b3dd97efd1c590d863f9483472fcbf252
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 (inst cmpxchg (make-ea :qword :base object
63 :disp (- (* offset n-word-bytes) lowtag))
64 new :lock)
65 (move result rax)))
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)
75 #!+sb-thread
76 (:temporary (:sc descriptor-reg) tls)
77 (:results (result :scs (descriptor-reg any-reg)))
78 (:policy :fast-safe)
79 (:vop-var vop)
80 (:generator 15
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))
85 (check (gen-label)))
86 (move rax old)
87 #!+sb-thread
88 (progn
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
92 :index tls :scale 1)
93 new)
94 (inst cmp rax no-tls-value-marker-widetag)
95 (inst jmp :ne check)
96 (move rax old))
97 (inst cmpxchg (make-ea :qword :base symbol
98 :disp (- (* symbol-value-slot n-word-bytes)
99 other-pointer-lowtag)
100 :scale 1)
101 new :lock)
102 (emit-label check)
103 (move result rax)
104 (inst cmp result unbound-marker-widetag)
105 (inst jmp :e unbound))))
107 (define-vop (%set-symbol-global-value cell-set)
108 (:variant symbol-value-slot other-pointer-lowtag))
110 (define-vop (fast-symbol-global-value cell-ref)
111 (:variant symbol-value-slot other-pointer-lowtag)
112 (:policy :fast)
113 (:translate symbol-global-value))
115 (define-vop (symbol-global-value)
116 (:policy :fast-safe)
117 (:translate symbol-global-value)
118 (:args (object :scs (descriptor-reg) :to (:result 1)))
119 (:results (value :scs (descriptor-reg any-reg)))
120 (:vop-var vop)
121 (:save-p :compute-only)
122 (:generator 9
123 (let ((err-lab (generate-error-code vop 'unbound-symbol-error object)))
124 (loadw value object symbol-value-slot other-pointer-lowtag)
125 (inst cmp value unbound-marker-widetag)
126 (inst jmp :e err-lab))))
128 #!+sb-thread
129 (progn
130 (define-vop (set)
131 (:args (symbol :scs (descriptor-reg))
132 (value :scs (descriptor-reg any-reg)))
133 (:temporary (:sc descriptor-reg) tls)
134 (:generator 4
135 (let ((global-val (gen-label))
136 (done (gen-label)))
137 (loadw tls symbol symbol-tls-index-slot other-pointer-lowtag)
138 (inst cmp (make-ea :qword :base thread-base-tn :scale 1 :index tls)
139 no-tls-value-marker-widetag)
140 (inst jmp :z global-val)
141 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls)
142 value)
143 (inst jmp done)
144 (emit-label global-val)
145 (storew value symbol symbol-value-slot other-pointer-lowtag)
146 (emit-label done))))
148 ;; With Symbol-Value, we check that the value isn't the trap object. So
149 ;; Symbol-Value of NIL is NIL.
150 (define-vop (symbol-value)
151 (:translate symbol-value)
152 (:policy :fast-safe)
153 (:args (object :scs (descriptor-reg) :to (:result 1)))
154 (:results (value :scs (descriptor-reg any-reg)))
155 (:vop-var vop)
156 (:save-p :compute-only)
157 (:generator 9
158 (let* ((check-unbound-label (gen-label))
159 (err-lab (generate-error-code vop 'unbound-symbol-error object))
160 (ret-lab (gen-label)))
161 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
162 (inst mov value (make-ea :qword :base thread-base-tn
163 :index value :scale 1))
164 (inst cmp value no-tls-value-marker-widetag)
165 (inst jmp :ne check-unbound-label)
166 (loadw value object symbol-value-slot other-pointer-lowtag)
167 (emit-label check-unbound-label)
168 (inst cmp value unbound-marker-widetag)
169 (inst jmp :e err-lab)
170 (emit-label ret-lab))))
172 (define-vop (fast-symbol-value symbol-value)
173 ;; KLUDGE: not really fast, in fact, because we're going to have to
174 ;; do a full lookup of the thread-local area anyway. But half of
175 ;; the meaning of FAST-SYMBOL-VALUE is "do not signal an error if
176 ;; unbound", which is used in the implementation of COPY-SYMBOL. --
177 ;; CSR, 2003-04-22
178 (:policy :fast)
179 (:translate symbol-value)
180 (:generator 8
181 (let ((ret-lab (gen-label)))
182 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
183 (inst mov value
184 (make-ea :qword :base thread-base-tn :index value :scale 1))
185 (inst cmp value no-tls-value-marker-widetag)
186 (inst jmp :ne ret-lab)
187 (loadw value object symbol-value-slot other-pointer-lowtag)
188 (emit-label ret-lab)))))
190 #!-sb-thread
191 (progn
192 (define-vop (symbol-value symbol-global-value)
193 (:translate symbol-value))
194 (define-vop (fast-symbol-value fast-symbol-global-value)
195 (:translate symbol-value))
196 (define-vop (set %set-symbol-global-value)))
198 #!+sb-thread
199 (define-vop (boundp)
200 (:translate boundp)
201 (:policy :fast-safe)
202 (:args (object :scs (descriptor-reg)))
203 (:conditional :ne)
204 (:temporary (:sc descriptor-reg #+nil(:from (:argument 0))) value)
205 (:generator 9
206 (let ((check-unbound-label (gen-label)))
207 (loadw value object symbol-tls-index-slot other-pointer-lowtag)
208 (inst mov value
209 (make-ea :qword :base thread-base-tn :index value :scale 1))
210 (inst cmp value no-tls-value-marker-widetag)
211 (inst jmp :ne check-unbound-label)
212 (loadw value object symbol-value-slot other-pointer-lowtag)
213 (emit-label check-unbound-label)
214 (inst cmp value unbound-marker-widetag))))
216 #!-sb-thread
217 (define-vop (boundp)
218 (:translate boundp)
219 (:policy :fast-safe)
220 (:args (object :scs (descriptor-reg)))
221 (:conditional :ne)
222 (:generator 9
223 (inst cmp (make-ea-for-object-slot object symbol-value-slot
224 other-pointer-lowtag)
225 unbound-marker-widetag)))
228 (define-vop (symbol-hash)
229 (:policy :fast-safe)
230 (:translate symbol-hash)
231 (:args (symbol :scs (descriptor-reg)))
232 (:results (res :scs (any-reg)))
233 (:result-types positive-fixnum)
234 (:generator 2
235 ;; The symbol-hash slot of NIL holds NIL because it is also the
236 ;; cdr slot, so we have to strip off the three low bits to make sure
237 ;; it is a fixnum. The lowtag selection magic that is required to
238 ;; ensure this is explained in the comment in objdef.lisp
239 (loadw res symbol symbol-hash-slot other-pointer-lowtag)
240 (inst and res (lognot #b111))))
242 ;;;; fdefinition (FDEFN) objects
244 (define-vop (fdefn-fun cell-ref) ; /pfw - alpha
245 (:variant fdefn-fun-slot other-pointer-lowtag))
247 (define-vop (safe-fdefn-fun)
248 (:args (object :scs (descriptor-reg) :to (:result 1)))
249 (:results (value :scs (descriptor-reg any-reg)))
250 (:vop-var vop)
251 (:save-p :compute-only)
252 (:generator 10
253 (loadw value object fdefn-fun-slot other-pointer-lowtag)
254 (inst cmp value nil-value)
255 (let ((err-lab (generate-error-code vop 'undefined-fun-error object)))
256 (inst jmp :e err-lab))))
258 (define-vop (set-fdefn-fun)
259 (:policy :fast-safe)
260 (:translate (setf fdefn-fun))
261 (:args (function :scs (descriptor-reg) :target result)
262 (fdefn :scs (descriptor-reg)))
263 (:temporary (:sc unsigned-reg) raw)
264 (:temporary (:sc byte-reg) type)
265 (:results (result :scs (descriptor-reg)))
266 (:generator 38
267 (load-type type function (- fun-pointer-lowtag))
268 (inst lea raw
269 (make-ea :byte :base function
270 :disp (- (* simple-fun-code-offset n-word-bytes)
271 fun-pointer-lowtag)))
272 (inst cmp type simple-fun-header-widetag)
273 (inst jmp :e NORMAL-FUN)
274 (inst lea raw (make-fixup "closure_tramp" :foreign))
275 NORMAL-FUN
276 (storew function fdefn fdefn-fun-slot other-pointer-lowtag)
277 (storew raw fdefn fdefn-raw-addr-slot other-pointer-lowtag)
278 (move result function)))
280 (define-vop (fdefn-makunbound)
281 (:policy :fast-safe)
282 (:translate fdefn-makunbound)
283 (:args (fdefn :scs (descriptor-reg) :target result))
284 (:results (result :scs (descriptor-reg)))
285 (:generator 38
286 (storew nil-value fdefn fdefn-fun-slot other-pointer-lowtag)
287 (storew (make-fixup "undefined_tramp" :foreign)
288 fdefn fdefn-raw-addr-slot other-pointer-lowtag)
289 (move result fdefn)))
291 ;;;; binding and unbinding
293 ;;; BIND -- Establish VAL as a binding for SYMBOL. Save the old value and
294 ;;; the symbol on the binding stack and stuff the new value into the
295 ;;; symbol.
297 #!+sb-thread
298 (define-vop (bind)
299 (:args (val :scs (any-reg descriptor-reg))
300 (symbol :scs (descriptor-reg)))
301 (:temporary (:sc unsigned-reg) tls-index bsp)
302 (:generator 10
303 (let ((tls-index-valid (gen-label)))
304 (load-binding-stack-pointer bsp)
305 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
306 (inst add bsp (* binding-size n-word-bytes))
307 (store-binding-stack-pointer bsp)
308 (inst or tls-index tls-index)
309 (inst jmp :ne tls-index-valid)
310 (inst mov tls-index symbol)
311 (inst lea temp-reg-tn
312 (make-ea :qword :disp
313 (make-fixup (ecase (tn-offset tls-index)
314 (#.rax-offset 'alloc-tls-index-in-rax)
315 (#.rcx-offset 'alloc-tls-index-in-rcx)
316 (#.rdx-offset 'alloc-tls-index-in-rdx)
317 (#.rbx-offset 'alloc-tls-index-in-rbx)
318 (#.rsi-offset 'alloc-tls-index-in-rsi)
319 (#.rdi-offset 'alloc-tls-index-in-rdi)
320 (#.r8-offset 'alloc-tls-index-in-r8)
321 (#.r9-offset 'alloc-tls-index-in-r9)
322 (#.r10-offset 'alloc-tls-index-in-r10)
323 (#.r12-offset 'alloc-tls-index-in-r12)
324 (#.r13-offset 'alloc-tls-index-in-r13)
325 (#.r14-offset 'alloc-tls-index-in-r14)
326 (#.r15-offset 'alloc-tls-index-in-r15))
327 :assembly-routine)))
328 (inst call temp-reg-tn)
329 (emit-label tls-index-valid)
330 (inst push (make-ea :qword :base thread-base-tn :scale 1 :index tls-index))
331 (popw bsp (- binding-value-slot binding-size))
332 (storew symbol bsp (- binding-symbol-slot binding-size))
333 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
334 val))))
336 #!-sb-thread
337 (define-vop (bind)
338 (:args (val :scs (any-reg descriptor-reg))
339 (symbol :scs (descriptor-reg)))
340 (:temporary (:sc unsigned-reg) temp bsp)
341 (:generator 5
342 (load-symbol-value bsp *binding-stack-pointer*)
343 (loadw temp symbol symbol-value-slot other-pointer-lowtag)
344 (inst add bsp (* binding-size n-word-bytes))
345 (store-symbol-value bsp *binding-stack-pointer*)
346 (storew temp bsp (- binding-value-slot binding-size))
347 (storew symbol bsp (- binding-symbol-slot binding-size))
348 (storew val symbol symbol-value-slot other-pointer-lowtag)))
350 #!+sb-thread
351 (define-vop (unbind)
352 (:temporary (:sc unsigned-reg) temp bsp tls-index)
353 (:generator 0
354 (load-binding-stack-pointer bsp)
355 ;; Load SYMBOL from stack, and get the TLS-INDEX
356 (loadw temp bsp (- binding-symbol-slot binding-size))
357 (loadw tls-index temp symbol-tls-index-slot other-pointer-lowtag)
358 ;; Load VALUE from stack, the restore it to the TLS area.
359 (loadw temp bsp (- binding-value-slot binding-size))
360 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
361 temp)
362 ;; Zero out the stack.
363 (storew 0 bsp (- binding-symbol-slot binding-size))
364 (storew 0 bsp (- binding-value-slot binding-size))
365 (inst sub bsp (* binding-size n-word-bytes))
366 (store-binding-stack-pointer bsp)))
368 #!-sb-thread
369 (define-vop (unbind)
370 (:temporary (:sc unsigned-reg) symbol value bsp)
371 (:generator 0
372 (load-symbol-value bsp *binding-stack-pointer*)
373 (loadw symbol bsp (- binding-symbol-slot binding-size))
374 (loadw value bsp (- binding-value-slot binding-size))
375 (storew value symbol symbol-value-slot other-pointer-lowtag)
376 (storew 0 bsp (- binding-symbol-slot binding-size))
377 (storew 0 bsp (- binding-value-slot binding-size))
378 (inst sub bsp (* binding-size n-word-bytes))
379 (store-symbol-value bsp *binding-stack-pointer*)))
381 (define-vop (unbind-to-here)
382 (:args (where :scs (descriptor-reg any-reg)))
383 (:temporary (:sc unsigned-reg) symbol value bsp #!+sb-thread tls-index)
384 (:generator 0
385 (load-binding-stack-pointer bsp)
386 (inst cmp where bsp)
387 (inst jmp :e DONE)
389 LOOP
390 (loadw symbol bsp (- binding-symbol-slot binding-size))
391 (inst or symbol symbol)
392 (inst jmp :z SKIP)
393 ;; Bind stack debug sentinels have the unbound marker in the symbol slot
394 (inst cmp symbol unbound-marker-widetag)
395 (inst jmp :eq SKIP)
396 (loadw value bsp (- binding-value-slot binding-size))
397 #!-sb-thread
398 (storew value symbol symbol-value-slot other-pointer-lowtag)
399 #!+sb-thread
400 (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag)
401 #!+sb-thread
402 (inst mov (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)
403 value)
404 (storew 0 bsp (- binding-symbol-slot binding-size))
406 SKIP
407 (storew 0 bsp (- binding-value-slot binding-size))
408 (inst sub bsp (* binding-size n-word-bytes))
409 (inst cmp where bsp)
410 (inst jmp :ne LOOP)
411 (store-binding-stack-pointer bsp)
413 DONE))
415 (define-vop (bind-sentinel)
416 (:temporary (:sc unsigned-reg) bsp)
417 (:generator 1
418 (load-binding-stack-pointer bsp)
419 (inst add bsp (* binding-size n-word-bytes))
420 (storew unbound-marker-widetag bsp (- binding-symbol-slot binding-size))
421 (storew rbp-tn bsp (- binding-value-slot binding-size))
422 (store-binding-stack-pointer bsp)))
424 (define-vop (unbind-sentinel)
425 (:temporary (:sc unsigned-reg) bsp)
426 (:generator 1
427 (load-binding-stack-pointer bsp)
428 (storew 0 bsp (- binding-value-slot binding-size))
429 (storew 0 bsp (- binding-symbol-slot binding-size))
430 (inst sub bsp (* binding-size n-word-bytes))
431 (store-binding-stack-pointer bsp)))
436 ;;;; closure indexing
438 (define-full-reffer closure-index-ref *
439 closure-info-offset fun-pointer-lowtag
440 (any-reg descriptor-reg) * %closure-index-ref)
442 (define-full-setter set-funcallable-instance-info *
443 funcallable-instance-info-offset fun-pointer-lowtag
444 (any-reg descriptor-reg) * %set-funcallable-instance-info)
446 (define-full-reffer funcallable-instance-info *
447 funcallable-instance-info-offset fun-pointer-lowtag
448 (descriptor-reg any-reg) * %funcallable-instance-info)
450 (define-vop (closure-ref slot-ref)
451 (:variant closure-info-offset fun-pointer-lowtag))
453 (define-vop (closure-init slot-set)
454 (:variant closure-info-offset fun-pointer-lowtag))
456 ;;;; value cell hackery
458 (define-vop (value-cell-ref cell-ref)
459 (:variant value-cell-value-slot other-pointer-lowtag))
461 (define-vop (value-cell-set cell-set)
462 (:variant value-cell-value-slot other-pointer-lowtag))
464 ;;;; structure hackery
466 (define-vop (instance-length)
467 (:policy :fast-safe)
468 (:translate %instance-length)
469 (:args (struct :scs (descriptor-reg)))
470 (:results (res :scs (unsigned-reg)))
471 (:result-types positive-fixnum)
472 (:generator 4
473 (loadw res struct 0 instance-pointer-lowtag)
474 (inst shr res n-widetag-bits)))
476 (define-full-reffer instance-index-ref * instance-slots-offset
477 instance-pointer-lowtag (any-reg descriptor-reg) * %instance-ref)
479 (define-full-setter instance-index-set * instance-slots-offset
480 instance-pointer-lowtag (any-reg descriptor-reg) * %instance-set)
482 (define-full-compare-and-swap %compare-and-swap-instance-ref instance
483 instance-slots-offset instance-pointer-lowtag
484 (any-reg descriptor-reg) *
485 %compare-and-swap-instance-ref)
487 ;;;; code object frobbing
489 (define-full-reffer code-header-ref * 0 other-pointer-lowtag
490 (any-reg descriptor-reg) * code-header-ref)
492 (define-full-setter code-header-set * 0 other-pointer-lowtag
493 (any-reg descriptor-reg) * code-header-set)
495 ;;;; raw instance slot accessors
497 (defun make-ea-for-raw-slot (object index instance-length
498 &optional (adjustment 0))
499 (if (integerp instance-length)
500 ;; For RAW-INSTANCE-INIT/* VOPs, which know the exact instance length
501 ;; at compile time.
502 (make-ea :qword
503 :base object
504 :disp (+ (* (- instance-length instance-slots-offset index)
505 n-word-bytes)
506 (- instance-pointer-lowtag)
507 adjustment))
508 (etypecase index
510 (make-ea :qword :base object :index instance-length
511 :disp (+ (* (1- instance-slots-offset) n-word-bytes)
512 (- instance-pointer-lowtag)
513 adjustment)))
514 (integer
515 (make-ea :qword :base object :index instance-length
516 :scale 8
517 :disp (+ (* (1- instance-slots-offset) n-word-bytes)
518 (- instance-pointer-lowtag)
519 adjustment
520 (* index (- n-word-bytes))))))))
522 (define-vop (raw-instance-ref/word)
523 (:translate %raw-instance-ref/word)
524 (:policy :fast-safe)
525 (:args (object :scs (descriptor-reg)) (index :scs (any-reg)))
526 (:arg-types * tagged-num)
527 (:temporary (:sc unsigned-reg) tmp)
528 (:results (value :scs (unsigned-reg)))
529 (:result-types unsigned-num)
530 (:generator 5
531 (loadw tmp object 0 instance-pointer-lowtag)
532 (inst shr tmp n-widetag-bits)
533 (inst shl tmp n-fixnum-tag-bits)
534 (inst sub tmp index)
535 (inst mov value (make-ea-for-raw-slot object index tmp))))
537 (define-vop (raw-instance-ref-c/word)
538 (:translate %raw-instance-ref/word)
539 (:policy :fast-safe)
540 (:args (object :scs (descriptor-reg)))
541 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
542 #.instance-pointer-lowtag
543 #.instance-slots-offset)))
544 (:info index)
545 (:temporary (:sc unsigned-reg) tmp)
546 (:results (value :scs (unsigned-reg)))
547 (:result-types unsigned-num)
548 (:generator 4
549 (loadw tmp object 0 instance-pointer-lowtag)
550 (inst shr tmp n-widetag-bits)
551 (inst mov value (make-ea-for-raw-slot object index tmp))))
553 (define-vop (raw-instance-set/word)
554 (:translate %raw-instance-set/word)
555 (:policy :fast-safe)
556 (:args (object :scs (descriptor-reg))
557 (index :scs (any-reg))
558 (value :scs (unsigned-reg) :target result))
559 (:arg-types * tagged-num unsigned-num)
560 (:temporary (:sc unsigned-reg) tmp)
561 (:results (result :scs (unsigned-reg)))
562 (:result-types unsigned-num)
563 (:generator 5
564 (loadw tmp object 0 instance-pointer-lowtag)
565 (inst shr tmp n-widetag-bits)
566 (inst shl tmp n-fixnum-tag-bits)
567 (inst sub tmp index)
568 (inst mov (make-ea-for-raw-slot object index tmp) value)
569 (move result value)))
571 (define-vop (raw-instance-set-c/word)
572 (:translate %raw-instance-set/word)
573 (:policy :fast-safe)
574 (:args (object :scs (descriptor-reg))
575 (value :scs (unsigned-reg) :target result))
576 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
577 #.instance-pointer-lowtag
578 #.instance-slots-offset))
579 unsigned-num)
580 (:info index)
581 (:temporary (:sc unsigned-reg) tmp)
582 (:results (result :scs (unsigned-reg)))
583 (:result-types unsigned-num)
584 (:generator 4
585 (loadw tmp object 0 instance-pointer-lowtag)
586 (inst shr tmp n-widetag-bits)
587 (inst mov (make-ea-for-raw-slot object index tmp) value)
588 (move result value)))
590 (define-vop (raw-instance-init/word)
591 (:args (object :scs (descriptor-reg))
592 (value :scs (unsigned-reg)))
593 (:arg-types * unsigned-num)
594 (:info instance-length index)
595 (:generator 4
596 (inst mov (make-ea-for-raw-slot object index instance-length) value)))
598 (define-vop (raw-instance-atomic-incf-c/word)
599 (:translate %raw-instance-atomic-incf/word)
600 (:policy :fast-safe)
601 (:args (object :scs (descriptor-reg))
602 (diff :scs (unsigned-reg) :target result))
603 (:arg-types * (:constant (load/store-index #.n-word-bytes
604 #.instance-pointer-lowtag
605 #.instance-slots-offset))
606 unsigned-num)
607 (:info index)
608 (:temporary (:sc unsigned-reg) tmp)
609 (:results (result :scs (unsigned-reg)))
610 (:result-types unsigned-num)
611 (:generator 4
612 (loadw tmp object 0 instance-pointer-lowtag)
613 (inst shr tmp n-widetag-bits)
614 (inst xadd (make-ea-for-raw-slot object index tmp) diff :lock)
615 (move result diff)))
617 (define-vop (raw-instance-ref/single)
618 (:translate %raw-instance-ref/single)
619 (:policy :fast-safe)
620 (:args (object :scs (descriptor-reg))
621 (index :scs (any-reg)))
622 (:arg-types * positive-fixnum)
623 (:temporary (:sc unsigned-reg) tmp)
624 (:results (value :scs (single-reg)))
625 (:result-types single-float)
626 (:generator 5
627 (loadw tmp object 0 instance-pointer-lowtag)
628 (inst shr tmp n-widetag-bits)
629 (inst shl tmp n-fixnum-tag-bits)
630 (inst sub tmp index)
631 (inst movss value (make-ea-for-raw-slot object index tmp))))
633 (define-vop (raw-instance-ref-c/single)
634 (:translate %raw-instance-ref/single)
635 (:policy :fast-safe)
636 (:args (object :scs (descriptor-reg)))
637 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
638 #.instance-pointer-lowtag
639 #.instance-slots-offset)))
640 (:info index)
641 (:temporary (:sc unsigned-reg) tmp)
642 (:results (value :scs (single-reg)))
643 (:result-types single-float)
644 (:generator 4
645 (loadw tmp object 0 instance-pointer-lowtag)
646 (inst shr tmp n-widetag-bits)
647 (inst movss value (make-ea-for-raw-slot object index tmp))))
649 (define-vop (raw-instance-set/single)
650 (:translate %raw-instance-set/single)
651 (:policy :fast-safe)
652 (:args (object :scs (descriptor-reg))
653 (index :scs (any-reg))
654 (value :scs (single-reg) :target result))
655 (:arg-types * positive-fixnum single-float)
656 (:temporary (:sc unsigned-reg) tmp)
657 (:results (result :scs (single-reg)))
658 (:result-types single-float)
659 (:generator 5
660 (loadw tmp object 0 instance-pointer-lowtag)
661 (inst shr tmp n-widetag-bits)
662 (inst shl tmp n-fixnum-tag-bits)
663 (inst sub tmp index)
664 (inst movss (make-ea-for-raw-slot object index tmp) value)
665 (move result value)))
667 (define-vop (raw-instance-set-c/single)
668 (:translate %raw-instance-set/single)
669 (:policy :fast-safe)
670 (:args (object :scs (descriptor-reg))
671 (value :scs (single-reg) :target result))
672 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
673 #.instance-pointer-lowtag
674 #.instance-slots-offset))
675 single-float)
676 (:info index)
677 (:temporary (:sc unsigned-reg) tmp)
678 (:results (result :scs (single-reg)))
679 (:result-types single-float)
680 (:generator 4
681 (loadw tmp object 0 instance-pointer-lowtag)
682 (inst shr tmp n-widetag-bits)
683 (inst movss (make-ea-for-raw-slot object index tmp) value)
684 (move result value)))
686 (define-vop (raw-instance-init/single)
687 (:args (object :scs (descriptor-reg))
688 (value :scs (single-reg)))
689 (:arg-types * single-float)
690 (:info instance-length index)
691 (:generator 4
692 (inst movss (make-ea-for-raw-slot object index instance-length) value)))
694 (define-vop (raw-instance-ref/double)
695 (:translate %raw-instance-ref/double)
696 (:policy :fast-safe)
697 (:args (object :scs (descriptor-reg))
698 (index :scs (any-reg)))
699 (:arg-types * positive-fixnum)
700 (:temporary (:sc unsigned-reg) tmp)
701 (:results (value :scs (double-reg)))
702 (:result-types double-float)
703 (:generator 5
704 (loadw tmp object 0 instance-pointer-lowtag)
705 (inst shr tmp n-widetag-bits)
706 (inst shl tmp n-fixnum-tag-bits)
707 (inst sub tmp index)
708 (inst movsd value (make-ea-for-raw-slot object index tmp))))
710 (define-vop (raw-instance-ref-c/double)
711 (:translate %raw-instance-ref/double)
712 (:policy :fast-safe)
713 (:args (object :scs (descriptor-reg)))
714 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
715 #.instance-pointer-lowtag
716 #.instance-slots-offset)))
717 (:info index)
718 (:temporary (:sc unsigned-reg) tmp)
719 (:results (value :scs (double-reg)))
720 (:result-types double-float)
721 (:generator 4
722 (loadw tmp object 0 instance-pointer-lowtag)
723 (inst shr tmp n-widetag-bits)
724 (inst movsd value (make-ea-for-raw-slot object index tmp))))
726 (define-vop (raw-instance-set/double)
727 (:translate %raw-instance-set/double)
728 (:policy :fast-safe)
729 (:args (object :scs (descriptor-reg))
730 (index :scs (any-reg))
731 (value :scs (double-reg) :target result))
732 (:arg-types * positive-fixnum double-float)
733 (:temporary (:sc unsigned-reg) tmp)
734 (:results (result :scs (double-reg)))
735 (:result-types double-float)
736 (:generator 5
737 (loadw tmp object 0 instance-pointer-lowtag)
738 (inst shr tmp n-widetag-bits)
739 (inst shl tmp n-fixnum-tag-bits)
740 (inst sub tmp index)
741 (inst movsd (make-ea-for-raw-slot object index tmp) value)
742 (move result value)))
744 (define-vop (raw-instance-set-c/double)
745 (:translate %raw-instance-set/double)
746 (:policy :fast-safe)
747 (:args (object :scs (descriptor-reg))
748 (value :scs (double-reg) :target result))
749 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
750 #.instance-pointer-lowtag
751 #.instance-slots-offset))
752 double-float)
753 (:info index)
754 (:temporary (:sc unsigned-reg) tmp)
755 (:results (result :scs (double-reg)))
756 (:result-types double-float)
757 (:generator 4
758 (loadw tmp object 0 instance-pointer-lowtag)
759 (inst shr tmp n-widetag-bits)
760 (inst movsd (make-ea-for-raw-slot object index tmp) value)
761 (move result value)))
763 (define-vop (raw-instance-init/double)
764 (:args (object :scs (descriptor-reg))
765 (value :scs (double-reg)))
766 (:arg-types * double-float)
767 (:info instance-length index)
768 (:generator 4
769 (inst movsd (make-ea-for-raw-slot object index instance-length) value)))
771 (define-vop (raw-instance-ref/complex-single)
772 (:translate %raw-instance-ref/complex-single)
773 (:policy :fast-safe)
774 (:args (object :scs (descriptor-reg))
775 (index :scs (any-reg)))
776 (:arg-types * positive-fixnum)
777 (:temporary (:sc unsigned-reg) tmp)
778 (:results (value :scs (complex-single-reg)))
779 (:result-types complex-single-float)
780 (:generator 5
781 (loadw tmp object 0 instance-pointer-lowtag)
782 (inst shr tmp n-widetag-bits)
783 (inst shl tmp n-fixnum-tag-bits)
784 (inst sub tmp index)
785 (inst movq value (make-ea-for-raw-slot object index tmp))))
787 (define-vop (raw-instance-ref-c/complex-single)
788 (:translate %raw-instance-ref/complex-single)
789 (:policy :fast-safe)
790 (:args (object :scs (descriptor-reg)))
791 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
792 #.instance-pointer-lowtag
793 #.instance-slots-offset)))
794 (:info index)
795 (:temporary (:sc unsigned-reg) tmp)
796 (:results (value :scs (complex-single-reg)))
797 (:result-types complex-single-float)
798 (:generator 4
799 (loadw tmp object 0 instance-pointer-lowtag)
800 (inst shr tmp n-widetag-bits)
801 (inst movq value (make-ea-for-raw-slot object index tmp))))
803 (define-vop (raw-instance-set/complex-single)
804 (:translate %raw-instance-set/complex-single)
805 (:policy :fast-safe)
806 (:args (object :scs (descriptor-reg))
807 (index :scs (any-reg))
808 (value :scs (complex-single-reg) :target result))
809 (:arg-types * positive-fixnum complex-single-float)
810 (:temporary (:sc unsigned-reg) tmp)
811 (:results (result :scs (complex-single-reg)))
812 (:result-types complex-single-float)
813 (:generator 5
814 (loadw tmp object 0 instance-pointer-lowtag)
815 (inst shr tmp n-widetag-bits)
816 (inst shl tmp n-fixnum-tag-bits)
817 (inst sub tmp index)
818 (move result value)
819 (inst movq (make-ea-for-raw-slot object index tmp) value)))
821 (define-vop (raw-instance-set-c/complex-single)
822 (:translate %raw-instance-set/complex-single)
823 (:policy :fast-safe)
824 (:args (object :scs (descriptor-reg))
825 (value :scs (complex-single-reg) :target result))
826 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
827 #.instance-pointer-lowtag
828 #.instance-slots-offset))
829 complex-single-float)
830 (:info index)
831 (:temporary (:sc unsigned-reg) tmp)
832 (:results (result :scs (complex-single-reg)))
833 (:result-types complex-single-float)
834 (:generator 4
835 (loadw tmp object 0 instance-pointer-lowtag)
836 (inst shr tmp n-widetag-bits)
837 (move result value)
838 (inst movq (make-ea-for-raw-slot object index tmp) value)))
840 (define-vop (raw-instance-init/complex-single)
841 (:args (object :scs (descriptor-reg))
842 (value :scs (complex-single-reg)))
843 (:arg-types * complex-single-float)
844 (:info instance-length index)
845 (:generator 4
846 (inst movq (make-ea-for-raw-slot object index instance-length) value)))
848 (define-vop (raw-instance-ref/complex-double)
849 (:translate %raw-instance-ref/complex-double)
850 (:policy :fast-safe)
851 (:args (object :scs (descriptor-reg))
852 (index :scs (any-reg)))
853 (:arg-types * positive-fixnum)
854 (:temporary (:sc unsigned-reg) tmp)
855 (:results (value :scs (complex-double-reg)))
856 (:result-types complex-double-float)
857 (:generator 5
858 (loadw tmp object 0 instance-pointer-lowtag)
859 (inst shr tmp n-widetag-bits)
860 (inst shl tmp n-fixnum-tag-bits)
861 (inst sub tmp index)
862 (inst movdqu value (make-ea-for-raw-slot object index tmp -8))))
864 (define-vop (raw-instance-ref-c/complex-double)
865 (:translate %raw-instance-ref/complex-double)
866 (:policy :fast-safe)
867 (:args (object :scs (descriptor-reg)))
868 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
869 #.instance-pointer-lowtag
870 #.instance-slots-offset)))
871 (:info index)
872 (:temporary (:sc unsigned-reg) tmp)
873 (:results (value :scs (complex-double-reg)))
874 (:result-types complex-double-float)
875 (:generator 4
876 (loadw tmp object 0 instance-pointer-lowtag)
877 (inst shr tmp n-widetag-bits)
878 (inst movdqu value (make-ea-for-raw-slot object index tmp -8))))
880 (define-vop (raw-instance-set/complex-double)
881 (:translate %raw-instance-set/complex-double)
882 (:policy :fast-safe)
883 (:args (object :scs (descriptor-reg))
884 (index :scs (any-reg))
885 (value :scs (complex-double-reg) :target result))
886 (:arg-types * positive-fixnum complex-double-float)
887 (:temporary (:sc unsigned-reg) tmp)
888 (:results (result :scs (complex-double-reg)))
889 (:result-types complex-double-float)
890 (:generator 5
891 (loadw tmp object 0 instance-pointer-lowtag)
892 (inst shr tmp n-widetag-bits)
893 (inst shl tmp n-fixnum-tag-bits)
894 (inst sub tmp index)
895 (move result value)
896 (inst movdqu (make-ea-for-raw-slot object index tmp -8) value)))
898 (define-vop (raw-instance-set-c/complex-double)
899 (:translate %raw-instance-set/complex-double)
900 (:policy :fast-safe)
901 (:args (object :scs (descriptor-reg))
902 (value :scs (complex-double-reg) :target result))
903 (:arg-types * (:constant (load/store-index #.sb!vm:n-word-bytes
904 #.instance-pointer-lowtag
905 #.instance-slots-offset))
906 complex-double-float)
907 (:info index)
908 (:temporary (:sc unsigned-reg) tmp)
909 (:results (result :scs (complex-double-reg)))
910 (:result-types complex-double-float)
911 (:generator 4
912 (loadw tmp object 0 instance-pointer-lowtag)
913 (inst shr tmp n-widetag-bits)
914 (move result value)
915 (inst movdqu (make-ea-for-raw-slot object index tmp -8) value)))
917 (define-vop (raw-instance-init/complex-double)
918 (:args (object :scs (descriptor-reg))
919 (value :scs (complex-double-reg)))
920 (:arg-types * complex-double-float)
921 (:info instance-length index)
922 (:generator 4
923 (inst movdqu (make-ea-for-raw-slot object index instance-length -8) value)))