| 1 | ;;;-*- Mode: Lisp; Package: CCL -*-
|
|---|
| 2 | ;;;
|
|---|
| 3 | ;;; Copyright (C) 2009 Clozure Associates
|
|---|
| 4 | ;;; Copyright (C) 2004, 2005 Clozure Associates
|
|---|
| 5 | ;;; This file is part of Clozure CL.
|
|---|
| 6 | ;;;
|
|---|
| 7 | ;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
|
|---|
| 8 | ;;; License , known as the LLGPL and distributed with Clozure CL as the
|
|---|
| 9 | ;;; file "LICENSE". The LLGPL consists of a preamble and the LGPL,
|
|---|
| 10 | ;;; which is distributed with Clozure CL as the file "LGPL". Where these
|
|---|
| 11 | ;;; conflict, the preamble takes precedence.
|
|---|
| 12 | ;;;
|
|---|
| 13 | ;;; Clozure CL is referenced in the preamble as the "LIBRARY."
|
|---|
| 14 | ;;;
|
|---|
| 15 | ;;; The LLGPL is also available online at
|
|---|
| 16 | ;;; http://opensource.franz.com/preamble.html
|
|---|
| 17 |
|
|---|
| 18 | (in-package "CCL")
|
|---|
| 19 | (eval-when (:compile-toplevel :load-toplevel :execute)
|
|---|
| 20 | (require "BACKEND"))
|
|---|
| 21 |
|
|---|
| 22 | (eval-when (:compile-toplevel :execute)
|
|---|
| 23 | (require "NXENV")
|
|---|
| 24 | (require "PPCENV"))
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 | ;;; Callbacks. Both LinuxPPC64 and DarwinPPC64 follow something
|
|---|
| 28 | ;;; close to the PowerOpen ABI. LinuxPPC uses transition vectors
|
|---|
| 29 | ;;; and a TOC, but it's not clear that we need to care about that
|
|---|
| 30 | ;;; here.
|
|---|
| 31 | (defun define-ppc64-poweropen-callback (name args body env)
|
|---|
| 32 | (let* ((stack-word (gensym))
|
|---|
| 33 | (stack-ptr (gensym))
|
|---|
| 34 | (fp-arg-regs (gensym))
|
|---|
| 35 | (fp-arg-num 0)
|
|---|
| 36 | (arg-names ())
|
|---|
| 37 | (arg-types ())
|
|---|
| 38 | (return-type :void)
|
|---|
| 39 | (args args)
|
|---|
| 40 | (woi nil)
|
|---|
| 41 | (monitor nil)
|
|---|
| 42 | (dynamic-extent-names ())
|
|---|
| 43 | (error-return nil))
|
|---|
| 44 | (loop
|
|---|
| 45 | (when (null args) (return))
|
|---|
| 46 | (when (null (cdr args))
|
|---|
| 47 | (setq return-type (car args))
|
|---|
| 48 | (return))
|
|---|
| 49 | (if (eq (car args) :without-interrupts)
|
|---|
| 50 | (setq woi (cadr args) args (cddr args))
|
|---|
| 51 | (if (eq (car args) :monitor-exception-ports)
|
|---|
| 52 | (setq monitor (cadr args) args (cddr args))
|
|---|
| 53 | (if (eq (car args) :error-return)
|
|---|
| 54 | (setq error-return
|
|---|
| 55 | (cadr args)
|
|---|
| 56 | args (cddr args))
|
|---|
| 57 | (progn
|
|---|
| 58 | (push (foreign-type-to-representation-type (pop args)) arg-types)
|
|---|
| 59 | (push (pop args) arg-names))))))
|
|---|
| 60 | (setq arg-names (nreverse arg-names)
|
|---|
| 61 | arg-types (nreverse arg-types))
|
|---|
| 62 | (setq return-type (foreign-type-to-representation-type return-type))
|
|---|
| 63 | (when (eq return-type :void)
|
|---|
| 64 | (setq return-type nil))
|
|---|
| 65 | (let* ((offset 0)
|
|---|
| 66 | (need-stack-pointer (or arg-names return-type error-return))
|
|---|
| 67 | (lets
|
|---|
| 68 | (mapcar
|
|---|
| 69 | #'(lambda (name type)
|
|---|
| 70 | (let* ((delta 8)
|
|---|
| 71 | (bias 0)
|
|---|
| 72 | (use-fp-args nil))
|
|---|
| 73 | (prog1
|
|---|
| 74 | (list name
|
|---|
| 75 | `(,
|
|---|
| 76 | (if (typep type 'unsigned-byte)
|
|---|
| 77 | (progn (setq delta (* 8 type)) '%inc-ptr)
|
|---|
| 78 | (ecase type
|
|---|
| 79 | (:single-float
|
|---|
| 80 | (if (< (incf fp-arg-num) 14)
|
|---|
| 81 | (progn
|
|---|
| 82 | (setq use-fp-args t)
|
|---|
| 83 | '%get-single-float-from-double-ptr)
|
|---|
| 84 | (progn
|
|---|
| 85 | (setq bias 4)
|
|---|
| 86 | '%get-single-float)))
|
|---|
| 87 | (:double-float
|
|---|
| 88 | (setq delta 8)
|
|---|
| 89 | (if (< (incf fp-arg-num) 14)
|
|---|
| 90 | (setq use-fp-args t))
|
|---|
| 91 | '%get-double-float)
|
|---|
| 92 | (:signed-doubleword (setq delta 8) '%%get-signed-longlong)
|
|---|
| 93 | (:signed-fullword
|
|---|
| 94 | (setq bias 4)
|
|---|
| 95 | '%get-signed-long)
|
|---|
| 96 | (:signed-halfword (setq bias 6)
|
|---|
| 97 | '%get-signed-word)
|
|---|
| 98 | (:signed-byte (setq bias 7)
|
|---|
| 99 | '%get-signed-byte)
|
|---|
| 100 | (:unsigned-doubleword (setq delta 8) '%%get-unsigned-longlong)
|
|---|
| 101 | (:unsigned-fullword
|
|---|
| 102 | (setq bias 4)
|
|---|
| 103 | '%get-unsigned-long)
|
|---|
| 104 | (:unsigned-halfword
|
|---|
| 105 | (setq bias 6)
|
|---|
| 106 | '%get-unsigned-word)
|
|---|
| 107 | (:unsigned-byte
|
|---|
| 108 | (setq bias 7)
|
|---|
| 109 | '%get-unsigned-byte)
|
|---|
| 110 | (:address '%get-ptr)))
|
|---|
| 111 | ,(if use-fp-args fp-arg-regs stack-ptr)
|
|---|
| 112 | ,(if use-fp-args (* 8 (1- fp-arg-num))
|
|---|
| 113 | `(+ ,offset ,bias))))
|
|---|
| 114 | (when (or (eq type :address)
|
|---|
| 115 | (typep type 'unsigned-byte))
|
|---|
| 116 | (push name dynamic-extent-names))
|
|---|
| 117 | (incf offset delta))))
|
|---|
| 118 | arg-names arg-types)))
|
|---|
| 119 | (multiple-value-bind (body decls doc) (parse-body body env t)
|
|---|
| 120 | `(progn
|
|---|
| 121 | (declaim (special ,name))
|
|---|
| 122 | (define-callback-function
|
|---|
| 123 | (nfunction ,name
|
|---|
| 124 | (lambda (,stack-word)
|
|---|
| 125 | (declare (ignorable ,stack-word))
|
|---|
| 126 | (block ,name
|
|---|
| 127 | (with-macptrs (,@(and need-stack-pointer (list `(,stack-ptr))))
|
|---|
| 128 | ,(when need-stack-pointer
|
|---|
| 129 | `(%setf-macptr-to-object ,stack-ptr ,stack-word))
|
|---|
| 130 | ,(defcallback-body stack-ptr lets dynamic-extent-names
|
|---|
| 131 | decls body return-type error-return
|
|---|
| 132 | (- ppc64::c-frame.savelr ppc64::c-frame.param0)
|
|---|
| 133 | fp-arg-regs
|
|---|
| 134 | )))))
|
|---|
| 135 | ,doc
|
|---|
| 136 | ,woi
|
|---|
| 137 | ,monitor))))))
|
|---|
| 138 |
|
|---|
| 139 | (defun defcallback-body-ppc64-poweropen (stack-ptr lets dynamic-extent-names decls body return-type error-return error-delta fp-arg-ptr)
|
|---|
| 140 | (let* ((result (gensym))
|
|---|
| 141 | (result-ptr (case return-type
|
|---|
| 142 | ((:single-float :double-float) fp-arg-ptr)
|
|---|
| 143 | (t stack-ptr)))
|
|---|
| 144 | (condition-name (if (atom error-return) 'error (car error-return)))
|
|---|
| 145 | (error-return-function (if (atom error-return) error-return (cadr error-return)))
|
|---|
| 146 | (body
|
|---|
| 147 | `(with-macptrs ((,fp-arg-ptr (%get-ptr ,stack-ptr (- ppc64::c-frame.unused-1 ppc64::c-frame.param0))))
|
|---|
| 148 | (declare (ignorable ,fp-arg-ptr))
|
|---|
| 149 | (let ,lets
|
|---|
| 150 | (declare (dynamic-extent ,@dynamic-extent-names))
|
|---|
| 151 | ,@decls
|
|---|
| 152 |
|
|---|
| 153 | (let ((,result (progn ,@body)))
|
|---|
| 154 | (declare (ignorable ,result))
|
|---|
| 155 | ,@(progn
|
|---|
| 156 | ;; Coerce SINGLE-FLOAT result to DOUBLE-FLOAT
|
|---|
| 157 | (when (eq return-type :single-float)
|
|---|
| 158 | (setq result `(float ,result 0.0d0)))
|
|---|
| 159 | nil)
|
|---|
| 160 |
|
|---|
| 161 | ,(when return-type
|
|---|
| 162 | `(setf (,
|
|---|
| 163 | (case return-type
|
|---|
| 164 | (:address '%get-ptr)
|
|---|
| 165 | (:signed-doubleword '%%get-signed-longlong)
|
|---|
| 166 | (:unsigned-doubleword '%%get-unsigned-longlong)
|
|---|
| 167 | ((:double-float :single-float) '%get-double-float)
|
|---|
| 168 | (t '%%get-signed-longlong )) ,result-ptr 0) ,result)))))))
|
|---|
| 169 | (if error-return
|
|---|
| 170 | (let* ((cond (gensym)))
|
|---|
| 171 | `(handler-case ,body
|
|---|
| 172 | (,condition-name (,cond) (,error-return-function ,cond ,stack-ptr (%inc-ptr ,stack-ptr ,error-delta)))))
|
|---|
| 173 | body)))
|
|---|
| 174 |
|
|---|
| 175 | (defvar *ppc64-vinsn-templates* (make-hash-table :test #'eq))
|
|---|
| 176 |
|
|---|
| 177 |
|
|---|
| 178 |
|
|---|
| 179 | (defvar *known-ppc64-backends* ())
|
|---|
| 180 |
|
|---|
| 181 |
|
|---|
| 182 | #+linuxppc-target
|
|---|
| 183 | (defvar *linuxppc64-backend*
|
|---|
| 184 | (make-backend :lookup-opcode #'lookup-ppc-opcode
|
|---|
| 185 | :lookup-macro #'ppc::ppc-macro-function
|
|---|
| 186 | :lap-opcodes ppc::*ppc-opcodes*
|
|---|
| 187 | :define-vinsn 'define-ppc-vinsn
|
|---|
| 188 | :platform-syscall-mask (logior platform-os-linux platform-cpu-ppc)
|
|---|
| 189 |
|
|---|
| 190 | :p2-dispatch *ppc2-specials*
|
|---|
| 191 | :p2-vinsn-templates *ppc64-vinsn-templates*
|
|---|
| 192 | :p2-template-hash-name '*ppc64-vinsn-templates*
|
|---|
| 193 | :p2-compile 'ppc2-compile
|
|---|
| 194 | :target-specific-features
|
|---|
| 195 | '(:powerpc :ppc-target :poweropen-target :linux-target :linuxppc-target :ppc64-target :64-bit-target :big-endian-target)
|
|---|
| 196 | :target-fasl-pathname (make-pathname :type "p64fsl")
|
|---|
| 197 | :target-platform (logior platform-cpu-ppc
|
|---|
| 198 | platform-os-linux
|
|---|
| 199 | platform-word-size-64)
|
|---|
| 200 | :target-os :linuxppc
|
|---|
| 201 | :name :linuxppc64
|
|---|
| 202 | :target-arch-name :ppc64
|
|---|
| 203 | :target-foreign-type-data nil
|
|---|
| 204 | :target-arch ppc64::*ppc64-target-arch*
|
|---|
| 205 | :define-callback 'define-ppc64-poweropen-callback
|
|---|
| 206 | :defcallback-body 'defcallback-body-ppc64-poweropen
|
|---|
| 207 | ))
|
|---|
| 208 |
|
|---|
| 209 |
|
|---|
| 210 | #+darwinppc-target
|
|---|
| 211 | (defvar *darwinppc64-backend*
|
|---|
| 212 | (make-backend :lookup-opcode #'lookup-ppc-opcode
|
|---|
| 213 | :lookup-macro #'ppc::ppc-macro-function
|
|---|
| 214 | :lap-opcodes ppc::*ppc-opcodes*
|
|---|
| 215 | :define-vinsn 'define-ppc-vinsn
|
|---|
| 216 | :platform-syscall-mask (logior platform-os-darwin platform-cpu-ppc)
|
|---|
| 217 |
|
|---|
| 218 | :p2-dispatch *ppc2-specials*
|
|---|
| 219 | :p2-vinsn-templates *ppc64-vinsn-templates*
|
|---|
| 220 | :p2-template-hash-name '*ppc64-vinsn-templates*
|
|---|
| 221 | :p2-compile 'ppc2-compile
|
|---|
| 222 | :target-specific-features
|
|---|
| 223 | '(:powerpc :ppc-target :darwin-target :darwinppc-target :ppc64-target :64-bit-target :big-endian-target)
|
|---|
| 224 | :target-fasl-pathname (make-pathname :type "d64fsl")
|
|---|
| 225 | :target-platform (logior platform-cpu-ppc
|
|---|
| 226 | platform-os-darwin
|
|---|
| 227 | platform-word-size-64)
|
|---|
| 228 | :target-os :darwinppc
|
|---|
| 229 | :name :darwinppc64
|
|---|
| 230 | :target-arch-name :ppc64
|
|---|
| 231 | :target-foreign-type-data nil
|
|---|
| 232 | :target-arch ppc64::*ppc64-target-arch*
|
|---|
| 233 | :define-callback 'define-ppc64-poweropen-callback
|
|---|
| 234 | :defcallback-body 'defcallback-body-ppc64-poweropen))
|
|---|
| 235 |
|
|---|
| 236 | #+linuxppc-target
|
|---|
| 237 | (pushnew *linuxppc64-backend* *known-ppc64-backends* :key #'backend-name)
|
|---|
| 238 |
|
|---|
| 239 |
|
|---|
| 240 | #+darwinppc-target
|
|---|
| 241 | (pushnew *darwinppc64-backend* *known-ppc64-backends* :key #'backend-name)
|
|---|
| 242 |
|
|---|
| 243 | (defvar *ppc64-backend* (car *known-ppc64-backends*))
|
|---|
| 244 |
|
|---|
| 245 | (defun fixup-ppc64-backend ()
|
|---|
| 246 | (dolist (b *known-ppc64-backends*)
|
|---|
| 247 | (setf (backend-lap-opcodes b) ppc::*ppc-opcodes*
|
|---|
| 248 | (backend-p2-dispatch b) *ppc2-specials*
|
|---|
| 249 | (backend-p2-vinsn-templates b) *ppc64-vinsn-templates*)
|
|---|
| 250 | (or (backend-lap-macros b) (setf (backend-lap-macros b)
|
|---|
| 251 | (make-hash-table :test #'equalp)))))
|
|---|
| 252 |
|
|---|
| 253 |
|
|---|
| 254 |
|
|---|
| 255 | (fixup-ppc64-backend)
|
|---|
| 256 |
|
|---|
| 257 | #+ppc64-target
|
|---|
| 258 | (setq *host-backend* *ppc64-backend* *target-backend* *ppc64-backend*)
|
|---|
| 259 | #-ppc64-target
|
|---|
| 260 | (unless (backend-target-foreign-type-data *ppc64-backend*)
|
|---|
| 261 | (let* ((ftd (make-ftd
|
|---|
| 262 | :interface-db-directory
|
|---|
| 263 | #+darwinppc-target "ccl:darwin-headers64;"
|
|---|
| 264 | #+linuxppc-target "ccl:headers64;"
|
|---|
| 265 | :interface-package-name
|
|---|
| 266 | #+darwinppc-target "DARWIN64"
|
|---|
| 267 | #+linuxppc-target "LINUX64"
|
|---|
| 268 | :attributes
|
|---|
| 269 | #+darwinppc-target
|
|---|
| 270 | '(:signed-char t
|
|---|
| 271 | :struct-by-value t
|
|---|
| 272 | :struct-return-in-registers t
|
|---|
| 273 | :struct-return-explicit t
|
|---|
| 274 | :struct-by-value-by-field t
|
|---|
| 275 | :prepend-underscores t
|
|---|
| 276 | :bits-per-word 64)
|
|---|
| 277 | #+linuxppc-target
|
|---|
| 278 | '(:bits-per-word 64)
|
|---|
| 279 | :ff-call-expand-function
|
|---|
| 280 | #+linuxppc-target
|
|---|
| 281 | 'linux64::expand-ff-call
|
|---|
| 282 | #+darwinppc-target
|
|---|
| 283 | 'darwin64::expand-ff-call
|
|---|
| 284 | :ff-call-struct-return-by-implicit-arg-function
|
|---|
| 285 | #+linuxppc-target
|
|---|
| 286 | linux64::record-type-returns-structure-as-first-arg
|
|---|
| 287 | #+darwinppc-target
|
|---|
| 288 | darwin64::record-type-returns-structure-as-first-arg
|
|---|
| 289 | :callback-bindings-function
|
|---|
| 290 | #+linuxppc-target
|
|---|
| 291 | linux64::generate-callback-bindings
|
|---|
| 292 | #+darwinppc-target
|
|---|
| 293 | darwin64::generate-callback-bindings
|
|---|
| 294 | :callback-return-value-function
|
|---|
| 295 | #+linuxppc-target
|
|---|
| 296 | linux64::generate-callback-return-value
|
|---|
| 297 | #+darwinppc-target
|
|---|
| 298 | darwin64::generate-callback-return-value
|
|---|
| 299 | )))
|
|---|
| 300 | (install-standard-foreign-types ftd)
|
|---|
| 301 | (use-interface-dir :libc ftd)
|
|---|
| 302 | (setf (backend-target-foreign-type-data *ppc64-backend*) ftd)))
|
|---|
| 303 |
|
|---|
| 304 | (pushnew *ppc64-backend* *known-backends* :key #'backend-name)
|
|---|
| 305 |
|
|---|
| 306 | #+ppc64-target
|
|---|
| 307 | (require "PPC64-VINSNS")
|
|---|
| 308 |
|
|---|
| 309 | (provide "PPC64-BACKEND")
|
|---|