| /* The IGEN simulator generator for GDB, the GNU Debugger. | 
 |  | 
 |    Copyright 2002-2016 Free Software Foundation, Inc. | 
 |  | 
 |    Contributed by Andrew Cagney. | 
 |  | 
 |    This file is part of GDB. | 
 |  | 
 |    This program is free software; you can redistribute it and/or modify | 
 |    it under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3 of the License, or | 
 |    (at your option) any later version. | 
 |  | 
 |    This program is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |    GNU General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU General Public License | 
 |    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 |  | 
 |  | 
 | typedef unsigned64 insn_uint; | 
 |  | 
 |  | 
 | /* Common among most entries: | 
 |  | 
 |    All non instruction records have the format: | 
 |  | 
 |    <...> ::= | 
 |        ":" <record-name> | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        ":" ... | 
 |     | 
 |  */ | 
 |  | 
 | enum | 
 | { | 
 |   record_type_field = 1, | 
 |   old_record_type_field = 2, | 
 |   record_filter_flags_field = 2, | 
 |   record_filter_models_field = 3, | 
 | }; | 
 |  | 
 |  | 
 | /* Include: | 
 |  | 
 |    Include the specified file. | 
 |  | 
 |    <include> ::= | 
 |        ":" "include" | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        ":" <filename> | 
 |        <nl> | 
 |        ; | 
 |  | 
 |    */ | 
 |  | 
 | enum | 
 | { | 
 |   include_filename_field = 4, | 
 |   nr_include_fields, | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | /* Options: | 
 |  | 
 |    Valid options are: hi-bit-nr (default 0), insn-bit-size (default | 
 |    32), insn-specifying-widths (default true), multi-sim (default false). | 
 |  | 
 |    <option> ::= | 
 |        ":" "option" | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        ":" <option-name> | 
 |        ":" <option-value> | 
 |        <nl> | 
 |        ; | 
 |  | 
 |    <option-name> ::= | 
 |        "insn-bit-size" | 
 |        | "insn-specifying-widths" | 
 |        | "hi-bit-nr" | 
 |        | "flags-filter" | 
 |        | "model-filter" | 
 |        | "multi-sim" | 
 |        | "format-names" | 
 |        ; | 
 |  | 
 |    <option-value> ::= | 
 |        "true" | 
 |        | "false" | 
 |        | <integer> | 
 |        | <list> | 
 |        ; | 
 |  | 
 |  | 
 |    These update the global options structure. */ | 
 |  | 
 |  | 
 | enum | 
 | { | 
 |   option_name_field = 4, | 
 |   option_value_field, | 
 |   nr_option_fields, | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | /* Macro definitions: | 
 |  | 
 |    <insn-macro> ::= | 
 |        ":" "define" | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        ":" <name> | 
 |        ":" <arg-list> | 
 |        ":" <expression> | 
 |        <nl> | 
 |        ; | 
 |  | 
 |    <arg-list> ::= | 
 |        [ <name> { "," <arg-list> } ] | 
 |        ; | 
 |  | 
 |    */ | 
 |  | 
 |  | 
 | enum | 
 | { | 
 |   macro_name_field = 4, | 
 |   macro_args_field, | 
 |   macro_expr_field, | 
 |   nr_macro_fields, | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | /* Functions and internal routins: | 
 |  | 
 |    NB: <filter-models> and <function-models> are equivalent. | 
 |  | 
 |  | 
 |    <function> ::= | 
 |        ":" "function" | 
 |        <function-spec> | 
 |        ; | 
 |  | 
 |    <internal> ::= | 
 |        ":" "internal" | 
 |        <function-spec> | 
 |        ; | 
 |  | 
 |    <format> ::= | 
 |        ":" ( "%s" | ... ) | 
 |        <function-spec> | 
 |        ; | 
 |  | 
 |    <function-model> ::= | 
 |        "*" [ <processor-list> ] | 
 |        ":" | 
 |        <nl> | 
 |        ; | 
 |  | 
 |    <function-spec> ::= | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        ":" <typedef> | 
 |        ":" <name> | 
 |        [ ":" <parameter-list> ] | 
 |        <nl> | 
 |        [ <function-model> ] | 
 |        <code-block> | 
 |        ; | 
 |  | 
 |    */ | 
 |  | 
 | enum | 
 | { | 
 |   function_typedef_field = 4, | 
 |   function_name_field, | 
 |   function_param_field, | 
 |   nr_function_fields, | 
 | }; | 
 |  | 
 | enum | 
 | { | 
 |   function_model_name_field = 0, | 
 |   nr_function_model_fields = 1, | 
 | }; | 
 |  | 
 | enum | 
 | { | 
 |   old_function_typedef_field = 0, | 
 |   old_function_type_field = 2, | 
 |   old_function_name_field = 4, | 
 |   old_function_param_field = 5, | 
 |   nr_old_function_fields = 5,	/* parameter-list is optional */ | 
 | }; | 
 |  | 
 |  | 
 | typedef struct _function_entry function_entry; | 
 | struct _function_entry | 
 | { | 
 |   line_ref *line; | 
 |   filter *flags; | 
 |   filter *models; | 
 |   char *type; | 
 |   char *name; | 
 |   char *param; | 
 |   table_entry *code; | 
 |   int is_internal; | 
 |   function_entry *next; | 
 | }; | 
 |  | 
 |  | 
 | typedef void function_entry_handler | 
 |   (lf *file, function_entry * function, void *data); | 
 |  | 
 | extern void function_entry_traverse | 
 |   (lf *file, | 
 |    function_entry * functions, function_entry_handler * handler, void *data); | 
 |  | 
 |  | 
 | /* cache-macro: | 
 |  | 
 |    <cache-macro> ::= | 
 |        ":" <macro-type> | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        ":" <typedef> | 
 |        ":" <name> | 
 |        ":" <field-name> { "," <field-name> } | 
 |        ":" <expression> | 
 |        <nl> | 
 |        ; | 
 |  | 
 |    <cache-macro-type> ::= | 
 |        "scratch" | 
 |        | "cache" | 
 |        | "compute" | 
 |        ; | 
 |  | 
 |    <name> ::= | 
 |        <ident> | 
 |        | <ident> "_is_" <integer> | 
 |        ; | 
 |  | 
 |    A cache entry is defined (for an instruction) when all | 
 |    <field-name>s are present as named opcode fields within the | 
 |    instructions format. | 
 |  | 
 |    SCRATCH and CACHE macros are defined during the cache fill stage | 
 |    while CACHE and COMPUTE macros are defined during the instruction | 
 |    execution stage. | 
 |  | 
 |    */ | 
 |  | 
 | enum | 
 | { | 
 |   cache_typedef_field = 4, | 
 |   cache_name_field, | 
 |   cache_original_fields_field, | 
 |   cache_expression_field, | 
 |   nr_cache_fields, | 
 | }; | 
 |  | 
 | typedef enum | 
 | { | 
 |   scratch_value, | 
 |   cache_value, | 
 |   compute_value, | 
 | } | 
 | cache_entry_type; | 
 |  | 
 | typedef struct _cache_entry cache_entry; | 
 | struct _cache_entry | 
 | { | 
 |   line_ref *line; | 
 |   filter *flags; | 
 |   filter *models; | 
 |   cache_entry_type entry_type; | 
 |   char *name; | 
 |   filter *original_fields; | 
 |   char *type; | 
 |   char *expression; | 
 |   cache_entry *next; | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | /* Model specs: | 
 |  | 
 |    <model-processor> ::= | 
 |        ":" "model" | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        ":" <processor> | 
 |        ":" <BFD-processor> | 
 |        ":" <function-unit-data> | 
 |        <nl> | 
 |        ; | 
 |  | 
 |    <model-macro> ::= | 
 |        ":" "model-macro" | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        <nl> | 
 |        <code-block> | 
 |        ; | 
 |  | 
 |    <model-data> ::= | 
 |        ":" "model-data" | 
 |        ":" <filter-flags> | 
 |        ":" <filter-models> | 
 |        <nl> | 
 |        <code-block> | 
 |        ; | 
 |  | 
 |    <model-static> ::= | 
 |        ":" "model-static" | 
 |        <function-spec> | 
 |        ; | 
 |  | 
 |    <model-internal> ::= | 
 |        ":" "model-internal" | 
 |        <function-spec> | 
 |        ; | 
 |  | 
 |    <model-function> ::= | 
 |        ":" "model-internal" | 
 |        <function-spec> | 
 |        ; | 
 |  | 
 |  */ | 
 |  | 
 | enum | 
 | { | 
 |   nr_model_macro_fields = 4, | 
 |   nr_model_data_fields = 4, | 
 |   nr_model_static_fields = nr_function_fields, | 
 |   nr_model_internal_fields = nr_function_fields, | 
 |   nr_model_function_fields = nr_function_fields, | 
 | }; | 
 |  | 
 | typedef struct _model_data model_data; | 
 | struct _model_data | 
 | { | 
 |   line_ref *line; | 
 |   filter *flags; | 
 |   table_entry *entry; | 
 |   table_entry *code; | 
 |   model_data *next; | 
 | }; | 
 |  | 
 | enum | 
 | { | 
 |   model_name_field = 4, | 
 |   model_full_name_field, | 
 |   model_unit_data_field, | 
 |   nr_model_processor_fields, | 
 | }; | 
 |  | 
 | typedef struct _model_entry model_entry; | 
 | struct _model_entry | 
 | { | 
 |   line_ref *line; | 
 |   filter *flags; | 
 |   char *name; | 
 |   char *full_name; | 
 |   char *unit_data; | 
 |   model_entry *next; | 
 | }; | 
 |  | 
 |  | 
 | typedef struct _model_table model_table; | 
 | struct _model_table | 
 | { | 
 |   filter *processors; | 
 |   int nr_models; | 
 |   model_entry *models; | 
 |   model_data *macros; | 
 |   model_data *data; | 
 |   function_entry *statics; | 
 |   function_entry *internals; | 
 |   function_entry *functions; | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | /* Instruction format: | 
 |  | 
 |    An instruction is composed of a sequence of N bit instruction | 
 |    words.  Each word broken into a number of instruction fields. | 
 |    Those fields being constant (ex. an opcode) or variable (register | 
 |    spec). | 
 |  | 
 |    <insn-word> ::= | 
 |        <insn-field> { "," <insn-field> } ; | 
 |  | 
 |    <insn-field> ::= | 
 |        ( <binary-value-implying-width> | 
 |        | <field-name-implying-width> | 
 |        | [ <start-or-width> "." ] <field>  | 
 |        ) | 
 |        { [ "!" | "=" ] [ <value> | <field-name> ] } | 
 |        ; | 
 |  | 
 |    <field> ::= | 
 |          { "*" }+ | 
 |        | { "/" }+ | 
 |        | <field-name> | 
 |        | "0x" <hex-value> | 
 |        | "0b" <binary-value> | 
 |        | "0" <octal-value> | 
 |        | <integer-value> ; | 
 |  | 
 | */ | 
 |  | 
 | typedef enum _insn_field_cond_type | 
 | { | 
 |   insn_field_cond_value, | 
 |   insn_field_cond_field, | 
 | } | 
 | insn_field_cond_type; | 
 | typedef enum _insn_field_cond_test | 
 | { | 
 |   insn_field_cond_eq, | 
 |   insn_field_cond_ne, | 
 | } | 
 | insn_field_cond_test; | 
 | typedef struct _insn_field_cond insn_field_cond; | 
 | struct _insn_field_cond | 
 | { | 
 |   insn_field_cond_type type; | 
 |   insn_field_cond_test test; | 
 |   insn_uint value; | 
 |   struct _insn_field_entry *field; | 
 |   char *string; | 
 |   insn_field_cond *next; | 
 | }; | 
 |  | 
 |  | 
 | typedef enum _insn_field_type | 
 | { | 
 |   insn_field_invalid, | 
 |   insn_field_int, | 
 |   insn_field_reserved, | 
 |   insn_field_wild, | 
 |   insn_field_string, | 
 | } | 
 | insn_field_type; | 
 |  | 
 | typedef struct _insn_field_entry insn_field_entry; | 
 | struct _insn_field_entry | 
 | { | 
 |   int first; | 
 |   int last; | 
 |   int width; | 
 |   int word_nr; | 
 |   insn_field_type type; | 
 |   insn_uint val_int; | 
 |   char *pos_string; | 
 |   char *val_string; | 
 |   insn_field_cond *conditions; | 
 |   insn_field_entry *next; | 
 |   insn_field_entry *prev; | 
 | }; | 
 |  | 
 | typedef struct _insn_bit_entry insn_bit_entry; | 
 | struct _insn_bit_entry | 
 | { | 
 |   int value; | 
 |   int mask; | 
 |   insn_field_entry *field; | 
 | }; | 
 |  | 
 |  | 
 |  | 
 |  | 
 | typedef struct _insn_entry insn_entry;	/* forward */ | 
 |  | 
 | typedef struct _insn_word_entry insn_word_entry; | 
 | struct _insn_word_entry | 
 | { | 
 |   /* list of sub-fields making up the instruction.  bit provides | 
 |      faster access to the field data for bit N.  */ | 
 |   insn_field_entry *first; | 
 |   insn_field_entry *last; | 
 |   insn_bit_entry *bit[max_insn_bit_size]; | 
 |   /* set of all the string fields */ | 
 |   filter *field_names; | 
 |   /* For multi-word instructions, The Nth word (from zero). */ | 
 |   insn_word_entry *next; | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | /* Instruction model: | 
 |  | 
 |    Provides scheduling and other data for the code modeling the | 
 |    instruction unit. | 
 |  | 
 |    <insn-model> ::= | 
 |        "*" [ <processor-list> ] | 
 |        ":" [ <function-unit-data> ] | 
 |        <nl> | 
 |        ; | 
 |  | 
 |    <processor-list> ::= | 
 |        <processor> { "," <processor>" } | 
 |        ; | 
 |  | 
 |    If the <processor-list> is empty, the model is made the default for | 
 |    this instruction. | 
 |  | 
 |    */ | 
 |  | 
 | enum | 
 | { | 
 |   insn_model_name_field = 0, | 
 |   insn_model_unit_data_field = 1, | 
 |   nr_insn_model_fields = 1, | 
 | }; | 
 |  | 
 | typedef struct _insn_model_entry insn_model_entry; | 
 | struct _insn_model_entry | 
 | { | 
 |   line_ref *line; | 
 |   insn_entry *insn; | 
 |   filter *names; | 
 |   char *full_name; | 
 |   char *unit_data; | 
 |   insn_model_entry *next; | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | /* Instruction mnemonic: | 
 |  | 
 |    List of assembler mnemonics for the instruction. | 
 |  | 
 |    <insn-mnenonic> ::= | 
 |        "\"" <assembler-mnemonic> "\"" | 
 |        [ ":" <conditional-expression> ] | 
 |        <nl> | 
 |        ; | 
 |  | 
 |    An assembler mnemonic string has the syntax: | 
 |  | 
 |    <assembler-mnemonic>  ::= | 
 |        ( [ "%" <format-spec> ] "<" <func> [ "#" <param-list> ] ">" | 
 |        | "%%" | 
 |        | <other-letter> | 
 |        )+ | 
 |  | 
 |     Where, for instance, the text is translated into a printf format | 
 |     and argument pair: | 
 |  | 
 |        "<FUNC>"         : "%ld", (long) FUNC | 
 |        "%<FUNC>..."     : "%...", FUNC | 
 |        "%s<FUNC>"       : "%s", <%s>FUNC (SD_, FUNC) | 
 |        "%s<FUNC#P1,P2>" : "%s", <%s>FUNC (SD_, P1,P2) | 
 |        "%lx<FUNC>"      : "%lx", (unsigned long) FUNC | 
 |        "%08lx<FUNC>"    : "%08lx", (unsigned long) FUNC | 
 |  | 
 |     And "<%s>FUNC" denotes a function declared using the "%s" record | 
 |     specifier. | 
 |  | 
 |  | 
 |  | 
 |        ; | 
 |  | 
 |    */ | 
 |  | 
 | enum | 
 | { | 
 |   insn_mnemonic_format_field = 0, | 
 |   insn_mnemonic_condition_field = 1, | 
 |   nr_insn_mnemonic_fields = 1, | 
 | }; | 
 |  | 
 | typedef struct _insn_mnemonic_entry insn_mnemonic_entry; | 
 | struct _insn_mnemonic_entry | 
 | { | 
 |   line_ref *line; | 
 |   insn_entry *insn; | 
 |   char *format; | 
 |   char *condition; | 
 |   insn_mnemonic_entry *next; | 
 | }; | 
 |  | 
 |  | 
 |  | 
 | /* Instruction: | 
 |  | 
 |    <insn> ::= | 
 |        <insn-word> { "+" <insn-word> } | 
 |        ":" <format-name> | 
 |        ":" <filter-flags> | 
 |        ":" <options> | 
 |        ":" <name> | 
 |        <nl> | 
 |        { <insn-model> } | 
 |        { <insn-mnemonic> } | 
 |        <code-block> | 
 |  | 
 |  */ | 
 |  | 
 | enum | 
 | { | 
 |   insn_word_field = 0, | 
 |   insn_format_name_field = 1, | 
 |   insn_filter_flags_field = 2, | 
 |   insn_options_field = 3, | 
 |   insn_name_field = 4, | 
 |   nr_insn_fields = 5, | 
 | }; | 
 |  | 
 |  | 
 | /* typedef struct _insn_entry insn_entry; */ | 
 | struct _insn_entry | 
 | { | 
 |   line_ref *line; | 
 |   filter *flags;		/* filtered by options.filters */ | 
 |   char *format_name; | 
 |   filter *options; | 
 |   char *name; | 
 |   /* the words that make up the instruction. Word provides direct | 
 |      access to word N. Pseudo instructions can be identified by | 
 |      nr_words == 0. */ | 
 |   int nr_words; | 
 |   insn_word_entry *words; | 
 |   insn_word_entry **word; | 
 |   /* a set of all the fields from all the words */ | 
 |   filter *field_names; | 
 |   /* an array of processor models, missing models are NULL! */ | 
 |   int nr_models; | 
 |   insn_model_entry *models; | 
 |   insn_model_entry **model; | 
 |   filter *processors; | 
 |   /* list of assember formats */ | 
 |   int nr_mnemonics; | 
 |   insn_mnemonic_entry *mnemonics; | 
 |   /* code body */ | 
 |   table_entry *code; | 
 |   insn_entry *next; | 
 | }; | 
 |  | 
 |  | 
 | /* Instruction table: | 
 |  | 
 |  */ | 
 |  | 
 | typedef struct _insn_table insn_table; | 
 | struct _insn_table | 
 | { | 
 |   cache_entry *caches; | 
 |   int max_nr_words; | 
 |   int nr_insns; | 
 |   insn_entry *insns; | 
 |   function_entry *functions; | 
 |   insn_entry *illegal_insn; | 
 |   model_table *model; | 
 |   filter *options; | 
 |   filter *flags; | 
 | }; | 
 |  | 
 | extern insn_table *load_insn_table (char *file_name, cache_entry *cache); | 
 |  | 
 | typedef void insn_entry_handler | 
 |   (lf *file, insn_table *isa, insn_entry * insn, void *data); | 
 |  | 
 | extern void insn_table_traverse_insn | 
 |   (lf *file, insn_table *isa, insn_entry_handler * handler, void *data); | 
 |  | 
 |  | 
 |  | 
 | /* Printing */ | 
 |  | 
 | extern void print_insn_words (lf *file, insn_entry * insn); | 
 |  | 
 |  | 
 |  | 
 | /* Debugging */ | 
 |  | 
 | void | 
 |   dump_insn_field | 
 |   (lf *file, char *prefix, insn_field_entry *field, char *suffix); | 
 |  | 
 | void | 
 |   dump_insn_word_entry | 
 |   (lf *file, char *prefix, insn_word_entry *word, char *suffix); | 
 |  | 
 | void | 
 |   dump_insn_entry (lf *file, char *prefix, insn_entry * insn, char *suffix); | 
 |  | 
 | void | 
 |   dump_cache_entries | 
 |   (lf *file, char *prefix, cache_entry *entry, char *suffix); | 
 |  | 
 | void dump_insn_table (lf *file, char *prefix, insn_table *isa, char *suffix); |