1 |
6 |
jlechner |
; RTL traversing support.
|
2 |
|
|
; Copyright (C) 2000, 2001, 2009 Red Hat, Inc.
|
3 |
|
|
; This file is part of CGEN.
|
4 |
|
|
; See file COPYING.CGEN for details.
|
5 |
|
|
|
6 |
|
|
; Traversal (and compilation) involves validating the source form and
|
7 |
|
|
; converting it to internal form.
|
8 |
|
|
; ??? At present the internal form is also the source form (easier debugging).
|
9 |
|
|
; Set to #t to debug rtx traversal.
|
10 |
|
|
|
11 |
|
|
; This is initialized before traversal, and modified (in a copy) as the
|
12 |
|
|
|
13 |
|
|
; This doesn't record all traversal state, just the more static elements.
|
14 |
|
|
|
15 |
|
|
; position as they change for every sub-traversal.
|
16 |
|
|
; The main raison d'etre for this class is so we can add more state without
|
17 |
|
|
; having to modify all the traversal handlers.
|
18 |
|
|
; ??? At present it's not a proper "class" as there's no real need.
|
19 |
|
|
;
|
20 |
|
|
; CONTEXT is a <context> object or #f if there is none.
|
21 |
|
|
; It is used for error messages.
|
22 |
|
|
;
|
23 |
|
|
; EXPR-FN is a dual-purpose beast. The first purpose is to just process
|
24 |
|
|
; the current expression and return the result. The second purpose is to
|
25 |
|
|
; lookup the function which will then process the expression.
|
26 |
|
|
; It is applied recursively to the expression and each sub-expression.
|
27 |
|
|
; It must be defined as
|
28 |
|
|
; (lambda (rtx-obj expr mode parent-expr op-pos tstate appstuff) ...).
|
29 |
|
|
; If the result of EXPR-FN is a lambda, it is applied to
|
30 |
|
|
; (cons TSTATE (cdr EXPR)). TSTATE is prepended to the arguments.
|
31 |
|
|
; For syntax expressions if the result of EXPR-FN is #f, the operands are
|
32 |
|
|
; processed using the builtin traverser.
|
33 |
|
|
; So to repeat: EXPR-FN can process the expression, and if its result is a
|
34 |
|
|
; lambda then it also processes the expression. The arguments to EXPR-FN
|
35 |
|
|
; are (rtx-obj expr mode parent-expr op-pos tstate appstuff). The format
|
36 |
|
|
; of the result of EXPR-FN are (cons TSTATE (cdr EXPR)).
|
37 |
|
|
; The reason for the duality is that when trying to understand EXPR (e.g. when
|
38 |
|
|
; computing the insn format) EXPR-FN processes the expression itself, and
|
39 |
|
|
; when evaluating EXPR it's the result of EXPR-FN that computes the value.
|
40 |
|
|
;
|
41 |
|
|
; ENV is the current environment. This is a stack of sequence locals.
|
42 |
|
|
;
|
43 |
|
|
; COND? is a boolean indicating if the current expression is on a conditional
|
44 |
|
|
; execution path. This is for optimization purposes only and it is always ok
|
45 |
|
|
; to pass #t, except for the top-level caller which must pass #f (since the top
|
46 |
|
|
; level expression obviously isn't subject to any condition).
|
47 |
|
|
; It is used, for example, to speed up the simulator: there's no need to keep
|
48 |
|
|
; track of whether an operand has been assigned to (or potentially read from)
|
49 |
|
|
; if it's known it's always assigned to.
|
50 |
|
|
;
|
51 |
|
|
; SET? is a boolean indicating if the current expression is an operand being
|
52 |
|
|
; set.
|
53 |
|
|
;
|
54 |
|
|
; OWNER is the owner of the expression or #f if there is none.
|
55 |
|
|
; Typically it is an <insn> object.
|
56 |
|
|
;
|
57 |
|
|
; KNOWN is an alist of known values. This is used by rtx-simplify.
|
58 |
|
|
; Each element is (name . value) where
|
59 |
|
|
; NAME is either an ifield or operand name (in the future it might be a
|
60 |
|
|
; sequence local name), and
|
61 |
|
|
; VALUE is either (const mode value) or (numlist mode value1 value2 ...).
|
62 |
|
|
;
|
63 |
|
|
; DEPTH is the current traversal depth.
|
64 |
|
|
; Create a copy of STATE.
|
65 |
|
|
; A fast vector-copy would be nice, but this is simple and portable.
|
66 |
|
|
; Create a copy of STATE with a new environment ENV.
|
67 |
|
|
; Create a copy of STATE with environment ENV pushed onto the existing
|
68 |
|
|
; environment list.
|
69 |
|
|
|
70 |
|
|
; need for it: we make a copy of the state when we push.
|
71 |
|
|
; Create a copy of STATE with a new COND? value.
|
72 |
|
|
; Create a copy of STATE with a new SET? value.
|
73 |
|
|
|
74 |
|
|
; Increment the recorded traversal depth of TSTATE.
|
75 |
|
|
; Decrement the recorded traversal depth of TSTATE.
|
76 |
|
|
; Issue an error given a tstate.
|
77 |
|
|
"During rtx traversal"; Traversal/compilation support.
|
78 |
|
|
; Return a boolean indicating if X is a mode.
|
79 |
|
|
; Return a boolean indicating if X is a symbol or rtx.
|
80 |
|
|
; Traverse a list of rtx's.
|
81 |
|
|
; ??? Shouldn't OP-NUM change for each element?
|
82 |
|
|
; Cover-fn to tstate-error for signalling an error during rtx traversal
|
83 |
|
|
; of operand OP-NUM.
|
84 |
|
|
; RTL-EXPR must be an rtl expression.
|
85 |
|
|
", operand #"; Rtx traversers.
|
86 |
|
|
; These are defined as individual functions that are then built into a table
|
87 |
|
|
; so that we can use Hobbit's "fastcall" support.
|
88 |
|
|
;
|
89 |
|
|
; The result is either a pair of the parsed VAL and new TSTATE,
|
90 |
|
|
|
91 |
|
|
"expecting a mode""expecting an integer mode""expecting a float mode""expecting a numeric mode""expecting a mode""DFLT and VOID not allowed here""mode can't be VOID""expecting mode VOID""expecting mode DFLT"; Commented out 'cus it doesn't quite work yet.
|
92 |
|
|
|
93 |
|
|
; (-rtx-traverse-error tstate "expecting an rtx"
|
94 |
|
|
; expr op-num))
|
95 |
|
|
; FIXME: Still need to turn it off for sub-exprs.
|
96 |
|
|
; e.g. (mem (reg ...))
|
97 |
|
|
|
98 |
|
|
; (if (not (rtx? val))
|
99 |
|
|
|
100 |
|
|
; expr op-num))
|
101 |
|
|
; This is the test of an `if'.
|
102 |
|
|
; Commented out 'cus it doesn't quite work yet.
|
103 |
|
|
; (if (not (rtx? val))
|
104 |
|
|
; (-rtx-traverse-error tstate "expecting an rtx"
|
105 |
|
|
|
106 |
|
|
"expecting an expression""`else' clause not last"; ??? Entries after the first are conditional.
|
107 |
|
|
"invalid `case' expression"; car is either 'else or list of symbols/numbers
|
108 |
|
|
"invalid `case' choice""`else' clause not last""bad locals list""bad locals list""bad iteration variable name"; VAL is an environment stack.
|
109 |
|
|
"environment not a list"; (cons val ; (atlist-source-form (atlist-parse (make-prefix-context "with-attr") val ""))
|
110 |
|
|
|
111 |
|
|
"expecting a symbol""expecting a string""expecting a number""expecting a symbol or number"; Table of rtx traversers.
|
112 |
|
|
; This is a vector of size rtx-max-num.
|
113 |
|
|
; Each entry is a list of (arg-type-name . traverser) elements
|
114 |
|
|
; for rtx-arg-types.
|
115 |
|
|
; Return a hash table of standard operand traversers.
|
116 |
|
|
|
117 |
|
|
; a possibly new traversal state or #f if there is no change.
|
118 |
|
|
|
119 |
|
|
; When not using Hobbit it is a macro that returns its argument.
|
120 |
|
|
; Traverse the operands of EXPR, a canonicalized RTL expression.
|
121 |
|
|
; Here "canonicalized" means that -rtx-munge-mode&options has been called to
|
122 |
|
|
; insert an option list and mode if they were absent in the original
|
123 |
|
|
; expression.
|
124 |
|
|
|
125 |
|
|
"Traversing operands of: ""end of operands""op-num "": "", "", "; Out of operands, check if we have the expected number.
|
126 |
|
|
|
127 |
|
|
; and the number of entries should be stable.
|
128 |
|
|
; FIXME: for now
|
129 |
|
|
; If there is an explicit mode, use it.
|
130 |
|
|
; Otherwise we have to look at operand 1.
|
131 |
|
|
; If there is an explicit mode, use it.
|
132 |
|
|
|
133 |
|
|
; Look up the traverser for this kind of operand and perform it.
|
134 |
|
|
|
135 |
|
|
; Publically accessible version of -rtx-traverse-operands as EXPR-FN may
|
136 |
|
|
; need to call it.
|
137 |
|
|
; Subroutine of -rtx-munge-mode&options.
|
138 |
|
|
; Return boolean indicating if X is an rtx option.
|
139 |
|
|
|
140 |
|
|
; Return boolean indicating if X is an rtx option list.
|
141 |
|
|
|
142 |
|
|
; collect the options into one list.
|
143 |
|
|
;
|
144 |
|
|
; ARGS is the list of arguments to the rtx function
|
145 |
|
|
|
146 |
|
|
; ??? "munge" is an awkward name to use here, but I like it for now because
|
147 |
|
|
|
148 |
|
|
; ??? An empty option list requires a mode to be present so that the empty
|
149 |
|
|
; list in `(sequence () foo bar)' is unambiguously recognized as the locals
|
150 |
|
|
; list. Icky, sure, but less icky than the alternatives thus far.
|
151 |
|
|
|
152 |
|
|
; Handle `(sequence () foo bar)'. If empty list isn't followed
|
153 |
|
|
|
154 |
|
|
; Pick off the mode if present.
|
155 |
|
|
; Now put option list and mode back.
|
156 |
|
|
; Subroutine of -rtx-traverse to traverse an expression.
|
157 |
|
|
;
|
158 |
|
|
; RTX-OBJ is the <rtx-func> object of the (outer) expression being traversed.
|
159 |
|
|
;
|
160 |
|
|
; EXPR is the expression to be traversed.
|
161 |
|
|
|
162 |
|
|
; MODE is the name of the mode of EXPR.
|
163 |
|
|
|
164 |
|
|
; PARENT-EXPR is the expression EXPR is contained in. The top-level
|
165 |
|
|
|
166 |
|
|
;
|
167 |
|
|
; OP-POS is the position EXPR appears in PARENT-EXPR. The
|
168 |
|
|
; top-level caller must pass 0 for it.
|
169 |
|
|
|
170 |
|
|
; TSTATE is the current traversal state.
|
171 |
|
|
|
172 |
|
|
; APPSTUFF is for application specific use.
|
173 |
|
|
;
|
174 |
|
|
; For syntax expressions arguments are not pre-evaluated before calling the
|
175 |
|
|
|
176 |
|
|
;
|
177 |
|
|
|
178 |
|
|
; evaluating them, one thing it can do is call back to rtx-traverse-operands.
|
179 |
|
|
; If (tstate-expr-fn TSTATE) returns #f, traverse the operands normally and
|
180 |
|
|
; return (rtx's-name ([options]) mode traversed-operand1 ...),
|
181 |
|
|
; i.e., the canonicalized form.
|
182 |
|
|
; This is for semantic-compile's sake and all traversal handlers are
|
183 |
|
|
; required to do this if the expr-fn returns #f.
|
184 |
|
|
|
185 |
|
|
; Main entry point for expression traversal.
|
186 |
|
|
; (Actually rtx-traverse is, but it's just a cover function for this.)
|
187 |
|
|
;
|
188 |
|
|
|
189 |
|
|
; in the case of expressions, or an operand object (usually <operand>)
|
190 |
|
|
; in the case of operands.
|
191 |
|
|
;
|
192 |
|
|
; EXPR is the expression to be traversed.
|
193 |
|
|
;
|
194 |
|
|
|
195 |
|
|
; or #f if it doesn't matter.
|
196 |
|
|
;
|
197 |
|
|
; MODE is the name of the mode of EXPR.
|
198 |
|
|
;
|
199 |
|
|
; PARENT-EXPR is the expression EXPR is contained in. The top-level
|
200 |
|
|
; caller must pass #f for it.
|
201 |
|
|
|
202 |
|
|
; OP-POS is the position EXPR appears in PARENT-EXPR. The
|
203 |
|
|
; top-level caller must pass 0 for it.
|
204 |
|
|
;
|
205 |
|
|
|
206 |
|
|
;
|
207 |
|
|
; APPSTUFF is for application specific use.
|
208 |
|
|
;
|
209 |
|
|
; All macros are expanded here. User code never sees them.
|
210 |
|
|
; All operand shortcuts are also expand here. User code never sees them.
|
211 |
|
|
; These are:
|
212 |
|
|
; - operands, ifields, and numbers appearing where an rtx is expected are
|
213 |
|
|
|
214 |
|
|
"Traversing expr: ""-expected: ""-mode: "; pair? -> cheap non-null-list?
|
215 |
|
|
"unknown rtx function"; EXPR is not a list.
|
216 |
|
|
; See if it's an operand shortcut.
|
217 |
|
|
; (current-op-lookup expr))
|
218 |
|
|
; (rtx-temp-lookup (tstate-env tstate) expr))
|
219 |
|
|
;; ??? If enums could have modes other than INT,
|
220 |
|
|
;; we'd want to propagate that mode here.
|
221 |
|
|
"unknown operand""unexpected operand"; Not expecting RTX or SETRTX.
|
222 |
|
|
"unexpected operand"; User visible procedures to traverse an rtl expression.
|
223 |
|
|
|
224 |
|
|
; See tstate-make for explanations of OWNER, EXPR-FN.
|
225 |
|
|
; CONTEXT is a <context> object or #f if there is none.
|
226 |
|
|
; LOCALS is a list of (mode . name) elements (the locals arg to `sequence').
|
227 |
|
|
; APPSTUFF is for application specific use.
|
228 |
|
|
; Traverser debugger.
|
229 |
|
|
"-expr: ""rtx="" expr="" mode="" parent="" op-pos="" cond?="; RTL evaluation state.
|
230 |
|
|
; Applications may subclass <eval-state> if they need to add things.
|
231 |
|
|
;
|
232 |
|
|
; This is initialized before evaluation, and modified (in a copy) as the
|
233 |
|
|
|
234 |
|
|
; This doesn't record all evaluation state, just the less dynamic elements.
|
235 |
|
|
; There's no point in recording things like the parent expression and operand
|
236 |
|
|
; position as they change for every sub-eval.
|
237 |
|
|
; The main raison d'etre for this class is so we can add more state without
|
238 |
|
|
; having to modify all the eval handlers.
|
239 |
|
|
; <context> object or #f if there is none
|
240 |
|
|
; Current object rtl is being evaluated for.
|
241 |
|
|
; We need to be able to access the current instruction while
|
242 |
|
|
; generating semantic code. However, the semantic description
|
243 |
|
|
|
244 |
|
|
; want it to). So we record the value here.
|
245 |
|
|
; EXPR-FN is a dual-purpose beast. The first purpose is to
|
246 |
|
|
; just process the current expression and return the result.
|
247 |
|
|
; The second purpose is to lookup the function which will then
|
248 |
|
|
; process the expression. It is applied recursively to the
|
249 |
|
|
; expression and each sub-expression. It must be defined as
|
250 |
|
|
; (lambda (rtx-obj expr mode estate) ...).
|
251 |
|
|
; If the result of EXPR-FN is a lambda, it is applied to
|
252 |
|
|
; (cons ESTATE (cdr EXPR)). ESTATE is prepended to the
|
253 |
|
|
; arguments.
|
254 |
|
|
|
255 |
|
|
; the operands are processed using the builtin evaluator.
|
256 |
|
|
; FIXME: This special handling of syntax expressions is
|
257 |
|
|
; not currently done.
|
258 |
|
|
; So to repeat: EXPR-FN can process the expression, and if its
|
259 |
|
|
; result is a lambda then it also processes the expression.
|
260 |
|
|
; The arguments to EXPR-FN are
|
261 |
|
|
|
262 |
|
|
; The arguments to the result of EXPR-FN are
|
263 |
|
|
; (cons ESTATE (cdr EXPR)).
|
264 |
|
|
; The reason for the duality is mostly history.
|
265 |
|
|
; In time things should be simplified.
|
266 |
|
|
; Current environment. This is a stack of sequence locals.
|
267 |
|
|
; Current evaluation depth. This is used, for example, to
|
268 |
|
|
|
269 |
|
|
; Associative list of modifiers.
|
270 |
|
|
; This is here to support things like `delay'.
|
271 |
|
|
; Create an <eval-state> object using a list of keyword/value elements.
|
272 |
|
|
; ARGS is a list of #:keyword/value elements.
|
273 |
|
|
; The result is a list of the unrecognized elements.
|
274 |
|
|
; Subclasses should override this method and send-next it first, then
|
275 |
|
|
|
276 |
|
|
; recognized.
|
277 |
|
|
; ??? Could invoke method to initialize here.
|
278 |
|
|
; Build in reverse order, as we reverse it back when we're done.
|
279 |
|
|
; Accessors.
|
280 |
|
|
; Build an estate for use in producing a value from rtl.
|
281 |
|
|
; CONTEXT is a <context> object or #f if there is none.
|
282 |
|
|
; OWNER is the owner of the expression or #f if there is none.
|
283 |
|
|
; Create a copy of ESTATE.
|
284 |
|
|
|
285 |
|
|
; Create a copy of ESTATE with environment ENV pushed onto the existing
|
286 |
|
|
; environment list.
|
287 |
|
|
; There's no routine to pop the environment list as there's no current
|
288 |
|
|
; need for it: we make a copy of the state when we push.
|
289 |
|
|
; Create a copy of ESTATE with the depth incremented by one.
|
290 |
|
|
; Create a copy of ESTATE with modifiers MODS.
|
291 |
|
|
; Convert a tstate to an estate.
|
292 |
|
|
; Issue an error given an estate.
|
293 |
|
|
"During rtx evalution"; RTL expression evaluation.
|
294 |
|
|
;
|
295 |
|
|
; ??? These used eval2 at one point. Not sure which is faster but I suspect
|
296 |
|
|
; eval2 is by far. On the otherhand this has yet to be compiled. And this way
|
297 |
|
|
|
298 |
|
|
; problems with eval'ing self referential vectors, though that's one reason to
|
299 |
|
|
|
300 |
|
|
; Set to #t to debug rtx evaluation.
|
301 |
|
|
; RTX expression evaluator.
|
302 |
|
|
;
|
303 |
|
|
; EXPR is the expression to be eval'd. It must be in compiled form.
|
304 |
|
|
; MODE is the mode of EXPR, a <mode> object or its name.
|
305 |
|
|
; ESTATE is the current evaluation state.
|
306 |
|
|
"Traversing "; pair? -> cheap non-null-list?
|
307 |
|
|
; ; Don't eval operands for syntax expressions.
|
308 |
|
|
; (if (rtx-style-syntax? rtx-obj)
|
309 |
|
|
; (apply fn (cons estate (cdr expr)))
|
310 |
|
|
|
311 |
|
|
; (-rtx-eval-operands rtx-obj expr estate)))
|
312 |
|
|
; (apply fn (cons estate operands))))
|
313 |
|
|
; Leave expr unchanged.
|
314 |
|
|
; (let ((operands
|
315 |
|
|
; (-rtx-traverse-operands rtx-obj expr estate)))
|
316 |
|
|
; (cons rtx-obj operands))))
|
317 |
|
|
; EXPR is not a list
|
318 |
|
|
"argument to rtx-eval-with-estate is not a list"; Evaluate rtx expression EXPR and return the computed value.
|
319 |
|
|
; EXPR must already be in compiled form (the result of rtx-compile).
|
320 |
|
|
; OWNER is the owner of the value, used for attribute computation,
|
321 |
|
|
; or #f if there isn't one.
|
322 |
|
|
; FIXME: context?
|
323 |
|
|
|