Changeset 5803


Ignore:
Timestamp:
Jan 28, 2007, 8:47:27 PM (18 years ago)
Author:
Gary Byers
Message:

Flesh things out a bit more, change the API, get things working ... still
a moving target.

Location:
trunk/ccl/lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lib/ffi-linuxppc32.lisp

    r5799 r5803  
    8686            call))))))
    8787
    88 ;;; Return N values:
     88;;; Return 7 values:
    8989;;; A list of RLET bindings
    9090;;; A list of LET* bindings
     
    9292;;; A list of initializaton forms for (some) structure args
    9393;;; A FOREIGN-TYPE representing the "actual" return type.
    94 (defun linux32::generate-callback-bindings (stack-ptr argvars argspecs result-spec struct-result-name)
     94;;; A form which can be used to initialize FP-ARGS-PTR, relative
     95;;;  to STACK-PTR.  (This is unused on linuxppc32.)
     96;;; The byte offset of the foreign return address, relative to STACK-PTR
     97(defun linux32::generate-callback-bindings (stack-ptr fp-args-ptr argvars argspecs result-spec struct-result-name)
     98  (declare (ignore fp-args-ptr))
    9599  (collect ((lets)
    96100            (rlets)
     
    110114                  (argspecs argspecs (cdr argspecs)))
    111115                 ((null argvars)
    112                   (values (rlets) (lets) (dynamic-extent-names) nil rtype))
     116                  (values (rlets) (lets) (dynamic-extent-names) nil rtype nil 0 #|wrong|#))
    113117              (let* ((name (car argvars))
    114118                     (spec (car argspecs))
     
    189193                  (setq gpr nextgpr fpr nextfpr offset nextoffset))))))))
    190194
    191 (defun linux32::generate-callback-return-value (stack-ptr result return-type struct-return-arg)
     195(defun linux32::generate-callback-return-value (stack-ptr fp-args-ptr result return-type struct-return-arg)
     196  (declare (ignore fp-args-ptr))
    192197  (unless (eq return-type *void-foreign-type*)
    193198    (let* ((return-type-keyword
  • trunk/ccl/lib/ffi-linuxppc64.lisp

    r5760 r5803  
    2020;;; Structures whose size is less than 64 bits are passed "right-justified"
    2121;;; in a GPR.
    22 ;;; Structures passed by value are passed in GPRs as N doublewords.
     22;;; Larger structures passed by value are passed in GPRs as N doublewords.
    2323;;; If the structure would require > 64-bit alignment, this might result
    2424;;; in some GPRs/parameter area words being skipped.  (We don't handle this).
     
    7878        (argforms (foreign-type-to-representation-type result-type))
    7979        (funcall result-coerce result-type-spec `(,@callform ,@(argforms)))))))
     80
     81(defun linux64::generate-callback-bindings (stack-ptr fp-args-ptr argvars argspecs result-spec struct-result-name)
     82  (collect ((lets)
     83            (rlets)
     84            (inits)
     85            (dynamic-extent-names))
     86    (let* ((rtype (parse-foreign-type result-spec))
     87           (fp-regs-form nil))
     88      (flet ((set-fp-regs-form ()
     89               (unless fp-regs-form
     90                 (setq fp-regs-form `(%get-ptr ,stack-ptr ,(- ppc64::c-frame.unused-1 ppc64::c-frame.param0))))))
     91        (when (typep rtype 'foreign-record-type)
     92          (setq argvars (cons struct-result-name argvars)
     93                argspecs (cons :address argspecs)
     94                rtype *void-foreign-type*))
     95        (when (typep rtype 'foreign-float-type)
     96          (set-fp-regs-form))
     97        (do* ((argvars argvars (cdr argvars))
     98              (argspecs argspecs (cdr argspecs))
     99              (fp-arg-num 0)
     100              (offset 0 (+ offset delta))
     101              (delta 8 8)
     102              (bias 0 0)
     103              (use-fp-args nil nil))
     104             ((null argvars)
     105              (values (rlets) (lets) (dynamic-extent-names) (inits) rtype fp-regs-form (- ppc64::c-frame.savelr ppc64::c-frame.param0)))
     106          (let* ((name (car argvars))
     107                 (spec (car argspecs))
     108                 (argtype (parse-foreign-type spec))
     109                 (bits (ensure-foreign-type-bits argtype)))
     110            (if (and (typep argtype 'foreign-record-type)
     111                     (< bits 63))
     112              (progn
     113                (rlets (list name (foreign-record-type-name argtype)))
     114                (inits `(setf (%%get-unsigned-longlong ,name 0)
     115                         (ash (%%get-unsigned-longlong ,stack-ptr ,offset)
     116                          ,(- 64 bits)))))
     117              (let* ((access-form
     118                      `(,(cond
     119                          ((typep argtype 'foreign-single-float-type)
     120                           (if (< (incf fp-arg-num) 14)
     121                             (progn
     122                               (setq use-fp-args t)
     123                               '%get-single-float-from-double-ptr)
     124                             (progn
     125                               (setq bias 4)
     126                               '%get-single-float)))
     127                          ((typep argtype 'foreign-double-float-type)
     128                           (if (< (incf fp-arg-num) 14)
     129                             (setq use-fp-args t))
     130                           '%get-double-float)
     131                          ((and (typep argtype 'foreign-integer-type)
     132                                (= (foreign-integer-type-bits argtype) 64)
     133                                (foreign-integer-type-signed argtype))
     134                           '%%get-signed-longlong)
     135                          ((and (typep argtype 'foreign-integer-type)
     136                                (= (foreign-integer-type-bits argtype) 64)
     137                                (not (foreign-integer-type-signed argtype)))
     138                           '%%get-unsigned-longlong)
     139                          ((or (typep argtype 'foreign-pointer-type)
     140                               (typep argtype 'foreign-array-type))
     141                           '%get-ptr)
     142                          (t
     143                           (cond ((typep argtype 'foreign-integer-type)
     144                                  (let* ((bits (foreign-integer-type-bits argtype))
     145                                         (signed (foreign-integer-type-signed argtype)))
     146                                    (cond ((<= bits 8)
     147                                           (setq bias 7)
     148                                           (if signed
     149                                             '%get-signed-byte '
     150                                             '%get-unsigned-byte))
     151                                          ((<= bits 16)
     152                                           (setq bias 6)
     153                                           (if signed
     154                                             '%get-signed-word
     155                                             '%get-unsigned-word))
     156                                          ((<= bits 32)
     157                                           (setq bias 4)
     158                                           (if signed
     159                                             '%get-signed-long
     160                                             '%get-unsigned-long))
     161                                          (t
     162                                           (error "Don't know how to access foreign argument of type ~s" (unparse-foreign-type argtype))))))
     163                                 (t
     164                                  (error "Don't know how to access foreign argument of type ~s" (unparse-foreign-type argtype))))))
     165                        ,(if use-fp-args fp-args-ptr stack-ptr)
     166                        ,(if use-fp-args (* 8 (1- fp-arg-num))
     167                             `(+ ,offset ,bias)))))
     168                (lets (list name access-form))
     169                (when (eq spec :address)
     170                  (dynamic-extent-names name))
     171                (when use-fp-args (set-fp-regs-form))))))))))
     172
     173
     174;;; All structures are "returned" via the implicit first argument; we'll have
     175;;; already translated the return type to :void in that case.
     176(defun linux64::generate-callback-return-value (stack-ptr fp-args-ptr result return-type struct-return-arg)
     177  (declare (ignore struct-return-arg))
     178  (unless (eq return-type *void-foreign-type*)
     179    (let* ((return-type-keyword (foreign-type-to-representation-type return-type))
     180           (result-ptr (case return-type-keyword
     181                   ((:single-float :double-float)
     182                    fp-args-ptr)
     183                   (t stack-ptr))))
     184      `(setf (,
     185              (case return-type-keyword
     186                                 (:address '%get-ptr)
     187                                 (:signed-doubleword '%%get-signed-longlong)
     188                                 (:unsigned-doubleword '%%get-unsigned-longlong)
     189                                 ((:double-float :single-float)
     190                                  (setq stack-ptr `(%get-ptr ,stack-ptr ,(- ppc64::c-frame.unused-1 ppc64::c-frame.param0)))
     191                                  '%get-double-float)
     192                                 (t '%%get-signed-longlong )
     193                                 ) ,result-ptr 0) ,result))))
Note: See TracChangeset for help on using the changeset viewer.