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 %}