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