/* Declarations for interface to insn recognizer and insn-output.cc.
   Copyright (C) 1987-2026 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_RECOG_H
#define GCC_RECOG_H

/* For enum tree_code ERROR_MARK.  */
#include "tree.h"

/* Random number that should be large enough for all purposes.  Also define
   a type that has at least MAX_RECOG_ALTERNATIVES + 1 bits, with the extra
   bit giving an invalid value that can be used to mean "uninitialized".  */
#define MAX_RECOG_ALTERNATIVES 35
typedef uint64_t alternative_mask;  /* Keep in sync with genattrtab.cc.  */

/* A mask of all alternatives.  */
#define ALL_ALTERNATIVES ((alternative_mask) -1)

/* A mask containing just alternative X.  */
#define ALTERNATIVE_BIT(X) ((alternative_mask) 1 << (X))

/* Types of operands.  */
enum op_type {
  OP_IN,
  OP_OUT,
  OP_INOUT
};

#ifndef GENERATOR_FILE
struct operand_alternative
{
  /* Pointer to the beginning of the constraint string for this alternative,
     for easier access by alternative number.  */
  const char *constraint;

  /* The register class valid for this alternative (possibly NO_REGS).  */
  ENUM_BITFIELD (reg_class) cl : 16;

  /* "Badness" of this alternative, computed from number of '?' and '!'
     characters in the constraint string.  */
  unsigned int reject : 16;

  /* -1 if no matching constraint was found, or an operand number.  */
  int matches : 8;
  /* The same information, but reversed: -1 if this operand is not
     matched by any other, or the operand number of the operand that
     matches this one.  */
  int matched : 8;

  /* Bit ID is set if the constraint string includes a register constraint with
     register filter ID.  Use test_register_filters (REGISTER_FILTERS, REGNO)
     to test whether REGNO is a valid start register for the operand.  */
  unsigned int register_filters : MAX (NUM_REGISTER_FILTERS, 1);

  /* Nonzero if '&' was found in the constraint string.  */
  unsigned int earlyclobber : 1;
  /* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint
     string.  */
  unsigned int memory_ok : 1;
  /* Nonzero if 'p' was found in the constraint string.  */
  unsigned int is_address : 1;
  /* Nonzero if 'X' was found in the constraint string, or if the constraint
     string for this alternative was empty.  */
  unsigned int anything_ok : 1;
};

/* Return the class for operand I of alternative ALT, taking matching
   constraints into account.  */

inline enum reg_class
alternative_class (const operand_alternative *alt, int i)
{
  return alt[i].matches >= 0 ? alt[alt[i].matches].cl : alt[i].cl;
}

/* Return the mask of register filters that should be applied to operand I
   of alternative ALT, taking matching constraints into account.  */

inline unsigned int
alternative_register_filters (const operand_alternative *alt, int i)
{
  return (alt[i].matches >= 0
	  ? alt[alt[i].matches].register_filters
	  : alt[i].register_filters);
}
#endif

/* A class for substituting one rtx for another within an instruction,
   or for recursively simplifying the instruction as-is.  Derived classes
   can record or filter certain decisions.  */

class insn_propagation : public simplify_context
{
public:
  /* Assignments for RESULT_FLAGS.

     UNSIMPLIFIED is true if a substitution has been made inside an rtx
     X and if neither X nor its parent expressions could be simplified.

     FIRST_SPARE_RESULT is the first flag available for derived classes.  */
  static const uint16_t UNSIMPLIFIED = 1U << 0;
  static const uint16_t FIRST_SPARE_RESULT = 1U << 1;

  insn_propagation (rtx_insn *);
  insn_propagation (rtx_insn *, rtx, rtx, bool = true);
  bool apply_to_pattern (rtx *);
  bool apply_to_rvalue (rtx *);
  bool apply_to_note (rtx *);

  /* Return true if we should accept a substitution into the address of
     memory expression MEM.  Undoing changes OLD_NUM_CHANGES and up restores
     MEM's original address.  */
  virtual bool check_mem (int /*old_num_changes*/,
			  rtx /*mem*/) { return true; }

