Mercurial > hg > truffle
comparison src/share/vm/adlc/output_c.cpp @ 14456:abec000618bf
Merge
author | kvn |
---|---|
date | Tue, 28 Jan 2014 12:25:34 -0800 |
parents | d16be2b85802 ad6695638a35 |
children | 194e8b7fe9ca |
comparison
equal
deleted
inserted
replaced
14269:2a8891e0a082 | 14456:abec000618bf |
---|---|
1551 for(expand->reset_instructions(); | 1551 for(expand->reset_instructions(); |
1552 (expand_instr = expand->iter_instructions()) != NULL; cnt++) { | 1552 (expand_instr = expand->iter_instructions()) != NULL; cnt++) { |
1553 new_id = expand_instr->name(); | 1553 new_id = expand_instr->name(); |
1554 | 1554 |
1555 InstructForm* expand_instruction = (InstructForm*)globalAD->globalNames()[new_id]; | 1555 InstructForm* expand_instruction = (InstructForm*)globalAD->globalNames()[new_id]; |
1556 | |
1557 if (!expand_instruction) { | |
1558 globalAD->syntax_err(node->_linenum, "In %s: instruction %s used in expand not declared\n", | |
1559 node->_ident, new_id); | |
1560 continue; | |
1561 } | |
1562 | |
1556 if (expand_instruction->has_temps()) { | 1563 if (expand_instruction->has_temps()) { |
1557 globalAD->syntax_err(node->_linenum, "In %s: expand rules using instructs with TEMPs aren't supported: %s", | 1564 globalAD->syntax_err(node->_linenum, "In %s: expand rules using instructs with TEMPs aren't supported: %s", |
1558 node->_ident, new_id); | 1565 node->_ident, new_id); |
1559 } | 1566 } |
1560 | 1567 |
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 } |
2275 if (strcmp(rep_var,"$Register") == 0) return "as_Register"; | 2302 if (strcmp(rep_var,"$Register") == 0) return "as_Register"; |
2276 if (strcmp(rep_var,"$FloatRegister") == 0) return "as_FloatRegister"; | 2303 if (strcmp(rep_var,"$FloatRegister") == 0) return "as_FloatRegister"; |
2277 #if defined(IA32) || defined(AMD64) | 2304 #if defined(IA32) || defined(AMD64) |
2278 if (strcmp(rep_var,"$XMMRegister") == 0) return "as_XMMRegister"; | 2305 if (strcmp(rep_var,"$XMMRegister") == 0) return "as_XMMRegister"; |
2279 #endif | 2306 #endif |
2307 if (strcmp(rep_var,"$CondRegister") == 0) return "as_ConditionRegister"; | |
2280 return NULL; | 2308 return NULL; |
2281 } | 2309 } |
2282 | 2310 |
2283 void emit_field(const char *rep_var) { | 2311 void emit_field(const char *rep_var) { |
2284 const char* reg_convert = reg_conversion(rep_var); | 2312 const char* reg_convert = reg_conversion(rep_var); |
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; |
2822 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); | 2956 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); |
2823 emit_position = true; | 2957 emit_position = true; |
2824 } else if ( (strcmp(name,"disp") == 0) ) { | 2958 } else if ( (strcmp(name,"disp") == 0) ) { |
2825 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); | 2959 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); |
2826 } else { | 2960 } else { |
2827 fprintf(fp,"() const { \n"); | 2961 fprintf(fp, "() const {\n"); |
2828 } | 2962 } |
2829 | 2963 |
2830 // Check for hexadecimal value OR replacement variable | 2964 // Check for hexadecimal value OR replacement variable |
2831 if( *encoding == '$' ) { | 2965 if( *encoding == '$' ) { |
2832 // Replacement variable | 2966 // Replacement variable |
2872 } | 3006 } |
2873 else if( *encoding == '0' && *(encoding+1) == 'x' ) { | 3007 else if( *encoding == '0' && *(encoding+1) == 'x' ) { |
2874 // Hex value | 3008 // Hex value |
2875 fprintf(fp," return %s;\n", encoding); | 3009 fprintf(fp," return %s;\n", encoding); |
2876 } else { | 3010 } else { |
3011 globalAD->syntax_err(oper._linenum, "In operand %s: Do not support this encode constant: '%s' for %s.", | |
3012 oper._ident, encoding, name); | |
2877 assert( false, "Do not support octal or decimal encode constants"); | 3013 assert( false, "Do not support octal or decimal encode constants"); |
2878 } | 3014 } |
2879 fprintf(fp," }\n"); | 3015 fprintf(fp," }\n"); |
2880 | 3016 |
2881 if( emit_position && (position != -1) && (oper.num_edges(globals) > 0) ) { | 3017 if( emit_position && (position != -1) && (oper.num_edges(globals) > 0) ) { |
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); |
3482 else if (!strcmp(calling_convention, "SOC")) callconv = 'C'; | 3627 else if (!strcmp(calling_convention, "SOC")) callconv = 'C'; |
3483 else if (!strcmp(calling_convention, "AS")) callconv = 'A'; | 3628 else if (!strcmp(calling_convention, "AS")) callconv = 'A'; |
3484 else callconv = 'Z'; | 3629 else callconv = 'Z'; |
3485 | 3630 |
3486 return callconv; | 3631 return callconv; |
3632 } | |
3633 | |
3634 void ArchDesc::generate_needs_clone_jvms(FILE *fp_cpp) { | |
3635 fprintf(fp_cpp, "bool Compile::needs_clone_jvms() { return %s; }\n\n", | |
3636 _needs_clone_jvms ? "true" : "false"); | |
3487 } | 3637 } |
3488 | 3638 |
3489 //---------------------------generate_assertion_checks------------------- | 3639 //---------------------------generate_assertion_checks------------------- |
3490 void ArchDesc::generate_adlc_verification(FILE *fp_cpp) { | 3640 void ArchDesc::generate_adlc_verification(FILE *fp_cpp) { |
3491 fprintf(fp_cpp, "\n"); | 3641 fprintf(fp_cpp, "\n"); |
3800 fprintf(fp_cpp, " );\n"); | 3950 fprintf(fp_cpp, " );\n"); |
3801 // ##### | 3951 // ##### |
3802 } | 3952 } |
3803 | 3953 |
3804 // Fill in the bottom_type where requested | 3954 // Fill in the bottom_type where requested |
3805 if ( inst->captures_bottom_type(_globalNames) ) { | 3955 if (inst->captures_bottom_type(_globalNames)) { |
3806 fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent); | 3956 if (strncmp("MachCall", inst->mach_base_class(_globalNames), strlen("MachCall"))) { |
3957 fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent); | |
3958 } | |
3807 } | 3959 } |
3808 if( inst->is_ideal_if() ) { | 3960 if( inst->is_ideal_if() ) { |
3809 fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent); | 3961 fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent); |
3810 fprintf(fp_cpp, "%s node->_fcnt = _leaf->as_If()->_fcnt;\n", indent); | 3962 fprintf(fp_cpp, "%s node->_fcnt = _leaf->as_If()->_fcnt;\n", indent); |
3811 } | 3963 } |