aa245b01937defd008f82be4e5f24b231feb52cc
[sbcl.git] / src / compiler / ppc / system.lisp
1 ;;;
2 ;;; Written by Rob MacLachlan
3 ;;;
4 ;;; Mips conversion by William Lott and Christopher Hoover.
5 ;;;
6 (in-package "SB!VM")
7
8
9 \f
10 ;;;; Type frobbing VOPs
11
12 (define-vop (lowtag-of)
13   (:translate lowtag-of)
14   (:policy :fast-safe)
15   (:args (object :scs (any-reg descriptor-reg)))
16   (:results (result :scs (unsigned-reg)))
17   (:result-types positive-fixnum)
18   (:generator 1
19     (inst andi. result object sb!vm:lowtag-mask)))
20
21 (define-vop (widetag-of)
22   (:translate widetag-of)
23   (:policy :fast-safe)
24   (:args (object :scs (descriptor-reg) :to (:eval 1)))
25   (:results (result :scs (unsigned-reg) :from (:eval 0)))
26   (:result-types positive-fixnum)
27   (:generator 6
28     ;; Grab the lowtag.
29     (inst andi. result object lowtag-mask)
30     ;; Check for various pointer types.
31     (inst cmpwi result list-pointer-lowtag)
32     (inst beq done)
33     (inst cmpwi result other-pointer-lowtag)
34     (inst beq other-pointer)
35     (inst cmpwi result fun-pointer-lowtag)
36     (inst beq function-pointer)
37     (inst cmpwi result instance-pointer-lowtag)
38     (inst beq done)
39     ;; Okay, it is an immediate.  If fixnum, we want zero.  Otherwise,
40     ;; we want the low 8 bits.
41     (inst andi. result object #b11)
42     (inst beq done)
43     ;; It wasn't a fixnum, so get the low 8 bits.
44     (inst andi. result object widetag-mask)
45     (inst b done)
46     
47     FUNCTION-POINTER
48     (load-type result object (- fun-pointer-lowtag))
49     (inst b done)
50
51     OTHER-POINTER
52     (load-type result object (- other-pointer-lowtag))
53
54     DONE))
55
56
57 (define-vop (fun-subtype)
58   (:translate fun-subtype)
59   (:policy :fast-safe)
60   (:args (function :scs (descriptor-reg)))
61   (:results (result :scs (unsigned-reg)))
62   (:result-types positive-fixnum)
63   (:generator 6
64     (load-type result function (- sb!vm:fun-pointer-lowtag))))
65
66 (define-vop (set-fun-subtype)
67   (:translate (setf fun-subtype))
68   (:policy :fast-safe)
69   (:args (type :scs (unsigned-reg) :target result)
70          (function :scs (descriptor-reg)))
71   (:arg-types positive-fixnum *)
72   (:results (result :scs (unsigned-reg)))
73   (:result-types positive-fixnum)
74   (:generator 6
75     (inst stb type function (- 3 fun-pointer-lowtag))
76     (move result type)))
77
78 (define-vop (get-header-data)
79   (:translate get-header-data)
80   (:policy :fast-safe)
81   (:args (x :scs (descriptor-reg)))
82   (:results (res :scs (unsigned-reg)))
83   (:result-types positive-fixnum)
84   (:generator 6
85     (loadw res x 0 sb!vm:other-pointer-lowtag)
86     (inst srwi res res sb!vm:n-widetag-bits)))
87
88 (define-vop (get-closure-length)
89   (:translate get-closure-length)
90   (:policy :fast-safe)
91   (:args (x :scs (descriptor-reg)))
92   (:results (res :scs (unsigned-reg)))
93   (:result-types positive-fixnum)
94   (:generator 6
95     (loadw res x 0 sb!vm:fun-pointer-lowtag)
96     (inst srwi res res sb!vm:n-widetag-bits)))
97
98 (define-vop (set-header-data)
99   (:translate set-header-data)
100   (:policy :fast-safe)
101   (:args (x :scs (descriptor-reg) :target res)
102          (data :scs (any-reg immediate zero)))
103   (:arg-types * positive-fixnum)
104   (:results (res :scs (descriptor-reg)))
105   (:temporary (:scs (non-descriptor-reg)) t1 t2)
106   (:generator 6
107     (loadw t1 x 0 sb!vm:other-pointer-lowtag)
108     (inst andi. t1 t1 sb!vm:widetag-mask)
109     (sc-case data
110       (any-reg
111        (inst slwi t2 data (- sb!vm:n-widetag-bits 2))
112        (inst or t1 t1 t2))
113       (immediate
114        (inst ori t1 t1 (ash (tn-value data) sb!vm:n-widetag-bits)))
115       (zero))
116     (storew t1 x 0 sb!vm:other-pointer-lowtag)
117     (move res x)))
118
119
120 (define-vop (make-fixnum)
121   (:args (ptr :scs (any-reg descriptor-reg)))
122   (:results (res :scs (any-reg descriptor-reg)))
123   (:generator 1
124     ;;
125     ;; Some code (the hash table code) depends on this returning a
126     ;; positive number so make sure it does.
127     (inst slwi res ptr 3)
128     (inst srwi res res 1)))
129
130 (define-vop (make-other-immediate-type)
131   (:args (val :scs (any-reg descriptor-reg))
132          (type :scs (any-reg descriptor-reg immediate)
133                :target temp))
134   (:results (res :scs (any-reg descriptor-reg)))
135   (:temporary (:scs (non-descriptor-reg)) temp)
136   (:generator 2
137     (sc-case type
138       (immediate
139        (inst slwi temp val sb!vm:n-widetag-bits)
140        (inst ori res temp (tn-value type)))
141       (t
142        (inst srawi temp type 2)
143        (inst slwi res val (- sb!vm:n-widetag-bits 2))
144        (inst or res res temp)))))
145
146 \f
147 ;;;; Allocation
148
149 (define-vop (dynamic-space-free-pointer)
150   (:results (int :scs (sap-reg)))
151   (:result-types system-area-pointer)
152   (:translate dynamic-space-free-pointer)
153   (:policy :fast-safe)
154   (:generator 1
155     (move int alloc-tn)))
156
157 (define-vop (binding-stack-pointer-sap)
158   (:results (int :scs (sap-reg)))
159   (:result-types system-area-pointer)
160   (:translate binding-stack-pointer-sap)
161   (:policy :fast-safe)
162   (:generator 1
163     (move int bsp-tn)))
164
165 (define-vop (control-stack-pointer-sap)
166   (:results (int :scs (sap-reg)))
167   (:result-types system-area-pointer)
168   (:translate control-stack-pointer-sap)
169   (:policy :fast-safe)
170   (:generator 1
171     (move int csp-tn)))
172
173 \f
174 ;;;; Code object frobbing.
175
176 (define-vop (code-instructions)
177   (:translate code-instructions)
178   (:policy :fast-safe)
179   (:args (code :scs (descriptor-reg)))
180   (:temporary (:scs (non-descriptor-reg)) ndescr)
181   (:results (sap :scs (sap-reg)))
182   (:result-types system-area-pointer)
183   (:generator 10
184     (loadw ndescr code 0 sb!vm:other-pointer-lowtag)
185     (inst srwi ndescr ndescr sb!vm:n-widetag-bits)
186     (inst slwi ndescr ndescr sb!vm:word-shift)
187     (inst subi ndescr ndescr sb!vm:other-pointer-lowtag)
188     (inst add sap code ndescr)))
189
190 (define-vop (compute-fun)
191   (:args (code :scs (descriptor-reg))
192          (offset :scs (signed-reg unsigned-reg)))
193   (:arg-types * positive-fixnum)
194   (:results (func :scs (descriptor-reg)))
195   (:temporary (:scs (non-descriptor-reg)) ndescr)
196   (:generator 10
197     (loadw ndescr code 0 sb!vm:other-pointer-lowtag)
198     (inst srwi ndescr ndescr sb!vm:n-widetag-bits)
199     (inst slwi ndescr ndescr sb!vm:word-shift)
200     (inst add ndescr ndescr offset)
201     (inst addi ndescr ndescr (- sb!vm:fun-pointer-lowtag sb!vm:other-pointer-lowtag))
202     (inst add func code ndescr)))
203
204
205 \f
206 ;;;; Other random VOPs.
207
208
209 (defknown sb!unix::do-pending-interrupt () (values))
210 (define-vop (sb!unix::do-pending-interrupt)
211   (:policy :fast-safe)
212   (:translate sb!unix::do-pending-interrupt)
213   (:generator 1
214     (inst unimp pending-interrupt-trap)))
215
216
217 (define-vop (halt)
218   (:generator 1
219     (inst unimp halt-trap)))
220
221
222 \f
223 ;;;; Dynamic vop count collection support
224
225 (define-vop (count-me)
226   (:args (count-vector :scs (descriptor-reg)))
227   (:info index)
228   (:temporary (:scs (non-descriptor-reg)) count)
229   (:generator 1
230     (let ((offset
231            (- (* (+ index vector-data-offset) n-word-bytes) other-pointer-lowtag)))
232       (assert (typep offset '(signed-byte 16)))
233       (inst lwz count count-vector offset)
234       (inst addi count count 1)
235       (inst stw count count-vector offset))))