09d21f00aa7ce8b2d8a983264ca8e915f123749d
[sbcl.git] / src / compiler / hppa / sap.lisp
1 ;;;; the MIPS VM definition of SAP operations
2
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
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.
11
12 (in-package "SB!VM")
13 \f
14 ;;;; Moves and coercions:
15
16 ;;; Move a tagged SAP to an untagged representation.
17 (define-vop (move-to-sap)
18   (:args (x :scs (descriptor-reg)))
19   (:results (y :scs (sap-reg)))
20   (:note "system area pointer indirection")
21   (:generator 1
22     (loadw y x sap-pointer-slot other-pointer-lowtag)))
23
24 (define-move-vop move-to-sap :move
25   (descriptor-reg) (sap-reg))
26
27
28 ;;; Move an untagged SAP to a tagged representation.
29 (define-vop (move-from-sap)
30   (:args (x :scs (sap-reg) :to (:eval 1)))
31   (:temporary (:scs (non-descriptor-reg)) ndescr)
32   (:results (y :scs (descriptor-reg) :from (:eval 0)))
33   (:note "system area pointer allocation")
34   (:generator 20
35     (with-fixed-allocation (y ndescr sap-widetag sap-size)
36       (storew x y sap-pointer-slot other-pointer-lowtag))))
37
38 (define-move-vop move-from-sap :move
39   (sap-reg) (descriptor-reg))
40
41 ;;; Move untagged sap values.
42 (define-vop (sap-move)
43   (:args (x :target y
44             :scs (sap-reg)
45             :load-if (not (location= x y))))
46   (:results (y :scs (sap-reg)
47                :load-if (not (location= x y))))
48   (:effects)
49   (:affected)
50   (:generator 0
51     (move x y)))
52
53 (define-move-vop sap-move :move
54   (sap-reg) (sap-reg))
55
56 ;;; Move untagged sap arguments/return-values.
57 (define-vop (move-sap-argument)
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 x y))
67       (sap-stack
68        (storew x fp (tn-offset y))))))
69
70 (define-move-vop move-sap-argument :move-arg
71   (descriptor-reg sap-reg) (sap-reg))
72
73 ;;; Use standard MOVE-ARG + coercion to move an untagged sap to a
74 ;;; descriptor passing location.
75 (define-move-vop move-argument :move-arg
76   (sap-reg) (descriptor-reg))
77 \f
78 ;;;; SAP-INT and INT-SAP
79 (define-vop (sap-int)
80   (:args (sap :scs (sap-reg) :target int))
81   (:arg-types system-area-pointer)
82   (:results (int :scs (unsigned-reg)))
83   (:result-types unsigned-num)
84   (:translate sap-int)
85   (:policy :fast-safe)
86   (:generator 1
87     (move sap int)))
88
89 (define-vop (int-sap)
90   (:args (int :scs (unsigned-reg) :target sap))
91   (:arg-types unsigned-num)
92   (:results (sap :scs (sap-reg)))
93   (:result-types system-area-pointer)
94   (:translate int-sap)
95   (:policy :fast-safe)
96   (:generator 1
97     (move int sap)))
98 \f
99 ;;;; POINTER+ and POINTER-
100 (define-vop (pointer+)
101   (:translate sap+)
102   (:args (ptr :scs (sap-reg) :target res)
103          (offset :scs (signed-reg)))
104   (:arg-types system-area-pointer signed-num)
105   (:results (res :scs (sap-reg)))
106   (:result-types system-area-pointer)
107   (:policy :fast-safe)
108   (:generator 1
109     (inst add ptr offset res)))
110
111 (define-vop (pointer+-c)
112   (:translate sap+)
113   (:args (ptr :scs (sap-reg)))
114   (:info offset)
115   (:arg-types system-area-pointer (:constant (signed-byte 11)))
116   (:results (res :scs (sap-reg)))
117   (:result-types system-area-pointer)
118   (:policy :fast-safe)
119   (:generator 1
120     (inst addi offset ptr res)))
121
122 (define-vop (pointer-)
123   (:translate sap-)
124   (:args (ptr1 :scs (sap-reg))
125          (ptr2 :scs (sap-reg)))
126   (:arg-types system-area-pointer system-area-pointer)
127   (:policy :fast-safe)
128   (:results (res :scs (signed-reg)))
129   (:result-types signed-num)
130   (:generator 1
131     (inst sub ptr1 ptr2 res)))
132 \f
133 ;;;; mumble-SYSTEM-REF and mumble-SYSTEM-SET
134 (macrolet ((def-system-ref-and-set
135           (ref-name set-name sc type size &optional signed)
136   (let ((ref-name-c (symbolicate ref-name "-C"))
137         (set-name-c (symbolicate set-name "-C")))
138     `(progn
139        (define-vop (,ref-name)
140          (:translate ,ref-name)
141          (:policy :fast-safe)
142          (:args (object :scs (sap-reg))
143                 (offset :scs (signed-reg)))
144          (:arg-types system-area-pointer signed-num)
145          (:results (result :scs (,sc)))
146          (:result-types ,type)
147          (:generator 5
148            (inst ,(ecase size
149                     (:byte 'ldbx)
150                     (:short 'ldhx)
151                     (:long 'ldwx)
152                     (:float 'fldx))
153                  offset object result)
154            ,@(when (and signed (not (eq size :long)))
155                `((inst extrs result 31 ,(ecase size
156                           (:byte 8)
157                           (:short 16))
158                        result)))))
159        (define-vop (,ref-name-c)
160          (:translate ,ref-name)
161          (:policy :fast-safe)
162          (:args (object :scs (sap-reg)))
163          (:arg-types system-area-pointer
164                      (:constant ,(if (eq size :float)
165                                      '(signed-byte 5)
166                                      '(signed-byte 14))))
167          (:info offset)
168          (:results (result :scs (,sc)))
169          (:result-types ,type)
170          (:generator 4
171            (inst ,(ecase size
172                     (:byte 'ldb)
173                     (:short 'ldh)
174                     (:long 'ldw)
175                     (:float 'flds))
176                  offset object result)
177            ,@(when (and signed (not (eq size :long)))
178                `((inst extrs result 31 ,(ecase size
179                           (:byte 8)
180                           (:short 16))
181                        result)))))
182        (define-vop (,set-name)
183          (:translate ,set-name)
184          (:policy :fast-safe)
185          (:args (object :scs (sap-reg)
186                         ,@(unless (eq size :float) '(:target sap)))
187                 (offset :scs (signed-reg))
188                 (value :scs (,sc) :target result))
189          (:arg-types system-area-pointer signed-num ,type)
190          (:results (result :scs (,sc)))
191          (:result-types ,type)
192          ,@(unless (eq size :float)
193              '((:temporary (:scs (sap-reg) :from (:argument 0)) sap)))
194          (:generator 5
195            ,@(if (eq size :float)
196                  `((inst fstx value offset object)
197                    (unless (location= value result)
198                      (inst funop :copy value result)))
199                  `((inst add object offset sap)
200                    (inst ,(ecase size (:byte 'stb) (:short 'sth) (:long 'stw))
201                          value 0 sap)
202                    (move value result)))))
203        (define-vop (,set-name-c)
204          (:translate ,set-name)
205          (:policy :fast-safe)
206          (:args (object :scs (sap-reg))
207                 (value :scs (,sc) :target result))
208          (:arg-types system-area-pointer
209                      (:constant ,(if (eq size :float)
210                                      '(signed-byte 5)
211                                      '(signed-byte 14)))
212                      ,type)
213          (:info offset)
214          (:results (result :scs (,sc)))
215          (:result-types ,type)
216          (:generator 5
217            ,@(if (eq size :float)
218                  `((inst fsts value offset object)
219                    (unless (location= value result)
220                      (inst funop :copy value result)))
221                  `((inst ,(ecase size (:byte 'stb) (:short 'sth) (:long 'stw))
222                          value offset object)
223                    (move value result)))))))))
224   (def-system-ref-and-set sap-ref-8 %set-sap-ref-8
225     unsigned-reg positive-fixnum :byte nil)
226   (def-system-ref-and-set signed-sap-ref-8 %set-signed-sap-ref-8
227     signed-reg tagged-num :byte t)
228   (def-system-ref-and-set sap-ref-16 %set-sap-ref-16
229     unsigned-reg positive-fixnum :short nil)
230   (def-system-ref-and-set signed-sap-ref-16 %set-signed-sap-ref-16
231     signed-reg tagged-num :short t)
232   (def-system-ref-and-set sap-ref-32 %set-sap-ref-32
233     unsigned-reg unsigned-num :long nil)
234   (def-system-ref-and-set signed-sap-ref-32 %set-signed-sap-ref-32
235     signed-reg signed-num :long t)
236   (def-system-ref-and-set sap-ref-sap %set-sap-ref-sap
237     sap-reg system-area-pointer :long)
238   (def-system-ref-and-set sap-ref-single %set-sap-ref-single
239     single-reg single-float :float)
240   (def-system-ref-and-set sap-ref-double %set-sap-ref-double
241     double-reg double-float :float))
242 \f
243 ;;; Noise to convert normal lisp data objects into SAPs.
244 (define-vop (vector-sap)
245   (:translate vector-sap)
246   (:policy :fast-safe)
247   (:args (vector :scs (descriptor-reg)))
248   (:results (sap :scs (sap-reg)))
249   (:result-types system-area-pointer)
250   (:generator 2
251     (inst addi
252           (- (* vector-data-offset n-word-bytes) other-pointer-lowtag)
253           vector
254           sap)))
255 \f
256 ;;; Transforms for 64-bit SAP accessors.
257
258 (deftransform sap-ref-64 ((sap offset) (* *))
259   '(logior (ash (sap-ref-32 sap offset) 32)
260            (sap-ref-32 sap (+ offset 4))))
261
262 (deftransform signed-sap-ref-64 ((sap offset) (* *))
263   '(logior (ash (signed-sap-ref-32 sap offset) 32)
264            (sap-ref-32 sap (+ 4 offset))))
265
266 (deftransform %set-sap-ref-64 ((sap offset value) (* * *))
267   '(progn
268      (%set-sap-ref-32 sap offset (ash value -32))
269      (%set-sap-ref-32 sap (+ offset 4) (logand value #xffffffff))))
270
271 (deftransform %set-signed-sap-ref-64 ((sap offset value) (* * *))
272   '(progn
273      (%set-signed-sap-ref-32 sap offset (ash value -32))
274      (%set-sap-ref-32 sap (+ 4 offset) (logand value #xffffffff))))