comparison src/share/vm/adlc/output_c.cpp @ 2008:2f644f85485d

6961690: load oops from constant table on SPARC Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence. Reviewed-by: never, kvn
author twisti
date Fri, 03 Dec 2010 01:34:31 -0800
parents 3e8fbc61cee8
children ab42c7e1cf83
comparison
equal deleted inserted replaced
2007:5ddfcf4b079e 2008:2f644f85485d
1494 void ArchDesc::defineExpand(FILE *fp, InstructForm *node) { 1494 void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
1495 unsigned cnt = 0; // Count nodes we have expand into 1495 unsigned cnt = 0; // Count nodes we have expand into
1496 unsigned i; 1496 unsigned i;
1497 1497
1498 // Generate Expand function header 1498 // Generate Expand function header
1499 fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident); 1499 fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident);
1500 fprintf(fp,"Compile* C = Compile::current();\n"); 1500 fprintf(fp, " Compile* C = Compile::current();\n");
1501 // Generate expand code 1501 // Generate expand code
1502 if( node->expands() ) { 1502 if( node->expands() ) {
1503 const char *opid; 1503 const char *opid;
1504 int new_pos, exp_pos; 1504 int new_pos, exp_pos;
1505 const char *new_id = NULL; 1505 const char *new_id = NULL;
1816 fprintf(fp," proj_list.push(kill);\n"); 1816 fprintf(fp," proj_list.push(kill);\n");
1817 } 1817 }
1818 } 1818 }
1819 } 1819 }
1820 1820
1821 // If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
1822 // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input).
1823 if (node->is_mach_constant()) {
1824 fprintf(fp," add_req(C->mach_constant_base_node());\n");
1825 }
1826
1821 fprintf(fp,"\n"); 1827 fprintf(fp,"\n");
1822 if( node->expands() ) { 1828 if( node->expands() ) {
1823 fprintf(fp," return result;\n"); 1829 fprintf(fp," return result;\n");
1824 } else { 1830 } else {
1825 fprintf(fp," return this;\n"); 1831 fprintf(fp," return this;\n");
1922 // check_rep_var( rep_var ); 1928 // check_rep_var( rep_var );
1923 if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) { 1929 if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
1924 // No state needed. 1930 // No state needed.
1925 assert( _opclass == NULL, 1931 assert( _opclass == NULL,
1926 "'primary', 'secondary' and 'tertiary' don't follow operand."); 1932 "'primary', 'secondary' and 'tertiary' don't follow operand.");
1927 } else { 1933 }
1934 else if ((strcmp(rep_var, "constanttablebase") == 0) ||
1935 (strcmp(rep_var, "constantoffset") == 0) ||
1936 (strcmp(rep_var, "constantaddress") == 0)) {
1937 if (!_inst.is_mach_constant()) {
1938 _AD.syntax_err(_encoding._linenum,
1939 "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n",
1940 rep_var, _encoding._name);
1941 }
1942 }
1943 else {
1928 // Lookup its position in parameter list 1944 // Lookup its position in parameter list
1929 int param_no = _encoding.rep_var_index(rep_var); 1945 int param_no = _encoding.rep_var_index(rep_var);
1930 if ( param_no == -1 ) { 1946 if ( param_no == -1 ) {
1931 _AD.syntax_err( _encoding._linenum, 1947 _AD.syntax_err( _encoding._linenum,
1932 "Replacement variable %s not found in enc_class %s.\n", 1948 "Replacement variable %s not found in enc_class %s.\n",
2378 _AD.syntax_err( _inst._linenum, 2394 _AD.syntax_err( _inst._linenum,
2379 "Missing $%s opcode definition in %s, used by encoding %s\n", 2395 "Missing $%s opcode definition in %s, used by encoding %s\n",
2380 rep_var, _inst._ident, _encoding._name); 2396 rep_var, _inst._ident, _encoding._name);
2381 } 2397 }
2382 } 2398 }
2399 else if (strcmp(rep_var, "constanttablebase") == 0) {
2400 fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))");
2401 }
2402 else if (strcmp(rep_var, "constantoffset") == 0) {
2403 fprintf(_fp, "constant_offset()");
2404 }
2405 else if (strcmp(rep_var, "constantaddress") == 0) {
2406 fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())");
2407 }
2383 else { 2408 else {
2384 // Lookup its position in parameter list 2409 // Lookup its position in parameter list
2385 int param_no = _encoding.rep_var_index(rep_var); 2410 int param_no = _encoding.rep_var_index(rep_var);
2386 if ( param_no == -1 ) { 2411 if ( param_no == -1 ) {
2387 _AD.syntax_err( _encoding._linenum, 2412 _AD.syntax_err( _encoding._linenum,
2463 2488
2464 // (3) and (4) 2489 // (3) and (4)
2465 fprintf(fp,"}\n"); 2490 fprintf(fp,"}\n");
2466 } 2491 }
2467 2492
2468 void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) { 2493 // defineEmit -----------------------------------------------------------------
2469 InsEncode *ins_encode = inst._insencode; 2494 void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) {
2495 InsEncode* encode = inst._insencode;
2470 2496
2471 // (1) 2497 // (1)
2472 // Output instruction's emit prototype 2498 // Output instruction's emit prototype
2473 fprintf(fp,"void %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n", 2499 fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident);
2474 inst._ident);
2475 2500
2476 // If user did not define an encode section, 2501 // If user did not define an encode section,
2477 // provide stub that does not generate any machine code. 2502 // provide stub that does not generate any machine code.
2478 if( (_encode == NULL) || (ins_encode == NULL) ) { 2503 if( (_encode == NULL) || (encode == NULL) ) {
2479 fprintf(fp, " // User did not define an encode section.\n"); 2504 fprintf(fp, " // User did not define an encode section.\n");
2480 fprintf(fp,"}\n"); 2505 fprintf(fp, "}\n");
2481 return; 2506 return;
2482 } 2507 }
2483 2508
2484 // Save current instruction's starting address (helps with relocation). 2509 // Save current instruction's starting address (helps with relocation).
2485 fprintf(fp, " cbuf.set_insts_mark();\n"); 2510 fprintf(fp, " cbuf.set_insts_mark();\n");
2486 2511
2487 // // // idx0 is only needed for syntactic purposes and only by "storeSSI" 2512 // For MachConstantNodes which are ideal jump nodes, fill the jump table.
2488 // fprintf( fp, " unsigned idx0 = 0;\n"); 2513 if (inst.is_mach_constant() && inst.is_ideal_jump()) {
2514 fprintf(fp, " ra_->C->constant_table().fill_jump_table(cbuf, (MachConstantNode*) this, _index2label);\n");
2515 }
2489 2516
2490 // Output each operand's offset into the array of registers. 2517 // Output each operand's offset into the array of registers.
2491 inst.index_temps( fp, _globalNames ); 2518 inst.index_temps(fp, _globalNames);
2492 2519
2493 // Output this instruction's encodings 2520 // Output this instruction's encodings
2494 const char *ec_name; 2521 const char *ec_name;
2495 bool user_defined = false; 2522 bool user_defined = false;
2496 ins_encode->reset(); 2523 encode->reset();
2497 while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) { 2524 while ((ec_name = encode->encode_class_iter()) != NULL) {
2498 fprintf(fp, " {"); 2525 fprintf(fp, " {\n");
2499 // Output user-defined encoding 2526 // Output user-defined encoding
2500 user_defined = true; 2527 user_defined = true;
2501 2528
2502 const char *ec_code = NULL; 2529 const char *ec_code = NULL;
2503 const char *ec_rep_var = NULL; 2530 const char *ec_rep_var = NULL;
2505 if (encoding == NULL) { 2532 if (encoding == NULL) {
2506 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); 2533 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2507 abort(); 2534 abort();
2508 } 2535 }
2509 2536
2510 if (ins_encode->current_encoding_num_args() != encoding->num_args()) { 2537 if (encode->current_encoding_num_args() != encoding->num_args()) {
2511 globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", 2538 globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2512 inst._ident, ins_encode->current_encoding_num_args(), 2539 inst._ident, encode->current_encoding_num_args(),
2513 ec_name, encoding->num_args()); 2540 ec_name, encoding->num_args());
2514 } 2541 }
2515 2542
2516 DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst ); 2543 DefineEmitState pending(fp, *this, *encoding, *encode, inst);
2517 encoding->_code.reset(); 2544 encoding->_code.reset();
2518 encoding->_rep_vars.reset(); 2545 encoding->_rep_vars.reset();
2519 // Process list of user-defined strings, 2546 // Process list of user-defined strings,
2520 // and occurrences of replacement variables. 2547 // and occurrences of replacement variables.
2521 // Replacement Vars are pushed into a list and then output 2548 // Replacement Vars are pushed into a list and then output
2522 while ( (ec_code = encoding->_code.iter()) != NULL ) { 2549 while ((ec_code = encoding->_code.iter()) != NULL) {
2523 if ( ! encoding->_code.is_signal( ec_code ) ) { 2550 if (!encoding->_code.is_signal(ec_code)) {
2524 // Emit pending code 2551 // Emit pending code
2525 pending.emit(); 2552 pending.emit();
2526 pending.clear(); 2553 pending.clear();
2527 // Emit this code section 2554 // Emit this code section
2528 fprintf(fp,"%s", ec_code); 2555 fprintf(fp, "%s", ec_code);
2529 } else { 2556 } else {
2530 // A replacement variable or one of its subfields 2557 // A replacement variable or one of its subfields
2531 // Obtain replacement variable from list 2558 // Obtain replacement variable from list
2532 ec_rep_var = encoding->_rep_vars.iter(); 2559 ec_rep_var = encoding->_rep_vars.iter();
2533 pending.add_rep_var(ec_rep_var); 2560 pending.add_rep_var(ec_rep_var);
2534 } 2561 }
2535 } 2562 }
2536 // Emit pending code 2563 // Emit pending code
2537 pending.emit(); 2564 pending.emit();
2538 pending.clear(); 2565 pending.clear();
2539 fprintf(fp, "}\n"); 2566 fprintf(fp, " }\n");
2540 } // end while instruction's encodings 2567 } // end while instruction's encodings
2541 2568
2542 // Check if user stated which encoding to user 2569 // Check if user stated which encoding to user
2543 if ( user_defined == false ) { 2570 if ( user_defined == false ) {
2544 fprintf(fp, " // User did not define which encode class to use.\n"); 2571 fprintf(fp, " // User did not define which encode class to use.\n");
2545 } 2572 }
2546 2573
2547 // (3) and (4) 2574 // (3) and (4)
2548 fprintf(fp,"}\n"); 2575 fprintf(fp, "}\n");
2576 }
2577
2578 // defineEvalConstant ---------------------------------------------------------
2579 void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) {
2580 InsEncode* encode = inst._constant;
2581
2582 // (1)
2583 // Output instruction's emit prototype
2584 fprintf(fp, "void %sNode::eval_constant(Compile* C) {\n", inst._ident);
2585
2586 // For ideal jump nodes, allocate a jump table.
2587 if (inst.is_ideal_jump()) {
2588 fprintf(fp, " _constant = C->constant_table().allocate_jump_table(this);\n");
2589 }
2590
2591 // If user did not define an encode section,
2592 // provide stub that does not generate any machine code.
2593 if ((_encode == NULL) || (encode == NULL)) {
2594 fprintf(fp, " // User did not define an encode section.\n");
2595 fprintf(fp, "}\n");
2596 return;
2597 }
2598
2599 // Output this instruction's encodings
2600 const char *ec_name;
2601 bool user_defined = false;
2602 encode->reset();
2603 while ((ec_name = encode->encode_class_iter()) != NULL) {
2604 fprintf(fp, " {\n");
2605 // Output user-defined encoding
2606 user_defined = true;
2607
2608 const char *ec_code = NULL;
2609 const char *ec_rep_var = NULL;
2610 EncClass *encoding = _encode->encClass(ec_name);
2611 if (encoding == NULL) {
2612 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2613 abort();
2614 }
2615
2616 if (encode->current_encoding_num_args() != encoding->num_args()) {
2617 globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2618 inst._ident, encode->current_encoding_num_args(),
2619 ec_name, encoding->num_args());
2620 }
2621
2622 DefineEmitState pending(fp, *this, *encoding, *encode, inst);
2623 encoding->_code.reset();
2624 encoding->_rep_vars.reset();
2625 // Process list of user-defined strings,
2626 // and occurrences of replacement variables.
2627 // Replacement Vars are pushed into a list and then output
2628 while ((ec_code = encoding->_code.iter()) != NULL) {
2629 if (!encoding->_code.is_signal(ec_code)) {
2630 // Emit pending code
2631 pending.emit();
2632 pending.clear();
2633 // Emit this code section
2634 fprintf(fp, "%s", ec_code);
2635 } else {
2636 // A replacement variable or one of its subfields
2637 // Obtain replacement variable from list
2638 ec_rep_var = encoding->_rep_vars.iter();
2639 pending.add_rep_var(ec_rep_var);
2640 }
2641 }
2642 // Emit pending code
2643 pending.emit();
2644 pending.clear();
2645 fprintf(fp, " }\n");
2646 } // end while instruction's encodings
2647
2648 // Check if user stated which encoding to user
2649 if (user_defined == false) {
2650 fprintf(fp, " // User did not define which encode class to use.\n");
2651 }
2652
2653 // (3) and (4)
2654 fprintf(fp, "}\n");
2549 } 2655 }
2550 2656
2551 // --------------------------------------------------------------------------- 2657 // ---------------------------------------------------------------------------
2552 //--------Utilities to build MachOper and MachNode derived Classes------------ 2658 //--------Utilities to build MachOper and MachNode derived Classes------------
2553 // --------------------------------------------------------------------------- 2659 // ---------------------------------------------------------------------------
2950 // Ensure this is a machine-world instruction 3056 // Ensure this is a machine-world instruction
2951 if ( instr->ideal_only() ) continue; 3057 if ( instr->ideal_only() ) continue;
2952 // If there are multiple defs/kills, or an explicit expand rule, build rule 3058 // If there are multiple defs/kills, or an explicit expand rule, build rule
2953 if( instr->expands() || instr->needs_projections() || 3059 if( instr->expands() || instr->needs_projections() ||
2954 instr->has_temps() || 3060 instr->has_temps() ||
3061 instr->is_mach_constant() ||
2955 instr->_matrule != NULL && 3062 instr->_matrule != NULL &&
2956 instr->num_opnds() != instr->num_unique_opnds() ) 3063 instr->num_opnds() != instr->num_unique_opnds() )
2957 defineExpand(_CPP_EXPAND_file._fp, instr); 3064 defineExpand(_CPP_EXPAND_file._fp, instr);
2958 // If there is an explicit peephole rule, build it 3065 // If there is an explicit peephole rule, build it
2959 if ( instr->peepholes() ) 3066 if ( instr->peepholes() )
3030 _instructions.reset(); 3137 _instructions.reset();
3031 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) { 3138 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3032 // Ensure this is a machine-world instruction 3139 // Ensure this is a machine-world instruction
3033 if ( instr->ideal_only() ) continue; 3140 if ( instr->ideal_only() ) continue;
3034 3141
3035 if (instr->_insencode) defineEmit(fp, *instr); 3142 if (instr->_insencode) defineEmit (fp, *instr);
3036 if (instr->_size) defineSize(fp, *instr); 3143 if (instr->is_mach_constant()) defineEvalConstant(fp, *instr);
3144 if (instr->_size) defineSize (fp, *instr);
3037 3145
3038 // side-call to generate output that used to be in the header file: 3146 // side-call to generate output that used to be in the header file:
3039 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file); 3147 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
3040 gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true); 3148 gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true);
3041 } 3149 }