  /* Note that we've simplified OLD_RTX into NEW_RTX.  When substituting,
     this only happens if a substitution occured within OLD_RTX.
     Undoing OLD_NUM_CHANGES and up will restore the old form of OLD_RTX.
     OLD_RESULT_FLAGS is the value that RESULT_FLAGS had before processing
     OLD_RTX.  */
  virtual void note_simplification (int /*old_num_changes*/,
				    uint16_t /*old_result_flags*/,
				    rtx /*old_rtx*/, rtx /*new_rtx*/) {}

private:
  bool apply_to_mem_1 (rtx);
  bool apply_to_lvalue_1 (rtx);
  bool apply_to_rvalue_1 (rtx *);
  bool apply_to_pattern_1 (rtx *);

public:
  /* The instruction that we are simplifying or propagating into.  */
  rtx_insn *insn;

  /* If FROM is nonnull, we're replacing FROM with TO, otherwise we're
     just doing a recursive simplification.  */
  rtx from;
  rtx to;

  /* The number of times that we have replaced FROM with TO.  */
  unsigned int num_replacements;

  /* A bitmask of flags that describe the result of the simplificiation;
     see above for details.  */
  uint16_t result_flags : 16;

  /* True if we should unshare TO when making the next substitution,
     false if we can use TO itself.  */
  uint16_t should_unshare : 1;

  /* True if we should call check_mem after substituting into a memory.  */
  uint16_t should_check_mems : 1;

  /* True if we should call note_simplification after each simplification.  */
  uint16_t should_note_simplifications : 1;

  /* For future expansion.  */
  uint16_t spare : 13;

  /* Gives the reason that a substitution failed, for debug purposes.  */
  const char *failure_reason;
};

/* Try to replace FROM with TO in INSN.  SHARED_P is true if TO is shared
   with other instructions, false if INSN can use TO directly.  */

inline insn_propagation::insn_propagation (rtx_insn *insn, rtx from, rtx to,
					   bool shared_p)
  : insn (insn),
    from (from),
    to (to),
    num_replacements (0),
    result_flags (0),
    should_unshare (shared_p),
    should_check_mems (false),
    should_note_simplifications (false),
    spare (0),
    failure_reason (nullptr)
{
}

/* Try to simplify INSN without performing a substitution.  */

inline insn_propagation::insn_propagation (rtx_insn *insn)
  : insn_propagation (insn, NULL_RTX, NULL_RTX)
{
}

/* An RAII class that temporarily undoes part of the current change group.
   The sequence:

     {
       ...;
       undo_recog_changes undo (NUM);
       STMTS;
     }

   executes STMTS with all the changes numbered NUM and up temporarily
   reverted.  STMTS must not try to add to the current change group.

   Nested uses are supported, but each nested NUM must be no greater than
   outer NUMs.  */

class undo_recog_changes
{
public:
  undo_recog_changes (int);
  ~undo_recog_changes ();

  static bool is_active () { return s_num_changes != 0; }

private:
  int m_old_num_changes;

  static int s_num_changes;
};

extern void init_recog (void);
extern void init_recog_no_volatile (void);
extern bool check_asm_operands (rtx);
extern int asm_operand_ok (rtx, const char *, const char **);
extern bool validate_change (rtx, rtx *, rtx, bool);
extern bool validate_unshare_change (rtx, rtx *, rtx, bool);
extern bool validate_change_xveclen (rtx, rtx *, int, bool);
extern bool canonicalize_change_group (rtx_insn *insn, rtx x);
extern bool insn_invalid_p (rtx_insn *, bool);
extern bool verify_changes (int);
extern void confirm_change_group (void);
extern bool apply_change_group (void);
extern int num_validated_changes (void);
extern void cancel_changes (int);
extern bool constrain_operands (int, alternative_mask);
extern bool constrain_operands_cached (rtx_insn *, int);
extern bool memory_address_addr_space_p (machine_mode, rtx, addr_space_t,
					 code_helper = ERROR_MARK);
#define memory_address_p(mode,addr) \
	memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
