URL
https://opencores.org/ocsvn/scarts/scarts/trunk
Subversion Repositories scarts
[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cgen/] [rtl-traverse.scm] - Rev 6
Compare with Previous | Blame | View Log
; RTL traversing support. ; Copyright (C) 2000, 2001, 2009 Red Hat, Inc. ; This file is part of CGEN. ; See file COPYING.CGEN for details. ; RTL expression traversal support. ; Traversal (and compilation) involves validating the source form and ; converting it to internal form. ; ??? At present the internal form is also the source form (easier debugging). ; Set to #t to debug rtx traversal. ; Container to record the current state of traversal. ; This is initialized before traversal, and modified (in a copy) as the ; traversal state changes. ; This doesn't record all traversal state, just the more static elements. ; There's no point in recording things like the parent expression and operand ; position as they change for every sub-traversal. ; The main raison d'etre for this class is so we can add more state without ; having to modify all the traversal handlers. ; ??? At present it's not a proper "class" as there's no real need. ; ; CONTEXT is a <context> object or #f if there is none. ; It is used for error messages. ; ; EXPR-FN is a dual-purpose beast. The first purpose is to just process ; the current expression and return the result. The second purpose is to ; lookup the function which will then process the expression. ; It is applied recursively to the expression and each sub-expression. ; It must be defined as ; (lambda (rtx-obj expr mode parent-expr op-pos tstate appstuff) ...). ; If the result of EXPR-FN is a lambda, it is applied to ; (cons TSTATE (cdr EXPR)). TSTATE is prepended to the arguments. ; For syntax expressions if the result of EXPR-FN is #f, the operands are ; processed using the builtin traverser. ; So to repeat: EXPR-FN can process the expression, and if its result is a ; lambda then it also processes the expression. The arguments to EXPR-FN ; are (rtx-obj expr mode parent-expr op-pos tstate appstuff). The format ; of the result of EXPR-FN are (cons TSTATE (cdr EXPR)). ; The reason for the duality is that when trying to understand EXPR (e.g. when ; computing the insn format) EXPR-FN processes the expression itself, and ; when evaluating EXPR it's the result of EXPR-FN that computes the value. ; ; ENV is the current environment. This is a stack of sequence locals. ; ; COND? is a boolean indicating if the current expression is on a conditional ; execution path. This is for optimization purposes only and it is always ok ; to pass #t, except for the top-level caller which must pass #f (since the top ; level expression obviously isn't subject to any condition). ; It is used, for example, to speed up the simulator: there's no need to keep ; track of whether an operand has been assigned to (or potentially read from) ; if it's known it's always assigned to. ; ; SET? is a boolean indicating if the current expression is an operand being ; set. ; ; OWNER is the owner of the expression or #f if there is none. ; Typically it is an <insn> object. ; ; KNOWN is an alist of known values. This is used by rtx-simplify. ; Each element is (name . value) where ; NAME is either an ifield or operand name (in the future it might be a ; sequence local name), and ; VALUE is either (const mode value) or (numlist mode value1 value2 ...). ; ; DEPTH is the current traversal depth. ; Create a copy of STATE. ; A fast vector-copy would be nice, but this is simple and portable. ; Create a copy of STATE with a new environment ENV. ; Create a copy of STATE with environment ENV pushed onto the existing ; environment list. ; There's no routine to pop the environment list as there's no current ; need for it: we make a copy of the state when we push. ; Create a copy of STATE with a new COND? value. ; Create a copy of STATE with a new SET? value. ; Lookup NAME in the known value table. Returns the value or #f if not found. ; Increment the recorded traversal depth of TSTATE. ; Decrement the recorded traversal depth of TSTATE. ; Issue an error given a tstate. "During rtx traversal"; Traversal/compilation support. ; Return a boolean indicating if X is a mode. ; Return a boolean indicating if X is a symbol or rtx. ; Traverse a list of rtx's. ; ??? Shouldn't OP-NUM change for each element? ; Cover-fn to tstate-error for signalling an error during rtx traversal ; of operand OP-NUM. ; RTL-EXPR must be an rtl expression. ", operand #"; Rtx traversers. ; These are defined as individual functions that are then built into a table ; so that we can use Hobbit's "fastcall" support. ; ; The result is either a pair of the parsed VAL and new TSTATE, ; or #f meaning there is no change (saves lots of unnecessarying cons'ing). "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. ; (if (not (rtx? val)) ; (-rtx-traverse-error tstate "expecting an rtx" ; expr op-num)) ; FIXME: Still need to turn it off for sub-exprs. ; e.g. (mem (reg ...)) ; Commented out 'cus it doesn't quite work yet. ; (if (not (rtx? val)) ; (-rtx-traverse-error tstate "expecting an rtx" ; expr op-num)) ; This is the test of an `if'. ; Commented out 'cus it doesn't quite work yet. ; (if (not (rtx? val)) ; (-rtx-traverse-error tstate "expecting an rtx" ; expr op-num)) "expecting an expression""`else' clause not last"; ??? Entries after the first are conditional. "invalid `case' expression"; car is either 'else or list of symbols/numbers "invalid `case' choice""`else' clause not last""bad locals list""bad locals list""bad iteration variable name"; VAL is an environment stack. "environment not a list"; (cons val ; (atlist-source-form (atlist-parse (make-prefix-context "with-attr") val "")) ; tstate) "expecting a symbol""expecting a string""expecting a number""expecting a symbol or number"; Table of rtx traversers. ; This is a vector of size rtx-max-num. ; Each entry is a list of (arg-type-name . traverser) elements ; for rtx-arg-types. ; Return a hash table of standard operand traversers. ; The result of each traverser is a pair of the compiled form of `val' and ; a possibly new traversal state or #f if there is no change. ; /fastcall-make is recognized by Hobbit and handled specially. ; When not using Hobbit it is a macro that returns its argument. ; Traverse the operands of EXPR, a canonicalized RTL expression. ; Here "canonicalized" means that -rtx-munge-mode&options has been called to ; insert an option list and mode if they were absent in the original ; expression. ; Note that this means that, yes, the options and mode are "traversed" too. "Traversing operands of: ""end of operands""op-num "": "", "", "; Out of operands, check if we have the expected number. "missing operands""too many operands"; This is small enough that this is fast enough, ; and the number of entries should be stable. ; FIXME: for now ; If there is an explicit mode, use it. ; Otherwise we have to look at operand 1. ; If there is an explicit mode, use it. ; Otherwise we have to look at operand 2. ; Look up the traverser for this kind of operand and perform it. ; Done with this operand, proceed to the next. ; Publically accessible version of -rtx-traverse-operands as EXPR-FN may ; need to call it. ; Subroutine of -rtx-munge-mode&options. ; Return boolean indicating if X is an rtx option. ; Subroutine of -rtx-munge-mode&options. ; Return boolean indicating if X is an rtx option list. ; Subroutine of -rtx-traverse-expr to fill in the mode if absent and to ; collect the options into one list. ; ; ARGS is the list of arguments to the rtx function ; (e.g. (1 2) in (add 1 2)). ; ??? "munge" is an awkward name to use here, but I like it for now because ; it's easy to grep for. ; ??? An empty option list requires a mode to be present so that the empty ; list in `(sequence () foo bar)' is unambiguously recognized as the locals ; list. Icky, sure, but less icky than the alternatives thus far. ; Pick off the option list if present. ; Handle `(sequence () foo bar)'. If empty list isn't followed ; by a mode, it is not an option list. ; Pick off the mode if present. ; Now put option list and mode back. ; Subroutine of -rtx-traverse to traverse an expression. ; ; RTX-OBJ is the <rtx-func> object of the (outer) expression being traversed. ; ; EXPR is the expression to be traversed. ; ; MODE is the name of the mode of EXPR. ; ; PARENT-EXPR is the expression EXPR is contained in. The top-level ; caller must pass #f for it. ; ; OP-POS is the position EXPR appears in PARENT-EXPR. The ; top-level caller must pass 0 for it. ; ; TSTATE is the current traversal state. ; ; APPSTUFF is for application specific use. ; ; For syntax expressions arguments are not pre-evaluated before calling the ; user's expression handler. Otherwise they are. ; ; If (tstate-expr-fn TSTATE) wants to just scan the operands, rather than ; evaluating them, one thing it can do is call back to rtx-traverse-operands. ; If (tstate-expr-fn TSTATE) returns #f, traverse the operands normally and ; return (rtx's-name ([options]) mode traversed-operand1 ...), ; i.e., the canonicalized form. ; This is for semantic-compile's sake and all traversal handlers are ; required to do this if the expr-fn returns #f. ; Don't traverse operands for syntax expressions. ; Main entry point for expression traversal. ; (Actually rtx-traverse is, but it's just a cover function for this.) ; ; The result is the result of the lambda (tstate-expr-fn TSTATE) looks up ; in the case of expressions, or an operand object (usually <operand>) ; in the case of operands. ; ; EXPR is the expression to be traversed. ; ; EXPECTED is one of `-rtx-valid-types' and indicates the expected rtx type ; or #f if it doesn't matter. ; ; MODE is the name of the mode of EXPR. ; ; PARENT-EXPR is the expression EXPR is contained in. The top-level ; caller must pass #f for it. ; ; OP-POS is the position EXPR appears in PARENT-EXPR. The ; top-level caller must pass 0 for it. ; ; TSTATE is the current traversal state. ; ; APPSTUFF is for application specific use. ; ; All macros are expanded here. User code never sees them. ; All operand shortcuts are also expand here. User code never sees them. ; These are: ; - operands, ifields, and numbers appearing where an rtx is expected are ; converted to use `operand', `ifield', or `const'. "Traversing expr: ""-expected: ""-mode: "; pair? -> cheap non-null-list? "unknown rtx function"; EXPR is not a list. ; See if it's an operand shortcut. ; (current-op-lookup expr)) ; (rtx-temp-lookup (tstate-env tstate) expr)) ;; ??? If enums could have modes other than INT, ;; we'd want to propagate that mode here. "unknown operand""unexpected operand"; Not expecting RTX or SETRTX. "unexpected operand"; User visible procedures to traverse an rtl expression. ; These calls -rtx-traverse to do most of the work. ; See tstate-make for explanations of OWNER, EXPR-FN. ; CONTEXT is a <context> object or #f if there is none. ; LOCALS is a list of (mode . name) elements (the locals arg to `sequence'). ; APPSTUFF is for application specific use. ; Traverser debugger. "-expr: ""rtx="" expr="" mode="" parent="" op-pos="" cond?="; RTL evaluation state. ; Applications may subclass <eval-state> if they need to add things. ; ; This is initialized before evaluation, and modified (in a copy) as the ; evaluation state changes. ; This doesn't record all evaluation state, just the less dynamic elements. ; There's no point in recording things like the parent expression and operand ; position as they change for every sub-eval. ; The main raison d'etre for this class is so we can add more state without ; having to modify all the eval handlers. ; <context> object or #f if there is none ; Current object rtl is being evaluated for. ; We need to be able to access the current instruction while ; generating semantic code. However, the semantic description ; doesn't specify it as an argument to anything (and we don't ; want it to). So we record the value here. ; EXPR-FN is a dual-purpose beast. The first purpose is to ; just process the current expression and return the result. ; The second purpose is to lookup the function which will then ; process the expression. It is applied recursively to the ; expression and each sub-expression. It must be defined as ; (lambda (rtx-obj expr mode estate) ...). ; If the result of EXPR-FN is a lambda, it is applied to ; (cons ESTATE (cdr EXPR)). ESTATE is prepended to the ; arguments. ; For syntax expressions if the result of EXPR-FN is #f, ; the operands are processed using the builtin evaluator. ; FIXME: This special handling of syntax expressions is ; not currently done. ; So to repeat: EXPR-FN can process the expression, and if its ; result is a lambda then it also processes the expression. ; The arguments to EXPR-FN are ; (rtx-obj expr mode estate). ; The arguments to the result of EXPR-FN are ; (cons ESTATE (cdr EXPR)). ; The reason for the duality is mostly history. ; In time things should be simplified. ; Current environment. This is a stack of sequence locals. ; Current evaluation depth. This is used, for example, to ; control indentation in generated output. ; Associative list of modifiers. ; This is here to support things like `delay'. ; Create an <eval-state> object using a list of keyword/value elements. ; ARGS is a list of #:keyword/value elements. ; The result is a list of the unrecognized elements. ; Subclasses should override this method and send-next it first, then ; see if they recognize anything in the result, returning what isn't ; recognized. ; ??? Could invoke method to initialize here. ; Build in reverse order, as we reverse it back when we're done. ; Accessors. ; Build an estate for use in producing a value from rtl. ; CONTEXT is a <context> object or #f if there is none. ; OWNER is the owner of the expression or #f if there is none. ; Create a copy of ESTATE. ; Create a copy of ESTATE with a new environment ENV. ; Create a copy of ESTATE with environment ENV pushed onto the existing ; environment list. ; There's no routine to pop the environment list as there's no current ; need for it: we make a copy of the state when we push. ; Create a copy of ESTATE with the depth incremented by one. ; Create a copy of ESTATE with modifiers MODS. ; Convert a tstate to an estate. ; Issue an error given an estate. "During rtx evalution"; RTL expression evaluation. ; ; ??? These used eval2 at one point. Not sure which is faster but I suspect ; eval2 is by far. On the otherhand this has yet to be compiled. And this way ; is more portable, more flexible, and works with guile 1.2 (which has ; problems with eval'ing self referential vectors, though that's one reason to ; use smobs). ; Set to #t to debug rtx evaluation. ; RTX expression evaluator. ; ; EXPR is the expression to be eval'd. It must be in compiled form. ; MODE is the mode of EXPR, a <mode> object or its name. ; ESTATE is the current evaluation state. "Traversing "; pair? -> cheap non-null-list? ; ; Don't eval operands for syntax expressions. ; (if (rtx-style-syntax? rtx-obj) ; (apply fn (cons estate (cdr expr))) ; (let ((operands ; (-rtx-eval-operands rtx-obj expr estate))) ; (apply fn (cons estate operands)))) ; Leave expr unchanged. ; (let ((operands ; (-rtx-traverse-operands rtx-obj expr estate))) ; (cons rtx-obj operands)))) ; EXPR is not a list "argument to rtx-eval-with-estate is not a list"; Evaluate rtx expression EXPR and return the computed value. ; EXPR must already be in compiled form (the result of rtx-compile). ; OWNER is the owner of the value, used for attribute computation, ; or #f if there isn't one. ; FIXME: context?