1 ;;;; VOPs and other machine-specific support routines for call-out to C
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.
17 (define-alien-type-method (integer :arg-tn
) (type state
)
18 (let ((stack-frame-size (arg-state-stack-frame-size state
)))
19 (setf (arg-state-stack-frame-size state
) (1+ stack-frame-size
))
21 (ptype reg-sc stack-sc
)
22 (if (alien-integer-type-signed type
)
23 (values 'signed-byte-64 signed-reg-sc-number signed-stack-sc-number
)
24 (values 'unsigned-byte-64 unsigned-reg-sc-number unsigned-stack-sc-number
))
25 (if (< stack-frame-size
4)
26 (make-wired-tn* ptype reg-sc
(+ stack-frame-size nl0-offset
))
27 (make-wired-tn* ptype stack-sc
(* 2 (- stack-frame-size
4)))))))
29 (define-alien-type-method (system-area-pointer :arg-tn
) (type state
)
30 (declare (ignore type
))
31 (let ((stack-frame-size (arg-state-stack-frame-size state
)))
32 (setf (arg-state-stack-frame-size state
) (1+ stack-frame-size
))
33 (if (< stack-frame-size
4)
34 (make-wired-tn* 'system-area-pointer sap-reg-sc-number
35 (+ stack-frame-size nl0-offset
))
36 (make-wired-tn* 'system-area-pointer sap-stack-sc-number
37 (* 2 (- stack-frame-size
4))))))
39 (define-alien-type-method (double-float :arg-tn
) (type state
)
40 (declare (ignore type
))
41 (let ((stack-frame-size (arg-state-stack-frame-size state
)))
42 (setf (arg-state-stack-frame-size state
) (1+ stack-frame-size
))
43 (if (< stack-frame-size
6)
44 (make-wired-tn* 'double-float double-reg-sc-number
45 (+ stack-frame-size nl0-offset
))
46 (make-wired-tn* 'double-float double-stack-sc-number
47 (* 2 (- stack-frame-size
4))))))
49 (define-alien-type-method (single-float :arg-tn
) (type state
)
50 (declare (ignore type
))
51 (let ((stack-frame-size (arg-state-stack-frame-size state
)))
52 (setf (arg-state-stack-frame-size state
) (1+ stack-frame-size
))
53 (if (< stack-frame-size
6)
54 (make-wired-tn* 'single-float single-reg-sc-number
55 (+ stack-frame-size nl0-offset
))
56 (make-wired-tn* 'single-float single-stack-sc-number
57 (* 2 (- stack-frame-size
4))))))
59 (define-alien-type-method (integer :result-tn
) (type state
)
60 (declare (ignore state
))
63 (if (alien-integer-type-signed type
)
64 (values 'signed-byte-64 signed-reg-sc-number
)
65 (values 'unsigned-byte-64 unsigned-reg-sc-number
))
66 (make-wired-tn* ptype reg-sc lip-offset
)))
68 (define-alien-type-method (integer :naturalize-gen
) (type alien
)
69 (if (<= (alien-type-bits type
) 32)
70 (if (alien-integer-type-signed type
)
71 `(sign-extend ,alien
,(alien-type-bits type
))
72 `(logand ,alien
,(1- (ash 1 (alien-type-bits type
)))))
75 (define-alien-type-method (system-area-pointer :result-tn
) (type state
)
76 (declare (ignore type state
))
77 (make-wired-tn* 'system-area-pointer sap-reg-sc-number lip-offset
))
79 (define-alien-type-method (double-float :result-tn
) (type state
)
80 (declare (ignore type state
))
81 (make-wired-tn* 'double-float double-reg-sc-number lip-offset
))
83 (define-alien-type-method (single-float :result-tn
) (type state
)
84 (declare (ignore type state
))
85 (make-wired-tn* 'single-float single-reg-sc-number lip-offset
))
87 (define-alien-type-method (values :result-tn
) (type state
)
88 (let ((values (alien-values-type-values type
)))
90 (error "Too many result values from c-call."))
92 (invoke-alien-type-method :result-tn
(car values
) state
))))
94 (defun make-call-out-tns (type)
95 (let ((arg-state (make-arg-state)))
97 (dolist (arg-type (alien-fun-type-arg-types type
))
98 (arg-tns (invoke-alien-type-method :arg-tn arg-type arg-state
)))
99 (values (make-wired-tn* 'positive-fixnum any-reg-sc-number nsp-offset
)
100 (* (max (- (logandc2 (1+ (arg-state-stack-frame-size arg-state
)) 1) 4) 2)
102 #.
(floor n-machine-word-bits n-word-bits
))
104 (invoke-alien-type-method :result-tn
105 (alien-fun-type-result-type type
)
108 (defknown sign-extend
((signed-byte 64) t
) fixnum
109 (foldable flushable movable
))
111 (define-vop (sign-extend)
112 (:translate sign-extend
)
114 (:args
(val :scs
(signed-reg) :target res
))
115 (:arg-types signed-num
(:constant fixnum
))
117 (:results
(res :scs
(signed-reg)))
118 (:result-types fixnum
)
122 ;;(inst sextb val res) ;; Under what circumstances can we use this?
123 (inst sll val
56 res
)
124 (inst sra res
56 res
))
126 ;;(inst sextw val res) ;; Under what circumstances can we use this?
127 (inst sll val
48 res
)
128 (inst sra res
48 res
))
130 (inst sll val
32 res
)
131 (inst sra res
32 res
)))))
134 (defun sign-extend (x size
)
135 (declare (type (signed-byte 64) x
))
137 (8 (sign-extend x size
))
138 (16 (sign-extend x size
))
139 (32 (sign-extend x size
))))
142 (defun sign-extend (x size
)
143 (if (logbitp (1- size
) x
)
144 (dpb x
(byte size
0) -
1)
147 (define-vop (foreign-symbol-sap)
148 (:translate foreign-symbol-sap
)
151 (:arg-types
(:constant simple-string
))
152 (:info foreign-symbol
)
153 (:results
(res :scs
(sap-reg)))
154 (:result-types system-area-pointer
)
156 (inst li
(make-fixup foreign-symbol
:foreign
) res
)))
158 (define-vop (call-out)
159 (:args
(function :scs
(sap-reg) :target cfunc
)
161 (:results
(results :more t
))
162 (:ignore args results
)
164 (:temporary
(:sc any-reg
:offset cfunc-offset
165 :from
(:argument
0) :to
(:result
0)) cfunc
)
166 (:temporary
(:sc control-stack
:offset nfp-save-offset
) nfp-save
)
167 (:temporary
(:scs
(non-descriptor-reg)) temp
)
170 (let ((cur-nfp (sb!c
::current-nfp-tn vop
)))
172 (store-stack-tn nfp-save cur-nfp
))
173 (move function cfunc
)
174 (inst li
(make-fixup "call_into_c" :foreign
) temp
)
175 (inst jsr lip-tn temp
(make-fixup "call_into_c" :foreign
))
177 (maybe-load-stack-nfp-tn cur-nfp nfp-save temp
)))))
179 (define-vop (alloc-number-stack-space)
181 (:results
(result :scs
(sap-reg any-reg
)))
182 (:result-types system-area-pointer
)
183 (:temporary
(:scs
(unsigned-reg) :to
(:result
0)) temp
)
185 (unless (zerop amount
)
186 (let ((delta (logandc2 (+ amount
7) 7)))
187 (cond ((< delta
(ash 1 15))
188 (inst lda nsp-tn
(- delta
) nsp-tn
))
191 (inst subq nsp-tn temp nsp-tn
)))))
192 (move nsp-tn result
)))
194 (define-vop (dealloc-number-stack-space)
197 (:temporary
(:scs
(unsigned-reg) :to
(:result
0)) temp
)
199 (unless (zerop amount
)
200 (let ((delta (logandc2 (+ amount
7) 7)))
201 (cond ((< delta
(ash 1 15))
202 (inst lda nsp-tn delta nsp-tn
))
205 (inst addq nsp-tn temp nsp-tn
)))))))