1.0.29.44: Complex float improvements
[sbcl.git] / src / compiler / x86-64 / cell.lisp
1 ;;;; various primitive memory access VOPs for the x86 VM
2
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.
11
12 (in-package "SB!VM")
13 \f
14 ;;;; data object ref/set stuff
15
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)))
23
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))))
49
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)))
66 \f
67 ;;;; symbol hacking VOPs
68
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))))
106
107 (define-vop (%set-symbol-global-value cell-set)
108   (:variant symbol-value-slot other-pointer-lowtag))
109
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))
114
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))))
127
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))))
147
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))))
171
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)))))
189
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)))
197
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))))
215
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)))
226
227
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))))
241 \f
242 ;;;; fdefinition (FDEFN) objects
243
244 (define-vop (fdefn-fun cell-ref)        ; /pfw - alpha
245   (:variant fdefn-fun-slot other-pointer-lowtag))
246
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))))
257
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)))
279
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)))
290 \f
291 ;;;; binding and unbinding
292
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.
296
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))))
335
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)))
349
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)))
367
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*)))
380
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)
388
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))
405
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)
412
413     DONE))
414
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)))
423
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)))
432
433 \f
434
435 \f
436 ;;;; closure indexing
437
438 (define-full-reffer closure-index-ref *
439   closure-info-offset fun-pointer-lowtag
440   (any-reg descriptor-reg) * %closure-index-ref)
441
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)
445
446 (define-full-reffer funcallable-instance-info *
447   funcallable-instance-info-offset fun-pointer-lowtag
448   (descriptor-reg any-reg) * %funcallable-instance-info)
449
450 (define-vop (closure-ref slot-ref)
451   (:variant closure-info-offset fun-pointer-lowtag))
452
453 (define-vop (closure-init slot-set)
454   (:variant closure-info-offset fun-pointer-lowtag))
455 \f
456 ;;;; value cell hackery
457
458 (define-vop (value-cell-ref cell-ref)
459   (:variant value-cell-value-slot other-pointer-lowtag))
460
461 (define-vop (value-cell-set cell-set)
462   (:variant value-cell-value-slot other-pointer-lowtag))
463 \f
464 ;;;; structure hackery
465
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)))
475
476 (define-full-reffer instance-index-ref * instance-slots-offset
477   instance-pointer-lowtag (any-reg descriptor-reg) * %instance-ref)
478
479 (define-full-setter instance-index-set * instance-slots-offset
480   instance-pointer-lowtag (any-reg descriptor-reg) * %instance-set)
481
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)
486 \f
487 ;;;; code object frobbing
488
489 (define-full-reffer code-header-ref * 0 other-pointer-lowtag
490   (any-reg descriptor-reg) * code-header-ref)
491
492 (define-full-setter code-header-set * 0 other-pointer-lowtag
493   (any-reg descriptor-reg) * code-header-set)
494 \f
495 ;;;; raw instance slot accessors
496
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
509         (tn
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))))))))
521
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 3)
534     (inst sub tmp index)
535     (inst mov value (make-ea-for-raw-slot object index tmp))))
536
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))))
552
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 3)
567     (inst sub tmp index)
568     (inst mov (make-ea-for-raw-slot object index tmp) value)
569     (move result value)))
570
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)))
589
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)))
597
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 (signed-reg) :target result))
603   (:arg-types * (:constant (load/store-index #.n-word-bytes
604                                              #.instance-pointer-lowtag
605                                              #.instance-slots-offset))
606               signed-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)))
616
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 3)
630     (inst sub tmp index)
631     (inst movss value (make-ea-for-raw-slot object index tmp))))
632
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))))
648
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 3)
663     (inst sub tmp index)
664     (inst movss (make-ea-for-raw-slot object index tmp) value)
665     (move result value)))
666
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)))
685
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)))
693
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 3)
707     (inst sub tmp index)
708     (inst movsd value (make-ea-for-raw-slot object index tmp))))
709
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))))
725
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 3)
740     (inst sub tmp index)
741     (inst movsd (make-ea-for-raw-slot object index tmp) value)
742     (move result value)))
743
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)))
762
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)))
770
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 3)
784     (inst sub tmp index)
785     (inst movq value (make-ea-for-raw-slot object index tmp))))
786
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))))
802
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 3)
817     (inst sub tmp index)
818     (move result value)
819     (inst movq (make-ea-for-raw-slot object index tmp) value)))
820
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)))
839
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)))
847
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 3)
861     (inst sub tmp index)
862     (inst movdqu value (make-ea-for-raw-slot object index tmp -8))))
863
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))))
879
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 3)
894     (inst sub tmp index)
895     (move result value)
896     (inst movdqu (make-ea-for-raw-slot object index tmp -8) value)))
897
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)))
916
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)))