Mercurial > hg > truffle
comparison src/cpu/sparc/vm/sparc.ad @ 113:ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author | coleenp |
---|---|
date | Sun, 13 Apr 2008 17:43:42 -0400 |
parents | dee7a3f3dc9d |
children | b130b98db9cf |
comparison
equal
deleted
inserted
replaced
110:a49a647afe9a | 113:ba764ed4b6f2 |
---|---|
542 NativeCall::instruction_size); // sethi; setlo; call; delay slot | 542 NativeCall::instruction_size); // sethi; setlo; call; delay slot |
543 } else { | 543 } else { |
544 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); | 544 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); |
545 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); | 545 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); |
546 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); | 546 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); |
547 int klass_load_size; | |
548 if (UseCompressedOops) { | |
549 klass_load_size = 3*BytesPerInstWord; // see MacroAssembler::load_klass() | |
550 } else { | |
551 klass_load_size = 1*BytesPerInstWord; | |
552 } | |
547 if( Assembler::is_simm13(v_off) ) { | 553 if( Assembler::is_simm13(v_off) ) { |
548 return (3*BytesPerInstWord + // ld_ptr, ld_ptr, ld_ptr | 554 return klass_load_size + |
555 (2*BytesPerInstWord + // ld_ptr, ld_ptr | |
549 NativeCall::instruction_size); // call; delay slot | 556 NativeCall::instruction_size); // call; delay slot |
550 } else { | 557 } else { |
551 return (5*BytesPerInstWord + // ld_ptr, set_hi, set, ld_ptr, ld_ptr | 558 return klass_load_size + |
559 (4*BytesPerInstWord + // set_hi, set, ld_ptr, ld_ptr | |
552 NativeCall::instruction_size); // call; delay slot | 560 NativeCall::instruction_size); // call; delay slot |
553 } | 561 } |
554 } | 562 } |
555 } | 563 } |
556 | 564 |
1589 //============================================================================= | 1597 //============================================================================= |
1590 #ifndef PRODUCT | 1598 #ifndef PRODUCT |
1591 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { | 1599 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { |
1592 st->print_cr("\nUEP:"); | 1600 st->print_cr("\nUEP:"); |
1593 #ifdef _LP64 | 1601 #ifdef _LP64 |
1594 st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); | 1602 if (UseCompressedOops) { |
1603 st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass"); | |
1604 st->print_cr("\tSLL R_G5,3,R_G5"); | |
1605 st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5"); | |
1606 } else { | |
1607 st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); | |
1608 } | |
1595 st->print_cr("\tCMP R_G5,R_G3" ); | 1609 st->print_cr("\tCMP R_G5,R_G3" ); |
1596 st->print ("\tTne xcc,R_G0+ST_RESERVED_FOR_USER_0+2"); | 1610 st->print ("\tTne xcc,R_G0+ST_RESERVED_FOR_USER_0+2"); |
1597 #else // _LP64 | 1611 #else // _LP64 |
1598 st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); | 1612 st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); |
1599 st->print_cr("\tCMP R_G5,R_G3" ); | 1613 st->print_cr("\tCMP R_G5,R_G3" ); |
1608 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); | 1622 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); |
1609 Register temp_reg = G3; | 1623 Register temp_reg = G3; |
1610 assert( G5_ic_reg != temp_reg, "conflicting registers" ); | 1624 assert( G5_ic_reg != temp_reg, "conflicting registers" ); |
1611 | 1625 |
1612 // Load klass from reciever | 1626 // Load klass from reciever |
1613 __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg); | 1627 __ load_klass(O0, temp_reg); |
1614 // Compare against expected klass | 1628 // Compare against expected klass |
1615 __ cmp(temp_reg, G5_ic_reg); | 1629 __ cmp(temp_reg, G5_ic_reg); |
1616 // Branch to miss code, checks xcc or icc depending | 1630 // Branch to miss code, checks xcc or icc depending |
1617 __ trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0+2); | 1631 __ trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0+2); |
1618 } | 1632 } |
1809 reg == R_I1H_num || | 1823 reg == R_I1H_num || |
1810 reg == R_I2H_num || | 1824 reg == R_I2H_num || |
1811 reg == R_I3H_num || | 1825 reg == R_I3H_num || |
1812 reg == R_I4H_num || | 1826 reg == R_I4H_num || |
1813 reg == R_I5H_num ) return true; | 1827 reg == R_I5H_num ) return true; |
1828 | |
1829 if ((UseCompressedOops) && (reg == R_G6_num || reg == R_G6H_num)) { | |
1830 return true; | |
1831 } | |
1832 | |
1814 #else | 1833 #else |
1815 // 32-bit builds with longs-in-one-entry pass longs in G1 & G4. | 1834 // 32-bit builds with longs-in-one-entry pass longs in G1 & G4. |
1816 // Longs cannot be passed in O regs, because O regs become I regs | 1835 // Longs cannot be passed in O regs, because O regs become I regs |
1817 // after a 'save' and I regs get their high bits chopped off on | 1836 // after a 'save' and I regs get their high bits chopped off on |
1818 // interrupt. | 1837 // interrupt. |
2472 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); | 2491 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); |
2473 // Just go thru the vtable | 2492 // Just go thru the vtable |
2474 // get receiver klass (receiver already checked for non-null) | 2493 // get receiver klass (receiver already checked for non-null) |
2475 // If we end up going thru a c2i adapter interpreter expects method in G5 | 2494 // If we end up going thru a c2i adapter interpreter expects method in G5 |
2476 int off = __ offset(); | 2495 int off = __ offset(); |
2477 __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); | 2496 __ load_klass(O0, G3_scratch); |
2497 int klass_load_size; | |
2498 if (UseCompressedOops) { | |
2499 klass_load_size = 3*BytesPerInstWord; | |
2500 } else { | |
2501 klass_load_size = 1*BytesPerInstWord; | |
2502 } | |
2478 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); | 2503 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); |
2479 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); | 2504 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); |
2480 if( __ is_simm13(v_off) ) { | 2505 if( __ is_simm13(v_off) ) { |
2481 __ ld_ptr(G3, v_off, G5_method); | 2506 __ ld_ptr(G3, v_off, G5_method); |
2482 } else { | 2507 } else { |
2483 // Generate 2 instructions | 2508 // Generate 2 instructions |
2484 __ Assembler::sethi(v_off & ~0x3ff, G5_method); | 2509 __ Assembler::sethi(v_off & ~0x3ff, G5_method); |
2485 __ or3(G5_method, v_off & 0x3ff, G5_method); | 2510 __ or3(G5_method, v_off & 0x3ff, G5_method); |
2486 // ld_ptr, set_hi, set | 2511 // ld_ptr, set_hi, set |
2487 assert(__ offset() - off == 3*BytesPerInstWord, "Unexpected instruction size(s)"); | 2512 assert(__ offset() - off == klass_load_size + 2*BytesPerInstWord, |
2513 "Unexpected instruction size(s)"); | |
2488 __ ld_ptr(G3, G5_method, G5_method); | 2514 __ ld_ptr(G3, G5_method, G5_method); |
2489 } | 2515 } |
2490 // NOTE: for vtable dispatches, the vtable entry will never be null. | 2516 // NOTE: for vtable dispatches, the vtable entry will never be null. |
2491 // However it may very well end up in handle_wrong_method if the | 2517 // However it may very well end up in handle_wrong_method if the |
2492 // method is abstract for the particular class. | 2518 // method is abstract for the particular class. |
2858 int value_offset = java_lang_String:: value_offset_in_bytes(); | 2884 int value_offset = java_lang_String:: value_offset_in_bytes(); |
2859 int offset_offset = java_lang_String::offset_offset_in_bytes(); | 2885 int offset_offset = java_lang_String::offset_offset_in_bytes(); |
2860 int count_offset = java_lang_String:: count_offset_in_bytes(); | 2886 int count_offset = java_lang_String:: count_offset_in_bytes(); |
2861 | 2887 |
2862 // load str1 (jchar*) base address into tmp1_reg | 2888 // load str1 (jchar*) base address into tmp1_reg |
2863 __ ld_ptr(Address(str1_reg, 0, value_offset), tmp1_reg); | 2889 __ load_heap_oop(Address(str1_reg, 0, value_offset), tmp1_reg); |
2864 __ ld(Address(str1_reg, 0, offset_offset), result_reg); | 2890 __ ld(Address(str1_reg, 0, offset_offset), result_reg); |
2865 __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg); | 2891 __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg); |
2866 __ ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted | 2892 __ ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted |
2867 __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg); | 2893 __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg); |
2868 __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted | 2894 __ load_heap_oop(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted |
2869 __ add(result_reg, tmp1_reg, tmp1_reg); | 2895 __ add(result_reg, tmp1_reg, tmp1_reg); |
2870 | 2896 |
2871 // load str2 (jchar*) base address into tmp2_reg | 2897 // load str2 (jchar*) base address into tmp2_reg |
2872 // __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted | 2898 // __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted |
2873 __ ld(Address(str2_reg, 0, offset_offset), result_reg); | 2899 __ ld(Address(str2_reg, 0, offset_offset), result_reg); |
3014 | 3040 |
3015 enc_class enc_membar_volatile %{ | 3041 enc_class enc_membar_volatile %{ |
3016 MacroAssembler _masm(&cbuf); | 3042 MacroAssembler _masm(&cbuf); |
3017 __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) ); | 3043 __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) ); |
3018 %} | 3044 %} |
3045 | |
3019 enc_class enc_repl8b( iRegI src, iRegL dst ) %{ | 3046 enc_class enc_repl8b( iRegI src, iRegL dst ) %{ |
3020 MacroAssembler _masm(&cbuf); | 3047 MacroAssembler _masm(&cbuf); |
3021 Register src_reg = reg_to_register_object($src$$reg); | 3048 Register src_reg = reg_to_register_object($src$$reg); |
3022 Register dst_reg = reg_to_register_object($dst$$reg); | 3049 Register dst_reg = reg_to_register_object($dst$$reg); |
3023 __ sllx(src_reg, 56, dst_reg); | 3050 __ sllx(src_reg, 56, dst_reg); |
3187 // to and from the register pairs is done by the appropriate call and epilog | 3214 // to and from the register pairs is done by the appropriate call and epilog |
3188 // opcodes. This simplifies the register allocator. | 3215 // opcodes. This simplifies the register allocator. |
3189 c_return_value %{ | 3216 c_return_value %{ |
3190 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); | 3217 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); |
3191 #ifdef _LP64 | 3218 #ifdef _LP64 |
3192 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; | 3219 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; |
3193 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; | 3220 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; |
3194 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; | 3221 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; |
3195 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; | 3222 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; |
3196 #else // !_LP64 | 3223 #else // !_LP64 |
3197 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; | 3224 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; |
3198 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; | 3225 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; |
3199 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; | 3226 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; |
3200 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; | 3227 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; |
3201 #endif | 3228 #endif |
3202 return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], | 3229 return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], |
3203 (is_outgoing?lo_out:lo_in)[ideal_reg] ); | 3230 (is_outgoing?lo_out:lo_in)[ideal_reg] ); |
3204 %} | 3231 %} |
3205 | 3232 |
3206 // Location of compiled Java return values. Same as C | 3233 // Location of compiled Java return values. Same as C |
3207 return_value %{ | 3234 return_value %{ |
3208 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); | 3235 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); |
3209 #ifdef _LP64 | 3236 #ifdef _LP64 |
3210 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; | 3237 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; |
3211 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; | 3238 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; |
3212 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; | 3239 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; |
3213 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; | 3240 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; |
3214 #else // !_LP64 | 3241 #else // !_LP64 |
3215 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; | 3242 static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; |
3216 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; | 3243 static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; |
3217 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; | 3244 static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; |
3218 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; | 3245 static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; |
3219 #endif | 3246 #endif |
3220 return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], | 3247 return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], |
3221 (is_outgoing?lo_out:lo_in)[ideal_reg] ); | 3248 (is_outgoing?lo_out:lo_in)[ideal_reg] ); |
3222 %} | 3249 %} |
3223 | 3250 |
3402 operand immP_poll() %{ | 3429 operand immP_poll() %{ |
3403 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page()); | 3430 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page()); |
3404 match(ConP); | 3431 match(ConP); |
3405 | 3432 |
3406 // formats are generated automatically for constants and base registers | 3433 // formats are generated automatically for constants and base registers |
3434 format %{ %} | |
3435 interface(CONST_INTER); | |
3436 %} | |
3437 | |
3438 // Pointer Immediate | |
3439 operand immN() | |
3440 %{ | |
3441 match(ConN); | |
3442 | |
3443 op_cost(10); | |
3444 format %{ %} | |
3445 interface(CONST_INTER); | |
3446 %} | |
3447 | |
3448 // NULL Pointer Immediate | |
3449 operand immN0() | |
3450 %{ | |
3451 predicate(n->get_narrowcon() == 0); | |
3452 match(ConN); | |
3453 | |
3454 op_cost(0); | |
3407 format %{ %} | 3455 format %{ %} |
3408 interface(CONST_INTER); | 3456 interface(CONST_INTER); |
3409 %} | 3457 %} |
3410 | 3458 |
3411 operand immL() %{ | 3459 operand immL() %{ |
3665 %} | 3713 %} |
3666 | 3714 |
3667 operand o7RegI() %{ | 3715 operand o7RegI() %{ |
3668 constraint(ALLOC_IN_RC(o7_regI)); | 3716 constraint(ALLOC_IN_RC(o7_regI)); |
3669 match(iRegI); | 3717 match(iRegI); |
3718 | |
3719 format %{ %} | |
3720 interface(REG_INTER); | |
3721 %} | |
3722 | |
3723 operand iRegN() %{ | |
3724 constraint(ALLOC_IN_RC(int_reg)); | |
3725 match(RegN); | |
3670 | 3726 |
3671 format %{ %} | 3727 format %{ %} |
3672 interface(REG_INTER); | 3728 interface(REG_INTER); |
3673 %} | 3729 %} |
3674 | 3730 |
5390 #endif | 5446 #endif |
5391 ins_encode( form3_mem_reg( mem, dst ) ); | 5447 ins_encode( form3_mem_reg( mem, dst ) ); |
5392 ins_pipe(iload_mem); | 5448 ins_pipe(iload_mem); |
5393 %} | 5449 %} |
5394 | 5450 |
5451 // Load Compressed Pointer | |
5452 instruct loadN(iRegN dst, memory mem) %{ | |
5453 match(Set dst (LoadN mem)); | |
5454 ins_cost(MEMORY_REF_COST); | |
5455 size(4); | |
5456 | |
5457 format %{ "LDUW $mem,$dst\t! compressed ptr" %} | |
5458 ins_encode %{ | |
5459 Register base = as_Register($mem$$base); | |
5460 Register index = as_Register($mem$$index); | |
5461 Register dst = $dst$$Register; | |
5462 if (index != G0) { | |
5463 __ lduw(base, index, dst); | |
5464 } else { | |
5465 __ lduw(base, $mem$$disp, dst); | |
5466 } | |
5467 %} | |
5468 ins_pipe(iload_mem); | |
5469 %} | |
5470 | |
5395 // Load Klass Pointer | 5471 // Load Klass Pointer |
5396 instruct loadKlass(iRegP dst, memory mem) %{ | 5472 instruct loadKlass(iRegP dst, memory mem) %{ |
5397 match(Set dst (LoadKlass mem)); | 5473 match(Set dst (LoadKlass mem)); |
5474 predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow()); | |
5398 ins_cost(MEMORY_REF_COST); | 5475 ins_cost(MEMORY_REF_COST); |
5399 size(4); | 5476 size(4); |
5400 | 5477 |
5401 #ifndef _LP64 | 5478 #ifndef _LP64 |
5402 format %{ "LDUW $mem,$dst\t! klass ptr" %} | 5479 format %{ "LDUW $mem,$dst\t! klass ptr" %} |
5404 #else | 5481 #else |
5405 format %{ "LDX $mem,$dst\t! klass ptr" %} | 5482 format %{ "LDX $mem,$dst\t! klass ptr" %} |
5406 opcode(Assembler::ldx_op3, 0, REGP_OP); | 5483 opcode(Assembler::ldx_op3, 0, REGP_OP); |
5407 #endif | 5484 #endif |
5408 ins_encode( form3_mem_reg( mem, dst ) ); | 5485 ins_encode( form3_mem_reg( mem, dst ) ); |
5486 ins_pipe(iload_mem); | |
5487 %} | |
5488 | |
5489 // Load Klass Pointer | |
5490 instruct loadKlassComp(iRegP dst, memory mem) %{ | |
5491 match(Set dst (LoadKlass mem)); | |
5492 predicate(n->in(MemNode::Address)->bottom_type()->is_narrow()); | |
5493 ins_cost(MEMORY_REF_COST); | |
5494 | |
5495 format %{ "LDUW $mem,$dst\t! compressed klass ptr" %} | |
5496 | |
5497 ins_encode %{ | |
5498 Register base = as_Register($mem$$base); | |
5499 Register index = as_Register($mem$$index); | |
5500 Register dst = $dst$$Register; | |
5501 if (index != G0) { | |
5502 __ lduw(base, index, dst); | |
5503 } else { | |
5504 __ lduw(base, $mem$$disp, dst); | |
5505 } | |
5506 // klass oop never null but this is generated for nonheader klass loads | |
5507 // too which can be null. | |
5508 __ decode_heap_oop(dst); | |
5509 %} | |
5409 ins_pipe(iload_mem); | 5510 ins_pipe(iload_mem); |
5410 %} | 5511 %} |
5411 | 5512 |
5412 // Load Short (16bit signed) | 5513 // Load Short (16bit signed) |
5413 instruct loadS(iRegI dst, memory mem) %{ | 5514 instruct loadS(iRegI dst, memory mem) %{ |
5506 __ sethi(polling_page, false ); | 5607 __ sethi(polling_page, false ); |
5507 %} | 5608 %} |
5508 ins_pipe(loadConP_poll); | 5609 ins_pipe(loadConP_poll); |
5509 %} | 5610 %} |
5510 | 5611 |
5612 instruct loadConN(iRegN dst, immN src) %{ | |
5613 match(Set dst src); | |
5614 ins_cost(DEFAULT_COST * 2); | |
5615 format %{ "SET $src,$dst\t!ptr" %} | |
5616 ins_encode %{ | |
5617 address con = (address)$src$$constant; | |
5618 Register dst = $dst$$Register; | |
5619 if (con == NULL) { | |
5620 __ mov(G0, dst); | |
5621 } else { | |
5622 __ set_oop((jobject)$src$$constant, dst); | |
5623 __ encode_heap_oop(dst); | |
5624 } | |
5625 %} | |
5626 ins_pipe(loadConP); | |
5627 | |
5628 %} | |
5629 | |
5511 instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ | 5630 instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ |
5512 // %%% maybe this should work like loadConD | 5631 // %%% maybe this should work like loadConD |
5513 match(Set dst src); | 5632 match(Set dst src); |
5514 effect(KILL tmp); | 5633 effect(KILL tmp); |
5515 ins_cost(DEFAULT_COST * 4); | 5634 ins_cost(DEFAULT_COST * 4); |
5739 #endif | 5858 #endif |
5740 ins_encode( form3_mem_reg( dst, R_G0 ) ); | 5859 ins_encode( form3_mem_reg( dst, R_G0 ) ); |
5741 ins_pipe(istore_mem_zero); | 5860 ins_pipe(istore_mem_zero); |
5742 %} | 5861 %} |
5743 | 5862 |
5863 // Store Compressed Pointer | |
5864 instruct storeN(memory dst, iRegN src) %{ | |
5865 match(Set dst (StoreN dst src)); | |
5866 ins_cost(MEMORY_REF_COST); | |
5867 size(4); | |
5868 | |
5869 format %{ "STW $src,$dst\t! compressed ptr" %} | |
5870 ins_encode %{ | |
5871 Register base = as_Register($dst$$base); | |
5872 Register index = as_Register($dst$$index); | |
5873 Register src = $src$$Register; | |
5874 if (index != G0) { | |
5875 __ stw(src, base, index); | |
5876 } else { | |
5877 __ stw(src, base, $dst$$disp); | |
5878 } | |
5879 %} | |
5880 ins_pipe(istore_mem_spORreg); | |
5881 %} | |
5882 | |
5883 instruct storeN0(memory dst, immN0 src) %{ | |
5884 match(Set dst (StoreN dst src)); | |
5885 ins_cost(MEMORY_REF_COST); | |
5886 size(4); | |
5887 | |
5888 format %{ "STW $src,$dst\t! compressed ptr" %} | |
5889 ins_encode %{ | |
5890 Register base = as_Register($dst$$base); | |
5891 Register index = as_Register($dst$$index); | |
5892 if (index != G0) { | |
5893 __ stw(0, base, index); | |
5894 } else { | |
5895 __ stw(0, base, $dst$$disp); | |
5896 } | |
5897 %} | |
5898 ins_pipe(istore_mem_zero); | |
5899 %} | |
5900 | |
5744 // Store Double | 5901 // Store Double |
5745 instruct storeD( memory mem, regD src) %{ | 5902 instruct storeD( memory mem, regD src) %{ |
5746 match(Set mem (StoreD mem src)); | 5903 match(Set mem (StoreD mem src)); |
5747 ins_cost(MEMORY_REF_COST); | 5904 ins_cost(MEMORY_REF_COST); |
5748 | 5905 |
5795 format %{ "STDF $src,$mem\t! packed8B" %} | 5952 format %{ "STDF $src,$mem\t! packed8B" %} |
5796 opcode(Assembler::stdf_op3); | 5953 opcode(Assembler::stdf_op3); |
5797 ins_encode( form3_mem_reg( mem, src ) ); | 5954 ins_encode( form3_mem_reg( mem, src ) ); |
5798 ins_pipe(fstoreD_mem_reg); | 5955 ins_pipe(fstoreD_mem_reg); |
5799 %} | 5956 %} |
5957 | |
5958 // Convert oop pointer into compressed form | |
5959 instruct encodeHeapOop(iRegN dst, iRegP src) %{ | |
5960 match(Set dst (EncodeP src)); | |
5961 format %{ "SRL $src,3,$dst\t encodeHeapOop" %} | |
5962 ins_encode %{ | |
5963 __ encode_heap_oop($src$$Register, $dst$$Register); | |
5964 %} | |
5965 ins_pipe(ialu_reg); | |
5966 %} | |
5967 | |
5968 instruct decodeHeapOop(iRegP dst, iRegN src) %{ | |
5969 match(Set dst (DecodeN src)); | |
5970 format %{ "decode_heap_oop $src, $dst" %} | |
5971 ins_encode %{ | |
5972 __ decode_heap_oop($src$$Register, $dst$$Register); | |
5973 %} | |
5974 ins_pipe(ialu_reg); | |
5975 %} | |
5976 | |
5800 | 5977 |
5801 // Store Zero into Aligned Packed Bytes | 5978 // Store Zero into Aligned Packed Bytes |
5802 instruct storeA8B0(memory mem, immI0 zero) %{ | 5979 instruct storeA8B0(memory mem, immI0 zero) %{ |
5803 match(Set mem (Store8B mem zero)); | 5980 match(Set mem (Store8B mem zero)); |
5804 ins_cost(MEMORY_REF_COST); | 5981 ins_cost(MEMORY_REF_COST); |
6432 %} | 6609 %} |
6433 | 6610 |
6434 instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ | 6611 instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ |
6435 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); | 6612 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); |
6436 effect( USE mem_ptr, KILL ccr, KILL tmp1); | 6613 effect( USE mem_ptr, KILL ccr, KILL tmp1); |
6437 #ifdef _LP64 | |
6438 format %{ | 6614 format %{ |
6439 "MOV $newval,O7\n\t" | 6615 "MOV $newval,O7\n\t" |
6440 "CASXA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" | 6616 "CASA_PTR [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" |
6441 "CMP $oldval,O7\t\t! See if we made progress\n\t" | 6617 "CMP $oldval,O7\t\t! See if we made progress\n\t" |
6442 "MOV 1,$res\n\t" | 6618 "MOV 1,$res\n\t" |
6443 "MOVne xcc,R_G0,$res" | 6619 "MOVne xcc,R_G0,$res" |
6444 %} | 6620 %} |
6621 #ifdef _LP64 | |
6445 ins_encode( enc_casx(mem_ptr, oldval, newval), | 6622 ins_encode( enc_casx(mem_ptr, oldval, newval), |
6446 enc_lflags_ne_to_boolean(res) ); | 6623 enc_lflags_ne_to_boolean(res) ); |
6447 #else | 6624 #else |
6625 ins_encode( enc_casi(mem_ptr, oldval, newval), | |
6626 enc_iflags_ne_to_boolean(res) ); | |
6627 #endif | |
6628 ins_pipe( long_memory_op ); | |
6629 %} | |
6630 | |
6631 instruct compareAndSwapN_bool_comp(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp, flagsReg ccr ) %{ | |
6632 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); | |
6633 effect( USE mem_ptr, KILL ccr, KILL tmp); | |
6634 | |
6448 format %{ | 6635 format %{ |
6449 "MOV $newval,O7\n\t" | 6636 "MOV $newval,O7\n\t" |
6450 "CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" | 6637 "CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" |
6451 "CMP $oldval,O7\t\t! See if we made progress\n\t" | 6638 "CMP $oldval,O7\t\t! See if we made progress\n\t" |
6452 "MOV 1,$res\n\t" | 6639 "MOV 1,$res\n\t" |
6453 "MOVne icc,R_G0,$res" | 6640 "MOVne icc,R_G0,$res" |
6454 %} | 6641 %} |
6455 ins_encode( enc_casi(mem_ptr, oldval, newval), | 6642 ins_encode %{ |
6456 enc_iflags_ne_to_boolean(res) ); | 6643 Register Rmem = reg_to_register_object($mem_ptr$$reg); |
6457 #endif | 6644 Register Rold = reg_to_register_object($oldval$$reg); |
6645 Register Rnew = reg_to_register_object($newval$$reg); | |
6646 Register Rres = reg_to_register_object($res$$reg); | |
6647 | |
6648 __ cas(Rmem, Rold, Rnew); | |
6649 __ cmp( Rold, Rnew ); | |
6650 __ mov(1, Rres); | |
6651 __ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres ); | |
6652 %} | |
6653 | |
6458 ins_pipe( long_memory_op ); | 6654 ins_pipe( long_memory_op ); |
6459 %} | 6655 %} |
6460 | 6656 |
6461 //--------------------- | 6657 //--------------------- |
6462 // Subtraction Instructions | 6658 // Subtraction Instructions |
8605 format %{ "CALL PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %} | 8801 format %{ "CALL PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %} |
8606 ins_encode( enc_PartialSubtypeCheck() ); | 8802 ins_encode( enc_PartialSubtypeCheck() ); |
8607 ins_pipe(partial_subtype_check_pipe); | 8803 ins_pipe(partial_subtype_check_pipe); |
8608 %} | 8804 %} |
8609 | 8805 |
8806 | |
8807 instruct compP_iRegN_immN0(flagsRegP pcc, iRegN op1, immN0 op2 ) %{ | |
8808 match(Set pcc (CmpN op1 op2)); | |
8809 | |
8810 size(4); | |
8811 format %{ "CMP $op1,$op2\t! ptr" %} | |
8812 opcode(Assembler::subcc_op3, Assembler::arith_op); | |
8813 ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); | |
8814 ins_pipe(ialu_cconly_reg_imm); | |
8815 %} | |
8816 | |
8610 // ============================================================================ | 8817 // ============================================================================ |
8611 // inlined locking and unlocking | 8818 // inlined locking and unlocking |
8612 | 8819 |
8613 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ | 8820 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ |
8614 match(Set pcc (FastLock object box)); | 8821 match(Set pcc (FastLock object box)); |
8646 " STX G0,[$base+$temp]\t! delay slot" %} | 8853 " STX G0,[$base+$temp]\t! delay slot" %} |
8647 ins_encode( enc_Clear_Array(cnt, base, temp) ); | 8854 ins_encode( enc_Clear_Array(cnt, base, temp) ); |
8648 ins_pipe(long_memory_op); | 8855 ins_pipe(long_memory_op); |
8649 %} | 8856 %} |
8650 | 8857 |
8651 instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, flagsReg ccr) %{ | 8858 instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, |
8859 o7RegI tmp3, flagsReg ccr) %{ | |
8652 match(Set result (StrComp str1 str2)); | 8860 match(Set result (StrComp str1 str2)); |
8653 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr); | 8861 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3); |
8654 ins_cost(300); | 8862 ins_cost(300); |
8655 format %{ "String Compare $str1,$str2 -> $result" %} | 8863 format %{ "String Compare $str1,$str2 -> $result" %} |
8656 ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) ); | 8864 ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) ); |
8657 ins_pipe(long_memory_op); | 8865 ins_pipe(long_memory_op); |
8658 %} | 8866 %} |