Initial revision
[sbcl.git] / src / compiler / x86 / memory.lisp
1 ;;;; the x86 definitions of some general purpose memory reference VOPs
2 ;;;; inherited by basic memory reference operations
3
4 ;;;; This software is part of the SBCL system. See the README file for
5 ;;;; more information.
6 ;;;;
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
12
13 (in-package "SB!VM")
14
15 (file-comment
16  "$Header$")
17
18 ;;; Cell-Ref and Cell-Set are used to define VOPs like CAR, where the
19 ;;; offset to be read or written is a property of the VOP used.
20 ;;; Cell-Setf is similar to Cell-Set, but delivers the new value as
21 ;;; the result. Cell-Setf-Function takes its arguments as if it were a
22 ;;; setf function (new value first, as apposed to a setf macro, which
23 ;;; takes the new value last).
24 (define-vop (cell-ref)
25   (:args (object :scs (descriptor-reg)))
26   (:results (value :scs (descriptor-reg any-reg)))
27   (:variant-vars offset lowtag)
28   (:policy :fast-safe)
29   (:generator 4
30     (loadw value object offset lowtag)))
31 (define-vop (cell-set)
32   (:args (object :scs (descriptor-reg))
33          (value :scs (descriptor-reg any-reg)))
34   (:variant-vars offset lowtag)
35   (:policy :fast-safe)
36   (:generator 4
37     (storew value object offset lowtag)))
38 (define-vop (cell-setf)
39   (:args (object :scs (descriptor-reg))
40          (value :scs (descriptor-reg any-reg) :target result))
41   (:results (result :scs (descriptor-reg any-reg)))
42   (:variant-vars offset lowtag)
43   (:policy :fast-safe)
44   (:generator 4
45     (storew value object offset lowtag)
46     (move result value)))
47 (define-vop (cell-setf-function)
48   (:args (value :scs (descriptor-reg any-reg) :target result)
49          (object :scs (descriptor-reg)))
50   (:results (result :scs (descriptor-reg any-reg)))
51   (:variant-vars offset lowtag)
52   (:policy :fast-safe)
53   (:generator 4
54     (storew value object offset lowtag)
55     (move result value)))
56
57 ;;; Define accessor VOPs for some cells in an object. If the operation name
58 ;;; is NIL, then that operation isn't defined. If the translate function is
59 ;;; null, then we don't define a translation.
60 (defmacro define-cell-accessors (offset lowtag
61                                         ref-op ref-trans set-op set-trans)
62   `(progn
63      ,@(when ref-op
64          `((define-vop (,ref-op cell-ref)
65              (:variant ,offset ,lowtag)
66              ,@(when ref-trans
67                  `((:translate ,ref-trans))))))
68      ,@(when set-op
69          `((define-vop (,set-op cell-setf)
70              (:variant ,offset ,lowtag)
71              ,@(when set-trans
72                  `((:translate ,set-trans))))))))
73
74 ;;; X86 special
75 (define-vop (cell-xadd)
76   (:args (object :scs (descriptor-reg) :to :result)
77          (value :scs (any-reg) :target result))
78   (:results (result :scs (any-reg) :from (:argument 1)))
79   (:result-types tagged-num)
80   (:variant-vars offset lowtag)
81   (:policy :fast-safe)
82   (:generator 4
83     (move result value)
84     (inst xadd (make-ea :dword :base object
85                         :disp (- (* offset word-bytes) lowtag))
86           value)))
87
88 ;;; Slot-Ref and Slot-Set are used to define VOPs like Closure-Ref, where the
89 ;;; offset is constant at compile time, but varies for different uses.
90 (define-vop (slot-ref)
91   (:args (object :scs (descriptor-reg)))
92   (:results (value :scs (descriptor-reg any-reg)))
93   (:variant-vars base lowtag)
94   (:info offset)
95   (:generator 4
96     (loadw value object (+ base offset) lowtag)))
97 (define-vop (slot-set)
98   (:args (object :scs (descriptor-reg))
99          (value :scs (descriptor-reg any-reg immediate)))
100   (:variant-vars base lowtag)
101   (:info offset)
102   (:generator 4
103      (if (sc-is value immediate)
104          (let ((val (tn-value value)))
105            (etypecase val
106              (integer
107               (inst mov
108                     (make-ea :dword :base object
109                              :disp (- (* (+ base offset) word-bytes) lowtag))
110                     (fixnumize val)))
111              (symbol
112               (inst mov
113                     (make-ea :dword :base object
114                              :disp (- (* (+ base offset) word-bytes) lowtag))
115                     (+ *nil-value* (static-symbol-offset val))))
116              (character
117               (inst mov
118                     (make-ea :dword :base object
119                              :disp (- (* (+ base offset) word-bytes) lowtag))
120                     (logior (ash (char-code val) type-bits)
121                             base-char-type)))))
122          ;; Else, value not immediate.
123          (storew value object (+ base offset) lowtag))))
124
125 (define-vop (slot-set-conditional)
126   (:args (object :scs (descriptor-reg) :to :eval)
127          (old-value :scs (descriptor-reg any-reg) :target eax)
128          (new-value :scs (descriptor-reg any-reg) :target temp))
129   (:temporary (:sc descriptor-reg :offset eax-offset
130                    :from (:argument 1) :to :result :target result)  eax)
131   (:temporary (:sc descriptor-reg :from (:argument 2) :to :result) temp)
132   (:variant-vars base lowtag)
133   (:results (result :scs (descriptor-reg)))
134   (:info offset)
135   (:generator 4
136     (move eax old-value)
137     (move temp new-value)
138     (inst cmpxchg (make-ea :dword :base object
139                            :disp (- (* (+ base offset) word-bytes) lowtag))
140           temp)
141     (move result eax)))
142
143 ;;; X86 special
144 (define-vop (slot-xadd)
145   (:args (object :scs (descriptor-reg) :to :result)
146          (value :scs (any-reg) :target result))
147   (:results (result :scs (any-reg) :from (:argument 1)))
148   (:result-types tagged-num)
149   (:variant-vars base lowtag)
150   (:info offset)
151   (:generator 4
152     (move result value)
153     (inst xadd (make-ea :dword :base object
154                         :disp (- (* (+ base offset) word-bytes) lowtag))
155           value)))