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