extern bool strict_memory_address_addr_space_p (machine_mode, rtx, addr_space_t,
						code_helper = ERROR_MARK);
#define strict_memory_address_p(mode,addr) \
	strict_memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
extern bool validate_replace_rtx_subexp (rtx, rtx, rtx_insn *, rtx *);
extern bool validate_replace_rtx (rtx, rtx, rtx_insn *);
extern bool validate_replace_rtx_part (rtx, rtx, rtx *, rtx_insn *);
extern bool validate_replace_rtx_part_nosimplify (rtx, rtx, rtx *, rtx_insn *);
extern void validate_replace_rtx_group (rtx, rtx, rtx_insn *);
extern void validate_replace_src_group (rtx, rtx, rtx_insn *);
extern bool validate_simplify_insn (rtx_insn *insn);
extern int num_changes_pending (void);
extern bool reg_fits_class_p (const_rtx, reg_class_t, int, machine_mode);
extern bool valid_insn_p (rtx_insn *);

extern bool offsettable_memref_p (rtx);
extern bool offsettable_nonstrict_memref_p (rtx);
extern bool offsettable_address_addr_space_p (int, machine_mode, rtx,
					     addr_space_t);
#define offsettable_address_p(strict,mode,addr) \
	offsettable_address_addr_space_p ((strict), (mode), (addr), \
					  ADDR_SPACE_GENERIC)
extern bool mode_dependent_address_p (rtx, addr_space_t);

extern int recog (rtx, rtx_insn *, int *);
#ifndef GENERATOR_FILE
inline int recog_memoized (rtx_insn *insn);
#endif
extern void add_clobbers (rtx, int);
extern bool added_clobbers_hard_reg_p (int);
extern void insn_extract (rtx_insn *);
extern void extract_insn (rtx_insn *);
extern void extract_constrain_insn (rtx_insn *insn);
extern void extract_constrain_insn_cached (rtx_insn *);
extern void extract_insn_cached (rtx_insn *);
#ifndef GENERATOR_FILE
extern void preprocess_constraints (int, int, const char **,
				    operand_alternative *, rtx **);
extern const operand_alternative *preprocess_insn_constraints (unsigned int);
#endif
extern void preprocess_constraints (rtx_insn *);
extern rtx_insn *peep2_next_insn (int);
extern bool peep2_regno_dead_p (int, int);
extern bool peep2_reg_dead_p (int, rtx);
#ifdef HARD_CONST
extern rtx peep2_find_free_register (int, int, const char *,
				     machine_mode, HARD_REG_SET *);
#endif
extern rtx_insn *peephole2_insns (rtx, rtx_insn *, int *);

extern bool store_data_bypass_p (rtx_insn *, rtx_insn *);
extern bool if_test_bypass_p (rtx_insn *, rtx_insn *);

extern void copy_frame_info_to_split_insn (rtx_insn *, rtx_insn *);

#ifndef GENERATOR_FILE
/* Try recognizing the instruction INSN,
   and return the code number that results.
   Remember the code so that repeated calls do not
   need to spend the time for actual rerecognition.

   This function is the normal interface to instruction recognition.
   The automatically-generated function `recog' is normally called
   through this one.  */

inline int
recog_memoized (rtx_insn *insn)
{
  if (INSN_CODE (insn) < 0)
    INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
  return INSN_CODE (insn);
}
#endif

/* Skip chars until the next ',' or the end of the string.  This is
   useful to skip alternatives in a constraint string.  */
inline const char *
skip_alternative (const char *p)
{
  const char *r = p;
  while (*r != '\0' && *r != ',')
    r++;
  if (*r == ',')
    r++;
  return r;
}

/* Nonzero means volatile operands are recognized.  */
extern int volatile_ok;

/* RAII class for temporarily setting volatile_ok.  */

class temporary_volatile_ok
{
public:
  temporary_volatile_ok (int value) : save_volatile_ok (volatile_ok)
  {
    volatile_ok = value;
  }

  ~temporary_volatile_ok () { volatile_ok = save_volatile_ok; }

private:
  temporary_volatile_ok (const temporary_volatile_ok &);
  int save_volatile_ok;
};

