Changeset 5814


Ignore:
Timestamp:
Jan 29, 2007, 6:27:17 AM (18 years ago)
Author:
Gary Byers
Message:

new callback stuff.

File:
1 edited

Legend:

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

    r5759 r5814  
    159159                                                  field-accessor-list)
    160160                                           ,valform)))))))
     161                   (do-fields (foreign-record-type-fields rtype) nil ))
     162                 `(progn ,@(forms) nil))))))))
     163
     164;;; "Return" the structure R of foreign type RTYPE, by storing the
     165;;; values of its fields in STACK-PTR and FP-ARG-PTR
     166(defun darwin64::return-struct-to-registers (r rtype stack-ptr fp-args-ptr)
     167  (let* ((bits (require-foreign-type-bits rtype)))
     168    (collect ((forms))
     169      (cond ((= bits 128)               ;(and (eql day 'tuesday) ...)
     170             (forms `(setf (ccl::%%get-signed-longlong ,stack-ptr 0)
     171                      (ccl::%%get-signed-longlong ,r 0)
     172                      (ccl::%%get-signed-longlong ,stack-ptr 8)
     173                      (ccl::%%get-signed-longlong ,r 8))))
     174            (t
     175             (let* ((gpr-offset 0)
     176                    (fpr-offset 0))
     177               (flet ((next-gpr-offset ()
     178                        (prog1 gpr-offset
     179                          (incf gpr-offset 8)))
     180                      (next-fpr-offset ()
     181                        (prog1 fpr-offset
     182                          (incf gpr-offset 8)
     183                          (incf fpr-offset 8))))
     184                 (labels ((do-fields (fields accessors)
     185                            (dolist (field fields)
     186                              (let* ((field-type (foreign-record-field-type field))
     187                                     (field-accessor-list (append accessors (list (foreign-record-field-name field))))
     188                                     (valform ()))
     189                                (etypecase field-type
     190                                  (foreign-record-type
     191                                   (do-fields (foreign-record-type-fields field-type)
     192                                     field-accessor-list))
     193                                  (foreign-pointer-type
     194                                   (setq valform
     195                                         `(%get-ptr ,stack-ptr ,(next-gpr-offset))))
     196                                  (foreign-double-float-type
     197                                   (setq valform
     198                                         `(%get-double-float  ,fp-args-ptr ,(next-fpr-offset))))
     199                                  (foreign-single-float-type
     200                                   (setq valform
     201                                         `(%get-double-float  ,fp-args-ptr ,(next-fpr-offset))))
     202                                  (foreign-integer-type
     203                                   (let* ((bits (foreign-integer-type-bits field-type))
     204                                          (signed (foreign-integer-type-signed field-type)))
     205                                     (case bits
     206                                       (64
     207                                        (setq valform
     208                                              `(,(if signed
     209                                                     '%%get-signed-longlong
     210                                                     '%%get-unsigned-longlong)
     211                                                ,stack-ptr
     212                                                ,(next-gpr-offset))))
     213                                       (32
     214                                        (setq valform
     215                                              `(,(if signed
     216                                                     '%get-signed-long
     217                                                     '%get-unsigned-long)
     218                                                ,stack-ptr
     219                                                (+ 4 ,(next-gpr-offset)))))
     220                                       (16
     221                                        (setq valform
     222                                              `(,(if signed
     223                                                     '%get-signed-word
     224                                                     '%get-unsigned-word)
     225                                                ,stack-ptr
     226                                                (+ 6 ,(next-gpr-offset)))))
     227                                       (8
     228                                        (setq valform
     229                                              `(,(if signed
     230                                                     '%get-signed-byte
     231                                                     '%get-unsigned-byte)
     232                                                ,stack-ptr
     233                                                (+ 7 ,(next-gpr-offset))))))))
     234                                  (foreign-array-type
     235                                   (error "Embedded array-type."))
     236                                  )
     237                                (when valform
     238                                  (let* ((field-form (%foreign-access-form
     239                                                      r
     240                                                      rtype
     241                                                      0
     242                                                      field-accessor-list)))
     243                                    (when (typep field-form 'foreign-single-float-type)
     244                                      (setq field-form `(float ,field-form 0.0d0)))
     245                                    (forms `(setf ,valform ,field-form))))))))
    161246                   (do-fields (foreign-record-type-fields rtype) nil ))
    162247                 `(progn ,@(forms) nil))))))))
     
    251336                    ,(darwin64::struct-from-regbuf-values result-temp struct-result-type regbuf)))
    252337                call))))))))
     338           
     339           
     340;;; Return 7 values:
     341;;; A list of RLET bindings
     342;;; A list of LET* bindings
     343;;; A list of DYNAMIC-EXTENT declarations for the LET* bindings
     344;;; A list of initializaton forms for (some) structure args
     345;;; A FOREIGN-TYPE representing the "actual" return type.
     346;;; A form which can be used to initialize FP-ARGS-PTR, relative
     347;;;  to STACK-PTR.  (This is unused on linuxppc32.)
     348;;; The byte offset of the foreign return address, relative to STACK-PTR
     349
     350(defun darwin64::generate-callback-bindings (stack-ptr fp-args-ptr argvars argspecs result-spec struct-result-name)
     351  (collect ((lets)
     352            (rlets)
     353            (inits)
     354            (dynamic-extent-names))
     355    (let* ((rtype (parse-foreign-type result-spec))
     356           (fp-regs-form nil))
     357      (flet ((set-fp-regs-form ()
     358               (unless fp-regs-form
     359                 (setq fp-regs-form `(%get-ptr ,stack-ptr ,(- ppc64::c-frame.unused-1 ppc64::c-frame.param0))))))
     360        (when (typep rtype 'foreign-record-type)
     361          (if (darwin64::record-type-contains-union rtype)
     362            (setq argvars (cons struct-result-name argvars)
     363                  argspecs (cons :address argspecs)
     364                  rtype *void-foreign-type*)
     365            (rlets (list struct-result-name (foreign-record-type-name rtype)))))
     366        (when (typep rtype 'foreign-float-type)
     367          (set-fp-regs-form))
     368        (do* ((argvars argvars (cdr argvars))
     369              (argspecs argspecs (cdr argspecs))
     370              (fp-arg-num 0)
     371              (offset 0 (+ offset delta))
     372              (delta 8 8)
     373              (bias 0 0)
     374              (use-fp-args nil nil))
     375             ((null argvars)
     376              (values (rlets) (lets) (dynamic-extent-names) (inits) rtype fp-regs-form (- ppc64::c-frame.savelr ppc64::c-frame.param0)))
     377          (flet ((next-scalar-arg (argtype)
     378                   `(,(cond
     379                       ((typep argtype 'foreign-single-float-type)
     380                        (if (< (incf fp-arg-num) 14)
     381                          (progn
     382                            (setq use-fp-args t)
     383                            '%get-single-float-from-double-ptr)
     384                          (progn
     385                            '%get-single-float)))
     386                       ((typep argtype 'foreign-double-float-type)
     387                        (setq delta 8)
     388                        (if (< (incf fp-arg-num) 14)
     389                          (setq use-fp-args t))
     390                        '%get-double-float)
     391                       ((and (typep argtype 'foreign-integer-type)
     392                             (= (foreign-integer-type-bits argtype) 64)
     393                             (foreign-integer-type-signed argtype))
     394                        (setq delta 8)
     395                        '%%get-signed-longlong)
     396                       ((and (typep argtype 'foreign-integer-type)
     397                             (= (foreign-integer-type-bits argtype) 64)
     398                             (not (foreign-integer-type-signed argtype)))
     399                        (setq delta 8)
     400                        '%%get-unsigned-longlong)
     401                       ((or (typep argtype 'foreign-pointer-type)
     402                            (typep argtype 'foreign-array-type))
     403                        '%get-ptr)
     404                       (t
     405                        (cond ((typep argtype 'foreign-integer-type)
     406                               (let* ((bits (foreign-integer-type-bits argtype))
     407                                      (signed (foreign-integer-type-signed argtype)))
     408                                 (cond ((<= bits 8)
     409                                        (setq bias 7)
     410                                        (if signed
     411                                          '%get-signed-byte '
     412                                          '%get-unsigned-byte))
     413                                       ((<= bits 16)
     414                                        (setq bias 6)
     415                                        (if signed
     416                                          '%get-signed-word
     417                                          '%get-unsigned-word))
     418                                       ((<= bits 32)
     419                                        (setq bias 4)
     420                                        (if signed
     421                                          '%get-signed-long
     422                                          '%get-unsigned-long))
     423                                       (t
     424                                        (error "Don't know how to access foreign argument of type ~s" (unparse-foreign-type argtype))))))
     425                              (t
     426                               (error "Don't know how to access foreign argument of type ~s" (unparse-foreign-type argtype))))))
     427                     ,(if use-fp-args fp-args-ptr stack-ptr)
     428                     ,(if use-fp-args (* 8 (1- fp-arg-num))
     429                          (+ offset bias)))))                   
     430          (let* ((name (car argvars))
     431                 (spec (car argspecs))
     432                 (argtype (parse-foreign-type spec)))
     433            (if (typep argtype 'foreign-record-type)
     434              (if (darwin64::record-type-contains-union argtype)
     435                (progn (setq delta (* (ceiling (foreign-record-type-bits argtype) 64) 8))
     436                       (lets (list name `(%inc-ptr ,stack-ptr ,offset ))))
     437
     438                 (labels ((do-fields (fields accessors)
     439                            (dolist (field fields)
     440                              (let* ((field-type (foreign-record-field-type field))
     441                                     (field-accessor-list (append accessors (list (foreign-record-field-name field))))
     442                                     (valform ()))
     443                                (typecase field-type
     444                                  (foreign-record-type
     445                                   (do-fields (foreign-record-type-fields field-type)
     446                                     field-accessor-list))
     447                                  (foreign-array-type
     448                                   (error "Embedded array type"))
     449                                  (t
     450                                   (setq valform (next-scalar-arg field-type))))
     451                                (when valform
     452                                  (inits `(setf ,(%foreign-access-form
     453                                                      name
     454                                                      argtype
     455                                                      0
     456                                                      field-accessor-list)
     457                                           ,valform)))))))
     458                   (rlets (list name (foreign-record-type-name argtype)))
     459                   (do-fields (foreign-record-type-fields argtype) nil)))
     460              (lets (list name (next-scalar-arg argtype))))
     461            (when (or (typep argtype 'foreign-pointer-type)
     462                      (typep argtype 'foreign-array-type))
     463              (dynamic-extent-names name))
     464            (when use-fp-args (set-fp-regs-form)))))))))
     465
     466(defun darwin64::generate-callback-return-value (stack-ptr fp-args-ptr result return-type struct-return-arg)
     467  (unless (eq return-type *void-foreign-type*)
     468    (if (typep return-type 'foreign-record-type)
     469      ;;; Would have been mapped to :VOID unless record-type contained
     470      ;;; a single scalar field.
     471      (darwin64::return-struct-to-registers struct-return-arg return-type stack-ptr fp-args-ptr)
     472      (let* ((return-type-keyword (foreign-type-to-representation-type return-type))
     473           (result-ptr (case return-type-keyword
     474                   ((:single-float :double-float)
     475                    fp-args-ptr)
     476                   (t stack-ptr))))
     477      `(setf (,
     478              (case return-type-keyword
     479                                 (:address '%get-ptr)
     480                                 (:signed-doubleword '%%get-signed-longlong)
     481                                 (:unsigned-doubleword '%%get-unsigned-longlong)
     482                                 ((:double-float :single-float)
     483                                  '%get-double-float)
     484                                 (:unsigned-fullword '%get-unsigned-long)
     485                                 (t '%%get-signed-longlong )
     486                                 ) ,result-ptr 0) ,result)))))
     487
     488
Note: See TracChangeset for help on using the changeset viewer.