OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.