hotspot/src/share/vm/adlc/output_c.cpp

Print this page
rev 611 : Merge
   1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)output_c.cpp 1.185 07/07/02 16:50:40 JVM"
   3 #endif
   4 /*
   5  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  


1532       }
1533     }
1534     cnt = 0;
1535     // Generate the temps to use for DAG building
1536     for(i = 0; i < numo; i++) {
1537       if (i < node->num_opnds()) {
1538         fprintf(fp,"  MachNode *tmp%d = this;\n", i);
1539       }
1540       else {
1541         fprintf(fp,"  MachNode *tmp%d = NULL;\n", i);
1542       }
1543     }
1544     // Build mapping from num_edges to local variables
1545     fprintf(fp,"  unsigned num0 = 0;\n");
1546     for( i = 1; i < node->num_opnds(); i++ ) {
1547       fprintf(fp,"  unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
1548     }
1549 
1550     // Build a mapping from operand index to input edges
1551     fprintf(fp,"  unsigned idx0 = oper_input_base();\n");












1552     for( i = 0; i < node->num_opnds(); i++ ) {
1553       fprintf(fp,"  unsigned idx%d = idx%d + num%d;\n",
1554               i+1,i,i);
1555     }
1556 
1557     // Declare variable to hold root of expansion
1558     fprintf(fp,"  MachNode *result = NULL;\n");
1559 
1560     // Iterate over the instructions 'node' expands into
1561     ExpandRule  *expand       = node->_exprule;
1562     NameAndList *expand_instr = NULL;
1563     for(expand->reset_instructions();
1564         (expand_instr = expand->iter_instructions()) != NULL; cnt++) {
1565       new_id = expand_instr->name();
1566 
1567       InstructForm* expand_instruction = (InstructForm*)globalAD->globalNames()[new_id];
1568       if (expand_instruction->has_temps()) {
1569         globalAD->syntax_err(node->_linenum, "In %s: expand rules using instructs with TEMPs aren't supported: %s",
1570                              node->_ident, new_id);
1571       }


1586       }
1587 
1588       if( node->is_ideal_fastlock() && new_inst->is_ideal_fastlock() ) {
1589         fprintf(fp, "  ((MachFastLockNode*)n%d)->_counters = _counters;\n",cnt);
1590       }
1591 
1592       const char *resultOper = new_inst->reduce_result();
1593       fprintf(fp,"  n%d->set_opnd_array(0, state->MachOperGenerator( %s, C ));\n", 
1594               cnt, machOperEnum(resultOper));
1595 
1596       // get the formal operand NameList
1597       NameList *formal_lst = &new_inst->_parameters;
1598       formal_lst->reset();
1599 
1600       // Handle any memory operand
1601       int memory_operand = new_inst->memory_operand(_globalNames);
1602       if( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
1603         int node_mem_op = node->memory_operand(_globalNames);
1604         assert( node_mem_op != InstructForm::NO_MEMORY_OPERAND, 
1605                 "expand rule member needs memory but top-level inst doesn't have any" );

1606         // Copy memory edge
1607         fprintf(fp,"  n%d->add_req(_in[1]);\t// Add memory edge\n", cnt);
1608       }

1609 
1610       // Iterate over the new instruction's operands

1611       for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
1612         // Use 'parameter' at current position in list of new instruction's formals
1613         // instead of 'opid' when looking up info internal to new_inst
1614         const char *parameter = formal_lst->iter();
1615         // Check for an operand which is created in the expand rule
1616         if ((exp_pos = node->_exprule->_newopers.index(opid)) != -1) {
1617           new_pos = new_inst->operand_position(parameter,Component::USE);
1618           exp_pos += node->num_opnds();
1619           // If there is no use of the created operand, just skip it
1620           if (new_pos != -1) {
1621             //Copy the operand from the original made above
1622             fprintf(fp,"  n%d->set_opnd_array(%d, op%d->clone(C)); // %s\n", 
1623                     cnt, new_pos, exp_pos-node->num_opnds(), opid);
1624             // Check for who defines this operand & add edge if needed
1625             fprintf(fp,"  if(tmp%d != NULL)\n", exp_pos);
1626             fprintf(fp,"    n%d->add_req(tmp%d);\n", cnt, exp_pos);
1627           }
1628         }
1629         else {
1630           // Use operand name to get an index into instruction component list
1631           // ins = (InstructForm *) _globalNames[new_id];
1632           exp_pos = node->operand_position_format(opid);
1633           assert(exp_pos != -1, "Bad expand rule");












1634           
1635           new_pos = new_inst->operand_position(parameter,Component::USE);
1636           if (new_pos != -1) {
1637             // Copy the operand from the ExpandNode to the new node
1638             fprintf(fp,"  n%d->set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n", 
1639                     cnt, new_pos, exp_pos, opid);
1640             // For each operand add appropriate input edges by looking at tmp's
1641             fprintf(fp,"  if(tmp%d == this) {\n", exp_pos);
1642             // Grab corresponding edges from ExpandNode and insert them here
1643             fprintf(fp,"    for(unsigned i = 0; i < num%d; i++) {\n", exp_pos);
1644             fprintf(fp,"      n%d->add_req(_in[i + idx%d]);\n", cnt, exp_pos);
1645             fprintf(fp,"    }\n");
1646             fprintf(fp,"  }\n");
1647             // This value is generated by one of the new instructions
1648             fprintf(fp,"  else n%d->add_req(tmp%d);\n", cnt, exp_pos);
1649           }
1650         }
1651 
1652         // Update the DAG tmp's for values defined by this instruction
1653         int new_def_pos = new_inst->operand_position(parameter,Component::DEF);


2278         fprintf(_fp,"->disp(ra_,this,idx%d)", _operand_idx);
2279       }
2280     }
2281     else if ( strcmp(rep_var,"$label") == 0 ) {
2282       fprintf(_fp,"->label()");
2283     }
2284     else if ( strcmp(rep_var,"$method") == 0 ) {
2285       fprintf(_fp,"->method()");
2286     }
2287     else {
2288       printf("emit_field: %s\n",rep_var);
2289       assert( false, "UnImplemented()");
2290     }
2291   }
2292 
2293 
2294   void emit_rep_var(const char *rep_var) {
2295     _processing_noninput = false;
2296     // A replacement variable, originally '$'
2297     if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
2298       _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) );





2299     }
2300     else {
2301       // Lookup its position in parameter list
2302       int   param_no  = _encoding.rep_var_index(rep_var);
2303       if ( param_no == -1 ) {
2304         _AD.syntax_err( _encoding._linenum,
2305                         "Replacement variable %s not found in enc_class %s.\n",
2306                         rep_var, _encoding._name);
2307       }
2308       // Lookup the corresponding ins_encode parameter
2309       const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
2310 
2311       // Check if instruction's actual parameter is a local name in the instruction
2312       const Form  *local     = _inst._localNames[inst_rep_var];
2313       OpClassForm *opc       = (local != NULL) ? local->is_opclass() : NULL;
2314       // Note: assert removed to allow constant and symbolic parameters
2315       // assert( opc, "replacement variable was not found in local names");
2316       // Lookup the index position iff the replacement variable is a localName
2317       int idx  = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
2318       if( idx != -1 ) {


2320           // This operand isn't a normal input so printing it is done
2321           // specially.
2322           _processing_noninput = true;
2323         } else {
2324           // Output the emit code for this operand
2325           fprintf(_fp,"opnd_array(%d)",idx);
2326         }
2327         assert( _operand == opc->is_operand(),
2328                 "Previous emit $operand does not match current");
2329       }
2330       else if( ADLParser::is_literal_constant(inst_rep_var) ) {
2331         // else check if it is a constant expression
2332         // Removed following assert to allow primitive C types as arguments to encodings
2333         // assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
2334         fprintf(_fp,"(%s)", inst_rep_var);
2335         _constant_status = LITERAL_OUTPUT;
2336       }
2337       else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
2338         // else check if "primary", "secondary", "tertiary"
2339         assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
2340         _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) );






2341         _constant_status = LITERAL_OUTPUT;
2342       }
2343       else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
2344         // Instruction provided a literal register name for this parameter
2345         // Check that encoding specifies $$$reg to resolve.as register.
2346         assert( _reg_status == LITERAL_ACCESSED, "Must be processing a literal register parameter");
2347         fprintf(_fp,"(%s_enc)", inst_rep_var);
2348         _reg_status = LITERAL_OUTPUT;
2349       }
2350       else {
2351         // Check for unimplemented functionality before hard failure
2352         assert( strcmp(opc->_ident,"label")==0, "Unimplemented() Label");
2353         assert( false, "ShouldNotReachHere()");
2354       }
2355       // all done
2356     }
2357   }
2358 
2359 };  // end class DefineEmitState
2360 
2361 
2362 void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
2363   
2364   //(1)
2365   // Output instruction's emit prototype
2366   fprintf(fp,"uint  %sNode::size(PhaseRegAlloc *ra_) const {\n",
2367           inst._ident);
2368 


2369   //(2)
2370   // Print the size
2371   fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
2372 
2373   // (3) and (4)
2374   fprintf(fp,"}\n");
2375 }
2376 
2377 void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
2378   InsEncode *ins_encode = inst._insencode;
2379 
2380   // (1)
2381   // Output instruction's emit prototype
2382   fprintf(fp,"void  %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n",
2383           inst._ident);
2384 
2385   // If user did not define an encode section, 
2386   // provide stub that does not generate any machine code.
2387   if( (_encode == NULL) || (ins_encode == NULL) ) {
2388     fprintf(fp, "  // User did not define an encode section.\n");


3412 
3413 // Recurse through match tree, building path through corresponding state tree,
3414 // Until we reach the constant we are looking for.
3415 static void path_to_constant(FILE *fp, FormDict &globals,
3416                              MatchNode *mnode, uint idx) {
3417   if ( ! mnode) return;
3418   
3419   unsigned    position = 0;
3420   const char *result   = NULL;
3421   const char *name     = NULL;
3422   const char *optype   = NULL;
3423 
3424   // Base Case: access constant in ideal node linked to current state node
3425   // Each type of constant has its own access function
3426   if ( (mnode->_lChild == NULL) && (mnode->_rChild == NULL)
3427        && mnode->base_operand(position, globals, result, name, optype) ) {
3428     if (         strcmp(optype,"ConI") == 0 ) {
3429       fprintf(fp, "_leaf->get_int()");
3430     } else if ( (strcmp(optype,"ConP") == 0) ) {
3431       fprintf(fp, "_leaf->bottom_type()->is_ptr()");


3432     } else if ( (strcmp(optype,"ConF") == 0) ) {
3433       fprintf(fp, "_leaf->getf()");
3434     } else if ( (strcmp(optype,"ConD") == 0) ) {
3435       fprintf(fp, "_leaf->getd()");
3436     } else if ( (strcmp(optype,"ConL") == 0) ) {
3437       fprintf(fp, "_leaf->get_long()");
3438     } else if ( (strcmp(optype,"Con")==0) ) {
3439       // !!!!! - Update if adding a machine-independent constant type
3440       fprintf(fp, "_leaf->get_int()");
3441       assert( false, "Unsupported constant type, pointer or indefinite");
3442     } else if ( (strcmp(optype,"Bool") == 0) ) {
3443       fprintf(fp, "_leaf->as_Bool()->_test._test");
3444     } else {
3445       assert( false, "Unsupported constant type");
3446     }
3447     return;
3448   }
3449 
3450   // If constant is in left child, build path and recurse 
3451   uint lConsts = (mnode->_lChild) ? (mnode->_lChild->num_consts(globals) ) : 0;


   1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)output_c.cpp 1.185 07/07/02 16:50:40 JVM"
   3 #endif
   4 /*
   5  * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  


1532       }
1533     }
1534     cnt = 0;
1535     // Generate the temps to use for DAG building
1536     for(i = 0; i < numo; i++) {
1537       if (i < node->num_opnds()) {
1538         fprintf(fp,"  MachNode *tmp%d = this;\n", i);
1539       }
1540       else {
1541         fprintf(fp,"  MachNode *tmp%d = NULL;\n", i);
1542       }
1543     }
1544     // Build mapping from num_edges to local variables
1545     fprintf(fp,"  unsigned num0 = 0;\n");
1546     for( i = 1; i < node->num_opnds(); i++ ) {
1547       fprintf(fp,"  unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
1548     }
1549 
1550     // Build a mapping from operand index to input edges
1551     fprintf(fp,"  unsigned idx0 = oper_input_base();\n");
1552 
1553     // The order in which inputs are added to a node is very
1554     // strange.  Store nodes get a memory input before Expand is
1555     // called and all other nodes get it afterwards so
1556     // oper_input_base is wrong during expansion.  This code adjusts
1557     // is so that expansion will work correctly.
1558     bool missing_memory_edge = node->_matrule->needs_ideal_memory_edge(_globalNames) &&
1559                                node->is_ideal_store() == Form::none;
1560     if (missing_memory_edge) {
1561       fprintf(fp,"  idx0--; // Adjust base because memory edge hasn't been inserted yet\n");
1562     }
1563 
1564     for( i = 0; i < node->num_opnds(); i++ ) {
1565       fprintf(fp,"  unsigned idx%d = idx%d + num%d;\n",
1566               i+1,i,i);
1567     }
1568 
1569     // Declare variable to hold root of expansion
1570     fprintf(fp,"  MachNode *result = NULL;\n");
1571 
1572     // Iterate over the instructions 'node' expands into
1573     ExpandRule  *expand       = node->_exprule;
1574     NameAndList *expand_instr = NULL;
1575     for(expand->reset_instructions();
1576         (expand_instr = expand->iter_instructions()) != NULL; cnt++) {
1577       new_id = expand_instr->name();
1578 
1579       InstructForm* expand_instruction = (InstructForm*)globalAD->globalNames()[new_id];
1580       if (expand_instruction->has_temps()) {
1581         globalAD->syntax_err(node->_linenum, "In %s: expand rules using instructs with TEMPs aren't supported: %s",
1582                              node->_ident, new_id);
1583       }


1598       }
1599 
1600       if( node->is_ideal_fastlock() && new_inst->is_ideal_fastlock() ) {
1601         fprintf(fp, "  ((MachFastLockNode*)n%d)->_counters = _counters;\n",cnt);
1602       }
1603 
1604       const char *resultOper = new_inst->reduce_result();
1605       fprintf(fp,"  n%d->set_opnd_array(0, state->MachOperGenerator( %s, C ));\n", 
1606               cnt, machOperEnum(resultOper));
1607 
1608       // get the formal operand NameList
1609       NameList *formal_lst = &new_inst->_parameters;
1610       formal_lst->reset();
1611 
1612       // Handle any memory operand
1613       int memory_operand = new_inst->memory_operand(_globalNames);
1614       if( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
1615         int node_mem_op = node->memory_operand(_globalNames);
1616         assert( node_mem_op != InstructForm::NO_MEMORY_OPERAND, 
1617                 "expand rule member needs memory but top-level inst doesn't have any" );
1618         if (!missing_memory_edge) {
1619           // Copy memory edge
1620           fprintf(fp,"  n%d->add_req(_in[1]);\t// Add memory edge\n", cnt);
1621         }
1622       }
1623 
1624       // Iterate over the new instruction's operands
1625       int prev_pos = -1;
1626       for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
1627         // Use 'parameter' at current position in list of new instruction's formals
1628         // instead of 'opid' when looking up info internal to new_inst
1629         const char *parameter = formal_lst->iter();
1630         // Check for an operand which is created in the expand rule
1631         if ((exp_pos = node->_exprule->_newopers.index(opid)) != -1) {
1632           new_pos = new_inst->operand_position(parameter,Component::USE);
1633           exp_pos += node->num_opnds();
1634           // If there is no use of the created operand, just skip it
1635           if (new_pos != -1) {
1636             //Copy the operand from the original made above
1637             fprintf(fp,"  n%d->set_opnd_array(%d, op%d->clone(C)); // %s\n", 
1638                     cnt, new_pos, exp_pos-node->num_opnds(), opid);
1639             // Check for who defines this operand & add edge if needed
1640             fprintf(fp,"  if(tmp%d != NULL)\n", exp_pos);
1641             fprintf(fp,"    n%d->add_req(tmp%d);\n", cnt, exp_pos);
1642           }
1643         }
1644         else {
1645           // Use operand name to get an index into instruction component list
1646           // ins = (InstructForm *) _globalNames[new_id];
1647           exp_pos = node->operand_position_format(opid);
1648           assert(exp_pos != -1, "Bad expand rule");
1649           if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
1650             // For the add_req calls below to work correctly they need
1651             // to added in the same order that a match would add them.
1652             // This means that they would need to be in the order of
1653             // the components list instead of the formal parameters.
1654             // This is a sort of hidden invariant that previously
1655             // wasn't checked and could lead to incorrectly
1656             // constructed nodes.
1657             syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
1658                        node->_ident, new_inst->_ident);
1659           }
1660           prev_pos = exp_pos;
1661 
1662           new_pos = new_inst->operand_position(parameter,Component::USE);
1663           if (new_pos != -1) {
1664             // Copy the operand from the ExpandNode to the new node
1665             fprintf(fp,"  n%d->set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n", 
1666                     cnt, new_pos, exp_pos, opid);
1667             // For each operand add appropriate input edges by looking at tmp's
1668             fprintf(fp,"  if(tmp%d == this) {\n", exp_pos);
1669             // Grab corresponding edges from ExpandNode and insert them here
1670             fprintf(fp,"    for(unsigned i = 0; i < num%d; i++) {\n", exp_pos);
1671             fprintf(fp,"      n%d->add_req(_in[i + idx%d]);\n", cnt, exp_pos);
1672             fprintf(fp,"    }\n");
1673             fprintf(fp,"  }\n");
1674             // This value is generated by one of the new instructions
1675             fprintf(fp,"  else n%d->add_req(tmp%d);\n", cnt, exp_pos);
1676           }
1677         }
1678 
1679         // Update the DAG tmp's for values defined by this instruction
1680         int new_def_pos = new_inst->operand_position(parameter,Component::DEF);


2305         fprintf(_fp,"->disp(ra_,this,idx%d)", _operand_idx);
2306       }
2307     }
2308     else if ( strcmp(rep_var,"$label") == 0 ) {
2309       fprintf(_fp,"->label()");
2310     }
2311     else if ( strcmp(rep_var,"$method") == 0 ) {
2312       fprintf(_fp,"->method()");
2313     }
2314     else {
2315       printf("emit_field: %s\n",rep_var);
2316       assert( false, "UnImplemented()");
2317     }
2318   }
2319 
2320 
2321   void emit_rep_var(const char *rep_var) {
2322     _processing_noninput = false;
2323     // A replacement variable, originally '$'
2324     if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
2325       if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
2326         // Missing opcode
2327         _AD.syntax_err( _inst._linenum,
2328                         "Missing $%s opcode definition in %s, used by encoding %s\n",
2329                         rep_var, _inst._ident, _encoding._name);
2330       }
2331     }
2332     else {
2333       // Lookup its position in parameter list
2334       int   param_no  = _encoding.rep_var_index(rep_var);
2335       if ( param_no == -1 ) {
2336         _AD.syntax_err( _encoding._linenum,
2337                         "Replacement variable %s not found in enc_class %s.\n",
2338                         rep_var, _encoding._name);
2339       }
2340       // Lookup the corresponding ins_encode parameter
2341       const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
2342 
2343       // Check if instruction's actual parameter is a local name in the instruction
2344       const Form  *local     = _inst._localNames[inst_rep_var];
2345       OpClassForm *opc       = (local != NULL) ? local->is_opclass() : NULL;
2346       // Note: assert removed to allow constant and symbolic parameters
2347       // assert( opc, "replacement variable was not found in local names");
2348       // Lookup the index position iff the replacement variable is a localName
2349       int idx  = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
2350       if( idx != -1 ) {


2352           // This operand isn't a normal input so printing it is done
2353           // specially.
2354           _processing_noninput = true;
2355         } else {
2356           // Output the emit code for this operand
2357           fprintf(_fp,"opnd_array(%d)",idx);
2358         }
2359         assert( _operand == opc->is_operand(),
2360                 "Previous emit $operand does not match current");
2361       }
2362       else if( ADLParser::is_literal_constant(inst_rep_var) ) {
2363         // else check if it is a constant expression
2364         // Removed following assert to allow primitive C types as arguments to encodings
2365         // assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
2366         fprintf(_fp,"(%s)", inst_rep_var);
2367         _constant_status = LITERAL_OUTPUT;
2368       }
2369       else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
2370         // else check if "primary", "secondary", "tertiary"
2371         assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
2372         if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
2373           // Missing opcode
2374           _AD.syntax_err( _inst._linenum,
2375                           "Missing $%s opcode definition in %s\n",
2376                           rep_var, _inst._ident);
2377 
2378         }
2379         _constant_status = LITERAL_OUTPUT;
2380       }
2381       else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
2382         // Instruction provided a literal register name for this parameter
2383         // Check that encoding specifies $$$reg to resolve.as register.
2384         assert( _reg_status == LITERAL_ACCESSED, "Must be processing a literal register parameter");
2385         fprintf(_fp,"(%s_enc)", inst_rep_var);
2386         _reg_status = LITERAL_OUTPUT;
2387       }
2388       else {
2389         // Check for unimplemented functionality before hard failure
2390         assert( strcmp(opc->_ident,"label")==0, "Unimplemented() Label");
2391         assert( false, "ShouldNotReachHere()");
2392       }
2393       // all done
2394     }
2395   }
2396 
2397 };  // end class DefineEmitState
2398 
2399 
2400 void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
2401   
2402   //(1)
2403   // Output instruction's emit prototype
2404   fprintf(fp,"uint  %sNode::size(PhaseRegAlloc *ra_) const {\n",
2405           inst._ident);
2406 
2407   fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
2408 
2409   //(2)
2410   // Print the size
2411   fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
2412 
2413   // (3) and (4)
2414   fprintf(fp,"}\n");
2415 }
2416 
2417 void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
2418   InsEncode *ins_encode = inst._insencode;
2419 
2420   // (1)
2421   // Output instruction's emit prototype
2422   fprintf(fp,"void  %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n",
2423           inst._ident);
2424 
2425   // If user did not define an encode section, 
2426   // provide stub that does not generate any machine code.
2427   if( (_encode == NULL) || (ins_encode == NULL) ) {
2428     fprintf(fp, "  // User did not define an encode section.\n");


3452 
3453 // Recurse through match tree, building path through corresponding state tree,
3454 // Until we reach the constant we are looking for.
3455 static void path_to_constant(FILE *fp, FormDict &globals,
3456                              MatchNode *mnode, uint idx) {
3457   if ( ! mnode) return;
3458   
3459   unsigned    position = 0;
3460   const char *result   = NULL;
3461   const char *name     = NULL;
3462   const char *optype   = NULL;
3463 
3464   // Base Case: access constant in ideal node linked to current state node
3465   // Each type of constant has its own access function
3466   if ( (mnode->_lChild == NULL) && (mnode->_rChild == NULL)
3467        && mnode->base_operand(position, globals, result, name, optype) ) {
3468     if (         strcmp(optype,"ConI") == 0 ) {
3469       fprintf(fp, "_leaf->get_int()");
3470     } else if ( (strcmp(optype,"ConP") == 0) ) {
3471       fprintf(fp, "_leaf->bottom_type()->is_ptr()");
3472     } else if ( (strcmp(optype,"ConN") == 0) ) {
3473       fprintf(fp, "_leaf->bottom_type()->is_narrowoop()");
3474     } else if ( (strcmp(optype,"ConF") == 0) ) {
3475       fprintf(fp, "_leaf->getf()");
3476     } else if ( (strcmp(optype,"ConD") == 0) ) {
3477       fprintf(fp, "_leaf->getd()");
3478     } else if ( (strcmp(optype,"ConL") == 0) ) {
3479       fprintf(fp, "_leaf->get_long()");
3480     } else if ( (strcmp(optype,"Con")==0) ) {
3481       // !!!!! - Update if adding a machine-independent constant type
3482       fprintf(fp, "_leaf->get_int()");
3483       assert( false, "Unsupported constant type, pointer or indefinite");
3484     } else if ( (strcmp(optype,"Bool") == 0) ) {
3485       fprintf(fp, "_leaf->as_Bool()->_test._test");
3486     } else {
3487       assert( false, "Unsupported constant type");
3488     }
3489     return;
3490   }
3491 
3492   // If constant is in left child, build path and recurse 
3493   uint lConsts = (mnode->_lChild) ? (mnode->_lChild->num_consts(globals) ) : 0;