Mercurial > hg > truffle
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 } |