/* Set by constrain_operands to the number of the alternative that
   matched.  */
extern int which_alternative;

/* True for inline asm operands with - constraint modifier.  */
extern bool raw_constraint_p;

/* The following vectors hold the results from insn_extract.  */

struct recog_data_d
{
  /* It is very tempting to make the 5 operand related arrays into a
     structure and index on that.  However, to be source compatible
     with all of the existing md file insn constraints and output
     templates, we need `operand' as a flat array.  Without that
     member, making an array for the rest seems pointless.  */

  /* Gives value of operand N.  */
  rtx operand[MAX_RECOG_OPERANDS];

  /* Gives location where operand N was found.  */
  rtx *operand_loc[MAX_RECOG_OPERANDS];

  /* Gives the constraint string for operand N.  */
  const char *constraints[MAX_RECOG_OPERANDS];

  /* Nonzero if operand N is a match_operator or a match_parallel.  */
  char is_operator[MAX_RECOG_OPERANDS];

  /* Gives the mode of operand N.  */
  machine_mode operand_mode[MAX_RECOG_OPERANDS];

  /* Gives the type (in, out, inout) for operand N.  */
  enum op_type operand_type[MAX_RECOG_OPERANDS];

  /* Gives location where the Nth duplicate-appearance of an operand
     was found.  This is something that matched MATCH_DUP.  */
  rtx *dup_loc[MAX_DUP_OPERANDS];

  /* Gives the operand number that was duplicated in the Nth
     duplicate-appearance of an operand.  */
  char dup_num[MAX_DUP_OPERANDS];

  /* ??? Note that these are `char' instead of `unsigned char' to (try to)
     avoid certain lossage from K&R C, wherein `unsigned char' default
     promotes to `unsigned int' instead of `int' as in ISO C.  As of 1999,
     the most common places to bootstrap from K&R C are SunOS and HPUX,
     both of which have signed characters by default.  The only other
     supported natives that have both K&R C and unsigned characters are
     ROMP and Irix 3, and neither have been seen for a while, but do
     continue to consider unsignedness when performing arithmetic inside
     a comparison.  */

  /* The number of operands of the insn.  */
  char n_operands;

  /* The number of MATCH_DUPs in the insn.  */
  char n_dups;

  /* The number of alternatives in the constraints for the insn.  */
  char n_alternatives;

  /* True if insn is ASM_OPERANDS.  */
  bool is_asm;

  /* In case we are caching, hold insn data was generated for.  */
  rtx_insn *insn;
};

extern struct recog_data_d recog_data;

/* RAII class for saving/restoring recog_data.  */

class recog_data_saver
{
  recog_data_d m_saved_data;
public:
  recog_data_saver () : m_saved_data (recog_data) {}
  ~recog_data_saver () { recog_data = m_saved_data; }
};

#ifndef GENERATOR_FILE
extern const operand_alternative *recog_op_alt;

/* Return a pointer to an array in which index OP describes the constraints
   on operand OP of the current instruction alternative (which_alternative).
   Only valid after calling preprocess_constraints and constrain_operands.  */

inline const operand_alternative *
which_op_alt ()
{
  gcc_checking_assert (IN_RANGE (which_alternative, 0,
				 recog_data.n_alternatives - 1));
  return &recog_op_alt[which_alternative * recog_data.n_operands];
}
#endif

/* A table defined in insn-output.cc that give information about
   each insn-code value.  */

typedef bool (*insn_operand_predicate_fn) (rtx, machine_mode);
typedef const char * (*insn_output_fn) (rtx *, rtx_insn *);

struct insn_gen_fn
{
  typedef void (*stored_funcptr) (void);

  template<typename ...Ts>
  rtx_insn *operator() (Ts... args) const
  {
    typedef rtx_insn *(*funcptr) (decltype ((void) args, NULL_RTX)...);
    return ((funcptr) func) (args...);
  }

  // This is for compatibility of code that invokes functions like
  //   (*funcptr) (arg)
  insn_gen_fn operator * (void) const { return *this; }

