X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86%2Fc-call.lisp;h=f2bd52a6f7e3a848052b55a0d2448f68bc8f9bc1;hb=dc33d6a6b84f8338e603759cec8e25da29055d50;hp=cb7f2daa546b55fb70cd04e06f887916e09ceeea;hpb=3a618201c9f2370bb8784217a866d000371769e5;p=sbcl.git diff --git a/src/compiler/x86/c-call.lisp b/src/compiler/x86/c-call.lisp index cb7f2da..f2bd52a 100644 --- a/src/compiler/x86/c-call.lisp +++ b/src/compiler/x86/c-call.lisp @@ -181,19 +181,28 @@ ,@(new-args)))))) (sb!c::give-up-ir1-transform)))) +(define-vop (foreign-symbol-sap) + (:translate foreign-symbol-sap) + (:policy :fast-safe) + (:args) + (:arg-types (:constant simple-string)) + (:info foreign-symbol) + (:results (res :scs (sap-reg))) + (:result-types system-area-pointer) + (:generator 2 + (inst lea res (make-fixup foreign-symbol :foreign)))) - - -(define-vop (foreign-symbol-address) - (:translate foreign-symbol-address) +#!+linkage-table +(define-vop (foreign-symbol-dataref-sap) + (:translate foreign-symbol-dataref-sap) (:policy :fast-safe) (:args) - (:arg-types (:constant simple-base-string)) + (:arg-types (:constant simple-string)) (:info foreign-symbol) (:results (res :scs (sap-reg))) (:result-types system-area-pointer) (:generator 2 - (inst lea res (make-fixup (extern-alien-name foreign-symbol) :foreign)))) + (inst mov res (make-fixup foreign-symbol :foreign-dataref)))) (define-vop (call-out) (:args (function :scs (sap-reg)) @@ -212,7 +221,7 @@ (:generator 0 (cond ((policy node (> space speed)) (move eax function) - (inst call (make-fixup (extern-alien-name "call_into_c") :foreign))) + (inst call (make-fixup "call_into_c" :foreign))) (t ;; Setup the NPX for C; all the FP registers need to be ;; empty; pop them all. @@ -260,6 +269,8 @@ (let ((delta (logandc2 (+ amount 3) 3))) (inst add esp-tn delta))) (when (policy node (= sb!c::float-accuracy 3)) + (inst fnstcw (make-ea :word :base esp-tn)) + (inst wait) (inst and (make-ea :word :base esp-tn) #xfeff) (inst fldcw (make-ea :word :base esp-tn)) (inst wait) @@ -344,3 +355,59 @@ (:generator 2 (inst add esp-tn (fixnumize number)))) +#-sb-xc-host +(defun alien-callback-accessor-form (type sp offset) + `(deref (sap-alien (sap+ ,sp ,offset) (* ,type)))) + +#-sb-xc-host +(defun alien-callback-assembler-wrapper (index return-type arg-types) + "Cons up a piece of code which calls call-callback with INDEX and a +pointer to the arguments." + (declare (ignore arg-types)) + (let* ((segment (make-segment)) + (eax eax-tn) + (edx edx-tn) + (ebp ebp-tn) + (esp esp-tn) + ([ebp-8] (make-ea :dword :base ebp :disp -8)) + ([ebp-4] (make-ea :dword :base ebp :disp -4))) + (assemble (segment) + (inst push ebp) ; save old frame pointer + (inst mov ebp esp) ; establish new frame + (inst mov eax esp) ; + (inst sub eax 8) ; place for result + (inst push eax) ; arg2 + (inst add eax 16) ; arguments + (inst push eax) ; arg1 + (inst push (ash index 2)) ; arg0 + (inst push (get-lisp-obj-address #'enter-alien-callback)) ; function + (inst mov eax (foreign-symbol-address "funcall3")) + (inst call eax) + ;; now put the result into the right register + (cond + ((and (alien-integer-type-p return-type) + (eql (alien-type-bits return-type) 64)) + (inst mov eax [ebp-8]) + (inst mov edx [ebp-4])) + ((or (alien-integer-type-p return-type) + (alien-pointer-type-p return-type) + (alien-type-= #.(parse-alien-type 'system-area-pointer nil) + return-type)) + (inst mov eax [ebp-8])) + ((alien-single-float-type-p return-type) + (inst fld [ebp-8])) + ((alien-double-float-type-p return-type) + (inst fldd [ebp-8])) + ((alien-void-type-p return-type)) + (t + (error "unrecognized alien type: ~A" return-type))) + (inst mov esp ebp) ; discard frame + (inst pop ebp) ; restore frame pointer + (inst ret)) + (finalize-segment segment) + ;; Now that the segment is done, convert it to a static + ;; vector we can point foreign code to. + (let ((buffer (sb!assem::segment-buffer segment))) + (make-static-vector (length buffer) + :element-type '(unsigned-byte 8) + :initial-contents buffer))))