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.
14 (defconstant +number-stack-allocation-granularity
+ n-word-bytes
)
16 (defconstant +max-register-args
+ 4)
18 (defun my-make-wired-tn (prim-type-name sc-name offset
)
19 (make-wired-tn (primitive-type-or-lose prim-type-name
)
20 (sc-number-or-lose sc-name
)
27 (defun register-args-offset (index)
28 (elt '(#.ocfp-offset
#.nargs-offset
#.nl2-offset
#.nl3-offset
)
31 (defun int-arg (state prim-type reg-sc stack-sc
)
32 (let ((reg-args (arg-state-num-register-args state
)))
33 (cond ((< reg-args
+max-register-args
+)
34 (setf (arg-state-num-register-args state
) (1+ reg-args
))
35 (my-make-wired-tn prim-type reg-sc
(register-args-offset reg-args
)))
37 (error "Don't know how to allocate stack arguments")
39 (let ((frame-size (arg-state-stack-frame-size state
)))
40 (setf (arg-state-stack-frame-size state
) (1+ frame-size
))
41 (my-make-wired-tn prim-type stack-sc frame-size
))))))
43 (define-alien-type-method (integer :arg-tn
) (type state
)
44 (if (alien-integer-type-signed type
)
45 (int-arg state
'signed-byte-32
'signed-reg
'signed-stack
)
46 (int-arg state
'unsigned-byte-32
'unsigned-reg
'unsigned-stack
)))
48 (define-alien-type-method (system-area-pointer :arg-tn
) (type state
)
49 (declare (ignore type
))
50 (int-arg state
'system-area-pointer
'sap-reg
'sap-stack
))
52 (define-alien-type-method (integer :result-tn
) (type state
)
53 (declare (ignore state
))
56 (if (alien-integer-type-signed type
)
57 (values 'signed-byte-32
'signed-reg
)
58 (values 'unsigned-byte-32
'unsigned-reg
))
59 (my-make-wired-tn ptype reg-sc nargs-offset
)))
61 (define-alien-type-method (system-area-pointer :result-tn
) (type state
)
62 (declare (ignore type state
))
63 (my-make-wired-tn 'system-area-pointer
'sap-reg nargs-offset
))
65 (define-alien-type-method (values :result-tn
) (type state
)
66 (let ((values (alien-values-type-values type
)))
68 (error "Too many result values from c-call."))
70 (invoke-alien-type-method :result-tn
(car values
) state
))))
72 (defun make-call-out-tns (type)
73 (let ((arg-state (make-arg-state)))
75 (dolist (arg-type (alien-fun-type-arg-types type
))
76 (arg-tns (invoke-alien-type-method :arg-tn arg-type arg-state
)))
77 (values (make-normal-tn *fixnum-primitive-type
*)
78 (* (arg-state-stack-frame-size arg-state
) n-word-bytes
)
80 (invoke-alien-type-method :result-tn
81 (alien-fun-type-result-type type
)
84 (define-vop (foreign-symbol-sap)
85 (:translate foreign-symbol-sap
)
88 (:arg-types
(:constant simple-string
))
89 (:info foreign-symbol
)
90 (:temporary
(:sc interior-reg
) lip
)
91 (:results
(res :scs
(sap-reg)))
92 (:result-types system-area-pointer
)
94 (let ((fixup-label (gen-label)))
95 (inst load-from-label res lip fixup-label
)
96 (assemble (*elsewhere
*)
97 (emit-label fixup-label
)
98 (inst word
(make-fixup foreign-symbol
:foreign
))))))
100 (define-vop (call-out)
101 (:args
(function :scs
(sap-reg) :target cfunc
)
103 (:results
(results :more t
))
104 (:ignore args results
)
106 (:temporary
(:sc any-reg
:offset r8-offset
107 :from
(:argument
0) :to
(:result
0)) cfunc
)
108 (:temporary
(:sc control-stack
:offset nfp-save-offset
) nfp-save
)
109 (:temporary
(:scs
(non-descriptor-reg)) temp
)
110 (:temporary
(:sc interior-reg
) lip
)
113 (let ((call-into-c-fixup (gen-label))
114 (cur-nfp (current-nfp-tn vop
)))
115 (assemble (*elsewhere
*)
116 (emit-label call-into-c-fixup
)
117 (inst word
(make-fixup "call_into_c" :foreign
)))
119 (store-stack-tn nfp-save cur-nfp
))
120 (inst load-from-label temp lip call-into-c-fixup
)
121 (move cfunc function
)
124 (load-stack-tn cur-nfp nfp-save
)))))
126 (define-vop (alloc-number-stack-space)
128 (:result-types system-area-pointer
)
129 (:results
(result :scs
(sap-reg any-reg
)))
131 (load-symbol-value result
*number-stack-pointer
*)
132 (unless (zerop amount
)
133 (let ((delta (logandc2 (+ amount
(1- +number-stack-allocation-granularity
+))
134 (1- +number-stack-allocation-granularity
+))))
135 (inst sub result result delta
)
136 (store-symbol-value result
*number-stack-pointer
*)))))
138 (define-vop (dealloc-number-stack-space)
141 (:temporary
(:scs
(unsigned-reg) :to
(:result
0)) temp
)
143 (unless (zerop amount
)
144 (let ((delta (logandc2 (+ amount
(1- +number-stack-allocation-granularity
+))
145 (1- +number-stack-allocation-granularity
+))))
146 (load-symbol-value temp
*number-stack-pointer
*)
147 (inst add temp temp delta
)
148 (store-symbol-value temp
*number-stack-pointer
*)))))