/*  This file is part of the program psim.

    Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>

    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 2 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, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
    */

/* code-generation options: */

typedef enum {

  /* Transfer control to an instructions semantic code using the the
     standard call/return mechanism */

  generate_calls,

  /* Transfer control to an instructions semantic code using
     (computed) goto's instead of the more conventional call/return
     mechanism */

  generate_jumps,

} igen_code;

typedef enum {
  nia_is_cia_plus_one,
  nia_is_void,
  nia_is_invalid,
} igen_nia;



typedef struct _igen_gen_options igen_gen_options;
struct _igen_gen_options {
  int direct_access;
  int semantic_icache;
  int insn_in_icache;
  int conditional_issue;
  int slot_verification;
  int delayed_branch;

  /* If zeroing a register, which one? */
  int zero_reg;
  int zero_reg_nr;

  /* should multiple simulators be generated? */
  int multi_sim;

  /* name of the default multi-sim model */
  char *default_model;

  /* should the simulator support multi word instructions and if so,
     what is the max nr of words. */
  int multi_word;

  /* SMP?  Should the generated code include SMP support (>0) and if
     so, for how many processors? */
  int smp;

  /* how should the next instruction address be computed? */
  igen_nia nia;

  /* nr of instructions in the decoded instruction cache */
  int icache;
  int icache_size;

  /* see above */
  igen_code code;
};


typedef struct _igen_trace_options igen_trace_options;
struct _igen_trace_options {
  int rule_selection;
  int rule_rejection;
  int insn_insertion;
  int insn_expansion;
  int entries;
  int combine;
};

typedef struct _igen_name {
  char *u;
  char *l;
} igen_name;
typedef struct _igen_module {
  igen_name prefix;
  igen_name suffix;
} igen_module;

typedef struct _igen_module_options {
  igen_module global;
  igen_module engine;
  igen_module icache;
  igen_module idecode;
  igen_module itable;
  igen_module semantics;
  igen_module support;
} igen_module_options;

typedef struct _igen_decode_options igen_decode_options ;
struct _igen_decode_options {

  /* Combine tables?  Should the generator make a second pass through
     each generated table looking for any sub-entries that contain the
     same instructions.  Those entries being merged into a single
     table */
  int combine;

  /* Instruction expansion? Should the semantic code for each
     instruction, when the oportunity arrises, be expanded according
     to the variable opcode files that the instruction decode process
     renders constant */
  int duplicate;

  /* Treat reserved fields as constant (zero) instead of ignoring
     their value when determining decode tables */
  int zero_reserved;

  /* Convert any padded switch rules into goto_switch */
  int switch_as_goto;

  /* Force all tables to be generated with this lookup mechanism */
  char *overriding_gen;
};


typedef struct _igen_warn_options igen_warn_options;
struct _igen_warn_options {

  /* Issue warning about discarded instructions */
  int discard;

  /* Issue warning about invalid instruction widths */
  int width;

  /* Issue warning about unimplemented instructions */
  int unimplemented;

};



typedef struct _igen_options igen_options;
struct _igen_options {

  /* What does the instruction look like - bit ordering, size, widths or
     offesets */
  int hi_bit_nr;
  int insn_bit_size;
  int insn_specifying_widths;

  /* what should global names be prefixed with? */
  igen_module_options module;

  /* See above for options and flags */
  igen_gen_options gen;

  /* See above for trace options */
  igen_trace_options trace;

  /* See above for include options */
  table_include *include;

  /* See above for decode options */
  igen_decode_options decode;

  /* Filter set to be used on the flag field of the instruction table */
  filter *flags_filter;

  /* See above for warn options */
  igen_warn_options warn;

  /* Be more picky about the input */
  error_func (*warning);

  /* Model (processor) set - like flags_filter. Used to select the
     specific ISA within a processor family. */
  filter *model_filter;

  /* Format name set */
  filter *format_name_filter;
};

extern igen_options options;

/* default options - hopefully backward compatible */ \
#define INIT_OPTIONS() \
do { \
  memset (&options, 0, sizeof options); \
  memset (&options.warn, -1, sizeof (options.warn)); \
  options.hi_bit_nr = 0; \
  options.insn_bit_size = default_insn_bit_size; \
  options.insn_specifying_widths = 0; \
  options.module.global.prefix.u = ""; \
  options.module.global.prefix.l = ""; \
  /* the prefixes */ \
  options.module.engine = options.module.global; \
  options.module.icache = options.module.global; \
  options.module.idecode = options.module.global; \
  options.module.itable = options.module.global; \
  options.module.semantics = options.module.global; \
  options.module.support = options.module.global; \
  /* the suffixes */ \
  options.module.engine.suffix.l = "engine"; \
  options.module.engine.suffix.u = "ENGINE"; \
  options.module.icache.suffix.l = "icache"; \
  options.module.icache.suffix.u = "ICACHE"; \
  options.module.idecode.suffix.l = "idecode"; \
  options.module.idecode.suffix.u = "IDECODE"; \
  options.module.itable.suffix.l = "itable"; \
  options.module.itable.suffix.u = "ITABLE"; \
  options.module.semantics.suffix.l = "semantics"; \
  options.module.semantics.suffix.u = "SEMANTICS"; \
  options.module.support.suffix.l = "support"; \
  options.module.support.suffix.u = "SUPPORT"; \
  /* misc stuff */ \
  options.gen.code = generate_calls; \
  options.gen.icache_size = 1024; \
  options.warning = warning; \
} while (0)