  // The wrapped function pointer must be public and there must not be any
  // constructors.  Otherwise the insn_data_d struct initializers generated
  // by genoutput.cc will result in static initializer functions, which defeats
  // the purpose of the generated insn_data_d array.
  stored_funcptr func;
};

struct insn_operand_data
{
  const insn_operand_predicate_fn predicate;

  const char *const constraint;

  ENUM_BITFIELD(machine_mode) const mode : 16;

  const char strict_low;

  const char is_operator;

  const char eliminable;

  const char allows_mem;
};

/* Legal values for insn_data.output_format.  Indicate what type of data
   is stored in insn_data.output.  */
#define INSN_OUTPUT_FORMAT_NONE		0	/* abort */
#define INSN_OUTPUT_FORMAT_SINGLE	1	/* const char * */
#define INSN_OUTPUT_FORMAT_MULTI	2	/* const char * const * */
#define INSN_OUTPUT_FORMAT_FUNCTION	3	/* const char * (*)(...) */

struct insn_data_d
{
  const char *const name;
#if HAVE_DESIGNATED_UNION_INITIALIZERS
  union {
    const char *single;
    const char *const *multi;
    insn_output_fn function;
  } output;
#else
  struct {
    const char *single;
    const char *const *multi;
    insn_output_fn function;
  } output;
#endif
  const insn_gen_fn genfun;
  const struct insn_operand_data *const operand;

  const char n_generator_args;
  const char n_operands;
  const char n_dups;
  const char n_alternatives;
  const char output_format;
};

extern const struct insn_data_d insn_data[];
extern int peep2_current_count;

#ifndef GENERATOR_FILE
#include "insn-codes.h"

/* An enum of boolean attributes that may only depend on the current
   subtarget, not on things like operands or compiler phase.  */
enum bool_attr {
  BA_ENABLED,
  BA_PREFERRED_FOR_SPEED,
  BA_PREFERRED_FOR_SIZE,
  BA_LAST = BA_PREFERRED_FOR_SIZE
};

/* Target-dependent globals.  */
struct target_recog {
  bool x_initialized;
  alternative_mask x_bool_attr_masks[NUM_INSN_CODES][BA_LAST + 1];
  operand_alternative *x_op_alt[NUM_INSN_CODES];
};

extern struct target_recog default_target_recog;
#if SWITCHABLE_TARGET
extern struct target_recog *this_target_recog;
#else
#define this_target_recog (&default_target_recog)
#endif

alternative_mask get_enabled_alternatives (rtx_insn *);
alternative_mask get_preferred_alternatives (rtx_insn *);
alternative_mask get_preferred_alternatives (rtx_insn *, basic_block);
bool check_bool_attrs (rtx_insn *);

void recog_init ();

/* This RAII class can help to undo tentative insn changes on failure.
   When an object of the class goes out of scope, it undoes all group
   changes that have been made via the validate_change machinery and
   not yet confirmed via confirm_change_group.

   For example:

      insn_change_watermark watermark;
      validate_change (..., true); // A
      ...
      if (test)
	// Undoes change A.
	return false;
      ...
      validate_change (..., true); // B
      ...
      if (test)
	// Undoes changes A and B.
	return false;
      ...
      confirm_change_group ();

   Code that wants to avoid this behavior can use keep ():

      insn_change_watermark watermark;
      validate_change (..., true); // A
      ...
      if (test)
	// Undoes change A.
	return false;
      ...
      watermark.keep ();
      validate_change (..., true); // B
      ...
      if (test)
	// Undoes change B, but not A.
	return false;
      ...
      confirm_change_group ();  */
class insn_change_watermark
{
public:
  insn_change_watermark () : m_old_num_changes (num_validated_changes ()) {}
  ~insn_change_watermark ();
  void keep () { m_old_num_changes = num_validated_changes (); }

private:
  int m_old_num_changes;
};

inline insn_change_watermark::~insn_change_watermark ()
{
  if (m_old_num_changes < num_validated_changes ())
    cancel_changes (m_old_num_changes);
}

#endif

#endif /* GCC_RECOG_H */
