close Warning: Can't use blame annotator:
No changeset 1100 in the repository

source: release/1.4/source/compiler/PPC/PPC64/ppc64-backend.lisp

Last change on this file was 13075, checked in by R. Matthew Emerson, 15 years ago

Merge trunk changes r13066 through r13067.
(copyright notices)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 KB
RevLine 
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")
Note: See TracBrowser for help on using the repository browser.