1609 int prev_pos = -1; |
1616 int prev_pos = -1; |
1610 for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) { |
1617 for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) { |
1611 // Use 'parameter' at current position in list of new instruction's formals |
1618 // Use 'parameter' at current position in list of new instruction's formals |
1612 // instead of 'opid' when looking up info internal to new_inst |
1619 // instead of 'opid' when looking up info internal to new_inst |
1613 const char *parameter = formal_lst->iter(); |
1620 const char *parameter = formal_lst->iter(); |
|
1621 if (!parameter) { |
|
1622 globalAD->syntax_err(node->_linenum, "Operand %s of expand instruction %s has" |
|
1623 " no equivalent in new instruction %s.", |
|
1624 opid, node->_ident, new_inst->_ident); |
|
1625 assert(0, "Wrong expand"); |
|
1626 } |
|
1627 |
1614 // Check for an operand which is created in the expand rule |
1628 // Check for an operand which is created in the expand rule |
1615 if ((exp_pos = node->_exprule->_newopers.index(opid)) != -1) { |
1629 if ((exp_pos = node->_exprule->_newopers.index(opid)) != -1) { |
1616 new_pos = new_inst->operand_position(parameter,Component::USE); |
1630 new_pos = new_inst->operand_position(parameter,Component::USE); |
1617 exp_pos += node->num_opnds(); |
1631 exp_pos += node->num_opnds(); |
1618 // If there is no use of the created operand, just skip it |
1632 // If there is no use of the created operand, just skip it |
1806 } |
1820 } |
1807 } |
1821 } |
1808 |
1822 |
1809 // If the node is a MachConstantNode, insert the MachConstantBaseNode edge. |
1823 // If the node is a MachConstantNode, insert the MachConstantBaseNode edge. |
1810 // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input). |
1824 // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input). |
1811 if (node->is_mach_constant()) { |
1825 // There are nodes that don't use $constantablebase, but still require that it |
1812 fprintf(fp," add_req(C->mach_constant_base_node());\n"); |
1826 // is an input to the node. Example: divF_reg_immN, Repl32B_imm on x86_64. |
1813 } |
1827 if (node->is_mach_constant() || node->needs_constant_base()) { |
1814 |
1828 if (node->is_ideal_call() != Form::invalid_type && |
1815 fprintf(fp,"\n"); |
1829 node->is_ideal_call() != Form::JAVA_LEAF) { |
1816 if( node->expands() ) { |
1830 fprintf(fp, " // MachConstantBaseNode added in matcher.\n"); |
1817 fprintf(fp," return result;\n"); |
1831 _needs_clone_jvms = true; |
|
1832 } else { |
|
1833 fprintf(fp, " add_req(C->mach_constant_base_node());\n"); |
|
1834 } |
|
1835 } |
|
1836 |
|
1837 fprintf(fp, "\n"); |
|
1838 if (node->expands()) { |
|
1839 fprintf(fp, " return result;\n"); |
1818 } else { |
1840 } else { |
1819 fprintf(fp," return this;\n"); |
1841 fprintf(fp, " return this;\n"); |
1820 } |
1842 } |
1821 fprintf(fp,"}\n"); |
1843 fprintf(fp, "}\n"); |
1822 fprintf(fp,"\n"); |
1844 fprintf(fp, "\n"); |
1823 } |
1845 } |
1824 |
1846 |
1825 |
1847 |
1826 //------------------------------Emit Routines---------------------------------- |
1848 //------------------------------Emit Routines---------------------------------- |
1827 // Special classes and routines for defining node emit routines which output |
1849 // Special classes and routines for defining node emit routines which output |
1919 "'primary', 'secondary' and 'tertiary' don't follow operand."); |
1941 "'primary', 'secondary' and 'tertiary' don't follow operand."); |
1920 } |
1942 } |
1921 else if ((strcmp(rep_var, "constanttablebase") == 0) || |
1943 else if ((strcmp(rep_var, "constanttablebase") == 0) || |
1922 (strcmp(rep_var, "constantoffset") == 0) || |
1944 (strcmp(rep_var, "constantoffset") == 0) || |
1923 (strcmp(rep_var, "constantaddress") == 0)) { |
1945 (strcmp(rep_var, "constantaddress") == 0)) { |
1924 if (!_inst.is_mach_constant()) { |
1946 if (!(_inst.is_mach_constant() || _inst.needs_constant_base())) { |
1925 _AD.syntax_err(_encoding._linenum, |
1947 _AD.syntax_err(_encoding._linenum, |
1926 "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n", |
1948 "Replacement variable %s not allowed in instruct %s (only in MachConstantNode or MachCall).\n", |
1927 rep_var, _encoding._name); |
1949 rep_var, _encoding._name); |
1928 } |
1950 } |
1929 } |
1951 } |
1930 else { |
1952 else { |
1931 // Lookup its position in (formal) parameter list of encoding |
1953 // Lookup its position in (formal) parameter list of encoding |
2084 if ( _reg_status != LITERAL_NOT_SEEN ) { |
2106 if ( _reg_status != LITERAL_NOT_SEEN ) { |
2085 assert( _reg_status == LITERAL_SEEN, "Must have seen register literal before now"); |
2107 assert( _reg_status == LITERAL_SEEN, "Must have seen register literal before now"); |
2086 if (strcmp(rep_var,"$reg") == 0 || reg_conversion(rep_var) != NULL) { |
2108 if (strcmp(rep_var,"$reg") == 0 || reg_conversion(rep_var) != NULL) { |
2087 _reg_status = LITERAL_ACCESSED; |
2109 _reg_status = LITERAL_ACCESSED; |
2088 } else { |
2110 } else { |
|
2111 _AD.syntax_err(_encoding._linenum, |
|
2112 "Invalid access to literal register parameter '%s' in %s.\n", |
|
2113 rep_var, _encoding._name); |
2089 assert( false, "invalid access to literal register parameter"); |
2114 assert( false, "invalid access to literal register parameter"); |
2090 } |
2115 } |
2091 } |
2116 } |
2092 // literal constant parameters must be accessed as a 'constant' field |
2117 // literal constant parameters must be accessed as a 'constant' field |
2093 if ( _constant_status != LITERAL_NOT_SEEN ) { |
2118 if (_constant_status != LITERAL_NOT_SEEN) { |
2094 assert( _constant_status == LITERAL_SEEN, "Must have seen constant literal before now"); |
2119 assert(_constant_status == LITERAL_SEEN, "Must have seen constant literal before now"); |
2095 if( strcmp(rep_var,"$constant") == 0 ) { |
2120 if (strcmp(rep_var,"$constant") == 0) { |
2096 _constant_status = LITERAL_ACCESSED; |
2121 _constant_status = LITERAL_ACCESSED; |
2097 } else { |
2122 } else { |
2098 assert( false, "invalid access to literal constant parameter"); |
2123 _AD.syntax_err(_encoding._linenum, |
|
2124 "Invalid access to literal constant parameter '%s' in %s.\n", |
|
2125 rep_var, _encoding._name); |
2099 } |
2126 } |
2100 } |
2127 } |
2101 } // end replacement and/or subfield |
2128 } // end replacement and/or subfield |
2102 |
2129 |
2103 } |
2130 } |
2469 //(2) |
2497 //(2) |
2470 // Print the size |
2498 // Print the size |
2471 fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size); |
2499 fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size); |
2472 |
2500 |
2473 // (3) and (4) |
2501 // (3) and (4) |
2474 fprintf(fp,"}\n"); |
2502 fprintf(fp,"}\n\n"); |
|
2503 } |
|
2504 |
|
2505 // Emit late expand function. |
|
2506 void ArchDesc::define_postalloc_expand(FILE *fp, InstructForm &inst) { |
|
2507 InsEncode *ins_encode = inst._insencode; |
|
2508 |
|
2509 // Output instruction's postalloc_expand prototype. |
|
2510 fprintf(fp, "void %sNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {\n", |
|
2511 inst._ident); |
|
2512 |
|
2513 assert((_encode != NULL) && (ins_encode != NULL), "You must define an encode section."); |
|
2514 |
|
2515 // Output each operand's offset into the array of registers. |
|
2516 inst.index_temps(fp, _globalNames); |
|
2517 |
|
2518 // Output variables "unsigned idx_<par_name>", Node *n_<par_name> and "MachOpnd *op_<par_name>" |
|
2519 // for each parameter <par_name> specified in the encoding. |
|
2520 ins_encode->reset(); |
|
2521 const char *ec_name = ins_encode->encode_class_iter(); |
|
2522 assert(ec_name != NULL, "late expand must specify an encoding"); |
|
2523 |
|
2524 EncClass *encoding = _encode->encClass(ec_name); |
|
2525 if (encoding == NULL) { |
|
2526 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); |
|
2527 abort(); |
|
2528 } |
|
2529 if (ins_encode->current_encoding_num_args() != encoding->num_args()) { |
|
2530 globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", |
|
2531 inst._ident, ins_encode->current_encoding_num_args(), |
|
2532 ec_name, encoding->num_args()); |
|
2533 } |
|
2534 |
|
2535 fprintf(fp, " // Access to ins and operands for late expand.\n"); |
|
2536 const int buflen = 2000; |
|
2537 char idxbuf[buflen]; char *ib = idxbuf; sprintf(ib, ""); |
|
2538 char nbuf [buflen]; char *nb = nbuf; sprintf(nb, ""); |
|
2539 char opbuf [buflen]; char *ob = opbuf; sprintf(ob, ""); |
|
2540 |
|
2541 encoding->_parameter_type.reset(); |
|
2542 encoding->_parameter_name.reset(); |
|
2543 const char *type = encoding->_parameter_type.iter(); |
|
2544 const char *name = encoding->_parameter_name.iter(); |
|
2545 int param_no = 0; |
|
2546 for (; (type != NULL) && (name != NULL); |
|
2547 (type = encoding->_parameter_type.iter()), (name = encoding->_parameter_name.iter())) { |
|
2548 const char* arg_name = ins_encode->rep_var_name(inst, param_no); |
|
2549 int idx = inst.operand_position_format(arg_name); |
|
2550 if (strcmp(arg_name, "constanttablebase") == 0) { |
|
2551 ib += sprintf(ib, " unsigned idx_%-5s = mach_constant_base_node_input(); \t// %s, \t%s\n", |
|
2552 name, type, arg_name); |
|
2553 nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); |
|
2554 // There is no operand for the constanttablebase. |
|
2555 } else if (inst.is_noninput_operand(idx)) { |
|
2556 globalAD->syntax_err(inst._linenum, |
|
2557 "In %s: you can not pass the non-input %s to a late expand encoding.\n", |
|
2558 inst._ident, arg_name); |
|
2559 } else { |
|
2560 ib += sprintf(ib, " unsigned idx_%-5s = idx%d; \t// %s, \t%s\n", |
|
2561 name, idx, type, arg_name); |
|
2562 nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); |
|
2563 ob += sprintf(ob, " %sOper *op_%s = (%sOper *)opnd_array(%d);\n", type, name, type, idx); |
|
2564 } |
|
2565 param_no++; |
|
2566 } |
|
2567 assert(ib < &idxbuf[buflen-1] && nb < &nbuf[buflen-1] && ob < &opbuf[buflen-1], "buffer overflow"); |
|
2568 |
|
2569 fprintf(fp, "%s", idxbuf); |
|
2570 fprintf(fp, " Node *n_region = lookup(0);\n"); |
|
2571 fprintf(fp, "%s%s", nbuf, opbuf); |
|
2572 fprintf(fp, " Compile *C = ra_->C;\n"); |
|
2573 |
|
2574 // Output this instruction's encodings. |
|
2575 fprintf(fp, " {"); |
|
2576 const char *ec_code = NULL; |
|
2577 const char *ec_rep_var = NULL; |
|
2578 assert(encoding == _encode->encClass(ec_name), ""); |
|
2579 |
|
2580 DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst); |
|
2581 encoding->_code.reset(); |
|
2582 encoding->_rep_vars.reset(); |
|
2583 // Process list of user-defined strings, |
|
2584 // and occurrences of replacement variables. |
|
2585 // Replacement Vars are pushed into a list and then output. |
|
2586 while ((ec_code = encoding->_code.iter()) != NULL) { |
|
2587 if (! encoding->_code.is_signal(ec_code)) { |
|
2588 // Emit pending code. |
|
2589 pending.emit(); |
|
2590 pending.clear(); |
|
2591 // Emit this code section. |
|
2592 fprintf(fp, "%s", ec_code); |
|
2593 } else { |
|
2594 // A replacement variable or one of its subfields. |
|
2595 // Obtain replacement variable from list. |
|
2596 ec_rep_var = encoding->_rep_vars.iter(); |
|
2597 pending.add_rep_var(ec_rep_var); |
|
2598 } |
|
2599 } |
|
2600 // Emit pending code. |
|
2601 pending.emit(); |
|
2602 pending.clear(); |
|
2603 fprintf(fp, " }\n"); |
|
2604 |
|
2605 fprintf(fp, "}\n\n"); |
|
2606 |
|
2607 ec_name = ins_encode->encode_class_iter(); |
|
2608 assert(ec_name == NULL, "Late expand may only have one encoding."); |
2475 } |
2609 } |
2476 |
2610 |
2477 // defineEmit ----------------------------------------------------------------- |
2611 // defineEmit ----------------------------------------------------------------- |
2478 void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { |
2612 void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { |
2479 InsEncode* encode = inst._insencode; |
2613 InsEncode* encode = inst._insencode; |
3036 if ( instr->ideal_only() ) continue; |
3172 if ( instr->ideal_only() ) continue; |
3037 // If there are multiple defs/kills, or an explicit expand rule, build rule |
3173 // If there are multiple defs/kills, or an explicit expand rule, build rule |
3038 if( instr->expands() || instr->needs_projections() || |
3174 if( instr->expands() || instr->needs_projections() || |
3039 instr->has_temps() || |
3175 instr->has_temps() || |
3040 instr->is_mach_constant() || |
3176 instr->is_mach_constant() || |
|
3177 instr->needs_constant_base() || |
3041 instr->_matrule != NULL && |
3178 instr->_matrule != NULL && |
3042 instr->num_opnds() != instr->num_unique_opnds() ) |
3179 instr->num_opnds() != instr->num_unique_opnds() ) |
3043 defineExpand(_CPP_EXPAND_file._fp, instr); |
3180 defineExpand(_CPP_EXPAND_file._fp, instr); |
3044 // If there is an explicit peephole rule, build it |
3181 // If there is an explicit peephole rule, build it |
3045 if ( instr->peepholes() ) |
3182 if ( instr->peepholes() ) |
3123 _instructions.reset(); |
3260 _instructions.reset(); |
3124 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) { |
3261 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) { |
3125 // Ensure this is a machine-world instruction |
3262 // Ensure this is a machine-world instruction |
3126 if ( instr->ideal_only() ) continue; |
3263 if ( instr->ideal_only() ) continue; |
3127 |
3264 |
3128 if (instr->_insencode) defineEmit (fp, *instr); |
3265 if (instr->_insencode) { |
|
3266 if (instr->postalloc_expands()) { |
|
3267 // Don't write this to _CPP_EXPAND_file, as the code generated calls C-code |
|
3268 // from code sections in ad file that is dumped to fp. |
|
3269 define_postalloc_expand(fp, *instr); |
|
3270 } else { |
|
3271 defineEmit(fp, *instr); |
|
3272 } |
|
3273 } |
3129 if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); |
3274 if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); |
3130 if (instr->_size) defineSize (fp, *instr); |
3275 if (instr->_size) defineSize (fp, *instr); |
3131 |
3276 |
3132 // side-call to generate output that used to be in the header file: |
3277 // side-call to generate output that used to be in the header file: |
3133 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file); |
3278 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file); |