Changeset 5814
- Timestamp:
- Jan 29, 2007, 6:27:17 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/ccl/lib/ffi-darwinppc64.lisp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/lib/ffi-darwinppc64.lisp
r5759 r5814 159 159 field-accessor-list) 160 160 ,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)))))))) 161 246 (do-fields (foreign-record-type-fields rtype) nil )) 162 247 `(progn ,@(forms) nil)))))))) … … 251 336 ,(darwin64::struct-from-regbuf-values result-temp struct-result-type regbuf))) 252 337 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.
