1533
1534 // virtual functions for attributes
1535 //
1536 // Each instruction attribute results in a virtual call of same name.
1537 // The ins_cost is not handled here.
1538 Attribute *attr = instr->_attribs;
1539 bool is_pc_relative = false;
1540 while (attr != NULL) {
1541 if (strcmp(attr->_ident,"ins_cost") &&
1542 strcmp(attr->_ident,"ins_pc_relative")) {
1543 fprintf(fp," int %s() const { return %s; }\n",
1544 attr->_ident, attr->_val);
1545 }
1546 // Check value for ins_pc_relative, and if it is true (1), set the flag
1547 if (!strcmp(attr->_ident,"ins_pc_relative") && attr->int_val(*this) != 0)
1548 is_pc_relative = true;
1549 attr = (Attribute *)attr->_next;
1550 }
1551
1552 // virtual functions for encode and format
1553 //
1554 // Output the opcode function and the encode function here using the
1555 // encoding class information in the _insencode slot.
1556 if ( instr->_insencode ) {
1557 fprintf(fp," virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;\n");
1558 }
1559
1560 // virtual function for getting the size of an instruction
1561 if ( instr->_size ) {
1562 fprintf(fp," virtual uint size(PhaseRegAlloc *ra_) const;\n");
1563 }
1564
1565 // Return the top-level ideal opcode.
1566 // Use MachNode::ideal_Opcode() for nodes based on MachNode class
1567 // if the ideal_Opcode == Op_Node.
1568 if ( strcmp("Node", instr->ideal_Opcode(_globalNames)) != 0 ||
1569 strcmp("MachNode", instr->mach_base_class(_globalNames)) != 0 ) {
1570 fprintf(fp," virtual int ideal_Opcode() const { return Op_%s; }\n",
1571 instr->ideal_Opcode(_globalNames) );
1572 }
1573
1735 }
1736
1737 if ( node_flags_set ) {
1738 fprintf(fp,"); ");
1739 }
1740
1741 if (instr->is_ideal_unlock() || instr->is_ideal_call_leaf()) {
1742 fprintf(fp,"clear_flag(Flag_is_safepoint_node); ");
1743 }
1744
1745 fprintf(fp,"}\n");
1746
1747 // size_of, used by base class's clone to obtain the correct size.
1748 fprintf(fp," virtual uint size_of() const {");
1749 fprintf(fp, " return sizeof(%sNode);", instr->_ident);
1750 fprintf(fp, " }\n");
1751
1752 // Virtual methods which are only generated to override base class
1753 if( instr->expands() || instr->needs_projections() ||
1754 instr->has_temps() ||
1755 instr->_matrule != NULL &&
1756 instr->num_opnds() != instr->num_unique_opnds() ) {
1757 fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list, Node* mem);\n");
1758 }
1759
1760 if (instr->is_pinned(_globalNames)) {
1761 fprintf(fp," virtual bool pinned() const { return ");
1762 if (instr->is_parm(_globalNames)) {
1763 fprintf(fp,"_in[0]->pinned();");
1764 } else {
1765 fprintf(fp,"true;");
1766 }
1767 fprintf(fp," }\n");
1768 }
1769 if (instr->is_projection(_globalNames)) {
1770 fprintf(fp," virtual const Node *is_block_proj() const { return this; }\n");
1771 }
1772 if ( instr->num_post_match_opnds() != 0
1773 || instr->is_chain_of_constant(_globalNames) ) {
1774 fprintf(fp," friend MachNode *State::MachNodeGenerator(int opcode, Compile* C);\n");
1775 }
1776 if ( instr->rematerialize(_globalNames, get_registers()) ) {
1777 fprintf(fp," // Rematerialize %s\n", instr->_ident);
1778 }
1779
1780 // Declare short branch methods, if applicable
1781 instr->declare_short_branch_methods(fp);
1782
1783 // Instructions containing a constant that will be entered into the
1784 // float/double table redefine the base virtual function
1785 #ifdef SPARC
1786 // Sparc doubles entries in the constant table require more space for
1787 // alignment. (expires 9/98)
1788 int table_entries = (3 * instr->num_consts( _globalNames, Form::idealD ))
1789 + instr->num_consts( _globalNames, Form::idealF );
1790 #else
1791 int table_entries = instr->num_consts( _globalNames, Form::idealD )
1792 + instr->num_consts( _globalNames, Form::idealF );
1793 #endif
1794 if( table_entries != 0 ) {
1795 fprintf(fp," virtual int const_size() const {");
1796 fprintf(fp, " return %d;", table_entries);
1797 fprintf(fp, " }\n");
1798 }
1799
1800
1801 // See if there is an "ins_pipe" declaration for this instruction
1802 if (instr->_ins_pipe) {
1803 fprintf(fp," static const Pipeline *pipeline_class();\n");
1804 fprintf(fp," virtual const Pipeline *pipeline() const;\n");
1805 }
1806
1807 // Generate virtual function for MachNodeX::bottom_type when necessary
1808 //
1809 // Note on accuracy: Pointer-types of machine nodes need to be accurate,
1810 // or else alias analysis on the matched graph may produce bad code.
1811 // Moreover, the aliasing decisions made on machine-node graph must be
1812 // no less accurate than those made on the ideal graph, or else the graph
1813 // may fail to schedule. (Reason: Memory ops which are reordered in
1814 // the ideal graph might look interdependent in the machine graph,
1815 // thereby removing degrees of scheduling freedom that the optimizer
1816 // assumed would be available.)
1817 //
1818 // %%% We should handle many of these cases with an explicit ADL clause:
1819 // instruct foo() %{ ... bottom_type(TypeRawPtr::BOTTOM); ... %}
1820 if( data_type != Form::none ) {
|
1533
1534 // virtual functions for attributes
1535 //
1536 // Each instruction attribute results in a virtual call of same name.
1537 // The ins_cost is not handled here.
1538 Attribute *attr = instr->_attribs;
1539 bool is_pc_relative = false;
1540 while (attr != NULL) {
1541 if (strcmp(attr->_ident,"ins_cost") &&
1542 strcmp(attr->_ident,"ins_pc_relative")) {
1543 fprintf(fp," int %s() const { return %s; }\n",
1544 attr->_ident, attr->_val);
1545 }
1546 // Check value for ins_pc_relative, and if it is true (1), set the flag
1547 if (!strcmp(attr->_ident,"ins_pc_relative") && attr->int_val(*this) != 0)
1548 is_pc_relative = true;
1549 attr = (Attribute *)attr->_next;
1550 }
1551
1552 // virtual functions for encode and format
1553
1554 // Virtual function for evaluating the constant.
1555 if (instr->is_mach_constant()) {
1556 fprintf(fp," virtual void eval_constant();\n");
1557 }
1558
1559 // Output the opcode function and the encode function here using the
1560 // encoding class information in the _insencode slot.
1561 if ( instr->_insencode ) {
1562 fprintf(fp," virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;\n");
1563 }
1564
1565 // virtual function for getting the size of an instruction
1566 if ( instr->_size ) {
1567 fprintf(fp," virtual uint size(PhaseRegAlloc *ra_) const;\n");
1568 }
1569
1570 // Return the top-level ideal opcode.
1571 // Use MachNode::ideal_Opcode() for nodes based on MachNode class
1572 // if the ideal_Opcode == Op_Node.
1573 if ( strcmp("Node", instr->ideal_Opcode(_globalNames)) != 0 ||
1574 strcmp("MachNode", instr->mach_base_class(_globalNames)) != 0 ) {
1575 fprintf(fp," virtual int ideal_Opcode() const { return Op_%s; }\n",
1576 instr->ideal_Opcode(_globalNames) );
1577 }
1578
1740 }
1741
1742 if ( node_flags_set ) {
1743 fprintf(fp,"); ");
1744 }
1745
1746 if (instr->is_ideal_unlock() || instr->is_ideal_call_leaf()) {
1747 fprintf(fp,"clear_flag(Flag_is_safepoint_node); ");
1748 }
1749
1750 fprintf(fp,"}\n");
1751
1752 // size_of, used by base class's clone to obtain the correct size.
1753 fprintf(fp," virtual uint size_of() const {");
1754 fprintf(fp, " return sizeof(%sNode);", instr->_ident);
1755 fprintf(fp, " }\n");
1756
1757 // Virtual methods which are only generated to override base class
1758 if( instr->expands() || instr->needs_projections() ||
1759 instr->has_temps() ||
1760 instr->is_mach_constant() ||
1761 instr->_matrule != NULL &&
1762 instr->num_opnds() != instr->num_unique_opnds() ) {
1763 fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list, Node* mem);\n");
1764 }
1765
1766 if (instr->is_pinned(_globalNames)) {
1767 fprintf(fp," virtual bool pinned() const { return ");
1768 if (instr->is_parm(_globalNames)) {
1769 fprintf(fp,"_in[0]->pinned();");
1770 } else {
1771 fprintf(fp,"true;");
1772 }
1773 fprintf(fp," }\n");
1774 }
1775 if (instr->is_projection(_globalNames)) {
1776 fprintf(fp," virtual const Node *is_block_proj() const { return this; }\n");
1777 }
1778 if ( instr->num_post_match_opnds() != 0
1779 || instr->is_chain_of_constant(_globalNames) ) {
1780 fprintf(fp," friend MachNode *State::MachNodeGenerator(int opcode, Compile* C);\n");
1781 }
1782 if ( instr->rematerialize(_globalNames, get_registers()) ) {
1783 fprintf(fp," // Rematerialize %s\n", instr->_ident);
1784 }
1785
1786 // Declare short branch methods, if applicable
1787 instr->declare_short_branch_methods(fp);
1788
1789 // See if there is an "ins_pipe" declaration for this instruction
1790 if (instr->_ins_pipe) {
1791 fprintf(fp," static const Pipeline *pipeline_class();\n");
1792 fprintf(fp," virtual const Pipeline *pipeline() const;\n");
1793 }
1794
1795 // Generate virtual function for MachNodeX::bottom_type when necessary
1796 //
1797 // Note on accuracy: Pointer-types of machine nodes need to be accurate,
1798 // or else alias analysis on the matched graph may produce bad code.
1799 // Moreover, the aliasing decisions made on machine-node graph must be
1800 // no less accurate than those made on the ideal graph, or else the graph
1801 // may fail to schedule. (Reason: Memory ops which are reordered in
1802 // the ideal graph might look interdependent in the machine graph,
1803 // thereby removing degrees of scheduling freedom that the optimizer
1804 // assumed would be available.)
1805 //
1806 // %%% We should handle many of these cases with an explicit ADL clause:
1807 // instruct foo() %{ ... bottom_type(TypeRawPtr::BOTTOM); ... %}
1808 if( data_type != Form::none ) {
|