Add SB-SYS:SAP-REF-LISPOBJ.
[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 (any-reg 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 ;;; 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   (:results (res :scs (descriptor-reg)))
32   (:note "system area pointer allocation")
33   (:generator 20
34     (with-fixed-allocation (res nil ndescr sap-widetag sap-size nil)
35       (storew sap res sap-pointer-slot other-pointer-lowtag))))
36
37 (define-move-vop move-from-sap :move
38   (sap-reg) (descriptor-reg))
39
40 ;;; Move untagged sap values.
41 (define-vop (sap-move)
42   (:args (x :target y
43             :scs (sap-reg)
44             :load-if (not (location= x y))))
45   (:results (y :scs (sap-reg)
46                :load-if (not (location= x y))))
47   (:note "SAP move")
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 args/return-values.
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   (:note "SAP argument move")
64   (:generator 0
65     (sc-case y
66       (sap-reg
67        (move x y))
68       (sap-stack
69        (storew x fp (tn-offset y))))))
70
71 (define-move-vop move-sap-arg :move-arg
72   (descriptor-reg sap-reg) (sap-reg))
73
74 ;;; Use standard MOVE-ARG + coercion to move an untagged sap to a
75 ;;; descriptor passing location.
76 (define-move-vop move-arg :move-arg
77   (sap-reg) (descriptor-reg))
78 \f
79 ;;;; SAP-INT and INT-SAP
80 (define-vop (sap-int)
81   (:args (sap :scs (sap-reg) :target int))
82   (:arg-types system-area-pointer)
83   (:results (int :scs (unsigned-reg)))
84   (:result-types unsigned-num)
85   (:translate sap-int)
86   (:policy :fast-safe)
87   (:generator 1
88     (move sap int)))
89
90 (define-vop (int-sap)
91   (:args (int :scs (unsigned-reg) :target sap))
92   (:arg-types unsigned-num)
93   (:results (sap :scs (sap-reg)))
94   (:result-types system-area-pointer)
95   (:translate int-sap)
96   (:policy :fast-safe)
97   (:generator 1
98     (move int sap)))
99 \f
100 ;;;; POINTER+ and POINTER-
101 (define-vop (pointer+)
102   (:translate sap+)
103   (:args (ptr :scs (sap-reg))
104          (offset :scs (signed-reg immediate)))
105   (:arg-types system-area-pointer signed-num)
106   (:results (res :scs (sap-reg)))
107   (:result-types system-area-pointer)
108   (:policy :fast-safe)
109   (:generator 1
110     (sc-case offset
111       (signed-reg
112         (inst add ptr offset res))
113       (immediate
114         (cond
115           ((and (< (tn-value offset) (ash 1 10))
116                 (> (tn-value offset) (- (ash 1 10))))
117             (inst addi (tn-value offset) ptr res))
118           (t
119             (inst li (tn-value offset) res)
120             (inst add ptr res 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-lispobj %set-sap-ref-lispobj
239     descriptor-reg * :long)
240   (def-system-ref-and-set sap-ref-single %set-sap-ref-single
241     single-reg single-float :float)
242   (def-system-ref-and-set sap-ref-double %set-sap-ref-double
243     double-reg double-float :float))
244 \f
245 ;;; Noise to convert normal lisp data objects into SAPs.
246 (define-vop (vector-sap)
247   (:translate vector-sap)
248   (:policy :fast-safe)
249   (:args (vector :scs (descriptor-reg)))
250   (:results (sap :scs (sap-reg)))
251   (:result-types system-area-pointer)
252   (:generator 2
253     (inst addi (- (* vector-data-offset n-word-bytes) other-pointer-lowtag)
254                vector sap)))