URL
https://opencores.org/ocsvn/scarts/scarts/trunk
Subversion Repositories scarts
[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cgen/] [utils-sim.scm] - Rev 7
Go to most recent revision | Compare with Previous | Blame | View Log
; Generic simulator application utilities. ; Copyright (C) 2000, 2005, 2006, 2009 Red Hat, Inc. ; This file is part of CGEN. ; See file COPYING.CGEN for details. ; The cache-addr? method. ; Return #t if the hardware element's address is stored in the scache buffer. ; This saves doing the index calculation during semantic processing. ; The needed-iflds method. ; Return list of ifields needed during semantic execution by hardware element ; SELF referenced by <operand> OP in <sformat> SFMT. ; Instead of the following, we now arrange to store the ifield in the ; argbuf, even for CACHE-ADDR operands. This way, the ifield values ; (register numbers, etc.) remain available during semantics tracing. ; (if (hw-cache-addr? self) ; nil ; (list (op-ifield op)))) ; For addresses this is none because we make our own copy of the ifield ; [because we want to use a special type]. ; Return a list of ifields of <operand> OP that must be recorded in ARGBUF ; for <sformat> SFMT. ; ??? At the moment there can only be at most one, but callers must not ; assume this. "op-needed-iflds op="" indx="" indx-type="" sfmt=""\n"; Operand extraction (ARGBUF) support code. ; ; Any operand that uses a non-empty ifield needs extraction support. ; Normally we just record the ifield's value. However, in cases where ; hardware elements have CACHE-ADDR specified or where the mode of the ; hardware index isn't compatible with the mode of the decoded ifield ; (this can happen for pc-relative instruction address), we need to record ; something else. ; Return a boolean indicating if <operand> OP needs any extraction processing. "op-extract? op="" =>""\n"; Return a list of operands that need special extraction processing. ; SFMT is an <sformat> object. ; Return a list of ifields that are needed by the semantic code. ; SFMT is an <sformat> object. ; ??? This redoes a lot of the calculation that sfmt-extracted-operands does. ; Sformat argument buffer. ; ; This contains the details needed to create an argument buffer `fields' union ; entry for the containing sformats. ; From <ident>: ; - NAME is derived from one of the containing sformats. ; List of structure elements. ; Each element is ("var name" "C type" bitsize). ; The list is sorted by decreasing size, then C type, ; then var name. ; Subroutine of -sfmt-contents to return an ifield element. ; The result is ("var-name" "C-type" bitsize). ; sbuf-elm method. ; The result is ("var-name" "C-type" approx-bitsize) or #f if unneeded. ; For the default case we use the ifield as is, which is computed elsewhere. "*"; Use 64 bits for size. Doesn't really matter, just put them ; near the front. ; We want to use ADDR/IADDR in ARGBUF for addresses "ADDR"; Use 64 bits for size. Doesn't really matter, just put them ; near the front. "IADDR"; Use 64 bits for size. Doesn't really matter, just put them ; near the front. ; Subroutine of -sfmt-contents to return an operand element. ; These are in addition (or instead of) the actual ifields. ; This is also used to compute definitions of local vars needed in the ; !with-scache case. ; The result is ("var-name" "C-type" approx-bitsize) or #f if unneeded. ; Subroutine of compute-sformat-bufs! to compute list of structure elements ; needed by <sformat> SFMT. ; The result is ; (SFMT ("var-name1" "C-type1" size1) ("var-name2" "C-type2" size2) ...) ; and is sorted by decreasing size, then C type, then variable name ; (as <sformat-argbuf> wants it). ; Sort by descending size, then ascending C type name, ; then ascending name. "-sfmt-contents sfmt="" needed-iflds="" extracted-ops="" in-ops="" out-ops=""\n"; Compute list of all things we need to record at extraction time. ; Discard #f entries, they indicate "unneeded". ; Profiling support. ??? This stuff is in flux. ; Return #t if ELM-LIST is a subset of SBUF. ; SBUF is an <sformat-argbuf> object. ; We take advantage of the fact that elements in each are already sorted. ; FIXME: Can speed up. ; Subroutine of compute-sformat-bufs!. ; Lookup ELM-LIST in SBUF-LIST. A match is found if ELM-LIST ; is a subset of one in SBUF-LIST. ; Return the containing <sformat-argbuf> object if found, otherwise return #f. ; SBUF-LIST is a list of <sformat-argbuf> objects. ; ELM-LIST is (elm1 elm2 ...). ; Compute and record the set of <sformat-argbuf> objects needed for SFMT-LIST, ; a list of all sformats. ; The result is the computed list of <sformat-argbuf> objects. ; ; This is used to further reduce the number of entries in the argument buffer's ; `fields' union. Some sformats have structs with the same contents or one is ; a subset of another's, thus there is no need to distinguish them as far as ; the struct is concerned (there may be other reasons to distinguish them of ; course). ; The consequence of this is fewer semantic fragments created in with-sem-frags ; pbb engines. "Computing sformat argument buffers ...\n"; Sort by descending length. This helps building the result: while ; iterating over each element, its sbuf is either a subset of a ; previous entry or requires a new entry. ; Build an <sformat-argbuf> object. ""; Start off with the first sfmt. ; Also build an empty sbuf. Which sbuf to use for an empty argument list ; is rather arbitrary. Rather than pick one, keep the empty sbuf unto ; itself. "no operands"; Now loop over the remaining sfmts. ; Done. ; Note that the result will be sorted by ascending number of elements ; (because the search list was sorted by descending length and the result ; is built up in reverse order of that). ; Not that it matters, but that's kinda nice. ; Profiling support. ; By default hardware elements are not profilable. ; Return boolean indicating if HW is profilable. ; Return a boolean indicating if OP is profilable. ; sbuf-profile-data method. ; Return a list of C type and size to use in an sformat's argument buffer. "sbuf-profile-elm not supported for this hw type"; Don't unnecessarily bloat size of argument buffer. "unsigned char""unsigned short"; Utility to return name of variable/structure-member to use to record ; profiling data for SYM. "out_""in_"; Return name of variable/structure-member to use to record data needed for ; profiling operand SELF. ; sbuf-profile-elm method. ; Return the ARGBUF member needed for profiling SELF in <sformat> SFMT. ; The result is (var-name "C-type" approx-bitsize) or #f if unneeded. ; Subroutine of -sfmt-contents to return an operand's profile element. ; The result is (var-name "C-type" approx-bitsize) or #f if unneeded. ; ARGBUF accessor support. ; Define and undefine C macros to tuck away details of instruction format used ; in the extraction and semantic code. Instruction format names can ; change frequently and this can result in unnecessarily large diffs from one ; generated version of the file to the next. Secondly, tucking away details of ; the extracted argument structure from the extraction code is a good thing. ; Name of macro to access fields in ARGBUF. "FLD"; NB: If sfmt is #f, then define the macro to pass through the argument ; symbol. This is appropriate for "simple" (non-scache) simulators ; that have no abuf/scache in the sem.c routines, but rather plain ; local variables. "#define ""(f) ""abuf->fields."".f\n""f\n""#undef ""\n"; For old code. Delete in time. ; Return a C reference to an ARGBUF field value. " ("")"; Return name of ARGBUF member for extracted <field> F. ; Return the C reference to a cached ifield. ; Return name of ARGBUF member holding processed from of extracted ; ifield value for <hw-index> index. ; Return C reference to a processed <hw-index> in ARGBUF. ; Decode support. ; Main procedure call tree: ; cgen-decode.{c,cxx} ; -gen-decode-fn ; gen-decoder [our entry point] ; decode-build-table ; -gen-decoder-switch ; -gen-decoder-switch ; ; decode-build-table is called to construct a tree of "table-guts" elements ; (??? Need better name obviously), ; and then gen-decoder is recursively called on each of these elements. ; Return C/C++ code that fetches the desired decode bits from C value VAL. ; SIZE is the size in bits of val (the MSB is 1 << (size - 1)) which we ; treat as bitnum 0. ; BITNUMS must be monotonically increasing. ; LSB0? is non-#f if bit number 0 is the least significant bit. ; FIXME: START may not be handled right in words beyond first. ; ; ENTIRE-VAL is passed as a hack for cgen 1.1 which would previously generate ; negative shifts. FIXME: Revisit for 1.2. ; ; e.g. (-gen-decode-bits '(0 1 2 3 8 9 10 11) 0 16 "insn" #f) ; --> "(((insn >> 8) & 0xf0) | ((insn >> 4) & 0xf))" ; FIXME: The generated code has some inefficiencies in edge cases. Later. ; Compute a list of lists of three numbers: ; (first bitnum in group, position in result (0=LSB), bits in result) ; POS = starting bit position of current group. ; COUNT = number of bits in group. ; Work from least to most significant bit so reverse bitnums. ;(display (list result pos count bitnums)) (newline) ; Are numbers not next to each other? ; While we could just always emit "(0" to handle the case of an empty set, ; keeping the code more readable for the normal case is important. "(0""("; Difference between where value is and where ; it needs to be. ; FIXME: There should never be a -ve shift here, ; but it can occur on the m32r. Compensate here ; with hack and fix in 1.2. ; END-FIXME " | (("" >> "") & ("" << ""))"")"; Convert decoder table into C code. ; Return code for the default entry of each switch table ; "itype = "";"" @prefix@_extract_sfmt_empty (this, current_cpu, pc, base_insn, entire_insn); goto done;\n"" goto extract_sfmt_empty;\n"" goto done;\n"; Return code for one insn entry. ; REST is the remaining entries. "Generating decode insn entry for "" ...\n"; Leave invalids to the default case. ""; If same contents as next case, fall through. ; FIXME: Can reduce more by sorting cases. Much later. ; Ensure both insns. ; Ensure same insn. " case "" : /* fall through */\n"" case "" :\n"; Compensate for base-insn-size > current-insn-size by adjusting entire_insn. ; Activate this logic only for sid simulators; they are consistent in ; interpreting base-insn-bitsize this way. " entire_insn = entire_insn >> "";\n"""; Generate code to check that all of the opcode bits for this insn match " if ((""entire_insn""base_insn"" & 0x"") == 0x"")\n"" { itype = "";"" @prefix@_extract_"" (this, current_cpu, pc, base_insn, entire_insn); goto done;"" goto extract_"";"" goto done;"" }\n"" "; Subroutine of -decode-expr-ifield-tracking. ; Return a list of all possible values for ifield IFLD-NAME. ; FIXME: Quick-n-dirty implementation. Should use bit arrays. ; Subroutine of -decode-expr-ifield-tracking,-decode-expr-ifield-mark-used. ; Create the search key for tracking table lookup. ; Subroutine of -gen-decode-expr-entry. ; Return a table to track used ifield values. ; The table is an associative list of (key . value-list). ; KEY is "iformat-name-x-ifield-name". ; VALUE-LIST is a list of the unused values. ; TABLE1 is a list of (insn ifld-name value1 value2 ...). ; Subroutine of -decode-expr-ifield-mark-used!. ; Return list of values completely used for ifield IFLD-NAME in EXPR. ; "completely used" here means the value won't appear elsewhere. ; e.g. in (andif (eq f-rd 15) (eq f-rx 14)) we don't know what happens ; for the (ne f-rx 14) case. ; FIXME: more needed ; Subroutine of -gen-decode-expr-entry. ; Mark ifield values used by EXPR-ENTRY in TRACKING-TABLE. ; Subroutine of -gen-decode-expr-entry. ; Return code to set `itype' and branch to the extraction phase. "{ itype = ""; ""@prefix@_extract_"" (this, current_cpu, pc, base_insn, entire_insn); goto done;""goto extract_"";""goto done;"" }\n"; Generate code to decode the expression table in ENTRY. ; INVALID-INSN is the <insn> object of the pseudo insn to handle invalid ones. "Generating decode expr entry for "" ...\n"" case "" :\n"" "; All done. If we used up all field values we don't need to ; "fall through" and select the invalid insn marker. "sfmt_empty"; Not all done, process next expr. ; Mark of those ifield values we use first. ; If there are none left afterwards, we can unconditionally ; choose this insn. ; If this is the last expression, and it uses up all ; remaining ifield values, there's no need to perform any ; test. ; Need this in a list for a later append!. ; We don't use up all ifield values, so emit a test. "{\n"" "" "" if ("")\n"" ""}\n"; Generate code to decode TABLE. ; REST is the remaining entries. ; SWITCH-NUM, STARTBIT, DECODE-BITSIZE, INDENT, LSB0?, INVALID-INSN are same ; as for -gen-decoder-switch. "Generating decode table entry for case "" ...\n"" case "" :"; If table is same as next, just emit a "fall through" to cut down on ; generated code. ; Ensure both tables. ; Ensure same table. " /* fall through */\n""\n"" "; Subroutine of -decode-sort-entries. ; Return a boolean indicating if A,B are equivalent entries. ; Ignore expr entries for now. ; A and B are not the same type. ; Subroutine of -gen-decoder-switch, sort ENTRIES according to desired ; print order (maximizes amount of fall-throughs, but maintains numerical ; order as much as possible). ; ??? This is an O(n^2) algorithm. An O(n Log(n)) algorithm can be done ; but it seemed more complicated than necessary for now. ; Return list of entries in non-empty list L that have the same decode ; entry as the first entry. Entries found are marked with #f so ; they're not processed again. ; Start off the result with the first entry, then see if the ; remaining ones match it. ; Generate switch statement to decode TABLE-GUTS. ; SWITCH-NUM is for compatibility with the computed goto decoder and ; isn't used. ; STARTBIT is the bit offset of the instruction value that C variable `insn' ; holds (note that this is independent of LSB0?). ; DECODE-BITSIZE is the number of bits of the insn that `insn' holds. ; LSB0? is non-#f if bit number 0 is the least significant bit. ; INVALID-INSN is the <insn> object of the pseudo insn to handle invalid ones. ; FIXME: for the few-alternative case (say, 2), generating ; if (0) {} ; else if (val == 0) { ... } ; else if (val == 1) { ... } ; else {} ; may well be less stressful on the compiler to optimize than small switch() stmts. ; For entries that are a single insn, we're done, otherwise recurse. "{\n"; Are we at the next word? ; FIXME: Bits may get fetched again during extraction. " unsigned int val;\n"" /* Must fetch more bits. */\n"" insn = ""pc"";\n"" val = "" unsigned int val = ""insn""entire_insn"";\n"" switch (val)\n"" {\n"; The code is more readable, and icache use is improved, if we collapse ; common code into one case and use "fall throughs" for all but the last of ; a set of common cases. ; FIXME: We currently rely on -gen-decode-foo-entry to recognize the fall ; through. We should take care of it ourselves. ; ??? Can delete if all cases are present. " default : "" }\n""}\n"; Decoder generation entry point. ; Generate code to decode INSN-LIST. ; BITNUMS is the set of bits to initially key off of. ; DECODE-BITSIZE is the number of bits of the instruction that `insn' holds. ; LSB0? is non-#f if bit number 0 is the least significant bit. ; INVALID-INSN is the <insn> object of the pseudo insn to handle invalid ones. ; FN? is non-#f if the extractors are functions rather than inline code "Building decode tree.\n""bitnums = "" ""\n""decode-bitsize = ""\n""lsb0? = ""#t""#f""\n""fn? = ""#t""#f""\n"; First build a table that decodes the instruction set. ; Now print it out. "0"
Go to most recent revision | Compare with Previous | Blame | View Log