diff -r fd16c54261b3 -r 489c9b5090e2 hotspot/src/share/vm/adlc/formssel.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/adlc/formssel.hpp Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,1045 @@ +/* + * Copyright 1998-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// 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 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 + uint _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; + 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 + 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 Scheduline description class + + uint *_uniq_idx; // Indexes of unique operands + uint _num_uniq; // Number of unique operands + ComponentList _components; // List of Components matches MachNode's + // operand structure + + // 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 ; + // 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_unlock() const; // node matches ideal 'Unlock' + virtual bool is_ideal_call_leaf() const; // node matches ideal 'CallLeaf' + 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 Form::CallType is_ideal_call() const; // matches ideal 'Call' + virtual Form::DataType is_ideal_load() const; // node matches ideal 'LoadXNode' + 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() const; + + virtual const char *cost(); // Access ins_cost attribute + virtual uint num_opnds(); // Count of num_opnds for MachNode class + 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 *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() 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; } + uint 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; } + + 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(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 ) + return _uniq_idx[idx]; + else + return 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 determing 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 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_preceeding_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 + void 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; + + // Public Methods + CondInterface(char *equal, char *not_equal, char *less, char *greater_equal, + char *less_equal, char *greater); + ~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* _ins_pc_relative; // "ins_pc_relative" + 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 + +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 + }; +}; + + +//------------------------------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; + void append_components(FormDict &locals, ComponentList &components, + bool def_flag) 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 * ®_type); + int cisc_spill_merge(int left_result, int right_result); + + 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(); + + void append_components(FormDict &locals, ComponentList &components) 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_unlock() const; + bool is_ideal_call_leaf() const; + 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' + Form::DataType is_ideal_load() const;// node matches ideal 'LoadXNode' + Form::DataType is_ideal_store() const;// node matches ideal 'StoreXNode' + + // Check if 'mRule2' is a cisc-spill variant of this MatchRule + int cisc_spill_match(FormDict &globals, RegisterForm *registers, + MatchRule *mRule2, const char * &operand, + const char * ®_type); + + // Check if 'mRule2' is equivalent to this MatchRule + bool equivalent(FormDict &globals, MatchRule *mRule2); + + void swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt); + + void dump(); + 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); +};