URL
https://opencores.org/ocsvn/scarts/scarts/trunk
Subversion Repositories scarts
[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cgen/] [operand.scm] - Rev 6
Compare with Previous | Blame | View Log
; Operands ; Copyright (C) 2000, 2001, 2005, 2009 Red Hat, Inc. ; This file is part of CGEN. ; See file COPYING.CGEN for details. ; Operands map a set of values (registers, whatever) to an instruction field ; or other indexing mechanism. Operands are also how the semantic code refers ; to hardware elements. ; The `<operand>' class. ; ; ??? Need a new lighterweight version for instances in semantics. ; This should only contain the static elements from the description file. ; ; ??? Derived operands don't use all the current class members. Perhaps ; split <operand> into two. ; Name as used in semantic code. ; Generally this is the same as NAME. It is changed by the ; `operand:' rtx function. One reason is to set a "pretty" ; name in tracing output (most useful in memory operands). ; A more important reason is to help match semantic operands ; with function unit input/output arguments. ; Pretty name as used in tracing code. ; Generally this is the same as the hardware element's name. ; Semantic name of hardware element refered to by this operand. ; Hardware type of operand, a subclass of <hardware-base>. ; This is computed lazily from HW-NAME as many hardware ; elements can have the same semantic name. Applications ; that require a unique hardware element to be refered to are ; required to ensure duplicates are discarded (usually done ; by keeping the appropriate machs). ; FIXME: Rename to hw. ; Name of mode, as specified in description file. ; This needn't be the actual mode, as WI will get coerced ; to the actual word int mode. ; The mode TYPE is being referenced in. ; This is also looked up lazily for the same reasons as TYPE. ; Selector. ; A number or #f used to select a variant of the hardware ; element. An example is ASI's on sparc. ; ??? I really need to be better at picking names. ; Index into type, class <hw-index>. ; For example in the case of an array of registers ; it can be an instruction field or in the case of a memory ; reference it can be a register operand (or general rtx). ; ??? At present <hw-index> is a facade over the real index ; type. Not sure what the best way to do this is. ; Code to run when the operand is read or #f meaning pass ; the request on to the hardware object. ; Code to run when the operand is written or #f meaning pass ; the request on to the hardware object. ; Associative list of (symbol . "handler") entries. ; Each entry maps an operation to its handler (which is up to ; the application but is generally a function name). ; Ordinal number of the operand in an insn's semantic ; description. There is no relation between the number and ; where in the semantics the operand appears. An operand that ; is both read and written are given separate ordinal numbers ; (inputs are treated separately from outputs). ; Boolean indicating if the operand is conditionally ; referenced. #f means the operand is always referenced by ; the instruction. ; whether (and by how much) this instance of the operand is ; delayed. ; The default make! assigns the default h/w selector. ; FIXME: The prefix field- doesn't seem right. Indices needn't be ; ifields, though for operands defined in .cpu files they usually are. ; Accessor fns ; FIXME: op:index should be named op:hwindex. ; Compute the hardware type lazily. ; FIXME: op:type should be named op:hwtype or some such. "cannot resolve h/w reference"; Compute the operand's mode lazily (depends on hardware type which is ; computed lazily). ; FIXME: wip ; Result is the <ifield> object or #f if there is none. " op-ifield op= "", indx= ""\n"" ifld=""\n"; Return mode to use for index or #f if scalar. ; This can't use method-make-forward! as we need to call op:type to ; resolve the hardware reference. ; Return the operand's enum. "@ARCH@_OPERAND_"; Return a boolean indicating if X is an operand. ; Default gen-pretty-name method. ; Return a C string of the name intended for users. ; ; FIXME: The current implementation is a quick hack. Parallel execution ; support can create operands with long names. e.g. h-memory-add-WI-src2-slo16 ; The eventual way this will be handled is to record with each operand the ; entry number (or some such) in the operand instance table so that for ; registers we can compute the register's name. "h-memory""memory""h-""\"""\""; PC support. ; This is a subclass of <operand>, used to give the simulator a place to ; hang a couple of methods. ; At the moment we only support one pc, a reasonable place to stop for now. "program counter""make! of pc""cgen_operand"; handlers ; getter setter ; Return a boolean indicating if operand op is the pc. ; This must not call op:type. op:type will try to resolve a hardware ; element that may be multiply specified, and this is used in contexts ; where that's not possible. ; Mode support. ; Create a copy of operand OP in mode NEW-MODE-NAME. ; NOTE: Even if the mode isn't changing this creates a copy. ; If OP has been subclassed the result must contain the complete class ; (e.g. the behaviour of `object-copy-top'). ; (logit 1 "op:new-mode op=" (op:sem-name op) ; " class=" (object-class-name op) ; " hw-name=" (op:hw-name op) ; " mode=" (op:mode op) ; " newmode=" new-mode-name) ; temporary: for upward compatibility ; Mode isn't changing. ; See if new mode is supported by the hardware. "op:new-mode: internal error, bad mode""op:new-mode""invalid mode for operand `""'"; Return #t if operand OP references its h/w element in its natural mode. ; Ifield support. ; Return list of ifields used by OP. ; else ; The `hw-index' class. ; [Was named `index' but that conflicts with the C library function and caused ; problems when using Hobbit. And `index' is too generic a name anyway.] ; ; An operand combines a hardware object with its index. ; e.g. in an array of registers an operand serves to combine the register bank ; with the instruction field that chooses which one. ; Hardware elements are accessed via other means as well besides instruction ; fields so we need a way to designate something as being an index. ; The `hw-index' class does that. It serves as a facade to the underlying ; details. ; ??? Not sure whether this is the best way to handle this or not. ; ; NAME is the name of the index or 'anonymous. ; This is used, for example, to give a name to the simulator extraction ; structure member. ; TYPE is a symbol that indicates what VALUE is. ; scalar: the hardware object is a scalar, no index is required ; [MODE and VALUE are #f to denote "undefined" in this case] ; constant: a (non-negative) integer ; str-expr: a C expression as a string ; rtx: an rtx to be expanded ; ifield: an ifield object ; operand: an operand object ; ??? A useful simplification may be to always record the value as an rtx ; [which may require extensions to rtl so is deferred]. ; ??? We could use runtime type identification, but doing things this way ; adds more structure. ; ; MODE is the mode of VALUE. If DFLT, mode must be obtained from VALUE. ; DFLT is only allowable for rtx and operand types. ; Accessors. ; Use obj:name for `name'. ; Allow the mode to be specified by its name. ; get-name handler ; get-atlist handler ; ??? Until other things settle. ; There only ever needs to be one of these objects, so create one. ; We can't use `make' here as the make! method calls mode:lookup which ; (a) doesn't exist if we're compiled with Hobbit and mode.scm isn't ; and (b) will fail anyway since #f isn't a valid mode. ; Placeholder for indices of "anyof" operands. ; There only needs to be one of these, so we create one and always use that. ; We can't use `make' here as the make! method calls mode:lookup which ; (a) doesn't exist if we're compiled with Hobbit and mode.scm isn't ; and (b) will fail anyway since #f isn't a valid mode. ; We can't use `make' here as the make! method calls mode:lookup which ; (a) doesn't exist if we're compiled with Hobbit and mode.scm isn't ; and (b) will fail anyway since #f isn't a valid mode. ; Hardware selector support. ; ; A hardware "selector" is like an index except is along an atypical axis ; and thus is rarely used. It exists to support things like ASI's on Sparc. ; What to pass to indicate "default selector". ; (??? value is temporary choice to be revisited). ; Hardware support. ; Return list of hardware elements refered to in OP-LIST ; with no duplicates. ; Build a list of hw elements. ; FIXME: hw-ref? is undefined ; Now build an alist of (name . obj) elements, take the nub, then the cdr. ; ??? These lists tend to be small so sorting first is probably overkill. ; Parsing support. ; Utility of -operand-parse-[gs]etter to build the expected syntax, ; for use in error messages. "("" index"" newval""newval"""") (expression)"; Parse a getter spec. ; The syntax is (([index-names]) (... code ...)). ; Omit `index-names' for scalar objects. ; {rank} is the required number of elements in {index-names}. ; use default "invalid getter, should be ""invalid rtx expression"; Parse a setter spec. ; The syntax is (([index-names] newval) (... code ...)). ; Omit `index-names' for scalar objects. ; {rank} is the required number of elements in {index-names}. ; use default "invalid setter, should be ""invalid rtx expression"; Parse an operand definition. ; This is the main routine for building an operand object from a ; description in the .cpu file. ; All arguments are in raw (non-evaluated) form. ; The result is the parsed object or #f if object isn't for selected mach(s). ; ??? This only takes insn fields as the index. May need another proc (or an ; enhancement of this one) that takes other kinds of indices. "Processing operand "" ...\n";; Pick out name first to augment the error context. "cgen_operand""unknown mode""unknown insn field"; Disallow some obviously invalid numeric indices. "invalid integer index"; Don't validate HW until we know whether this operand will be kept ; or not. If not, HW may have been discarded too. "unknown hardware element"; At this point IFLD-VAL is either an integer or an <ifield> object. ; Since we can't look up the hardware element at this time ; [well, actually we should be able to with a bit of work], ; we determine scalarness from the index. ; FIXME: constant -> const ; Copy FLD's attributes so one needn't duplicate attrs like ; PCREL-ADDR, etc. An operand inherits the attributes of ; its field. They are overridable of course, which is why we use ; `atlist-append' here. ; note that this is the hw's name, not an object ; ditto, this is a name, not an object "Ignoring "".\n"; Read an operand description. ; This is the main routine for analyzing operands in the .cpu file. ; CONTEXT is a <context> object for error messages. ; ARG-LIST is an associative list of field name and field value. ; -operand-parse is invoked to create the <operand> object. ; use default mode of TYPE "invalid operand arg"; Now that we've identified the elements, build the object. ; Define an operand object, name/value pair list version. "define-operand"; Define an operand object, all arguments specified. "define-full-operand"; Derived operands. ; ; Derived operands are used to implement operands more complex than just ; the mapping of an instruction field to a register bank. Their present ; raison d'etre is to create a new axis on which to implement the complex ; addressing modes of the i386 and m68k. The brute force way of describing ; these instruction sets would be to have one `dni' per addressing mode ; per instruction. What's needed is to abstract away the various addressing ; modes within something like operands. ; ; ??? While internally we end up with the "brute force" approach, in and of ; itself that's ok because it's an internal implementation issue. ; See <multi-insn>. ; ; ??? Another way to go is to have one dni per addressing mode. That seems ; less clean though as one dni would be any of add, sub, and, or, xor, etc. ; ; ??? Some addressing modes have side-effects (e.g. pre-dec, etc. like insns). ; This can be represented, but if two operands have side-effects special ; trickery may be required to get the order of side-effects right. Need to ; avoid any "trickery" at all. ; ; ??? Not yet handled are modelling parameters. ; ??? Not yet handled are the handlers,getter,setter spec of normal operands. ; ; ??? Division of class members b/w <operand> and <derived-operand> is wip. ; ??? As is potential introduction of other classes to properly organize ; things. ; Args (list of <operands> objects). ; Syntax string. ; Base ifield, common to all choices. ; ??? experiment ; <derived-ifield> object. ; Assertions of any ifield values or #f if none. ; "anyof" operands are subclassed from derived operands. ; They typically handle multiple addressing modes of CISC architectures. ; Base ifield, common to all choices. ; FIXME: wip ; List of <derived-operand> objects. ; ??? Maybe allow <operand>'s too? ; Set index to a special marker value. ; Derived/Anyof parsing support. ; Subroutine of -derived-operand-parse to parse the encoding. ; The result is a <derived-ifield> object. ; The {owner} member still needs to be set! "encoding not a list""encoding must begin with `+'"; ??? Calling -parse-insn-format is a quick hack. ; It's an internal routine of some other file. ; (string-append "<derived-ifield> for " operand-name) ; owner ; subfields ; Subroutine of -derived-operand-parse to parse the ifield assertion. ; The ifield assertion is either () or an RTL expression asserting something ; about the ifield values of the containing insn. ; Operands are specified by name, but what is used is their indices (there's ; an implicit `index-of' going on). ; FIXME: for now ; Parse a derived operand definition. ; This is the main routine for building a derived operand object from a ; description in the .cpu file. ; All arguments are in raw (non-evaluated) form. ; The result is the parsed object or #f if object isn't for selected mach(s). ; ; ??? Currently no support for handlers(,???) found in normal operands. ; Later, when necessary. "Processing derived operand "" ...\n";; Pick out name first to augment the error context. "cgen_operand""unknown mode""arg not a symbol""not an operand"; FIXME: validate ;(elm-set! result 'hw-name (obj:name parsed-encoding)) ;(elm-set! result 'hw-name base-ifield) ; (elm-set! result 'index (hw-index-derived)) ; A temporary dummy " new derived-operand; name= "", hw-name= "", index=""\n""Ignoring "".\n"; Read a derived operand description. ; This is the main routine for analyzing derived operands in the .cpu file. ; CONTEXT is a <context> object for error messages. ; ARG-LIST is an associative list of field name and field value. ; -derived-operand-parse is invoked to create the <derived-operand> object. ; use default mode of TYPE "invalid derived-operand arg"; Now that we've identified the elements, build the object. ; Define a derived operand object, name/value pair list version. "define-derived-operand"; Define a derived operand object, all arguments specified. ; ??? Not supported (yet). ; ;(define (define-full-derived-operand name comment attrs mode ...) ; (let ((op (-derived-operand-parse (make-current-context "define-full-derived-operand") ; name comment attrs ; mode ...))) ; (if op ; (current-op-add! op)) ; op) ;) ; Parse an "anyof" choice, which is a derived-operand name. ; The result is {choice} unchanged. "anyof choice not a symbol""anyof choice not a derived-operand"; Parse an "anyof" derived operand. ; This is the main routine for building a derived operand object from a ; description in the .cpu file. ; All arguments are in raw (non-evaluated) form. ; The result is the parsed object or #f if object isn't for selected mach(s). ; ; ??? Currently no support for handlers(,???) found in normal operands. ; Later, when necessary. "Processing anyof operand "" ...\n";; Pick out name first to augment the error context. "cgen_operand""unknown mode""Ignoring "".\n"; Read an anyof operand description. ; This is the main routine for analyzing anyof operands in the .cpu file. ; CONTEXT is a <context> object for error messages. ; ARG-LIST is an associative list of field name and field value. ; -anyof-operand-parse is invoked to create the <anyof-operand> object. ; use default mode of TYPE "invalid anyof-operand arg"; Now that we've identified the elements, build the object. ; Define an anyof operand object, name/value pair list version. "define-anyof-operand"; Utilities to flatten out the <anyof-operand> derivation heirarchy. ; Utility class used when instantiating insns with derived operands. ; This collects together in one place all the appropriate data of an ; instantiated "anyof" operand. ; <anyof-operand> object we were instantiated from. ; Return initial list of known ifield values in {anyof-instance}. ; Return true if {anyof-instance} satisfies its ifield assertions. ; {known-values} is the {known} argument to rtx-solve. ; FIXME: context ; owner ; Subroutine of -anyof-merge-subchoices. ; Merge syntaxes of VALUE-NAMES/VALUES into SYNTAX. ; ; Example: ; If SYNTAX is "$a+$b", and VALUE-NAMES is (b), and VALUES is ; ("$c+$d"-object), then return "$a+$c+$d". "Name "" not one of "; Subroutine of -anyof-merge-subchoices. ; Merge syntaxes of {value-names}/{values} into <derived-ifield> {encoding}. ; The result is a new <derived-ifield> object with subfields matching ; {value-names} replaced with {values}. ; {container} is the containing <anyof-operand>. ; ; Example: ; If {encoding} is (a-ifield-object b-anyof-ifield-object), and {value-names} ; is (b), and {values} is (c-choice-of-b-object), then return ; (a-ifield-object c-choice-of-b-ifield-object). ; Delete all the elements that are being replaced with ifields from ; {values} and add the new ifields. ; Subroutine of -anyof-merge-subchoices. ; Merge semantics of VALUE-NAMES/VALUES into GETTER. ; ; Example: ; If GETTER is (mem QI foo), and VALUE-NAMES is (foo), and VALUES is ; ((add a b)-object), then return (mem QI (add a b)). ;(debug-repl-env getter value-names values) ; ??? This implementation is a quick hack, intended to evolve or be replaced. ; pair? -> cheap non-null-list? ; Subroutine of -anyof-merge-subchoices. ; Merge semantics of VALUE-NAMES/VALUES into SETTER. ; ; Example: ; If SETTER is (set (mem QI foo) newval), and VALUE-NAMES is (foo), ; and VALUES is ((add a b)-object), then return ; (set (mem QI (add a b)) newval). ; ; ??? `newval' in this context is a reserved word. ;(debug-repl-env setter value-names values) ; ??? This implementation is a quick hack, intended to evolve or be replaced. "-anyof-merge-setter: unsupported form"; Subroutine of -sub-insn-make!. ; Merge semantics of VALUE-NAMES/VALUES into SEMANTICS. ; Defined here and not in insn.scm to keep it with the getter/setter mergers. ; ; Example: ; If SEMANTICS is (mem QI foo), and VALUE-NAMES is (foo), and VALUES is ; ((add a b)-object), then return (mem QI (add a b)). ;(debug-repl-env semantics value-names values) ; ??? This implementation is a quick hack, intended to evolve or be replaced. ; (op:sem-name (list-ref values indx)) ; pair? -> cheap non-null-list? " merged semantics: [""] -> [""]\n"; Subroutine of -anyof-merge-subchoices. ; Merge assertion of VALUE-NAMES/VALUES into ASSERTION. ; ; Example: ; If ASSERTION is (ne f-base-reg 5), and VALUE-NAMES is ; (foo), and VALUES is ((ne f-mod 0)), then return ; (andif (ne f-base-reg 5) (ne f-mod 0)). ; ; FIXME: Perform simplification pass, based on combined set of known ; ifield values. ; Subroutine of -anyof-all-subchoices. ; Return a copy of <derived-operand> CHOICE with NEW-ARGS from ANYOF-ARGS ; merged in. This is for when a derived operand is itself composed of ; anyof operands. ; ANYOF-ARGS is a list of <anyof-operand>'s to be replaced in CHOICE. ; NEW-ARGS is a corresponding list of values (<derived-operands>'s) of each ; element in ANYOF-ARGS. ; CONTAINER is the <anyof-operand> containing CHOICE. ; Creating the link from {encoding} to {result}. ; Subroutine of -anyof-all-choices-1. ; Return a list of all possible subchoices of <derived-operand> ANYOF-CHOICE, ; known to use <anyof-operand>'s itself. ; CONTAINER is the containing <anyof-operand>. ; Split args into anyof and non-anyof elements. ; Iterate over all combinations. ; {todo} is a list with one element for each anyof argument. ; Each element is in turn a list of all <derived-operand> choices for the ; <anyof-operand>. The result we want is every possible combination. ; Example: ; If {todo} is ((1 2 3) (a) (B C)) the result we want is ; ((1 a B) (1 a C) (2 a B) (2 a C) (3 a B) (3 a C)). ; ; Note that some of these values may be derived from nested ; <anyof-operand>'s which is why we recursively call -anyof-all-choices-1. ; ??? -anyof-all-choices-1 should cache the results. ; ??? One might prefer a `do' loop here, but every time I see one I ; have to spend too long remembering its syntax. ;(display "new-args: " (current-error-port)) ;(display (map obj:name new-args) (current-error-port)) ;(newline (current-error-port)) ; Return an <anyof-instance> object from <derived-operand> {derop}, which is a ; choice of {anyof-operand}. ; Creating the link from {encoding} to {result}. ; Return list of <anyof-instance> objects, one for each possible variant of ; ANYOF-OPERAND. ; ; One could move this up into the cpu description file using pmacros. ; However, that's not the right way to go. How we currently implement ; the notion of derived operands is separate from the notion of having them ; in the description language. pmacros are not "in" the language (to the ; extent that the cpu description file reader "sees" them), they live ; above it. And the right way to do this is with something "in" the language. ; Derived operands are the first cut at it. They'll evolve or be replaced ; (and it's the implementation of them that will evolve first). ; For each choice, scan the operands for further derived operands. ; If found, replace the choice with the list of its subchoices. ; If not found, create an <anyof-instance> object for it. This is ; basically just a copy of the object, but {anyof-operand} is recorded ; with it so that we can later resolve `follows' specs. ; This operand has "anyof" operands so we need to turn this ; choice into a list of all possible subchoices. ; No <anyof-operand> arguments. ; Cover fn of -anyof-all-choices-1. ; Return list of <anyof-instance> objects, one for each possible variant of ; ANYOF-OPERAND. ; We want to delete choices that fail their ifield assertions, but since ; -anyof-all-choices-1 can recursively call itself, assertion checking is ; defered until it returns. ; Delete ones that fail their ifield assertions. ; Sometimes there isn't enough information yet to completely do this. ; When that happens it is the caller's responsibility to deal with it. ; However, it is our responsibility to assert as much as we can. ; Operand utilities. ; Look up operand NAME in the operand table. ; This proc isolates the strategy we use to record operand objects. ; Look up an operand via SEM-NAME. ; Given an operand, return the starting bit number. ; Note that the field isn't necessarily contiguous. ; Given an operand, return the total length in bits. ; Note that the field isn't necessarily contiguous. ; Return the nub of a list of operands, base on their names. ; Return a sorted list of operand lists. ; Each element in the inner list is an operand with the same name, but for ; whatever reason were defined separately. ; The outer list is sorted by name. ; We assume there is at least one operand. "op-sort: no operands!"; First sort by name. ; Current set of operands with same name. ; Reverse things to keep them in file order (minimizes random ; changes in generated files). ; Not done. Check for new set. ; FIXME: Not used anymore but leave in for now. ; Objects used in assembler syntax ($0, $1, ...). ; ;(define <syntax-operand> ; (class-make '<syntax-operand> nil '(number value) nil)) ;(method-make-make! <syntax-operand> '(number)) ; ;(define $0 (make <syntax-operand> 0)) ;(define $1 (make <syntax-operand> 1)) ;(define $2 (make <syntax-operand> 2)) ;(define $3 (make <syntax-operand> 3)) ; Called before/after loading the .cpu file to initialize/finalize. ; Builtins. ; The pc operand used in rtl expressions. ; Called before reading a .cpu file in. "\ Define an operand, name/value pair list version. ""\ Define an operand, all arguments specified. ""\ Define a derived operand, name/value pair list version. ""\ Define an anyof operand, name/value pair list version. "; Install builtin operands. ; Standard operand attributes. ; ??? Some of these can be combined into one. "value is negative"; Operand plays a part in RELAXABLE/RELAXED insns. "operand is the relax participant"; ??? Might be able to make SEM-ONLY go away (or machine compute it) ; by scanning which operands are refered to by the insn syntax strings. "operand is for semantic use only"; Also (defined elsewhere): PCREL-ADDR ABS-ADDR. ; Called after a .cpu file has been read in.