0.8.2.8:
[sbcl.git] / src / compiler / ppc / cell.lisp
1 ;;; VOPs for the PPC.
2 ;;;
3 ;;; Written by Rob MacLachlan
4 ;;;
5 ;;; Converted by William Lott.
6 ;;; 
7
8 (in-package "SB!VM")
9
10 \f
11 ;;;; Data object ref/set stuff.
12
13 (define-vop (slot)
14   (:args (object :scs (descriptor-reg)))
15   (:info name offset lowtag)
16   (:ignore name)
17   (:results (result :scs (descriptor-reg any-reg)))
18   (:generator 1
19     (loadw result object offset lowtag)))
20
21 (define-vop (set-slot)
22   (:args (object :scs (descriptor-reg))
23          (value :scs (descriptor-reg any-reg)))
24   (:info name offset lowtag)
25   (:ignore name)
26   (:results)
27   (:generator 1
28     (storew value object offset lowtag)))
29
30
31 \f
32 ;;;; Symbol hacking VOPs:
33
34 ;;; The compiler likes to be able to directly SET symbols.
35 ;;;
36 (define-vop (set cell-set)
37   (:variant symbol-value-slot other-pointer-lowtag))
38
39 ;;; Do a cell ref with an error check for being unbound.
40 ;;;
41 (define-vop (checked-cell-ref)
42   (:args (object :scs (descriptor-reg) :target obj-temp))
43   (:results (value :scs (descriptor-reg any-reg)))
44   (:policy :fast-safe)
45   (:vop-var vop)
46   (:save-p :compute-only)
47   (:temporary (:scs (descriptor-reg) :from (:argument 0)) obj-temp))
48
49 ;;; With Symbol-Value, we check that the value isn't the trap object.  So
50 ;;; Symbol-Value of NIL is NIL.
51 ;;;
52 (define-vop (symbol-value checked-cell-ref)
53   (:translate symbol-value)
54   (:generator 9
55     (move obj-temp object)
56     (loadw value obj-temp sb!vm:symbol-value-slot sb!vm:other-pointer-lowtag)
57     (let ((err-lab (generate-error-code vop unbound-symbol-error obj-temp)))
58       (inst cmpwi value sb!vm:unbound-marker-widetag)
59       (inst beq err-lab))))
60
61 ;;; Like CHECKED-CELL-REF, only we are a predicate to see if the cell is bound.
62 (define-vop (boundp-frob)
63   (:args (object :scs (descriptor-reg)))
64   (:conditional)
65   (:info target not-p)
66   (:policy :fast-safe)
67   (:temporary (:scs (descriptor-reg)) value))
68
69 (define-vop (boundp boundp-frob)
70   (:translate boundp)
71   (:generator 9
72     (loadw value object sb!vm:symbol-value-slot sb!vm:other-pointer-lowtag)
73     (inst cmpwi value sb!vm:unbound-marker-widetag)
74     (inst b? (if not-p :eq :ne) target)))
75
76 (define-vop (fast-symbol-value cell-ref)
77   (:variant sb!vm:symbol-value-slot sb!vm:other-pointer-lowtag)
78   (:policy :fast)
79   (:translate symbol-value))
80
81 \f
82 ;;;; Fdefinition (fdefn) objects.
83
84 (define-vop (fdefn-fun cell-ref)
85   (:variant fdefn-fun-slot other-pointer-lowtag))
86
87 (define-vop (safe-fdefn-fun)
88   (:args (object :scs (descriptor-reg) :target obj-temp))
89   (:results (value :scs (descriptor-reg any-reg)))
90   (:vop-var vop)
91   (:save-p :compute-only)
92   (:temporary (:scs (descriptor-reg) :from (:argument 0)) obj-temp)
93   (:generator 10
94     (move obj-temp object)
95     (loadw value obj-temp fdefn-fun-slot other-pointer-lowtag)
96     (inst cmpw value null-tn)
97     (let ((err-lab (generate-error-code vop undefined-fun-error obj-temp)))
98       (inst beq err-lab))))
99
100 (define-vop (set-fdefn-fun)
101   (:policy :fast-safe)
102   (:translate (setf fdefn-fun))
103   (:args (function :scs (descriptor-reg) :target result)
104          (fdefn :scs (descriptor-reg)))
105   (:temporary (:scs (interior-reg)) lip)
106   (:temporary (:scs (non-descriptor-reg)) type)
107   (:results (result :scs (descriptor-reg)))
108   (:generator 38
109     (let ((normal-fn (gen-label)))
110       (load-type type function (- fun-pointer-lowtag))
111       (inst cmpwi type simple-fun-header-widetag)
112       ;;(inst mr lip function)
113       (inst addi lip function
114             (- (ash simple-fun-code-offset word-shift) fun-pointer-lowtag))
115       (inst beq normal-fn)
116       (inst lr lip  (make-fixup (extern-alien-name "closure_tramp") :foreign))
117       (emit-label normal-fn)
118       (storew lip fdefn fdefn-raw-addr-slot other-pointer-lowtag)
119       (storew function fdefn fdefn-fun-slot other-pointer-lowtag)
120       (move result function))))
121
122 (define-vop (fdefn-makunbound)
123   (:policy :fast-safe)
124   (:translate fdefn-makunbound)
125   (:args (fdefn :scs (descriptor-reg) :target result))
126   (:temporary (:scs (non-descriptor-reg)) temp)
127   (:results (result :scs (descriptor-reg)))
128   (:generator 38
129     (storew null-tn fdefn fdefn-fun-slot other-pointer-lowtag)
130     (inst lr temp  (make-fixup (extern-alien-name "undefined_tramp") :foreign))
131     (storew temp fdefn fdefn-raw-addr-slot other-pointer-lowtag)
132     (move result fdefn)))
133
134
135 \f
136 ;;;; Binding and Unbinding.
137
138 ;;; BIND -- Establish VAL as a binding for SYMBOL.  Save the old value and
139 ;;; the symbol on the binding stack and stuff the new value into the
140 ;;; symbol.
141
142 (define-vop (bind)
143   (:args (val :scs (any-reg descriptor-reg))
144          (symbol :scs (descriptor-reg)))
145   (:temporary (:scs (descriptor-reg)) temp)
146   (:generator 5
147     (loadw temp symbol sb!vm:symbol-value-slot sb!vm:other-pointer-lowtag)
148     (inst addi bsp-tn bsp-tn (* 2 sb!vm:n-word-bytes))
149     (storew temp bsp-tn (- sb!vm:binding-value-slot sb!vm:binding-size))
150     (storew symbol bsp-tn (- sb!vm:binding-symbol-slot sb!vm:binding-size))
151     (storew val symbol sb!vm:symbol-value-slot sb!vm:other-pointer-lowtag)))
152
153
154 (define-vop (unbind)
155   (:temporary (:scs (descriptor-reg)) symbol value)
156   (:generator 0
157     (loadw symbol bsp-tn (- sb!vm:binding-symbol-slot sb!vm:binding-size))
158     (loadw value bsp-tn (- sb!vm:binding-value-slot sb!vm:binding-size))
159     (storew value symbol sb!vm:symbol-value-slot sb!vm:other-pointer-lowtag)
160     (storew zero-tn bsp-tn (- sb!vm:binding-symbol-slot sb!vm:binding-size))
161     (inst subi bsp-tn bsp-tn (* 2 sb!vm:n-word-bytes))))
162
163
164 (define-vop (unbind-to-here)
165   (:args (arg :scs (descriptor-reg any-reg) :target where))
166   (:temporary (:scs (any-reg) :from (:argument 0)) where)
167   (:temporary (:scs (descriptor-reg)) symbol value)
168   (:generator 0
169     (let ((loop (gen-label))
170           (skip (gen-label))
171           (done (gen-label)))
172       (move where arg)
173       (inst cmpw where bsp-tn)
174       (inst beq done)
175
176       (emit-label loop)
177       (loadw symbol bsp-tn (- sb!vm:binding-symbol-slot sb!vm:binding-size))
178       (inst cmpwi symbol 0)
179       (inst beq skip)
180       (loadw value bsp-tn (- sb!vm:binding-value-slot sb!vm:binding-size))
181       (storew value symbol sb!vm:symbol-value-slot sb!vm:other-pointer-lowtag)
182       (storew zero-tn bsp-tn (- sb!vm:binding-symbol-slot sb!vm:binding-size))
183
184       (emit-label skip)
185       (inst subi bsp-tn bsp-tn (* 2 sb!vm:n-word-bytes))
186       (inst cmpw where bsp-tn)
187       (inst bne loop)
188
189       (emit-label done))))
190
191
192 \f
193 ;;;; Closure indexing.
194
195 (define-vop (closure-index-ref word-index-ref)
196   (:variant sb!vm:closure-info-offset sb!vm:fun-pointer-lowtag)
197   (:translate %closure-index-ref))
198
199 (define-vop (funcallable-instance-info word-index-ref)
200   (:variant funcallable-instance-info-offset sb!vm:fun-pointer-lowtag)
201   (:translate %funcallable-instance-info))
202
203 (define-vop (set-funcallable-instance-info word-index-set)
204   (:variant funcallable-instance-info-offset fun-pointer-lowtag)
205   (:translate %set-funcallable-instance-info))
206
207 (define-vop (funcallable-instance-lexenv cell-ref)
208   (:variant funcallable-instance-lexenv-slot fun-pointer-lowtag))
209
210
211 (define-vop (closure-ref slot-ref)
212   (:variant closure-info-offset fun-pointer-lowtag))
213
214 (define-vop (closure-init slot-set)
215   (:variant closure-info-offset fun-pointer-lowtag))
216
217 \f
218 ;;;; Value Cell hackery.
219
220 (define-vop (value-cell-ref cell-ref)
221   (:variant value-cell-value-slot other-pointer-lowtag))
222
223 (define-vop (value-cell-set cell-set)
224   (:variant value-cell-value-slot other-pointer-lowtag))
225
226
227 \f
228 ;;;; Instance hackery:
229
230 (define-vop (instance-length)
231   (:policy :fast-safe)
232   (:translate %instance-length)
233   (:args (struct :scs (descriptor-reg)))
234   (:temporary (:scs (non-descriptor-reg)) temp)
235   (:results (res :scs (unsigned-reg)))
236   (:result-types positive-fixnum)
237   (:generator 4
238     (loadw temp struct 0 instance-pointer-lowtag)
239     (inst srwi res temp sb!vm:n-widetag-bits)))
240
241 (define-vop (instance-ref slot-ref)
242   (:variant instance-slots-offset instance-pointer-lowtag)
243   (:policy :fast-safe)
244   (:translate %instance-ref)
245   (:arg-types * (:constant index)))
246
247 #+nil
248 (define-vop (instance-set slot-set)
249   (:policy :fast-safe)
250   (:translate %instance-set)
251   (:variant instance-slots-offset instance-pointer-lowtag)
252   (:arg-types instance (:constant index) *))
253
254 (define-vop (instance-index-ref word-index-ref)
255   (:policy :fast-safe) 
256   (:translate %instance-ref)
257   (:variant instance-slots-offset instance-pointer-lowtag)
258   (:arg-types instance positive-fixnum))
259
260 (define-vop (instance-index-set word-index-set)
261   (:policy :fast-safe) 
262   (:translate %instance-set)
263   (:variant instance-slots-offset instance-pointer-lowtag)
264   (:arg-types instance positive-fixnum *))
265
266
267
268 \f
269 ;;;; Code object frobbing.
270
271 (define-vop (code-header-ref word-index-ref)
272   (:translate code-header-ref)
273   (:policy :fast-safe)
274   (:variant 0 other-pointer-lowtag))
275
276 (define-vop (code-header-set word-index-set)
277   (:translate code-header-set)
278   (:policy :fast-safe)
279   (:variant 0 other-pointer-lowtag))
280