1 ;;; -*- Package: ALPHA -*-
3 ;;; **********************************************************************
4 ;;; This code was written as part of the CMU Common Lisp project at
5 ;;; Carnegie Mellon University, and has been placed in the public domain.
9 ;;; **********************************************************************
11 ;;; This file contains the VOPs and other necessary machine specific support
12 ;;; routines for call-out to C.
14 ;;; Written by William Lott.
15 ;;; Converted by Sean Hallgren.
19 (use-package "SB!ALIEN")
20 (use-package "SB!ALIEN-INTERNALS")
22 (defun my-make-wired-tn (prim-type-name sc-name offset)
23 (make-wired-tn (primitive-type-or-lose prim-type-name )
24 (sc-number-or-lose sc-name )
30 (def-alien-type-method (integer :arg-tn) (type state)
31 (let ((stack-frame-size (arg-state-stack-frame-size state)))
32 (setf (arg-state-stack-frame-size state) (1+ stack-frame-size))
34 (ptype reg-sc stack-sc)
35 (if (alien-integer-type-signed type)
36 (values 'signed-byte-64 'signed-reg 'signed-stack)
37 (values 'unsigned-byte-64 'unsigned-reg 'unsigned-stack))
38 (if (< stack-frame-size 4)
39 (my-make-wired-tn ptype reg-sc (+ stack-frame-size nl0-offset))
40 (my-make-wired-tn ptype stack-sc (* 2 (- stack-frame-size 4)))))))
42 (def-alien-type-method (system-area-pointer :arg-tn) (type state)
43 (declare (ignore type))
44 (let ((stack-frame-size (arg-state-stack-frame-size state)))
45 (setf (arg-state-stack-frame-size state) (1+ stack-frame-size))
46 (if (< stack-frame-size 4)
47 (my-make-wired-tn 'system-area-pointer
49 (+ stack-frame-size nl0-offset))
50 (my-make-wired-tn 'system-area-pointer
52 (* 2 (- stack-frame-size 4))))))
54 (def-alien-type-method (double-float :arg-tn) (type state)
55 (declare (ignore type))
56 (let ((stack-frame-size (arg-state-stack-frame-size state)))
57 (setf (arg-state-stack-frame-size state) (1+ stack-frame-size))
58 (if (< stack-frame-size 6)
59 (my-make-wired-tn 'double-float
61 (+ stack-frame-size nl0-offset))
62 (my-make-wired-tn 'double-float
64 (* 2 (- stack-frame-size 6))))))
66 (def-alien-type-method (single-float :arg-tn) (type state)
67 (declare (ignore type))
68 (let ((stack-frame-size (arg-state-stack-frame-size state)))
69 (setf (arg-state-stack-frame-size state) (1+ stack-frame-size))
70 (if (< stack-frame-size 6)
71 (my-make-wired-tn 'single-float
73 (+ stack-frame-size nl0-offset))
74 (my-make-wired-tn 'single-float
76 (* 2 (- stack-frame-size 6))))))
80 (def-alien-type-method (integer :result-tn) (type state)
81 (declare (ignore state))
84 (if (alien-integer-type-signed type)
85 (values 'signed-byte-64 'signed-reg)
86 (values 'unsigned-byte-64 'unsigned-reg))
87 (my-make-wired-tn ptype reg-sc lip-offset)))
89 (def-alien-type-method (system-area-pointer :result-tn) (type state)
90 (declare (ignore type state))
91 (my-make-wired-tn 'system-area-pointer 'sap-reg lip-offset))
93 (def-alien-type-method (double-float :result-tn) (type state)
94 (declare (ignore type state))
95 (my-make-wired-tn 'double-float 'double-reg lip-offset))
97 (def-alien-type-method (single-float :result-tn) (type state)
98 (declare (ignore type state))
99 (my-make-wired-tn 'single-float 'single-reg lip-offset))
101 (def-alien-type-method (values :result-tn) (type state)
102 (let ((values (alien-values-type-values type)))
104 (error "Too many result values from c-call."))
106 (invoke-alien-type-method :result-tn (car values) state))))
108 (!def-vm-support-routine make-call-out-tns (type)
109 (let ((arg-state (make-arg-state)))
111 (dolist (arg-type (alien-function-type-arg-types type))
112 (arg-tns (invoke-alien-type-method :arg-tn arg-type arg-state)))
113 (values (my-make-wired-tn 'positive-fixnum 'any-reg nsp-offset)
114 (* (max (arg-state-stack-frame-size arg-state) 4) word-bytes)
116 (invoke-alien-type-method :result-tn
117 (alien-function-type-result-type type)
121 (define-vop (foreign-symbol-address)
122 (:translate foreign-symbol-address)
125 (:arg-types (:constant simple-string))
126 (:info foreign-symbol)
127 (:results (res :scs (sap-reg)))
128 (:result-types system-area-pointer)
130 (inst li (make-fixup foreign-symbol :foreign) res)))
132 (define-vop (call-out)
133 (:args (function :scs (sap-reg) :target cfunc)
135 (:results (results :more t))
136 (:ignore args results)
138 (:temporary (:sc any-reg :offset cfunc-offset
139 :from (:argument 0) :to (:result 0)) cfunc)
140 (:temporary (:sc control-stack :offset nfp-save-offset) nfp-save)
141 (:temporary (:scs (non-descriptor-reg)) temp)
144 (let ((cur-nfp (sb!c::current-nfp-tn vop)))
146 (store-stack-tn nfp-save cur-nfp))
147 (move function cfunc)
148 (inst li (make-fixup "call_into_c" :foreign) temp)
149 (inst jsr lip-tn temp (make-fixup "call_into_c" :foreign))
151 (maybe-load-stack-nfp-tn cur-nfp nfp-save temp)))))
153 (define-vop (alloc-number-stack-space)
155 (:results (result :scs (sap-reg any-reg)))
156 (:temporary (:scs (unsigned-reg) :to (:result 0)) temp)
158 (unless (zerop amount)
159 (let ((delta (logandc2 (+ amount 7) 7)))
160 (cond ((< delta (ash 1 15))
161 (inst lda nsp-tn (- delta) nsp-tn))
164 (inst subq nsp-tn temp nsp-tn)))))
165 (move nsp-tn result)))
167 (define-vop (dealloc-number-stack-space)
170 (:temporary (:scs (unsigned-reg) :to (:result 0)) temp)
172 (unless (zerop amount)
173 (let ((delta (logandc2 (+ amount 7) 7)))
174 (cond ((< delta (ash 1 15))
175 (inst lda nsp-tn delta nsp-tn))
178 (inst addq nsp-tn temp nsp-tn)))))))