/* 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/>.  */


/* Instruction decode table:

   <decode-rule> ::=
       { <option> }
       ":" [ <first> ]
       ":" [ <last> ]
       ":" [ <force-first> ]
       ":" [ <force-last> ]
       ":" [ <constant-field-names> ]
       ":" [ <word-nr> ]
       ":" [ <format-names> ]
       ":" [ <model-names> ]
       ":" [ <constant> ]
       ":" [ <path> { "," <path> } ]
       { ":" <special-mask>
         ":" [ "!" ] <special-value>
         ":" <word-nr> }
       <nl>
       ;


   <path> ::= <int> "," <int> ;;

   <option> ::=
       <reserved-options>
       | <code-options>
       | <optimize-options>
       | <decode-options>
       | <constant>
       | <search-options>
       ;

   <reserved-options> ::= "zero-reserved" ;
   <gen-options> ::= "array" | "switch" | "padded-switch" | "goto-switch" ;
   <optimize-options> ::= "duplicate" | "combine"
   <decode-options> ::= "normal" | "boolean" ;
   <search-options> ::= "constants" | "variables" | "mixed"

   Ignore the below:


   The instruction decode table contains rules that dictate how igen
   is going to firstly break down the opcode table and secondly

   The table that follows is used by gen to construct a decision tree
   that can identify each possible instruction.  Gen then outputs this
   decision tree as (according to config) a table or switch statement
   as the function idecode.

   In parallel to this, as mentioned above, WITH_EXPANDED_SEMANTICS
   determines of the semantic functions themselves should be expanded
   in a similar way.

   <first>
   <last>

   Range of bits (within the instruction) that should be searched for
   an instruction field.  Within such ranges, gen looks for opcodes
   (constants), registers (strings) and reserved bits (slash) and
   according to the rules that follows includes or excludes them from
   a possible instruction field.

   <force_first>
   <force_last>

   If an instruction field was found, enlarge the field size so that
   it is forced to at least include bits starting from <force_first>
   (<force_last>).  To stop this occuring, use <force_first> = <last>
   + 1 and <force_last> = <first> - 1.

   <force_reserved>

   Treat `/' (reserved) fields as a constant (zero) instead of
   variable when looking for an instruction field.

   <force_expansion>

   Treat any contained register (string) fields as constant when
   determining the instruction field.  For the instruction decode (and
   controled by IDECODE_EXPAND_SEMANTICS) this forces the expansion of
   what would otherwize be non constant bits of an instruction.

   <use_switch>

   Should this table be expanded using a switch statement (val 1) and
   if so, should it be padded with entries so as to force the compiler
   to generate a jump table (val 2). Or a branch table (val 3).

   <special_mask>
   <special_value>
   <special_rule>
   <special_constant>

   Special rule to fine tune how specific (or groups) of instructions
   are expanded.  The applicability of the rule is determined by

     <special_mask> != 0 && (instruction> & <special_mask>) == <special_value>

   Where <instruction> is obtained by looking only at constant fields
   with in an instructions spec.  When determining an expansion, the
   rule is only considered when a node contains a single instruction.
   <special_rule> can be any of:

        0: for this instruction, expand by earlier rules
   	1: expand bits <force_low> .. <force_hi> only
	2: boolean expansion of only zero/non-zero cases
	3: boolean expansion of equality of special constant

	*/


typedef enum
{
  normal_decode_rule,
  boolean_rule,
}
decode_special_type;


typedef enum
{
  invalid_gen,
  array_gen,
  switch_gen,
  padded_switch_gen,
  goto_switch_gen,
}
decode_gen_type;


enum
{
  decode_cond_mask_field,
  decode_cond_value_field,
  decode_cond_word_nr_field,
  nr_decode_cond_fields,
};

typedef struct _decode_path decode_path;
struct _decode_path
{
  int opcode_nr;
  decode_path *parent;
};

typedef struct _decode_path_list decode_path_list;
struct _decode_path_list
{
  decode_path *path;
  decode_path_list *next;
};


typedef struct _decode_cond decode_cond;
struct _decode_cond
{
  int word_nr;
  int mask[max_insn_bit_size];
  int value[max_insn_bit_size];
  int is_equal;
  decode_cond *next;
};

typedef enum
{
  decode_find_mixed,
  decode_find_constants,
  decode_find_strings,
}
decode_search_type;

enum
{
  decode_options_field,
  decode_first_field,
  decode_last_field,
  decode_force_first_field,
  decode_force_last_field,
  decode_constant_field_names_field,
  decode_word_nr_field,
  decode_format_names_field,
  decode_model_names_field,
  decode_paths_field,
  nr_decode_fields,
  min_nr_decode_fields = decode_last_field + 1,
};


typedef struct _decode_table decode_table;
struct _decode_table
{
  line_ref *line;
  decode_special_type type;
  decode_gen_type gen;
  decode_search_type search;
  int first;
  int last;
  int force_first;
  int force_last;
  filter *constant_field_names;
  int word_nr;
  /* if a boolean */
  unsigned constant;
  /* options */
  int with_zero_reserved;
  int with_duplicates;
  int with_combine;
  /* conditions on the rule being applied */
  decode_path_list *paths;
  filter *format_names;
  filter *model_names;
  decode_cond *conditions;
  decode_table *next;
};


extern decode_table *load_decode_table (char *file_name);

extern int decode_table_max_word_nr (decode_table *rule);

extern void dump_decode_rule
  (lf *file, char *prefix, decode_table *rule, char *suffix);
