src/share/vm/adlc/output_c.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/adlc/output_c.cpp	Fri Nov 12 05:56:34 2010
--- new/src/share/vm/adlc/output_c.cpp	Fri Nov 12 05:56:34 2010

*** 1494,1505 **** --- 1494,1505 ---- void ArchDesc::defineExpand(FILE *fp, InstructForm *node) { unsigned cnt = 0; // Count nodes we have expand into unsigned i; // Generate Expand function header ! fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident); ! fprintf(fp,"Compile* C = Compile::current();\n"); ! fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident); ! fprintf(fp, " Compile* C = Compile::current();\n"); // Generate expand code if( node->expands() ) { const char *opid; int new_pos, exp_pos; const char *new_id = NULL;
*** 1816,1825 **** --- 1816,1831 ---- fprintf(fp," proj_list.push(kill);\n"); } } } + // If the node is a MachConstantNode, insert the MachConstantBaseNode edge. + // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input). + if (node->is_mach_constant()) { + fprintf(fp," add_req(C->mach_constant_base_node());\n"); + } + fprintf(fp,"\n"); if( node->expands() ) { fprintf(fp," return result;\n"); } else { fprintf(fp," return this;\n");
*** 1922,1932 **** --- 1928,1948 ---- // check_rep_var( rep_var ); if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) { // No state needed. assert( _opclass == NULL, "'primary', 'secondary' and 'tertiary' don't follow operand."); } else { + } + else if ((strcmp(rep_var, "constanttablebase") == 0) || + (strcmp(rep_var, "constantoffset") == 0) || + (strcmp(rep_var, "constantaddress") == 0)) { + if (!_inst.is_mach_constant()) { + _AD.syntax_err(_encoding._linenum, + "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n", + rep_var, _encoding._name); + } + } + else { // Lookup its position in parameter list int param_no = _encoding.rep_var_index(rep_var); if ( param_no == -1 ) { _AD.syntax_err( _encoding._linenum, "Replacement variable %s not found in enc_class %s.\n",
*** 2378,2387 **** --- 2394,2412 ---- _AD.syntax_err( _inst._linenum, "Missing $%s opcode definition in %s, used by encoding %s\n", rep_var, _inst._ident, _encoding._name); } } + else if (strcmp(rep_var, "constanttablebase") == 0) { + fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))"); + } + else if (strcmp(rep_var, "constantoffset") == 0) { + fprintf(_fp, "constant_offset()"); + } + else if (strcmp(rep_var, "constantaddress") == 0) { + fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())"); + } else { // Lookup its position in parameter list int param_no = _encoding.rep_var_index(rep_var); if ( param_no == -1 ) { _AD.syntax_err( _encoding._linenum,
*** 2463,2503 **** --- 2488,2530 ---- // (3) and (4) fprintf(fp,"}\n"); } void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) { InsEncode *ins_encode = inst._insencode; + // defineEmit ----------------------------------------------------------------- + void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { + InsEncode* encode = inst._insencode; // (1) // Output instruction's emit prototype ! fprintf(fp,"void %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n", inst._ident); ! fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident); // If user did not define an encode section, // provide stub that does not generate any machine code. - if( (_encode == NULL) || (ins_encode == NULL) ) { fprintf(fp, " // User did not define an encode section.\n"); ! fprintf(fp, "}\n"); return; } // Save current instruction's starting address (helps with relocation). fprintf(fp, " cbuf.set_insts_mark();\n"); // // // idx0 is only needed for syntactic purposes and only by "storeSSI" // fprintf( fp, " unsigned idx0 = 0;\n"); + // For MachConstantNodes which are ideal jump nodes, fill the jump table. + if (inst.is_mach_constant() && inst.is_ideal_jump()) { + fprintf(fp, " fill_jump_table_in_constant_table(cbuf, _index2label);\n"); + } // Output each operand's offset into the array of registers. ! inst.index_temps( fp, _globalNames ); // Output this instruction's encodings const char *ec_name; bool user_defined = false; - ins_encode->reset(); ! while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) { ! fprintf(fp, " {"); ! while ((ec_name = encode->encode_class_iter()) != NULL) { ! fprintf(fp, " {\n"); // Output user-defined encoding user_defined = true; const char *ec_code = NULL; const char *ec_rep_var = NULL;
*** 2505,2553 **** --- 2532,2659 ---- if (encoding == NULL) { fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); abort(); } - if (ins_encode->current_encoding_num_args() != encoding->num_args()) { - globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", - inst._ident, ins_encode->current_encoding_num_args(), ec_name, encoding->num_args()); } ! DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst ); ! DefineEmitState pending(fp, *this, *encoding, *encode, inst); encoding->_code.reset(); encoding->_rep_vars.reset(); // Process list of user-defined strings, // and occurrences of replacement variables. // Replacement Vars are pushed into a list and then output ! while ( (ec_code = encoding->_code.iter()) != NULL ) { ! if ( ! encoding->_code.is_signal( ec_code ) ) { ! if (!encoding->_code.is_signal(ec_code)) { // Emit pending code pending.emit(); pending.clear(); // Emit this code section ! fprintf(fp, "%s", ec_code); } else { // A replacement variable or one of its subfields // Obtain replacement variable from list ec_rep_var = encoding->_rep_vars.iter(); pending.add_rep_var(ec_rep_var); } } // Emit pending code pending.emit(); pending.clear(); ! fprintf(fp, " }\n"); } // end while instruction's encodings // Check if user stated which encoding to user if ( user_defined == false ) { fprintf(fp, " // User did not define which encode class to use.\n"); } // (3) and (4) ! fprintf(fp, "}\n"); + } + + // defineEvalConstant --------------------------------------------------------- + void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) { + InsEncode* encode = inst._constant; + + // (1) + // Output instruction's emit prototype + fprintf(fp, "void %sNode::eval_constant() {\n", inst._ident); + + // For ideal jump nodes, allocate a jump table. + if (inst.is_ideal_jump()) { + fprintf(fp, " allocate_jump_table_in_constant_table();\n"); + } + + // If user did not define an encode section, + // provide stub that does not generate any machine code. + if ((_encode == NULL) || (encode == NULL)) { + fprintf(fp, " // User did not define an encode section.\n"); + fprintf(fp, "}\n"); + return; + } + + // Output this instruction's encodings + const char *ec_name; + bool user_defined = false; + encode->reset(); + while ((ec_name = encode->encode_class_iter()) != NULL) { + fprintf(fp, " {\n"); + // Output user-defined encoding + user_defined = true; + + const char *ec_code = NULL; + const char *ec_rep_var = NULL; + EncClass *encoding = _encode->encClass(ec_name); + if (encoding == NULL) { + fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); + abort(); + } + + if (encode->current_encoding_num_args() != encoding->num_args()) { + globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", + inst._ident, encode->current_encoding_num_args(), + ec_name, encoding->num_args()); + } + + DefineEmitState pending(fp, *this, *encoding, *encode, inst); + encoding->_code.reset(); + encoding->_rep_vars.reset(); + // Process list of user-defined strings, + // and occurrences of replacement variables. + // Replacement Vars are pushed into a list and then output + while ((ec_code = encoding->_code.iter()) != NULL) { + if (!encoding->_code.is_signal(ec_code)) { + // Emit pending code + pending.emit(); + pending.clear(); + // Emit this code section + fprintf(fp, "%s", ec_code); + } else { + // A replacement variable or one of its subfields + // Obtain replacement variable from list + ec_rep_var = encoding->_rep_vars.iter(); + pending.add_rep_var(ec_rep_var); + } + } + // Emit pending code + pending.emit(); + pending.clear(); + fprintf(fp, " }\n"); + } // end while instruction's encodings + + // Check if user stated which encoding to user + if (user_defined == false) { + fprintf(fp, " // User did not define which encode class to use.\n"); + } + + // (3) and (4) + fprintf(fp, "}\n"); } // --------------------------------------------------------------------------- //--------Utilities to build MachOper and MachNode derived Classes------------ // ---------------------------------------------------------------------------
*** 2950,2959 **** --- 3056,3066 ---- // Ensure this is a machine-world instruction if ( instr->ideal_only() ) continue; // If there are multiple defs/kills, or an explicit expand rule, build rule if( instr->expands() || instr->needs_projections() || instr->has_temps() || + instr->is_mach_constant() || instr->_matrule != NULL && instr->num_opnds() != instr->num_unique_opnds() ) defineExpand(_CPP_EXPAND_file._fp, instr); // If there is an explicit peephole rule, build it if ( instr->peepholes() )
*** 3030,3041 **** --- 3137,3149 ---- _instructions.reset(); for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) { // Ensure this is a machine-world instruction if ( instr->ideal_only() ) continue; ! if (instr->_insencode) defineEmit (fp, *instr); ! if (instr->_size) defineSize(fp, *instr); ! if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); + if (instr->_size) defineSize (fp, *instr); // side-call to generate output that used to be in the header file: extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file); gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true); }

src/share/vm/adlc/output_c.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File