/* The IGEN simulator generator for GDB, the GNU Debugger.

   Copyright 2002-2025 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/>.  */

#ifndef IGEN_LD_DECODE_H
#define IGEN_LD_DECODE_H

/* 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 occurring, 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
   controlled 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 (const char *file_name);

extern int decode_table_max_word_nr (const decode_table *rule);

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

#endif /* IGEN_LD_DECODE_H */
