1.1 --- a/src/share/vm/adlc/output_c.cpp Thu Dec 02 17:21:12 2010 -0800 1.2 +++ b/src/share/vm/adlc/output_c.cpp Fri Dec 03 01:34:31 2010 -0800 1.3 @@ -1496,8 +1496,8 @@ 1.4 unsigned i; 1.5 1.6 // Generate Expand function header 1.7 - fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident); 1.8 - fprintf(fp,"Compile* C = Compile::current();\n"); 1.9 + fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident); 1.10 + fprintf(fp, " Compile* C = Compile::current();\n"); 1.11 // Generate expand code 1.12 if( node->expands() ) { 1.13 const char *opid; 1.14 @@ -1818,6 +1818,12 @@ 1.15 } 1.16 } 1.17 1.18 + // If the node is a MachConstantNode, insert the MachConstantBaseNode edge. 1.19 + // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input). 1.20 + if (node->is_mach_constant()) { 1.21 + fprintf(fp," add_req(C->mach_constant_base_node());\n"); 1.22 + } 1.23 + 1.24 fprintf(fp,"\n"); 1.25 if( node->expands() ) { 1.26 fprintf(fp," return result;\n"); 1.27 @@ -1924,7 +1930,17 @@ 1.28 // No state needed. 1.29 assert( _opclass == NULL, 1.30 "'primary', 'secondary' and 'tertiary' don't follow operand."); 1.31 - } else { 1.32 + } 1.33 + else if ((strcmp(rep_var, "constanttablebase") == 0) || 1.34 + (strcmp(rep_var, "constantoffset") == 0) || 1.35 + (strcmp(rep_var, "constantaddress") == 0)) { 1.36 + if (!_inst.is_mach_constant()) { 1.37 + _AD.syntax_err(_encoding._linenum, 1.38 + "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n", 1.39 + rep_var, _encoding._name); 1.40 + } 1.41 + } 1.42 + else { 1.43 // Lookup its position in parameter list 1.44 int param_no = _encoding.rep_var_index(rep_var); 1.45 if ( param_no == -1 ) { 1.46 @@ -2380,6 +2396,15 @@ 1.47 rep_var, _inst._ident, _encoding._name); 1.48 } 1.49 } 1.50 + else if (strcmp(rep_var, "constanttablebase") == 0) { 1.51 + fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))"); 1.52 + } 1.53 + else if (strcmp(rep_var, "constantoffset") == 0) { 1.54 + fprintf(_fp, "constant_offset()"); 1.55 + } 1.56 + else if (strcmp(rep_var, "constantaddress") == 0) { 1.57 + fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())"); 1.58 + } 1.59 else { 1.60 // Lookup its position in parameter list 1.61 int param_no = _encoding.rep_var_index(rep_var); 1.62 @@ -2465,37 +2490,39 @@ 1.63 fprintf(fp,"}\n"); 1.64 } 1.65 1.66 -void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) { 1.67 - InsEncode *ins_encode = inst._insencode; 1.68 +// defineEmit ----------------------------------------------------------------- 1.69 +void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { 1.70 + InsEncode* encode = inst._insencode; 1.71 1.72 // (1) 1.73 // Output instruction's emit prototype 1.74 - fprintf(fp,"void %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n", 1.75 - inst._ident); 1.76 + fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident); 1.77 1.78 // If user did not define an encode section, 1.79 // provide stub that does not generate any machine code. 1.80 - if( (_encode == NULL) || (ins_encode == NULL) ) { 1.81 + if( (_encode == NULL) || (encode == NULL) ) { 1.82 fprintf(fp, " // User did not define an encode section.\n"); 1.83 - fprintf(fp,"}\n"); 1.84 + fprintf(fp, "}\n"); 1.85 return; 1.86 } 1.87 1.88 // Save current instruction's starting address (helps with relocation). 1.89 - fprintf(fp, " cbuf.set_insts_mark();\n"); 1.90 - 1.91 - // // // idx0 is only needed for syntactic purposes and only by "storeSSI" 1.92 - // fprintf( fp, " unsigned idx0 = 0;\n"); 1.93 + fprintf(fp, " cbuf.set_insts_mark();\n"); 1.94 + 1.95 + // For MachConstantNodes which are ideal jump nodes, fill the jump table. 1.96 + if (inst.is_mach_constant() && inst.is_ideal_jump()) { 1.97 + fprintf(fp, " ra_->C->constant_table().fill_jump_table(cbuf, (MachConstantNode*) this, _index2label);\n"); 1.98 + } 1.99 1.100 // Output each operand's offset into the array of registers. 1.101 - inst.index_temps( fp, _globalNames ); 1.102 + inst.index_temps(fp, _globalNames); 1.103 1.104 // Output this instruction's encodings 1.105 const char *ec_name; 1.106 bool user_defined = false; 1.107 - ins_encode->reset(); 1.108 - while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) { 1.109 - fprintf(fp, " {"); 1.110 + encode->reset(); 1.111 + while ((ec_name = encode->encode_class_iter()) != NULL) { 1.112 + fprintf(fp, " {\n"); 1.113 // Output user-defined encoding 1.114 user_defined = true; 1.115 1.116 @@ -2507,25 +2534,25 @@ 1.117 abort(); 1.118 } 1.119 1.120 - if (ins_encode->current_encoding_num_args() != encoding->num_args()) { 1.121 - globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", 1.122 - inst._ident, ins_encode->current_encoding_num_args(), 1.123 + if (encode->current_encoding_num_args() != encoding->num_args()) { 1.124 + globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", 1.125 + inst._ident, encode->current_encoding_num_args(), 1.126 ec_name, encoding->num_args()); 1.127 } 1.128 1.129 - DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst ); 1.130 + DefineEmitState pending(fp, *this, *encoding, *encode, inst); 1.131 encoding->_code.reset(); 1.132 encoding->_rep_vars.reset(); 1.133 // Process list of user-defined strings, 1.134 // and occurrences of replacement variables. 1.135 // Replacement Vars are pushed into a list and then output 1.136 - while ( (ec_code = encoding->_code.iter()) != NULL ) { 1.137 - if ( ! encoding->_code.is_signal( ec_code ) ) { 1.138 + while ((ec_code = encoding->_code.iter()) != NULL) { 1.139 + if (!encoding->_code.is_signal(ec_code)) { 1.140 // Emit pending code 1.141 pending.emit(); 1.142 pending.clear(); 1.143 // Emit this code section 1.144 - fprintf(fp,"%s", ec_code); 1.145 + fprintf(fp, "%s", ec_code); 1.146 } else { 1.147 // A replacement variable or one of its subfields 1.148 // Obtain replacement variable from list 1.149 @@ -2536,7 +2563,7 @@ 1.150 // Emit pending code 1.151 pending.emit(); 1.152 pending.clear(); 1.153 - fprintf(fp, "}\n"); 1.154 + fprintf(fp, " }\n"); 1.155 } // end while instruction's encodings 1.156 1.157 // Check if user stated which encoding to user 1.158 @@ -2545,7 +2572,86 @@ 1.159 } 1.160 1.161 // (3) and (4) 1.162 - fprintf(fp,"}\n"); 1.163 + fprintf(fp, "}\n"); 1.164 +} 1.165 + 1.166 +// defineEvalConstant --------------------------------------------------------- 1.167 +void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) { 1.168 + InsEncode* encode = inst._constant; 1.169 + 1.170 + // (1) 1.171 + // Output instruction's emit prototype 1.172 + fprintf(fp, "void %sNode::eval_constant(Compile* C) {\n", inst._ident); 1.173 + 1.174 + // For ideal jump nodes, allocate a jump table. 1.175 + if (inst.is_ideal_jump()) { 1.176 + fprintf(fp, " _constant = C->constant_table().allocate_jump_table(this);\n"); 1.177 + } 1.178 + 1.179 + // If user did not define an encode section, 1.180 + // provide stub that does not generate any machine code. 1.181 + if ((_encode == NULL) || (encode == NULL)) { 1.182 + fprintf(fp, " // User did not define an encode section.\n"); 1.183 + fprintf(fp, "}\n"); 1.184 + return; 1.185 + } 1.186 + 1.187 + // Output this instruction's encodings 1.188 + const char *ec_name; 1.189 + bool user_defined = false; 1.190 + encode->reset(); 1.191 + while ((ec_name = encode->encode_class_iter()) != NULL) { 1.192 + fprintf(fp, " {\n"); 1.193 + // Output user-defined encoding 1.194 + user_defined = true; 1.195 + 1.196 + const char *ec_code = NULL; 1.197 + const char *ec_rep_var = NULL; 1.198 + EncClass *encoding = _encode->encClass(ec_name); 1.199 + if (encoding == NULL) { 1.200 + fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); 1.201 + abort(); 1.202 + } 1.203 + 1.204 + if (encode->current_encoding_num_args() != encoding->num_args()) { 1.205 + globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", 1.206 + inst._ident, encode->current_encoding_num_args(), 1.207 + ec_name, encoding->num_args()); 1.208 + } 1.209 + 1.210 + DefineEmitState pending(fp, *this, *encoding, *encode, inst); 1.211 + encoding->_code.reset(); 1.212 + encoding->_rep_vars.reset(); 1.213 + // Process list of user-defined strings, 1.214 + // and occurrences of replacement variables. 1.215 + // Replacement Vars are pushed into a list and then output 1.216 + while ((ec_code = encoding->_code.iter()) != NULL) { 1.217 + if (!encoding->_code.is_signal(ec_code)) { 1.218 + // Emit pending code 1.219 + pending.emit(); 1.220 + pending.clear(); 1.221 + // Emit this code section 1.222 + fprintf(fp, "%s", ec_code); 1.223 + } else { 1.224 + // A replacement variable or one of its subfields 1.225 + // Obtain replacement variable from list 1.226 + ec_rep_var = encoding->_rep_vars.iter(); 1.227 + pending.add_rep_var(ec_rep_var); 1.228 + } 1.229 + } 1.230 + // Emit pending code 1.231 + pending.emit(); 1.232 + pending.clear(); 1.233 + fprintf(fp, " }\n"); 1.234 + } // end while instruction's encodings 1.235 + 1.236 + // Check if user stated which encoding to user 1.237 + if (user_defined == false) { 1.238 + fprintf(fp, " // User did not define which encode class to use.\n"); 1.239 + } 1.240 + 1.241 + // (3) and (4) 1.242 + fprintf(fp, "}\n"); 1.243 } 1.244 1.245 // --------------------------------------------------------------------------- 1.246 @@ -2952,6 +3058,7 @@ 1.247 // If there are multiple defs/kills, or an explicit expand rule, build rule 1.248 if( instr->expands() || instr->needs_projections() || 1.249 instr->has_temps() || 1.250 + instr->is_mach_constant() || 1.251 instr->_matrule != NULL && 1.252 instr->num_opnds() != instr->num_unique_opnds() ) 1.253 defineExpand(_CPP_EXPAND_file._fp, instr); 1.254 @@ -3032,8 +3139,9 @@ 1.255 // Ensure this is a machine-world instruction 1.256 if ( instr->ideal_only() ) continue; 1.257 1.258 - if (instr->_insencode) defineEmit(fp, *instr); 1.259 - if (instr->_size) defineSize(fp, *instr); 1.260 + if (instr->_insencode) defineEmit (fp, *instr); 1.261 + if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); 1.262 + if (instr->_size) defineSize (fp, *instr); 1.263 1.264 // side-call to generate output that used to be in the header file: 1.265 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);