/*
 * Copyright (c) 1998, 2013, 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_VM_ADLC_FORMSSEL_HPP
#define SHARE_VM_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 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

  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;
          bool        is_wide_memory_kill(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);
  bool                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 != NULL; }
  // Output short branch prototypes and method bodies
  void                declare_short_branch_methods(FILE *fp_cpp);
  bool                define_short_branch_methods(ArchDesc &AD, FILE *fp_cpp);

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

  // Seach 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 != NULL && 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
};

//------------------------------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
};

//------------------------------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);
};

//------------------------------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 preceeded 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);
};

//------------------------------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
};

//------------------------------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
};


//==============================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
};

//------------------------------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 = NULL) 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
};

//------------------------------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
};

//------------------------------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   = 0x3,
    KILL    = 0x4, USE_KILL  = 0x5,
    SYNTHETIC = 0x8,
    TEMP = USE | SYNTHETIC,
    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 = 0, const char *expr = 0,
            const char *opType=0, MatchNode *lChild=NULL,
            MatchNode *rChild=NULL);
  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 );
  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);
};

//------------------------------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);
};

//------------------------------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_VM_ADLC_FORMSSEL_HPP
