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