0.7.7.9:
[sbcl.git] / src / compiler / mips / sap.lisp
1 (in-package "SB!VM")
2
3 \f
4 ;;;; Moves and coercions:
5
6 ;;; Move a tagged SAP to an untagged representation.
7 ;;;
8 (define-vop (move-to-sap)
9   (:args (x :scs (descriptor-reg)))
10   (:results (y :scs (sap-reg)))
11   (:note "system area pointer indirection")
12   (:generator 1
13     (loadw y x sap-pointer-slot other-pointer-lowtag)))
14
15 ;;;
16 (define-move-vop move-to-sap :move
17   (descriptor-reg) (sap-reg))
18
19
20 ;;; Move an untagged SAP to a tagged representation.
21 ;;;
22 (define-vop (move-from-sap)
23   (:args (x :scs (sap-reg) :target sap))
24   (:temporary (:scs (sap-reg) :from (:argument 0)) sap)
25   (:temporary (:scs (non-descriptor-reg)) ndescr)
26   (:temporary (:sc non-descriptor-reg :offset nl4-offset) pa-flag)
27   (:results (y :scs (descriptor-reg)))
28   (:note "system area pointer allocation")
29   (:generator 20
30     (move sap x)
31     (with-fixed-allocation (y pa-flag ndescr sap-widetag sap-size)
32       (storew sap y sap-pointer-slot other-pointer-lowtag))))
33 ;;;
34 (define-move-vop move-from-sap :move
35   (sap-reg) (descriptor-reg))
36
37
38 ;;; Move untagged sap values.
39 ;;;
40 (define-vop (sap-move)
41   (:args (x :target y
42             :scs (sap-reg)
43             :load-if (not (location= x y))))
44   (:results (y :scs (sap-reg)
45                :load-if (not (location= x y))))
46   (:effects)
47   (:affected)
48   (:generator 0
49     (move y x)))
50 ;;;
51 (define-move-vop sap-move :move
52   (sap-reg) (sap-reg))
53
54
55 ;;; Move untagged sap arguments/return-values.
56 ;;;
57 (define-vop (move-sap-arg)
58   (:args (x :target y
59             :scs (sap-reg))
60          (fp :scs (any-reg)
61              :load-if (not (sc-is y sap-reg))))
62   (:results (y))
63   (:generator 0
64     (sc-case y
65       (sap-reg
66        (move y x))
67       (sap-stack
68        (storew x fp (tn-offset y))))))
69 ;;;
70 (define-move-vop move-sap-arg :move-arg
71   (descriptor-reg sap-reg) (sap-reg))
72
73
74 ;;; Use standard MOVE-ARGUMENT + coercion to move an untagged sap to a
75 ;;; descriptor passing location.
76 ;;;
77 (define-move-vop move-arg :move-arg
78   (sap-reg) (descriptor-reg))
79
80
81 \f
82 ;;;; SAP-INT and INT-SAP
83
84 (define-vop (sap-int)
85   (:args (sap :scs (sap-reg) :target int))
86   (:arg-types system-area-pointer)
87   (:results (int :scs (unsigned-reg)))
88   (:result-types unsigned-num)
89   (:translate sap-int)
90   (:policy :fast-safe)
91   (:generator 1
92     (move int sap)))
93
94 (define-vop (int-sap)
95   (:args (int :scs (unsigned-reg) :target sap))
96   (:arg-types unsigned-num)
97   (:results (sap :scs (sap-reg)))
98   (:result-types system-area-pointer)
99   (:translate int-sap)
100   (:policy :fast-safe)
101   (:generator 1
102     (move sap int)))
103
104
105 \f
106 ;;;; POINTER+ and POINTER-
107
108 (define-vop (pointer+)
109   (:translate sap+)
110   (:args (ptr :scs (sap-reg))
111          (offset :scs (signed-reg immediate)))
112   (:arg-types system-area-pointer signed-num)
113   (:results (res :scs (sap-reg)))
114   (:result-types system-area-pointer)
115   (:policy :fast-safe)
116   (:generator 1
117     (sc-case offset
118       (signed-reg
119        (inst addu res ptr offset))
120       (immediate
121        (inst addu res ptr (tn-value offset))))))
122
123 (define-vop (pointer-)
124   (:translate sap-)
125   (:args (ptr1 :scs (sap-reg))
126          (ptr2 :scs (sap-reg)))
127   (:arg-types system-area-pointer system-area-pointer)
128   (:policy :fast-safe)
129   (:results (res :scs (signed-reg)))
130   (:result-types signed-num)
131   (:generator 1
132     (inst subu res ptr1 ptr2)))
133
134
135 \f
136 ;;;; mumble-SYSTEM-REF and mumble-SYSTEM-SET
137
138 (macrolet ((def-system-ref-and-set
139           (ref-name set-name sc type size &optional signed)
140   (let ((ref-name-c (symbolicate ref-name "-C"))
141         (set-name-c (symbolicate set-name "-C")))
142     `(progn
143        (define-vop (,ref-name)
144          (:translate ,ref-name)
145          (:policy :fast-safe)
146          (:args (object :scs (sap-reg) :target sap)
147                 (offset :scs (signed-reg)))
148          (:arg-types system-area-pointer signed-num)
149          (:results (result :scs (,sc)))
150          (:result-types ,type)
151          (:temporary (:scs (sap-reg) :from (:argument 0)) sap)
152          (:generator 5
153            (inst addu sap object offset)
154            ,@(ecase size
155                (:byte
156                 (if signed
157                     '((inst lb result sap 0))
158                     '((inst lbu result sap 0))))
159                  (:short
160                   (if signed
161                       '((inst lh result sap 0))
162                       '((inst lhu result sap 0))))
163                  (:long
164                   '((inst lw result sap 0)))
165                  (:single
166                   '((inst lwc1 result sap 0)))
167                  (:double
168                   (ecase *backend-byte-order*
169                     (:big-endian
170                      '((inst lwc1 result sap n-word-bytes)
171                        (inst lwc1-odd result sap 0)))
172                     (:little-endian
173                      '((inst lwc1 result sap 0)
174                        (inst lwc1-odd result sap n-word-bytes))))))
175            (inst nop)))
176        (define-vop (,ref-name-c)
177          (:translate ,ref-name)
178          (:policy :fast-safe)
179          (:args (object :scs (sap-reg)))
180          (:arg-types system-area-pointer
181                      (:constant ,(if (eq size :double)
182                                      ;; We need to be able to add 4.
183                                      `(integer ,(- (ash 1 16))
184                                                ,(- (ash 1 16) 5))
185                                      '(signed-byte 16))))
186          (:info offset)
187          (:results (result :scs (,sc)))
188          (:result-types ,type)
189          (:generator 4
190            ,@(ecase size
191                (:byte
192                 (if signed
193                     '((inst lb result object offset))
194                     '((inst lbu result object offset))))
195                (:short
196                 (if signed
197                     '((inst lh result object offset))
198                     '((inst lhu result object offset))))
199                (:long
200                 '((inst lw result object offset)))
201                (:single
202                 '((inst lwc1 result object offset)))
203                (:double
204                 (ecase *backend-byte-order*
205                   (:big-endian
206                    '((inst lwc1 result object (+ offset n-word-bytes))
207                      (inst lwc1-odd result object offset)))
208                   (:little-endian
209                    '((inst lwc1 result object offset)
210                      (inst lwc1-odd result object (+ offset n-word-bytes)))))))
211            (inst nop)))
212        (define-vop (,set-name)
213          (:translate ,set-name)
214          (:policy :fast-safe)
215          (:args (object :scs (sap-reg) :target sap)
216                 (offset :scs (signed-reg))
217                 (value :scs (,sc) :target result))
218          (:arg-types system-area-pointer signed-num ,type)
219          (:results (result :scs (,sc)))
220          (:result-types ,type)
221          (:temporary (:scs (sap-reg) :from (:argument 0)) sap)
222          (:generator 5
223            (inst addu sap object offset)
224            ,@(ecase size
225                (:byte
226                 '((inst sb value sap 0)
227                   (move result value)))
228                (:short
229                 '((inst sh value sap 0)
230                   (move result value)))
231                (:long
232                 '((inst sw value sap 0)
233                   (move result value)))
234                (:single
235                 '((inst swc1 value sap 0)
236                   (unless (location= result value)
237                     (inst fmove :single result value))))
238                (:double
239                 (ecase *backend-byte-order*
240                   (:big-endian
241                    '((inst swc1 value sap n-word-bytes)
242                      (inst swc1-odd value sap 0)
243                      (unless (location= result value)
244                        (inst fmove :double result value))))
245                   (:little-endian
246                    '((inst swc1 value sap 0)
247                      (inst swc1-odd value sap n-word-bytes)
248                      (unless (location= result value)
249                        (inst fmove :double result value)))))))))
250        (define-vop (,set-name-c)
251          (:translate ,set-name)
252          (:policy :fast-safe)
253          (:args (object :scs (sap-reg))
254                 (value :scs (,sc) :target result))
255          (:arg-types system-area-pointer
256                      (:constant ,(if (eq size :double)
257                                      ;; We need to be able to add 4.
258                                      `(integer ,(- (ash 1 16))
259                                                ,(- (ash 1 16) 5))
260                                      '(signed-byte 16)))
261                      ,type)
262          (:info offset)
263          (:results (result :scs (,sc)))
264          (:result-types ,type)
265          (:generator 5
266            ,@(ecase size
267                (:byte
268                 '((inst sb value object offset)
269                   (move result value)))
270                (:short
271                 '((inst sh value object offset)
272                   (move result value)))
273                (:long
274                 '((inst sw value object offset)
275                   (move result value)))
276                (:single
277                 '((inst swc1 value object offset)
278                   (unless (location= result value)
279                     (inst fmove :single result value))))
280                (:double
281                 (ecase *backend-byte-order*
282                   (:big-endian
283                    '((inst swc1 value object (+ offset n-word-bytes))
284                      (inst swc1-odd value object (+ offset n-word-bytes))
285                      (unless (location= result value)
286                        (inst fmove :double result value))))
287                   (:little-endian
288                    '((inst swc1 value object offset)
289                      (inst swc1-odd value object (+ offset n-word-bytes))
290                      (unless (location= result value)
291                        (inst fmove :double result value)))))))))))))
292   (def-system-ref-and-set sap-ref-8 %set-sap-ref-8
293     unsigned-reg positive-fixnum :byte nil)
294   (def-system-ref-and-set signed-sap-ref-8 %set-signed-sap-ref-8
295     signed-reg tagged-num :byte t)
296   (def-system-ref-and-set sap-ref-16 %set-sap-ref-16
297     unsigned-reg positive-fixnum :short nil)
298   (def-system-ref-and-set signed-sap-ref-16 %set-signed-sap-ref-16
299     signed-reg tagged-num :short t)
300   (def-system-ref-and-set sap-ref-32 %set-sap-ref-32
301     unsigned-reg unsigned-num :long nil)
302   (def-system-ref-and-set signed-sap-ref-32 %set-signed-sap-ref-32
303     signed-reg signed-num :long t)
304   (def-system-ref-and-set sap-ref-sap %set-sap-ref-sap
305     sap-reg system-area-pointer :long)
306   (def-system-ref-and-set sap-ref-single %set-sap-ref-single
307     single-reg single-float :single)
308   (def-system-ref-and-set sap-ref-double %set-sap-ref-double
309     double-reg double-float :double))
310
311 \f
312 ;;; Noise to convert normal lisp data objects into SAPs.
313
314 (define-vop (vector-sap)
315   (:translate vector-sap)
316   (:policy :fast-safe)
317   (:args (vector :scs (descriptor-reg)))
318   (:results (sap :scs (sap-reg)))
319   (:result-types system-area-pointer)
320   (:generator 2
321     (inst addu sap vector
322           (- (* vector-data-offset n-word-bytes) other-pointer-lowtag))))
323