source: branches/1.1/ccl/compiler/PPC/ppc-backend.lisp

Last change on this file was 5219, checked in by Gary Byers, 18 years ago

clean up an error message.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1;;;-*- Mode: Lisp; Package: CCL -*-
2;;;
3;;; Copyright (C) 1994-2001 Digitool, Inc
4;;; This file is part of OpenMCL.
5;;;
6;;; OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
7;;; License , known as the LLGPL and distributed with OpenMCL as the
8;;; file "LICENSE". The LLGPL consists of a preamble and the LGPL,
9;;; which is distributed with OpenMCL as the file "LGPL". Where these
10;;; conflict, the preamble takes precedence.
11;;;
12;;; OpenMCL is referenced in the preamble as the "LIBRARY."
13;;;
14;;; The LLGPL is also available online at
15;;; http://opensource.franz.com/preamble.html
16
17(in-package "CCL")
18
19(next-nx-defops)
20(defvar *ppc2-specials* nil)
21(let* ((newsize (%i+ (next-nx-num-ops) 10))
22 (old *ppc2-specials*)
23 (oldsize (length old)))
24 (declare (fixnum newsize oldsize))
25 (unless (>= oldsize newsize)
26 (let* ((v (make-array newsize :initial-element nil)))
27 (dotimes (i oldsize (setq *ppc2-specials* v))
28 (setf (svref v i) (svref old i))))))
29
30;;; This defines a template. All expressions in the body must be
31;;; evaluable at macroexpansion time.
32(defun define-ppc-vinsn (backend vinsn-name results args temps body)
33 (let* ((opcode-vector (backend-lap-opcodes backend))
34 (opcode-lookup (backend-lookup-opcode backend))
35 (opcode-expander (backend-lookup-macro backend))
36 (backend-name (backend-name backend))
37 (arch-name (backend-target-arch-name backend))
38 (template-hash (backend-p2-template-hash-name backend))
39 (name-list ())
40 (attrs 0)
41 (nhybrids 0)
42 (local-labels ())
43 (referenced-labels ())
44 (source-indicator (form-symbol arch-name "-VINSN"))
45 (opcode-alist ()))
46 (flet ((valid-spec-name (x)
47 (or (and (consp x)
48 (consp (cdr x))
49 (null (cddr x))
50 (atom (car x))
51 (or (assoc (cadr x) *vreg-specifier-constant-constraints* :test #'eq)
52 (assoc (cadr x) *spec-class-storage-class-alist* :test #'eq)
53 (eq (cadr x) :label)
54 (and (consp (cadr x))
55 (or
56 (assoc (caadr x) *vreg-specifier-constant-constraints* :test #'eq)
57 (assoc (caadr x) *spec-class-storage-class-alist* :test #'eq))))
58 (car x))
59 (error "Invalid vreg spec: ~s" x)))
60 (add-spec-name (vname)
61 (if (member vname name-list :test #'eq)
62 (error "Duplicate name ~s in vinsn ~s" vname vinsn-name)
63 (push vname name-list))))
64 (declare (dynamic-extent valid-spec-name add-spec-name))
65 (when (consp vinsn-name)
66 (setq attrs (encode-vinsn-attributes (cdr vinsn-name))
67 vinsn-name (car vinsn-name)))
68 (unless (and (symbolp vinsn-name) (eq *CCL-PACKAGE* (symbol-package vinsn-name)))
69 (setq vinsn-name (intern (string vinsn-name) *CCL-PACKAGE*)))
70 (dolist (n (append args temps))
71 (add-spec-name (valid-spec-name n)))
72 (dolist (form body)
73 (if (atom form)
74 (add-spec-name form)))
75 (setq name-list (nreverse name-list))
76 ;; We now know that "args" is an alist; we don't know if
77 ;; "results" is. First, make sure that there are no duplicate
78 ;; result names (and validate "results".)
79 (do* ((res results tail)
80 (tail (cdr res) (cdr tail)))
81 ((null res))
82 (let* ((name (valid-spec-name (car res))))
83 (if (assoc name tail :test #'eq)
84 (error "Duplicate result name ~s in ~s." name results))))
85 (let* ((non-hybrid-results ())
86 (match-args args))
87 (dolist (res results)
88 (let* ((res-name (car res)))
89 (if (not (assoc res-name args :test #'eq))
90 (if (not (= nhybrids 0))
91 (error "result ~s should also name an argument. " res-name)
92 (push res-name non-hybrid-results))
93 (if (eq res-name (caar match-args))
94 (setf nhybrids (1+ nhybrids)
95 match-args (cdr match-args))
96 (error "~S - hybrid results should appear in same order as arguments." res-name)))))
97 (dolist (name non-hybrid-results)
98 (add-spec-name name)))
99 (let* ((k -1))
100 (declare (fixnum k))
101 (let* ((name-alist (mapcar #'(lambda (n) (cons n (list (incf k)))) name-list)))
102 (flet ((find-name (n)
103 (let* ((pair (assoc n name-alist :test #'eq)))
104 (declare (list pair))
105 (if pair
106 (cdr pair)
107 (or (subprim-name->offset n backend)
108 (error "Unknown name ~s" n))))))
109 (labels ((simplify-operand (op)
110 (if (atom op)
111 (if (typep op 'fixnum)
112 op
113 (if (constantp op)
114 (progn
115 (if (keywordp op)
116 (pushnew op referenced-labels))
117 (eval op))
118 (find-name op)))
119 (if (eq (car op) :apply)
120 `(,(cadr op) ,@(mapcar #'simplify-operand (cddr op)))
121 (simplify-operand (eval op)))))) ; Handler-case this?
122 (labels ((simplify-constraint (guard)
123 ;; A constraint is one of
124
125 ;; (:eq|:lt|:gt vreg-name constant)
126
127 ;; value" of vreg relop constant
128
129 ;; (:pred <function-name> <operand>* ;
130 ;; <function-name> unquoted, each <operand>
131 ;; is a vreg-name or constant expression.
132
133 ;; (:type vreg-name typeval) ; vreg is of
134 ;; "type" typeval
135 ;;
136 ;;(:not <constraint>) ; constraint is false
137 ;; (:and <constraint> ...) ; conjuntion
138 ;; (:or <constraint> ...) ; disjunction
139 ;; There's no "else"; we'll see how ugly it
140 ;; is without one.
141 (destructuring-bind (guardname &rest others) guard
142 (ecase guardname
143 (:not
144 (destructuring-bind (negation) others
145 `(:not ,(simplify-constraint negation))))
146 (:pred
147 (destructuring-bind (predicate &rest operands) others
148 `(:pred ,predicate ,@(mapcar #'simplify-operand operands))))
149 ((:eq :lt :gt :type)
150 (destructuring-bind (vreg constant) others
151 (unless (constantp constant)
152 (error "~S : not constant in constraint ~s ." constant guard))
153 `(,guardname ,(find-name vreg) ,(eval constant))))
154 ((:or :and)
155 (unless others (error "Missing constraint list in ~s ." guard))
156 `(,guardname ,(mapcar #'simplify-constraint others))))))
157 (simplify-form (form)
158 (if (atom form)
159 (progn
160 (if (keywordp form) (push form local-labels) )
161 form)
162 (destructuring-bind (&whole w opname &rest opvals) form
163 (if (consp opname) ; A constraint, we presume ...
164 (cons (simplify-constraint opname)
165 (mapcar #'simplify-form opvals))
166 (if (keywordp opname)
167 form
168 (let* ((name (string opname))
169 (opnum (funcall opcode-lookup name)))
170 (if (and (not opnum) opcode-expander)
171 (let* ((expander (funcall opcode-expander name)))
172 (if expander
173 (simplify-form (funcall expander form nil))
174 (error "Unknown ~A instruction in ~s" backend-name form)))
175 (let* ((opcode (if (< -1 opnum (length opcode-vector))
176 (svref opcode-vector opnum)
177 (error "~& Invalid ~A opcode: ~s" backend-name name)))
178 (opvals (mapcar #'simplify-operand opvals)))
179 (setf (assq opnum opcode-alist) name)
180 (let* ((operands (opcode-vinsn-operands opcode))
181 (nmin (opcode-min-vinsn-args opcode))
182 (nmax (opcode-max-vinsn-args opcode))
183 (nhave (length opvals)))
184 (declare (fixnum nreq nhave))
185 (if (= nhave nmax)
186 `(,opnum ,@opvals)
187 (if (> nhave nmax)
188 (error "Too many operands in ~s (~a accepts at most ~d)"
189 (cdr w) name nmax)
190 (if (= nhave nmin)
191 (let* ((newops ()))
192 (dolist (op operands `(,opnum ,@(nreverse newops)))
193 (let* ((flags (operand-flags op)))
194 (unless (logbitp operand-fake flags)
195 (push (if (logbitp operand-optional flags)
196 0
197 (pop opvals))
198 newops)))))
199 (error "Too few operands in ~s : (~a requires at least ~d)"
200 (cdr w) name nmin))))))))))))))
201 (let* ((template (make-vinsn-template
202 :name vinsn-name
203 :result-vreg-specs results
204 :argument-vreg-specs args
205 :temp-vreg-specs temps
206 :nhybrids nhybrids
207 :results&args (append results (nthcdr nhybrids args))
208 :nvp (- (+ (length results) (length args) (length temps))
209 nhybrids)
210 :body (prog1 (mapcar #'simplify-form body)
211 (dolist (ref referenced-labels)
212 (unless (memq ref local-labels)
213 (error
214 "local label ~S was referenced but never defined in VINSN-TEMPLATE definition for ~s" ref vinsn-name))))
215 :local-labels local-labels :attributes attrs :opcode-alist
216 opcode-alist)))
217 `(progn (set-vinsn-template ',vinsn-name ,template
218 ,template-hash) (record-source-file ',vinsn-name ',source-indicator)
219 ',vinsn-name))))))))))
220
221#+ppc32-target
222(require "PPC32-BACKEND")
223#+ppc64-target
224(require "PPC64-BACKEND")
225
226(defparameter *ppc-backend*
227 #+ppc32-target *ppc32-backend*
228 #+ppc64-target *ppc64-backend*
229 #-(or ppc32-target ppc64-target)
230 nil)
231
232
233
234(defun fixup-ppc-backend (&rest args)
235 #+ppc32-target (apply #'fixup-ppc32-backend args)
236 #+ppc64-target (apply #'fixup-ppc64-backend args))
237
238
Note: See TracBrowser for help on using the repository browser.