1 ;;;; the MIPS VM definition of SAP operations
3 ;;;; This software is part of the SBCL system. See the README file for
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.
14 ;;;; Moves and coercions:
16 ;;; Move a tagged SAP to an untagged representation.
17 (define-vop (move-to-sap)
18 (:args (x :scs (any-reg descriptor-reg)))
19 (:results (y :scs (sap-reg)))
20 (:note "pointer to SAP coercion")
22 (loadw y x sap-pointer-slot other-pointer-lowtag)))
24 (define-move-vop move-to-sap :move
25 (descriptor-reg) (sap-reg))
27 ;;; Move an untagged SAP to a tagged representation.
28 (define-vop (move-from-sap)
29 (:args (sap :scs (sap-reg) :to :save))
30 (:temporary (:scs (non-descriptor-reg)) ndescr)
31 (:temporary (:sc non-descriptor-reg :offset nl4-offset) pa-flag)
32 (:results (res :scs (descriptor-reg)))
33 (:note "SAP to pointer coercion")
35 (with-fixed-allocation (res pa-flag ndescr sap-widetag sap-size)
36 (storew sap res sap-pointer-slot other-pointer-lowtag))))
38 (define-move-vop move-from-sap :move
39 (sap-reg) (descriptor-reg))
41 ;;; Move untagged SAP values.
42 (define-vop (sap-move)
45 :load-if (not (location= x y))))
46 (:results (y :scs (sap-reg)
47 :load-if (not (location= x y))))
54 (define-move-vop sap-move :move
57 ;;; Move untagged SAP arguments/return-values.
58 (define-vop (move-sap-arg)
62 :load-if (not (sc-is y sap-reg))))
64 (:note "SAP argument move")
70 (storew x fp (tn-offset y))))))
72 (define-move-vop move-sap-arg :move-arg
73 (descriptor-reg sap-reg) (sap-reg))
75 ;;; Use standard MOVE-ARG + coercion to move an untagged SAP to a
76 ;;; descriptor passing location.
77 (define-move-vop move-arg :move-arg
78 (sap-reg) (descriptor-reg))
80 ;;;; SAP-INT and INT-SAP
82 ;;; The function SAP-INT is used to generate an integer corresponding
83 ;;; to the system area pointer, suitable for passing to the kernel
84 ;;; interfaces (which want all addresses specified as integers). The
85 ;;; function INT-SAP is used to do the opposite conversion. The
86 ;;; integer representation of a SAP is the byte offset of the SAP from
87 ;;; the start of the address space.
89 (:args (sap :scs (sap-reg) :target int))
90 (:arg-types system-area-pointer)
91 (:results (int :scs (unsigned-reg)))
92 (:result-types unsigned-num)
99 (:args (int :scs (unsigned-reg) :target sap))
100 (:arg-types unsigned-num)
101 (:results (sap :scs (sap-reg)))
102 (:result-types system-area-pointer)
108 ;;;; POINTER+ and POINTER-
109 (define-vop (pointer+)
111 (:args (ptr :scs (sap-reg))
112 (offset :scs (signed-reg immediate)))
113 (:arg-types system-area-pointer signed-num)
114 (:results (res :scs (sap-reg)))
115 (:result-types system-area-pointer)
120 (inst addu res ptr offset))
122 (inst addu res ptr (tn-value offset))))))
124 (define-vop (pointer-)
126 (:args (ptr1 :scs (sap-reg))
127 (ptr2 :scs (sap-reg)))
128 (:arg-types system-area-pointer system-area-pointer)
130 (:results (res :scs (signed-reg)))
131 (:result-types signed-num)
133 (inst subu res ptr1 ptr2)))
135 ;;;; mumble-SYSTEM-REF and mumble-SYSTEM-SET
136 (macrolet ((def-system-ref-and-set
137 (ref-name set-name sc type size &optional signed)
138 (let ((ref-name-c (symbolicate ref-name "-C"))
139 (set-name-c (symbolicate set-name "-C")))
141 (define-vop (,ref-name)
142 (:translate ,ref-name)
144 (:args (object :scs (sap-reg) :target sap)
145 (offset :scs (signed-reg)))
146 (:arg-types system-area-pointer signed-num)
147 (:results (result :scs (,sc)))
148 (:result-types ,type)
149 (:temporary (:scs (sap-reg) :from (:argument 0)) sap)
151 (inst addu sap object offset)
155 '((inst lb result sap 0))
156 '((inst lbu result sap 0))))
159 '((inst lh result sap 0))
160 '((inst lhu result sap 0))))
162 '((inst lw result sap 0)))
164 '((inst lwc1 result sap 0)))
166 (ecase *backend-byte-order*
168 '((inst lwc1 result sap n-word-bytes)
169 (inst lwc1-odd result sap 0)))
171 '((inst lwc1 result sap 0)
172 (inst lwc1-odd result sap n-word-bytes))))))
174 (define-vop (,ref-name-c)
175 (:translate ,ref-name)
177 (:args (object :scs (sap-reg)))
178 (:arg-types system-area-pointer
179 (:constant ,(if (eq size :double)
180 ;; We need to be able to add 4.
181 `(integer ,(- (ash 1 16))
185 (:results (result :scs (,sc)))
186 (:result-types ,type)
191 '((inst lb result object offset))
192 '((inst lbu result object offset))))
195 '((inst lh result object offset))
196 '((inst lhu result object offset))))
198 '((inst lw result object offset)))
200 '((inst lwc1 result object offset)))
202 (ecase *backend-byte-order*
204 '((inst lwc1 result object (+ offset n-word-bytes))
205 (inst lwc1-odd result object offset)))
207 '((inst lwc1 result object offset)
208 (inst lwc1-odd result object (+ offset n-word-bytes)))))))
210 (define-vop (,set-name)
211 (:translate ,set-name)
213 (:args (object :scs (sap-reg) :target sap)
214 (offset :scs (signed-reg))
215 (value :scs (,sc) :target result))
216 (:arg-types system-area-pointer signed-num ,type)
217 (:results (result :scs (,sc)))
218 (:result-types ,type)
219 (:temporary (:scs (sap-reg) :from (:argument 0)) sap)
221 (inst addu sap object offset)
224 '((inst sb value sap 0)
225 (move result value)))
227 '((inst sh value sap 0)
228 (move result value)))
230 '((inst sw value sap 0)
231 (move result value)))
233 '((inst swc1 value sap 0)
234 (unless (location= result value)
235 (inst fmove :single result value))))
237 (ecase *backend-byte-order*
239 '((inst swc1 value sap n-word-bytes)
240 (inst swc1-odd value sap 0)
241 (unless (location= result value)
242 (inst fmove :double result value))))
244 '((inst swc1 value sap 0)
245 (inst swc1-odd value sap n-word-bytes)
246 (unless (location= result value)
247 (inst fmove :double result value)))))))))
248 (define-vop (,set-name-c)
249 (:translate ,set-name)
251 (:args (object :scs (sap-reg))
252 (value :scs (,sc) :target result))
253 (:arg-types system-area-pointer
254 (:constant ,(if (eq size :double)
255 ;; We need to be able to add 4.
256 `(integer ,(- (ash 1 16))
261 (:results (result :scs (,sc)))
262 (:result-types ,type)
266 '((inst sb value object offset)
267 (move result value)))
269 '((inst sh value object offset)
270 (move result value)))
272 '((inst sw value object offset)
273 (move result value)))
275 '((inst swc1 value object offset)
276 (unless (location= result value)
277 (inst fmove :single result value))))
279 (ecase *backend-byte-order*
281 '((inst swc1 value object (+ offset n-word-bytes))
282 (inst swc1-odd value object (+ offset n-word-bytes))
283 (unless (location= result value)
284 (inst fmove :double result value))))
286 '((inst swc1 value object offset)
287 (inst swc1-odd value object (+ offset n-word-bytes))
288 (unless (location= result value)
289 (inst fmove :double result value)))))))))))))
290 (def-system-ref-and-set sap-ref-8 %set-sap-ref-8
291 unsigned-reg positive-fixnum :byte nil)
292 (def-system-ref-and-set signed-sap-ref-8 %set-signed-sap-ref-8
293 signed-reg tagged-num :byte t)
294 (def-system-ref-and-set sap-ref-16 %set-sap-ref-16
295 unsigned-reg positive-fixnum :short nil)
296 (def-system-ref-and-set signed-sap-ref-16 %set-signed-sap-ref-16
297 signed-reg tagged-num :short t)
298 (def-system-ref-and-set sap-ref-32 %set-sap-ref-32
299 unsigned-reg unsigned-num :long nil)
300 (def-system-ref-and-set signed-sap-ref-32 %set-signed-sap-ref-32
301 signed-reg signed-num :long t)
302 (def-system-ref-and-set sap-ref-sap %set-sap-ref-sap
303 sap-reg system-area-pointer :long)
304 (def-system-ref-and-set sap-ref-single %set-sap-ref-single
305 single-reg single-float :single)
306 (def-system-ref-and-set sap-ref-double %set-sap-ref-double
307 double-reg double-float :double))
309 ;;; Noise to convert normal lisp data objects into SAPs.
310 (define-vop (vector-sap)
311 (:translate vector-sap)
313 (:args (vector :scs (descriptor-reg)))
314 (:results (sap :scs (sap-reg)))
315 (:result-types system-area-pointer)
317 (inst addu sap vector
318 (- (* vector-data-offset n-word-bytes) other-pointer-lowtag))))
320 ;;; Transforms for 64-bit SAP accessors.
323 (deftransform sap-ref-64 ((sap offset) (* *))
324 '(logior (sap-ref-32 sap offset)
325 (ash (sap-ref-32 sap (+ offset 4)) 32)))
327 (deftransform signed-sap-ref-64 ((sap offset) (* *))
328 '(logior (sap-ref-32 sap offset)
329 (ash (signed-sap-ref-32 sap (+ offset 4)) 32)))
331 (deftransform %set-sap-ref-64 ((sap offset value) (* * *))
333 (%set-sap-ref-32 sap offset (logand value #xffffffff))
334 (%set-sap-ref-32 sap (+ offset 4) (ash value -32))))
336 (deftransform %set-signed-sap-ref-64 ((sap offset value) (* * *))
338 (%set-sap-ref-32 sap offset (logand value #xffffffff))
339 (%set-signed-sap-ref-32 sap (+ offset 4) (ash value -32)))))
343 (deftransform sap-ref-64 ((sap offset) (* *))
344 '(logior (ash (sap-ref-32 sap offset) 32)
345 (sap-ref-32 sap (+ offset 4))))
347 (deftransform signed-sap-ref-64 ((sap offset) (* *))
348 '(logior (ash (signed-sap-ref-32 sap offset) 32)
349 (sap-ref-32 sap (+ 4 offset))))
351 (deftransform %set-sap-ref-64 ((sap offset value) (* * *))
353 (%set-sap-ref-32 sap offset (ash value -32))
354 (%set-sap-ref-32 sap (+ offset 4) (logand value #xffffffff))))
356 (deftransform %set-signed-sap-ref-64 ((sap offset value) (* * *))
358 (%set-signed-sap-ref-32 sap offset (ash value -32))
359 (%set-sap-ref-32 sap (+ 4 offset) (logand value #xffffffff)))))