/*
 * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_ADLC_FORMSSEL_HPP
#define SHARE_ADLC_FORMSSEL_HPP

// FORMSSEL.HPP - ADL Parser Instruction Selection Forms Classes

// Class List
class Form;
class InstructForm;
class MachNodeForm;
class OperandForm;
class OpClassForm;
class AttributeForm;
class RegisterForm;
class PipelineForm;
class SourceForm;
class EncodeForm;
class Component;
class Constraint;
class Predicate;
class MatchRule;
class Attribute;
class Effect;
class ExpandRule;
class Flag;
class RewriteRule;
class ConstructRule;
class FormatRule;
class Peephole;
class EncClass;
class Interface;
class RegInterface;
class ConstInterface;
class MemInterface;
class CondInterface;
class Opcode;
class InsEncode;
class RegDef;
class RegClass;
class CodeSnippetRegClass;
class ConditionalRegClass;
class AllocClass;
class ResourceForm;
class PipeDesc;
class PipeClass;
class PeepMatch;
class PeepConstraint;
class PeepReplace;
class MatchList;

class ArchDesc;

//==============================Instructions===================================
//------------------------------InstructForm-----------------------------------
class InstructForm : public Form {
private:
  bool           _ideal_only;       // Not a user-defined instruction
  // Members used for tracking CISC-spilling
  int            _cisc_spill_operand;// Which operand may cisc-spill
  void           set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; }
  bool           _is_cisc_alternate;
  InstructForm  *_cisc_spill_alternate;// cisc possible replacement
  const char    *_cisc_reg_mask_name;
  InstructForm  *_short_branch_form;
  bool           _is_short_branch;
  bool           _is_mach_constant;    // True if Node is a MachConstantNode.
  bool           _needs_constant_base; // True if Node needs the mach_constant_base input.
  uint           _alignment;

public:
  // Public Data
  const char    *_ident;               // Name of this instruction
  NameList       _parameters;          // Locally defined names
  FormDict       _localNames;          // Table of operands & their types
  MatchRule     *_matrule;             // Matching rule for this instruction
  Opcode        *_opcode;              // Encoding of the opcode for instruction
  char          *_size;                // Size of instruction
  InsEncode     *_insencode;           // Encoding class instruction belongs to
  InsEncode     *_constant;            // Encoding class constant value belongs to
  bool           _is_postalloc_expand; // Indicates that encoding just does a lateExpand.
  Attribute     *_attribs;             // List of Attribute rules
  Predicate     *_predicate;           // Predicate test for this instruction
  FormDict       _effects;             // Dictionary of effect rules
  ExpandRule    *_exprule;             // Expand rule for this instruction
  RewriteRule   *_rewrule;             // Rewrite rule for this instruction
  FormatRule    *_format;              // Format for assembly generation
  Peephole      *_peephole;            // List of peephole rules for instruction
  const char    *_ins_pipe;            // Instruction Scheduling description class
  Flag          *_flag;               // List of Flags that should be set by default for this node

  uint          *_uniq_idx;            // Indexes of unique operands
  uint           _uniq_idx_length;     // Length of _uniq_idx array
  uint           _num_uniq;            // Number  of unique operands
  ComponentList  _components;          // List of Components matches MachNode's
                                       // operand structure

  bool           _has_call;            // contain a call and caller save registers should be saved?

  // Public Methods
  InstructForm(const char *id, bool ideal_only = false);
  InstructForm(const char *id, InstructForm *instr, MatchRule *rule);
  ~InstructForm();

  // Dynamic type check
  virtual InstructForm *is_instruction() const;

  virtual bool        ideal_only() const;

  // This instruction sets a result
  virtual bool        sets_result() const;
  // This instruction needs projections for additional DEFs or KILLs
  virtual bool        needs_projections();
  // This instruction needs extra nodes for temporary inputs
  virtual bool        has_temps();
  // This instruction defines or kills more than one object
  virtual uint        num_defs_or_kills();
  // This instruction has an expand rule?
  virtual bool        expands() const ;
  // This instruction has a late expand rule?
  virtual bool        postalloc_expands() const;
  // Return this instruction's first peephole rule, or null
  virtual Peephole   *peepholes() const;
  // Add a peephole rule to this instruction
  virtual void        append_peephole(Peephole *peep);

  virtual bool        is_pinned(FormDict &globals); // should be pinned inside block
  virtual bool        is_projection(FormDict &globals); // node requires projection
  virtual bool        is_parm(FormDict &globals); // node matches ideal 'Parm'
  // ideal opcode enumeration
  virtual const char *ideal_Opcode(FormDict &globals)  const;
  virtual int         is_expensive() const;     // node matches ideal 'CosD'
  virtual int         is_empty_encoding() const; // _size=0 and/or _insencode empty
  virtual int         is_tls_instruction() const; // tlsLoadP rule or ideal ThreadLocal
  virtual int         is_ideal_copy() const;    // node matches ideal 'Copy*'
  virtual bool        is_ideal_negD() const;    // node matches ideal 'NegD'
  virtual bool        is_ideal_if()   const;    // node matches ideal 'If'
  virtual bool        is_ideal_fastlock() const; // node matches 'FastLock'
  virtual bool        is_ideal_membar() const;  // node matches ideal 'MemBarXXX'
  virtual bool        is_ideal_loadPC() const;  // node matches ideal 'LoadPC'
  virtual bool        is_ideal_box() const;     // node matches ideal 'Box'
  virtual bool        is_ideal_goto() const;    // node matches ideal 'Goto'
  virtual bool        is_ideal_branch() const;  // "" 'If' | 'Goto' | 'LoopEnd' | 'Jump'
  virtual bool        is_ideal_jump() const;    // node matches ideal 'Jump'
  virtual bool        is_ideal_return() const;  // node matches ideal 'Return'
  virtual bool        is_ideal_halt() const;    // node matches ideal 'Halt'
  virtual bool        is_ideal_safepoint() const; // node matches 'SafePoint'
  virtual bool        is_ideal_nop() const;     // node matches 'Nop'
  virtual bool        is_ideal_control() const; // control node
  virtual bool        is_vector() const;        // vector instruction

  virtual Form::CallType is_ideal_call() const; // matches ideal 'Call'
  virtual Form::DataType is_ideal_load() const; // node matches ideal 'LoadXNode'
  // Should antidep checks be disabled for this Instruct
  // See definition of MatchRule::skip_antidep_check
  bool skip_antidep_check() const;
  virtual Form::DataType is_ideal_store() const;// node matches ideal 'StoreXNode'
          bool        is_ideal_mem() const { return is_ideal_load() != Form::none || is_ideal_store() != Form::none; }
  virtual uint        two_address(FormDict &globals); // output reg must match input reg
  // when chaining a constant to an instruction, return 'true' and set opType
  virtual Form::DataType is_chain_of_constant(FormDict &globals);
  virtual Form::DataType is_chain_of_constant(FormDict &globals, const char * &opType);
  virtual Form::DataType is_chain_of_constant(FormDict &globals, const char * &opType, const char * &result_type);

  // Check if a simple chain rule
  virtual bool        is_simple_chain_rule(FormDict &globals) const;

  // check for structural rematerialization
  virtual bool        rematerialize(FormDict &globals, RegisterForm *registers);

  // loads from memory, so must check for anti-dependence
  virtual bool        needs_anti_dependence_check(FormDict &globals) const;
  virtual int         memory_operand(FormDict &globals) const;

  enum memory_operand_type {
    NO_MEMORY_OPERAND = -1,
    MANY_MEMORY_OPERANDS = 999999
  };


  // This instruction captures the machine-independent bottom_type
  // Expected use is for pointer vs oop determination for LoadP
  virtual bool        captures_bottom_type(FormDict& globals) const;

  virtual const char *cost();      // Access ins_cost attribute
  virtual uint        num_opnds(); // Count of num_opnds for MachNode class
                                   // Counts USE_DEF opnds twice.  See also num_unique_opnds().
  virtual uint        num_post_match_opnds();
  virtual uint        num_consts(FormDict &globals) const;// Constants in match rule
  // Constants in match rule with specified type
  virtual uint        num_consts(FormDict &globals, Form::DataType type) const;

  // Return the register class associated with 'leaf'.
  virtual const char *out_reg_class(FormDict &globals);

  // number of ideal node inputs to skip
  virtual uint        oper_input_base(FormDict &globals);

  // Does this instruction need a base-oop edge?
  int needs_base_oop_edge(FormDict &globals) const;

  // Build instruction predicates.  If the user uses the same operand name
  // twice, we need to check that the operands are pointer-eequivalent in
  // the DFA during the labeling process.
  Predicate *build_predicate();

  virtual void        build_components(); // top-level operands
  // Return zero-based position in component list; -1 if not in list.
  virtual int         operand_position(const char *name, int usedef);
  virtual int         operand_position_format(const char *name);

  // Return zero-based position in component list; -1 if not in list.
  virtual int         label_position();
  virtual int         method_position();
  // Return number of relocation entries needed for this instruction.
  virtual uint        reloc(FormDict &globals);

  const char         *opnd_ident(int idx);  // Name of operand #idx.
  const char         *reduce_result();
  // Return the name of the operand on the right hand side of the binary match
  // Return null if there is no right hand side
  const char         *reduce_right(FormDict &globals)  const;
  const char         *reduce_left(FormDict &globals)   const;

  // Base class for this instruction, MachNode except for calls
  virtual const char *mach_base_class(FormDict &globals)  const;

  // Check if this instruction can cisc-spill to 'alternate'
  bool                cisc_spills_to(ArchDesc &AD, InstructForm *alternate);
  InstructForm       *cisc_spill_alternate() { return _cisc_spill_alternate; }
  int                 cisc_spill_operand() const { return _cisc_spill_operand; }
  bool                is_cisc_alternate() const { return _is_cisc_alternate; }
  void                set_cisc_alternate(bool val) { _is_cisc_alternate = val; }
  const char         *cisc_reg_mask_name() const { return _cisc_reg_mask_name; }
  void                set_cisc_reg_mask_name(const char *rm_name) { _cisc_reg_mask_name = rm_name; }
  // Output cisc-method prototypes and method bodies
  void                declare_cisc_version(ArchDesc &AD, FILE *fp_cpp);
  void                define_cisc_version(ArchDesc& AD, FILE* fp_cpp);

  bool                check_branch_variant(ArchDesc &AD, InstructForm *short_branch);

  bool                is_short_branch() { return _is_short_branch; }
  void                set_short_branch(bool val) { _is_short_branch = val; }

  bool                    is_mach_constant() const { return _is_mach_constant;     }
  void                set_is_mach_constant(bool x) {        _is_mach_constant = x; }
  bool                    needs_constant_base() const { return _needs_constant_base;     }
  void                set_needs_constant_base(bool x) {        _needs_constant_base = x; }

  InstructForm       *short_branch_form() { return _short_branch_form; }
  bool                has_short_branch_form() { return _short_branch_form != nullptr; }
  // Output short branch prototypes and method bodies
  void                declare_short_branch_methods(FILE *fp_cpp);
  void                define_short_branch_methods(ArchDesc& AD, FILE* fp_cpp);

  uint                alignment() { return _alignment; }
  void                set_alignment(uint val) { _alignment = val; }

  // Search through operands to determine operands unique positions.
  void                set_unique_opnds();
  uint                num_unique_opnds() { return _num_uniq; }
  uint                unique_opnds_idx(int idx) {
    if (_uniq_idx != nullptr && idx > 0) {
      assert((uint)idx < _uniq_idx_length, "out of bounds");
      return _uniq_idx[idx];
    } else {
      return idx;
    }
  }
  const char         *unique_opnd_ident(uint idx);  // Name of operand at unique idx.

  // Operands which are only KILLs aren't part of the input array and
  // require special handling in some cases.  Their position in this
  // operand list is higher than the number of unique operands.
  bool is_noninput_operand(uint idx) {
    return (idx >= num_unique_opnds());
  }

  // --------------------------- FILE *output_routines
  //
  // Generate the format call for the replacement variable
  void                rep_var_format(FILE *fp, const char *rep_var);
  // Generate index values needed for determining the operand position
  void                index_temps   (FILE *fp, FormDict &globals, const char *prefix = "", const char *receiver = "");
  // ---------------------------

  virtual bool verify();           // Check consistency after parsing

  virtual void dump();             // Debug printer
  virtual void output(FILE *fp);   // Write to output files
  virtual void forms_do(FormClosure *f);
};

//------------------------------EncodeForm-------------------------------------
class EncodeForm : public Form {
private:

public:
  // Public Data
  NameList  _eclasses;            // List of encode class names
  Dict      _encClass;            // Map encode class names to EncClass objects

  // Public Methods
  EncodeForm();
  ~EncodeForm();

  EncClass   *add_EncClass(const char *className);
  EncClass   *encClass(const char *className);

  const char *encClassPrototype(const char *className);
  const char *encClassBody(const char *className);

  void dump();                     // Debug printer
  void output(FILE *fp);           // Write info to output files
  virtual void forms_do(FormClosure *f);
};

//------------------------------EncClass---------------------------------------
class EncClass : public Form {
public:
  // NameList for parameter type and name
  NameList       _parameter_type;
  NameList       _parameter_name;

  // Breakdown the encoding into strings separated by $replacement_variables
  // There is an entry in _strings, perhaps null, that precedes each _rep_vars
  NameList       _code;            // Strings passed through to tty->print
  NameList       _rep_vars;        // replacement variables

  NameList       _parameters;      // Locally defined names
  FormDict       _localNames;      // Table of components & their types

public:
  // Public Data
  const char    *_name;            // encoding class name

  // Public Methods
  EncClass(const char *name);
  ~EncClass();

  // --------------------------- Parameters
  // Add a parameter <type,name> pair
  void add_parameter(const char *parameter_type, const char *parameter_name);
  // Verify operand types in parameter list
  bool check_parameter_types(FormDict &globals);
  // Obtain the zero-based index corresponding to a replacement variable
  int         rep_var_index(const char *rep_var);
  int         num_args() { return _parameter_name.count(); }

  // --------------------------- Code Block
  // Add code
  void add_code(const char *string_preceding_replacement_var);
  // Add a replacement variable or one of its subfields
  // Subfields are stored with a leading '$'
  void add_rep_var(char *replacement_var);

  bool verify();
  void dump();
  void output(FILE *fp);
  virtual void forms_do(FormClosure* f);
};

//------------------------------MachNode---------------------------------------
class MachNodeForm: public Form {
private:

public:
  char          *_ident;           // Name of this instruction
  const char    *_machnode_pipe;   // Instruction Scheduline description class

  // Public Methods
  MachNodeForm(char *id);
  ~MachNodeForm();

  virtual MachNodeForm *is_machnode() const;

  void dump();                     // Debug printer
  void output(FILE *fp);           // Write info to output files
};

//------------------------------Opcode-----------------------------------------
class Opcode : public Form {
private:

public:
  // Public Data
  // Strings representing instruction opcodes, user defines placement in emit
  char *_primary;
  char *_secondary;
  char *_tertiary;

  enum opcode_type {
    NOT_AN_OPCODE = -1,
    PRIMARY   = 1,
    SECONDARY = 2,
    TERTIARY  = 3
  };

  // Public Methods
  Opcode(char *primary, char *secondary, char *tertiary);
  ~Opcode();

  static Opcode::opcode_type as_opcode_type(const char *designator);

  void dump();
  void output(FILE *fp);

  // --------------------------- FILE *output_routines
  bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
};

//------------------------------InsEncode--------------------------------------
class InsEncode : public Form {
private:
  // Public Data (access directly only for reads)
  // The encodings can only have the values predefined by the ADLC:
  // blank, RegReg, RegMem, MemReg, ...
  NameList    _encoding;
  // NameList    _parameter;
  // The parameters for each encoding are preceded by a NameList::_signal
  // and follow the parameters for the previous encoding.

  // char *_encode;                  // Type of instruction encoding

public:
  // Public Methods
  InsEncode();
  ~InsEncode();

  // Add "encode class name" and its parameters
  NameAndList  *add_encode(char *encode_method_name);
  // Parameters are added to the returned "NameAndList" by the parser

  // Access the list of encodings
  void          reset();
  const char   *encode_class_iter();

  // Returns the number of arguments to the current encoding in the iteration
  int current_encoding_num_args() {
    return ((NameAndList*)_encoding.current())->count();
  }

  // --------------------------- Parameters
  // The following call depends upon position within encode_class_iteration
  //
  // Obtain parameter name from zero based index
  const char   *rep_var_name(InstructForm &inst, uint param_no);
  // ---------------------------

  void dump();
  void output(FILE *fp);
  virtual void forms_do(FormClosure *f);
};

//------------------------------Effect-----------------------------------------
class Effect : public Form {
private:

public:
  // Public Data
  const char  *_name;            // Pre-defined name for effect
  int         _use_def;          // Enumeration value of effect

  // Public Methods
  Effect(const char *name);      // Constructor
  ~Effect();                     // Destructor

  // Dynamic type check
  virtual Effect *is_effect() const;

  // Return 'true' if this use def info equals the parameter
  bool  is(int use_def_kill_enum) const;
  // Return 'true' if this use def info is a superset of parameter
  bool  isa(int use_def_kill_enum) const;

  void dump();                   // Debug printer
  void output(FILE *fp);         // Write info to output files
};

//------------------------------ExpandRule-------------------------------------
class ExpandRule : public Form {
private:
  NameList _expand_instrs;        // ordered list of instructions and operands

public:
  // Public Data
  NameList _newopers;             // List of newly created operands
  Dict     _newopconst;           // Map new operands to their constructors

  void     add_instruction(NameAndList *instruction_name_and_operand_list);
  void     reset_instructions();
  NameAndList *iter_instructions();

  // Public Methods
  ExpandRule();                   // Constructor
  ~ExpandRule();                  // Destructor

  void dump();                    // Debug printer
  void output(FILE *fp);          // Write info to output files
  virtual void forms_do(FormClosure *f);
};

//---------------------------------Flag----------------------------------------
class Flag : public Form {
private:
    Flag* _next;
public:
  const char *_name; // Name of the flag (See Node::<flag_name> or Node::Pd::<flag_name>

  // Public Methods
  Flag(const char *name);      // Constructor
  ~Flag();                     // Destructor

  // Append a flag rule for the same instruction
  void append_flag(Flag *next_flag);

  Flag* next();

  void dump();                   // Debug printer
  void output(FILE *fp);         // Write info to output files
};

//------------------------------RewriteRule------------------------------------
class RewriteRule : public Form {
private:

public:
  // Public Data
  SourceForm     *_condition;      // Rewrite condition code
  InstructForm   *_instrs;         // List of instructions to expand to
  OperandForm    *_opers;          // List of operands generated by expand
  char           *_tempParams;     // Hold string until parser is finished.
  char           *_tempBlock;      // Hold string until parser is finished.

  // Public Methods
  RewriteRule(char* params, char* block) ;
  ~RewriteRule();                  // Destructor
  void dump();                     // Debug printer
  void output(FILE *fp);           // Write info to output files
  virtual void forms_do(FormClosure* f);
};


//==============================Operands=======================================
//------------------------------OpClassForm------------------------------------
class OpClassForm : public Form {
public:
  // Public Data
  const char    *_ident;           // Name of this operand
  NameList       _oplst;           // List of operand forms included in class

  // Public Methods
  OpClassForm(const char *id);
  ~OpClassForm();

  // dynamic type check
  virtual OpClassForm         *is_opclass() const;
  virtual Form::InterfaceType  interface_type(FormDict &globals) const;
  virtual bool                 stack_slots_only(FormDict &globals) const;

  virtual bool                 is_cisc_mem(FormDict &globals) const;


  // Min and Max opcodes of operands in this operand class
  int _minCode;
  int _maxCode;

  virtual bool ideal_only() const;
  virtual void dump();             // Debug printer
  virtual void output(FILE *fp);   // Write to output files
  virtual void forms_do(FormClosure* f);
};

//------------------------------OperandForm------------------------------------
class OperandForm : public OpClassForm {
private:
  bool         _ideal_only; // Not a user-defined instruction

public:
  // Public Data
  NameList       _parameters; // Locally defined names
  FormDict       _localNames; // Table of components & their types
  MatchRule     *_matrule;    // Matching rule for this operand
  Interface     *_interface;  // Encoding interface for this operand
  Attribute     *_attribs;    // List of Attribute rules
  Predicate     *_predicate;  // Predicate test for this operand
  Constraint    *_constraint; // Constraint Rule for this operand
  ConstructRule *_construct;  // Construction of operand data after matching
  FormatRule    *_format;     // Format for assembly generation
  NameList       _classes;    // List of opclasses which contain this oper

  ComponentList _components;  //

  // Public Methods
  OperandForm(const char *id);
  OperandForm(const char *id, bool ideal_only);
  ~OperandForm();

  // Dynamic type check
  virtual OperandForm *is_operand() const;

  virtual bool        ideal_only() const;
  virtual Form::InterfaceType interface_type(FormDict &globals) const;
  virtual bool                 stack_slots_only(FormDict &globals) const;

  virtual const char *cost();  // Access ins_cost attribute
  virtual uint        num_leaves() const;// Leaves in complex operand
  // Constants in operands' match rules
  virtual uint        num_consts(FormDict &globals) const;
  // Constants in operand's match rule with specified type
  virtual uint        num_consts(FormDict &globals, Form::DataType type) const;
  // Pointer Constants in operands' match rules
  virtual uint        num_const_ptrs(FormDict &globals) const;
  // The number of input edges in the machine world == num_leaves - num_consts
  virtual uint        num_edges(FormDict &globals) const;

  // Check if this operand is usable for cisc-spilling
  virtual bool        is_cisc_reg(FormDict &globals) const;

  // node matches ideal 'Bool', grab condition codes from the ideal world
  virtual bool        is_ideal_bool()  const;

  // Has an integer constant suitable for spill offsets
  bool has_conI(FormDict &globals) const {
    return (num_consts(globals,idealI) == 1) && !is_ideal_bool(); }
  bool has_conL(FormDict &globals) const {
    return (num_consts(globals,idealL) == 1) && !is_ideal_bool(); }

  // Node is user-defined operand for an sRegX
  virtual Form::DataType is_user_name_for_sReg() const;

  // Return ideal type, if there is a single ideal type for this operand
  virtual const char *ideal_type(FormDict &globals, RegisterForm *registers = nullptr) const;
  // If there is a single ideal type for this interface field, return it.
  virtual const char *interface_ideal_type(FormDict   &globals,
                                           const char *field_name) const;

  // Return true if this operand represents a bound register class
  bool is_bound_register() const;

  // Return the Register class for this operand.  Returns null if
  // operand isn't a register form.
  RegClass* get_RegClass() const;

  virtual       bool  is_interface_field(const char   *field_name,
                                         const char   * &value) const;

  // If this operand has a single ideal type, return its type
  virtual Form::DataType simple_type(FormDict &globals) const;
  // If this operand is an ideal constant, return its type
  virtual Form::DataType is_base_constant(FormDict &globals) const;

  // "true" if this operand is a simple type that is swallowed
  virtual bool        swallowed(FormDict &globals) const;

  // Return register class name if a constraint specifies the register class.
  virtual const char *constrained_reg_class() const;
  // Return the register class associated with 'leaf'.
  virtual const char *in_reg_class(uint leaf, FormDict &globals);

  // Build component list from MatchRule and operand's parameter list
  virtual void        build_components(); // top-level operands

  // Return zero-based position in component list; -1 if not in list.
  virtual int         operand_position(const char *name, int usedef);

  // Return zero-based position in component list; -1 if not in list.
  virtual int         constant_position(FormDict &globals, const Component *comp);
  virtual int         constant_position(FormDict &globals, const char *local_name);
  // Return the operand form corresponding to the given index, else null.
  virtual OperandForm *constant_operand(FormDict &globals, uint const_index);

  // Return zero-based position in component list; -1 if not in list.
  virtual int         register_position(FormDict &globals, const char *regname);

  const char         *reduce_result() const;
  // Return the name of the operand on the right hand side of the binary match
  // Return null if there is no right hand side
  const char         *reduce_right(FormDict &globals)  const;
  const char         *reduce_left(FormDict &globals)   const;


  // --------------------------- FILE *output_routines
  //
  // Output code for disp_is_oop, if true.
  void                disp_is_oop(FILE *fp, FormDict &globals);
  // Generate code for internal and external format methods
  void                int_format(FILE *fp, FormDict &globals, uint index);
  void                ext_format(FILE *fp, FormDict &globals, uint index);
  void                format_constant(FILE *fp, uint con_index, uint con_type);
  // Output code to access the value of the index'th constant
  void                access_constant(FILE *fp, FormDict &globals,
                                      uint con_index);
  // ---------------------------


  virtual void dump();             // Debug printer
  virtual void output(FILE *fp);   // Write to output files
  virtual void forms_do(FormClosure* f);
};

//------------------------------Constraint-------------------------------------
class Constraint : public Form {
private:

public:
  const char      *_func;          // Constraint function
  const char      *_arg;           // function's argument

  // Public Methods
  Constraint(const char *func, const char *arg); // Constructor
  ~Constraint();

  bool stack_slots_only() const;

  void dump();                     // Debug printer
  void output(FILE *fp);           // Write info to output files
  virtual void forms_do(FormClosure* f);
};

//------------------------------Predicate--------------------------------------
class Predicate : public Form {
private:

public:
  // Public Data
  char *_pred;                     // C++ source string for predicate

  // Public Methods
  Predicate(char *pr);
  ~Predicate();

  void dump();
  void output(FILE *fp);
};

//------------------------------Interface--------------------------------------
class Interface : public Form {
private:

public:
  // Public Data
  const char *_name;               // String representing the interface name

  // Public Methods
  Interface(const char *name);
  ~Interface();

  virtual Form::InterfaceType interface_type(FormDict &globals) const;

  RegInterface   *is_RegInterface();
  MemInterface   *is_MemInterface();
  ConstInterface *is_ConstInterface();
  CondInterface  *is_CondInterface();


  void dump();
  void output(FILE *fp);
};

//------------------------------RegInterface-----------------------------------
class RegInterface : public Interface {
private:

public:
  // Public Methods
  RegInterface();
  ~RegInterface();

  void dump();
  void output(FILE *fp);
};

//------------------------------ConstInterface---------------------------------
class ConstInterface : public Interface {
private:

public:
  // Public Methods
  ConstInterface();
  ~ConstInterface();

  void dump();
  void output(FILE *fp);
};

//------------------------------MemInterface-----------------------------------
class MemInterface : public Interface {
private:

public:
  // Public Data
  char *_base;                     // Base address
  char *_index;                    // index
  char *_scale;                    // scaling factor
  char *_disp;                     // displacement

  // Public Methods
  MemInterface(char *base, char *index, char *scale, char *disp);
  ~MemInterface();

  void dump();
  void output(FILE *fp);
};

//------------------------------CondInterface----------------------------------
class CondInterface : public Interface {
private:

public:
  const char *_equal;
  const char *_not_equal;
  const char *_less;
  const char *_greater_equal;
  const char *_less_equal;
  const char *_greater;
  const char *_overflow;
  const char *_no_overflow;
  const char *_equal_format;
  const char *_not_equal_format;
  const char *_less_format;
  const char *_greater_equal_format;
  const char *_less_equal_format;
  const char *_greater_format;
  const char *_overflow_format;
  const char *_no_overflow_format;

  // Public Methods
  CondInterface(const char* equal,         const char* equal_format,
                const char* not_equal,     const char* not_equal_format,
                const char* less,          const char* less_format,
                const char* greater_equal, const char* greater_equal_format,
                const char* less_equal,    const char* less_equal_format,
                const char* greater,       const char* greater_format,
                const char* overflow,      const char* overflow_format,
                const char* no_overflow,   const char* no_overflow_format);
  ~CondInterface();

  void dump();
  void output(FILE *fp);
};

//------------------------------ConstructRule----------------------------------
class ConstructRule : public Form {
private:

public:
  // Public Data
  char *_expr;                     // String representing the match expression
  char *_construct;                // String representing C++ constructor code

  // Public Methods
  ConstructRule(char *cnstr);
  ~ConstructRule();

  void dump();
  void output(FILE *fp);
};


//==============================Shared=========================================
//------------------------------AttributeForm----------------------------------
class AttributeForm : public Form {
private:
  // counters for unique instruction or operand ID
  static int   _insId;             // user-defined machine instruction types
  static int   _opId;              // user-defined operand types

  int  id;                         // hold type for this object

public:
  // Public Data
  char *_attrname;                 // Name of attribute
  int   _atype;                    // Either INS_ATTR or OP_ATTR
  char *_attrdef;                  // C++ source which evaluates to constant

  // Public Methods
  AttributeForm(char *attr, int type, char *attrdef);
  ~AttributeForm();

  // Dynamic type check
  virtual AttributeForm *is_attribute() const;

  int  type() { return id;}        // return this object's "id"

  static const char* _ins_cost;        // "ins_cost"
  static const char* _op_cost;         // "op_cost"

  void dump();                     // Debug printer
  void output(FILE *fp);           // Write output files
};

//------------------------------Component--------------------------------------
class Component : public Form {
private:

public:
  // Public Data
  const char *_name;              // Name of this component
  const char *_type;              // Type of this component
  int         _usedef;            // Value of component

  // Public Methods
  Component(const char *name, const char *type, int usedef);
  ~Component();


  // Return 'true' if this use def info equals the parameter
  bool  is(int use_def_kill_enum) const;
  // Return 'true' if this use def info is a superset of parameter
  bool  isa(int use_def_kill_enum) const;
  int   promote_use_def_info(int new_use_def);
  const char *base_type(FormDict &globals);
  // Form::DataType is_base_constant(FormDict &globals);

  void dump();                     // Debug printer
  void output(FILE *fp);           // Write to output files
  const char* getUsedefName();

public:
  // Implementation depends upon working bit intersection and union.
  enum use_def_enum {
    INVALID   = 0x0,
    USE       = 0x1,
    DEF       = 0x2,
    USE_DEF   = USE | DEF,
    KILL      = 0x4,
    USE_KILL  = USE | KILL,
    SYNTHETIC = 0x8,
    TEMP      = USE | SYNTHETIC,
    TEMP_DEF  = TEMP | DEF,
    CALL      = 0x10
  };
};


//------------------------------MatchNode--------------------------------------
class MatchNode : public Form {
private:

public:
  // Public Data
  const char  *_result;            // The name of the output of this node
  const char  *_name;              // The name that appeared in the match rule
  const char  *_opType;            // The Operation/Type matched
  MatchNode   *_lChild;            // Left child in expression tree
  MatchNode   *_rChild;            // Right child in expression tree
  int         _numleaves;          // Sum of numleaves for all direct children
  ArchDesc    &_AD;                // Reference to ArchDesc object
  char        *_internalop;        // String representing internal operand
  int         _commutative_id;     // id of commutative operation

  // Public Methods
  MatchNode(ArchDesc &ad, const char *result = nullptr, const char *expr = nullptr,
            const char *opType=nullptr, MatchNode *lChild=nullptr,
            MatchNode *rChild=nullptr);
  MatchNode(ArchDesc &ad, MatchNode& mNode); // Shallow copy constructor;
  MatchNode(ArchDesc &ad, MatchNode& mNode, int clone); // Construct clone
  ~MatchNode();

  // return 0 if not found:
  // return 1 if found and position is incremented by operand offset in rule
  bool       find_name(const char *str, int &position) const;
  bool       find_type(const char *str, int &position) const;
  virtual void append_components(FormDict& locals, ComponentList& components,
                                 bool def_flag = false) const;
  bool       base_operand(uint &position, FormDict &globals,
                         const char * &result, const char * &name,
                         const char * &opType) const;
  // recursive count on operands
  uint       num_consts(FormDict &globals) const;
  uint       num_const_ptrs(FormDict &globals) const;
  // recursive count of constants with specified type
  uint       num_consts(FormDict &globals, Form::DataType type) const;
  // uint       num_consts() const;   // Local inspection only
  int        needs_ideal_memory_edge(FormDict &globals) const;
  int        needs_base_oop_edge() const;

  // Help build instruction predicates.  Search for operand names.
  void count_instr_names( Dict &names );
  int build_instr_pred( char *buf, const char *name, int cnt, int path_bitmask, int level);
  void build_internalop( );

  // Return the name of the operands associated with reducing to this operand:
  // The result type, plus the left and right sides of the binary match
  // Return null if there is no left or right hand side
  bool       sets_result()   const;    // rule "Set"s result of match
  const char *reduce_right(FormDict &globals)  const;
  const char *reduce_left (FormDict &globals)  const;

  // Recursive version of check in MatchRule
  int        cisc_spill_match(FormDict& globals, RegisterForm* registers,
                              MatchNode* mRule2, const char* &operand,
                              const char* &reg_type);
  int        cisc_spill_merge(int left_result, int right_result);

  virtual bool equivalent(FormDict& globals, MatchNode* mNode2);

  void       count_commutative_op(int& count);
  void       swap_commutative_op(bool atroot, int count);

  void dump();
  void output(FILE *fp);
  virtual void forms_do(FormClosure* f);
};

//------------------------------MatchRule--------------------------------------
class MatchRule : public MatchNode {
private:

public:
  // Public Data
  const char *_machType;            // Machine type index
  int         _depth;               // Expression tree depth
  char       *_construct;           // String representing C++ constructor code
  int         _numchilds;           // Number of direct children
  MatchRule  *_next;                // Pointer to next match rule

  // Public Methods
  MatchRule(ArchDesc &ad);
  MatchRule(ArchDesc &ad, MatchRule* mRule); // Shallow copy constructor;
  MatchRule(ArchDesc &ad, MatchNode* mroot, int depth, char* construct, int numleaves);
  ~MatchRule();

  virtual void append_components(FormDict& locals, ComponentList& components, bool def_flag = false) const;
  // Recursive call on all operands' match rules in my match rule.
  bool       base_operand(uint &position, FormDict &globals,
                         const char * &result, const char * &name,
                         const char * &opType) const;


  bool       is_base_register(FormDict &globals) const;
  Form::DataType is_base_constant(FormDict &globals) const;
  bool       is_chain_rule(FormDict &globals) const;
  int        is_ideal_copy() const;
  int        is_expensive() const;     // node matches ideal 'CosD'
  bool       is_ideal_if()   const;    // node matches ideal 'If'
  bool       is_ideal_fastlock() const; // node matches ideal 'FastLock'
  bool       is_ideal_jump()   const;  // node matches ideal 'Jump'
  bool       is_ideal_membar() const;  // node matches ideal 'MemBarXXX'
  bool       is_ideal_loadPC() const;  // node matches ideal 'LoadPC'
  bool       is_ideal_box() const;     // node matches ideal 'Box'
  bool       is_ideal_goto() const;    // node matches ideal 'Goto'
  bool       is_ideal_loopEnd() const; // node matches ideal 'LoopEnd'
  bool       is_ideal_bool() const;    // node matches ideal 'Bool'
  bool       is_vector() const;        // vector instruction
  Form::DataType is_ideal_load() const;// node matches ideal 'LoadXNode'
  // Should antidep checks be disabled for this rule
  // See definition of MatchRule::skip_antidep_check
  bool skip_antidep_check() const;
  Form::DataType is_ideal_store() const;// node matches ideal 'StoreXNode'

  // Check if 'mRule2' is a cisc-spill variant of this MatchRule
  int        matchrule_cisc_spill_match(FormDict &globals, RegisterForm* registers,
                                        MatchRule* mRule2, const char* &operand,
                                        const char* &reg_type);

  // Check if 'mRule2' is equivalent to this MatchRule
  virtual bool equivalent(FormDict& globals, MatchNode* mRule2);

  void       matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt);

  void dump();
  void output_short(FILE *fp);
  void output(FILE *fp);
  virtual void forms_do(FormClosure* f);
};

//------------------------------Attribute--------------------------------------
class Attribute : public Form {
private:

public:
  // Public Data
  char *_ident;                    // Name of predefined attribute
  char *_val;                      // C++ source which evaluates to constant
  int   _atype;                    // Either INS_ATTR or OP_ATTR
  int   int_val(ArchDesc &ad);     // Return atoi(_val), ensuring syntax.

  // Public Methods
  Attribute(char *id, char* val, int type);
  ~Attribute();

  void dump();
  void output(FILE *fp);
};

//------------------------------FormatRule-------------------------------------
class FormatRule : public Form {
private:

public:
  // Public Data
  // There is an entry in _strings, perhaps null, that precedes each _rep_vars
  NameList  _strings;              // Strings passed through to tty->print
  NameList  _rep_vars;             // replacement variables
  char     *_temp;                 // String representing the assembly code

  // Public Methods
  FormatRule(char *temp);
  ~FormatRule();

  void dump();
  void output(FILE *fp);
};

#endif // SHARE_ADLC_FORMSSEL_HPP
