Mercurial > hg > truffle
diff src/cpu/sparc/vm/assembler_sparc.cpp @ 727:6b2273dd6fa9
6822110: Add AddressLiteral class on SPARC
Summary: The Address class on SPARC currently handles both, addresses and address literals, what makes the Address class more complicated than it has to be.
Reviewed-by: never, kvn
author | twisti |
---|---|
date | Tue, 21 Apr 2009 11:16:30 -0700 |
parents | e5b0439ef4ae |
children | 315a5d70b295 |
line wrap: on
line diff
--- a/src/cpu/sparc/vm/assembler_sparc.cpp Mon Apr 20 14:48:03 2009 -0700 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp Tue Apr 21 11:16:30 2009 -0700 @@ -25,24 +25,36 @@ #include "incls/_precompiled.incl" #include "incls/_assembler_sparc.cpp.incl" -// Implementation of Address - -Address::Address( addr_type t, int which ) { - switch (t) { - case extra_in_argument: - case extra_out_argument: - _base = t == extra_in_argument ? FP : SP; - _hi = 0; -// Warning: In LP64 mode, _disp will occupy more than 10 bits. -// This is inconsistent with the other constructors but op -// codes such as ld or ldx, only access disp() to get their -// simm13 argument. - _disp = ((which - Argument::n_register_parameters + frame::memory_parameter_word_sp_offset) * BytesPerWord) + STACK_BIAS; - break; - default: - ShouldNotReachHere(); - break; +// Convert the raw encoding form into the form expected by the +// constructor for Address. +Address Address::make_raw(int base, int index, int scale, int disp, bool disp_is_oop) { + assert(scale == 0, "not supported"); + RelocationHolder rspec; + if (disp_is_oop) { + rspec = Relocation::spec_simple(relocInfo::oop_type); } + + Register rindex = as_Register(index); + if (rindex != G0) { + Address madr(as_Register(base), rindex); + madr._rspec = rspec; + return madr; + } else { + Address madr(as_Register(base), disp); + madr._rspec = rspec; + return madr; + } +} + +Address Argument::address_in_frame() const { + // Warning: In LP64 mode disp will occupy more than 10 bits, but + // op codes such as ld or ldx, only access disp() to get + // their simm13 argument. + int disp = ((_number - Argument::n_register_parameters + frame::memory_parameter_word_sp_offset) * BytesPerWord) + STACK_BIAS; + if (is_in()) + return Address(FP, disp); // In argument. + else + return Address(SP, disp); // Out argument. } static const char* argumentNames[][2] = { @@ -614,16 +626,17 @@ } // This code sequence is relocatable to any address, even on LP64. -void MacroAssembler::jumpl( Address& a, Register d, int offset, const char* file, int line ) { +void MacroAssembler::jumpl(AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line) { assert_not_delayed(); // Force fixed length sethi because NativeJump and NativeFarCall don't handle // variable length instruction streams. - sethi(a, /*ForceRelocatable=*/ true); + patchable_sethi(addrlit, temp); + Address a(temp, addrlit.low10() + offset); // Add the offset to the displacement. if (TraceJumps) { #ifndef PRODUCT // Must do the add here so relocation can find the remainder of the // value to be relocated. - add(a.base(), a.disp() + offset, a.base(), a.rspec(offset)); + add(a.base(), a.disp(), a.base(), addrlit.rspec(offset)); save_frame(0); verify_thread(); ld(G2_thread, in_bytes(JavaThread::jmp_ring_index_offset()), O0); @@ -652,15 +665,15 @@ restore(); jmpl(a.base(), G0, d); #else - jmpl(a, d, offset); + jmpl(a.base(), a.disp(), d); #endif /* PRODUCT */ } else { - jmpl(a, d, offset); + jmpl(a.base(), a.disp(), d); } } -void MacroAssembler::jump( Address& a, int offset, const char* file, int line ) { - jumpl( a, G0, offset, file, line ); +void MacroAssembler::jump(AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) { + jumpl(addrlit, temp, G0, offset, file, line); } @@ -678,7 +691,8 @@ st_ptr(savePtr.as_register(), savePtr.address_in_frame()); } // return the address of the first memory slot - add(inArg.address_in_frame(), d); + Address a = inArg.address_in_frame(); + add(a.base(), a.disp(), d); } // Conditional breakpoint (for assertion checks in assembly code) @@ -702,7 +716,6 @@ // offset to write to within the page. This minimizes bus traffic // due to cache line collision. void MacroAssembler::serialize_memory(Register thread, Register tmp1, Register tmp2) { - Address mem_serialize_page(tmp1, os::get_memory_serialize_page()); srl(thread, os::get_serialize_page_shift_count(), tmp2); if (Assembler::is_simm13(os::vm_page_size())) { and3(tmp2, (os::vm_page_size() - sizeof(int)), tmp2); @@ -711,7 +724,7 @@ set((os::vm_page_size() - sizeof(int)), tmp1); and3(tmp2, tmp1, tmp2); } - load_address(mem_serialize_page); + set(os::get_memory_serialize_page(), tmp1); st(G0, tmp1, tmp2); } @@ -830,10 +843,10 @@ mov(G3, L2); // avoid clobbering G3 also mov(G4, L5); // avoid clobbering G4 #ifdef ASSERT - Address last_get_thread_addr(L3, (address)&last_get_thread); - sethi(last_get_thread_addr); + AddressLiteral last_get_thread_addrlit(&last_get_thread); + set(last_get_thread_addrlit, L3); inc(L4, get_pc(L4) + 2 * BytesPerInstWord); // skip getpc() code + inc + st_ptr to point L4 at call - st_ptr(L4, last_get_thread_addr); + st_ptr(L4, L3, 0); #endif call(CAST_FROM_FN_PTR(address, reinitialize_thread), relocInfo::runtime_call_type); delayed()->nop(); @@ -919,13 +932,9 @@ // %%% maybe get rid of [re]set_last_Java_frame void MacroAssembler::set_last_Java_frame(Register last_java_sp, Register last_Java_pc) { assert_not_delayed(); - Address flags(G2_thread, - 0, - in_bytes(JavaThread::frame_anchor_offset()) + - in_bytes(JavaFrameAnchor::flags_offset())); - Address pc_addr(G2_thread, - 0, - in_bytes(JavaThread::last_Java_pc_offset())); + Address flags(G2_thread, JavaThread::frame_anchor_offset() + + JavaFrameAnchor::flags_offset()); + Address pc_addr(G2_thread, JavaThread::last_Java_pc_offset()); // Always set last_Java_pc and flags first because once last_Java_sp is visible // has_last_Java_frame is true and users will look at the rest of the fields. @@ -977,22 +986,18 @@ #endif // ASSERT assert( last_java_sp != G4_scratch, "bad register usage in set_last_Java_frame"); add( last_java_sp, STACK_BIAS, G4_scratch ); - st_ptr(G4_scratch, Address(G2_thread, 0, in_bytes(JavaThread::last_Java_sp_offset()))); + st_ptr(G4_scratch, G2_thread, JavaThread::last_Java_sp_offset()); #else - st_ptr(last_java_sp, Address(G2_thread, 0, in_bytes(JavaThread::last_Java_sp_offset()))); + st_ptr(last_java_sp, G2_thread, JavaThread::last_Java_sp_offset()); #endif // _LP64 } void MacroAssembler::reset_last_Java_frame(void) { assert_not_delayed(); - Address sp_addr(G2_thread, 0, in_bytes(JavaThread::last_Java_sp_offset())); - Address pc_addr(G2_thread, - 0, - in_bytes(JavaThread::frame_anchor_offset()) + in_bytes(JavaFrameAnchor::last_Java_pc_offset())); - Address flags(G2_thread, - 0, - in_bytes(JavaThread::frame_anchor_offset()) + in_bytes(JavaFrameAnchor::flags_offset())); + Address sp_addr(G2_thread, JavaThread::last_Java_sp_offset()); + Address pc_addr(G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()); + Address flags (G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::flags_offset()); #ifdef ASSERT // check that it WAS previously set @@ -1063,7 +1068,7 @@ check_and_handle_popframe(scratch_reg); check_and_handle_earlyret(scratch_reg); - Address exception_addr(G2_thread, 0, in_bytes(Thread::pending_exception_offset())); + Address exception_addr(G2_thread, Thread::pending_exception_offset()); ld_ptr(exception_addr, scratch_reg); br_null(scratch_reg,false,pt,L); delayed()->nop(); @@ -1186,7 +1191,7 @@ void MacroAssembler::get_vm_result(Register oop_result) { verify_thread(); - Address vm_result_addr(G2_thread, 0, in_bytes(JavaThread::vm_result_offset())); + Address vm_result_addr(G2_thread, JavaThread::vm_result_offset()); ld_ptr( vm_result_addr, oop_result); st_ptr(G0, vm_result_addr); verify_oop(oop_result); @@ -1195,7 +1200,7 @@ void MacroAssembler::get_vm_result_2(Register oop_result) { verify_thread(); - Address vm_result_addr_2(G2_thread, 0, in_bytes(JavaThread::vm_result_2_offset())); + Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset()); ld_ptr(vm_result_addr_2, oop_result); st_ptr(G0, vm_result_addr_2); verify_oop(oop_result); @@ -1206,7 +1211,7 @@ // leave it undisturbed. void MacroAssembler::set_vm_result(Register oop_result) { verify_thread(); - Address vm_result_addr(G2_thread, 0, in_bytes(JavaThread::vm_result_offset())); + Address vm_result_addr(G2_thread, JavaThread::vm_result_offset()); verify_oop(oop_result); # ifdef ASSERT @@ -1234,81 +1239,78 @@ #else srl(obj, CardTableModRefBS::card_shift, obj); #endif - assert( tmp != obj, "need separate temp reg"); - Address rs(tmp, (address)byte_map_base); - load_address(rs); - stb(G0, rs.base(), obj); + assert(tmp != obj, "need separate temp reg"); + set((address) byte_map_base, tmp); + stb(G0, tmp, obj); } -// %%% Note: The following six instructions have been moved, -// unchanged, from assembler_sparc.inline.hpp. -// They will be refactored at a later date. - -void MacroAssembler::sethi(intptr_t imm22a, - Register d, - bool ForceRelocatable, - RelocationHolder const& rspec) { - Address adr( d, (address)imm22a, rspec ); - MacroAssembler::sethi( adr, ForceRelocatable ); -} - - -void MacroAssembler::sethi(Address& a, bool ForceRelocatable) { + +void MacroAssembler::internal_sethi(const AddressLiteral& addrlit, Register d, bool ForceRelocatable) { address save_pc; int shiftcnt; - // if addr of local, do not need to load it - assert(a.base() != FP && a.base() != SP, "just use ld or st for locals"); #ifdef _LP64 # ifdef CHECK_DELAY - assert_not_delayed( (char *)"cannot put two instructions in delay slot" ); + assert_not_delayed((char*) "cannot put two instructions in delay slot"); # endif v9_dep(); -// ForceRelocatable = 1; save_pc = pc(); - if (a.hi32() == 0 && a.low32() >= 0) { - Assembler::sethi(a.low32(), a.base(), a.rspec()); + + int msb32 = (int) (addrlit.value() >> 32); + int lsb32 = (int) (addrlit.value()); + + if (msb32 == 0 && lsb32 >= 0) { + Assembler::sethi(lsb32, d, addrlit.rspec()); } - else if (a.hi32() == -1) { - Assembler::sethi(~a.low32(), a.base(), a.rspec()); - xor3(a.base(), ~low10(~0), a.base()); + else if (msb32 == -1) { + Assembler::sethi(~lsb32, d, addrlit.rspec()); + xor3(d, ~low10(~0), d); } else { - Assembler::sethi(a.hi32(), a.base(), a.rspec() ); // 22 - if ( a.hi32() & 0x3ff ) // Any bits? - or3( a.base(), a.hi32() & 0x3ff ,a.base() ); // High 32 bits are now in low 32 - if ( a.low32() & 0xFFFFFC00 ) { // done? - if( (a.low32() >> 20) & 0xfff ) { // Any bits set? - sllx(a.base(), 12, a.base()); // Make room for next 12 bits - or3( a.base(), (a.low32() >> 20) & 0xfff,a.base() ); // Or in next 12 - shiftcnt = 0; // We already shifted + Assembler::sethi(msb32, d, addrlit.rspec()); // msb 22-bits + if (msb32 & 0x3ff) // Any bits? + or3(d, msb32 & 0x3ff, d); // msb 32-bits are now in lsb 32 + if (lsb32 & 0xFFFFFC00) { // done? + if ((lsb32 >> 20) & 0xfff) { // Any bits set? + sllx(d, 12, d); // Make room for next 12 bits + or3(d, (lsb32 >> 20) & 0xfff, d); // Or in next 12 + shiftcnt = 0; // We already shifted } else shiftcnt = 12; - if( (a.low32() >> 10) & 0x3ff ) { - sllx(a.base(), shiftcnt+10, a.base());// Make room for last 10 bits - or3( a.base(), (a.low32() >> 10) & 0x3ff,a.base() ); // Or in next 10 + if ((lsb32 >> 10) & 0x3ff) { + sllx(d, shiftcnt + 10, d); // Make room for last 10 bits + or3(d, (lsb32 >> 10) & 0x3ff, d); // Or in next 10 shiftcnt = 0; } else shiftcnt = 10; - sllx(a.base(), shiftcnt+10 , a.base()); // Shift leaving disp field 0'd + sllx(d, shiftcnt + 10, d); // Shift leaving disp field 0'd } else - sllx( a.base(), 32, a.base() ); + sllx(d, 32, d); } - // Pad out the instruction sequence so it can be - // patched later. - if ( ForceRelocatable || (a.rtype() != relocInfo::none && - a.rtype() != relocInfo::runtime_call_type) ) { - while ( pc() < (save_pc + (7 * BytesPerInstWord )) ) + // Pad out the instruction sequence so it can be patched later. + if (ForceRelocatable || (addrlit.rtype() != relocInfo::none && + addrlit.rtype() != relocInfo::runtime_call_type)) { + while (pc() < (save_pc + (7 * BytesPerInstWord))) nop(); } #else - Assembler::sethi(a.hi(), a.base(), a.rspec()); + Assembler::sethi(addrlit.value(), d, addrlit.rspec()); #endif - +} + + +void MacroAssembler::sethi(const AddressLiteral& addrlit, Register d) { + internal_sethi(addrlit, d, false); } + +void MacroAssembler::patchable_sethi(const AddressLiteral& addrlit, Register d) { + internal_sethi(addrlit, d, true); +} + + int MacroAssembler::size_of_sethi(address a, bool worst_case) { #ifdef _LP64 if (worst_case) return 7; @@ -1339,61 +1341,50 @@ return size_of_sethi(NULL, true) + 1; } -void MacroAssembler::set(intptr_t value, Register d, - RelocationHolder const& rspec) { - Address val( d, (address)value, rspec); - - if ( rspec.type() == relocInfo::none ) { + +void MacroAssembler::internal_set(const AddressLiteral& addrlit, Register d, bool ForceRelocatable) { + intptr_t value = addrlit.value(); + + if (!ForceRelocatable && addrlit.rspec().type() == relocInfo::none) { // can optimize - if (-4096 <= value && value <= 4095) { + if (-4096 <= value && value <= 4095) { or3(G0, value, d); // setsw (this leaves upper 32 bits sign-extended) return; } if (inv_hi22(hi22(value)) == value) { - sethi(val); + sethi(addrlit, d); return; } } - assert_not_delayed( (char *)"cannot put two instructions in delay slot" ); - sethi( val ); - if (rspec.type() != relocInfo::none || (value & 0x3ff) != 0) { - add( d, value & 0x3ff, d, rspec); + assert_not_delayed((char*) "cannot put two instructions in delay slot"); + internal_sethi(addrlit, d, ForceRelocatable); + if (ForceRelocatable || addrlit.rspec().type() != relocInfo::none || addrlit.low10() != 0) { + add(d, addrlit.low10(), d, addrlit.rspec()); } } -void MacroAssembler::setsw(int value, Register d, - RelocationHolder const& rspec) { - Address val( d, (address)value, rspec); - if ( rspec.type() == relocInfo::none ) { - // can optimize - if (-4096 <= value && value <= 4095) { - or3(G0, value, d); - return; - } - if (inv_hi22(hi22(value)) == value) { - sethi( val ); -#ifndef _LP64 - if ( value < 0 ) { - assert_not_delayed(); - sra (d, G0, d); - } -#endif - return; - } - } - assert_not_delayed(); - sethi( val ); - add( d, value & 0x3ff, d, rspec); - - // (A negative value could be loaded in 2 insns with sethi/xor, - // but it would take a more complex relocation.) -#ifndef _LP64 - if ( value < 0) - sra(d, G0, d); -#endif +void MacroAssembler::set(const AddressLiteral& al, Register d) { + internal_set(al, d, false); +} + +void MacroAssembler::set(intptr_t value, Register d) { + AddressLiteral al(value); + internal_set(al, d, false); } -// %%% End of moved six set instructions. +void MacroAssembler::set(address addr, Register d, RelocationHolder const& rspec) { + AddressLiteral al(addr, rspec); + internal_set(al, d, false); +} + +void MacroAssembler::patchable_set(const AddressLiteral& al, Register d) { + internal_set(al, d, true); +} + +void MacroAssembler::patchable_set(intptr_t value, Register d) { + AddressLiteral al(value); + internal_set(al, d, true); +} void MacroAssembler::set64(jlong value, Register d, Register tmp) { @@ -1512,17 +1503,17 @@ } -Address MacroAssembler::allocate_oop_address(jobject obj, Register d) { +AddressLiteral MacroAssembler::allocate_oop_address(jobject obj) { assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); int oop_index = oop_recorder()->allocate_index(obj); - return Address(d, address(obj), oop_Relocation::spec(oop_index)); + return AddressLiteral(obj, oop_Relocation::spec(oop_index)); } -Address MacroAssembler::constant_oop_address(jobject obj, Register d) { +AddressLiteral MacroAssembler::constant_oop_address(jobject obj) { assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); int oop_index = oop_recorder()->find_index(obj); - return Address(d, address(obj), oop_Relocation::spec(oop_index)); + return AddressLiteral(obj, oop_Relocation::spec(oop_index)); } void MacroAssembler::set_narrow_oop(jobject obj, Register d) { @@ -1682,7 +1673,7 @@ sprintf(real_msg, "%s%s(%s:%d)", msg, buffer, file, line); // Call indirectly to solve generation ordering problem - Address a(O7, (address)StubRoutines::verify_oop_subroutine_entry_address()); + AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address()); // Make some space on stack above the current register window. // Enough to hold 8 64-bit registers. @@ -1718,7 +1709,7 @@ sprintf(real_msg, "%s at SP+%d (%s:%d)", msg, addr.disp(), file, line); // Call indirectly to solve generation ordering problem - Address a(O7, (address)StubRoutines::verify_oop_subroutine_entry_address()); + AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address()); // Make some space on stack above the current register window. // Enough to hold 8 64-bit registers. @@ -1772,11 +1763,7 @@ { // count number of verifies Register O2_adr = O2; Register O3_accum = O3; - Address count_addr( O2_adr, (address) StubRoutines::verify_oop_count_addr() ); - sethi(count_addr); - ld(count_addr, O3_accum); - inc(O3_accum); - st(O3_accum, count_addr); + inc_counter(StubRoutines::verify_oop_count_addr(), O2_adr, O3_accum); } Register O2_mask = O2; @@ -1870,8 +1857,8 @@ assert(StubRoutines::Sparc::stop_subroutine_entry_address(), "hasn't been generated yet"); // call indirectly to solve generation ordering problem - Address a(O5, (address)StubRoutines::Sparc::stop_subroutine_entry_address()); - load_ptr_contents(a, O5); + AddressLiteral al(StubRoutines::Sparc::stop_subroutine_entry_address()); + load_ptr_contents(al, O5); jmpl(O5, 0, O7); delayed()->nop(); } @@ -1891,7 +1878,7 @@ assert(StubRoutines::Sparc::stop_subroutine_entry_address(), "hasn't been generated yet"); // call indirectly to solve generation ordering problem - Address a(O5, (address)StubRoutines::Sparc::stop_subroutine_entry_address()); + AddressLiteral a(StubRoutines::Sparc::stop_subroutine_entry_address()); load_ptr_contents(a, O5); jmpl(O5, 0, O7); delayed()->nop(); @@ -2003,7 +1990,7 @@ subcc( Rparam_words, Argument::n_register_parameters, Rresult); // how many mem words? Label no_extras; br( negative, true, pt, no_extras ); // if neg, clear reg - delayed()->set( 0, Rresult); // annuled, so only if taken + delayed()->set(0, Rresult); // annuled, so only if taken bind( no_extras ); } @@ -2623,7 +2610,7 @@ return RegisterOrConstant(value + offset); // load indirectly to solve generation ordering problem - Address a(tmp, (address) delayed_value_addr); + AddressLiteral a(delayed_value_addr); load_ptr_contents(a, tmp); #ifdef ASSERT @@ -3107,21 +3094,21 @@ delayed()->nop(); load_klass(obj_reg, temp_reg); - ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); + ld_ptr(Address(temp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); or3(G2_thread, temp_reg, temp_reg); xor3(mark_reg, temp_reg, temp_reg); andcc(temp_reg, ~((int) markOopDesc::age_mask_in_place), temp_reg); if (counters != NULL) { cond_inc(Assembler::equal, (address) counters->biased_lock_entry_count_addr(), mark_reg, temp_reg); // Reload mark_reg as we may need it later - ld_ptr(Address(obj_reg, 0, oopDesc::mark_offset_in_bytes()), mark_reg); + ld_ptr(Address(obj_reg, oopDesc::mark_offset_in_bytes()), mark_reg); } brx(Assembler::equal, true, Assembler::pt, done); delayed()->nop(); Label try_revoke_bias; Label try_rebias; - Address mark_addr = Address(obj_reg, 0, oopDesc::mark_offset_in_bytes()); + Address mark_addr = Address(obj_reg, oopDesc::mark_offset_in_bytes()); assert(mark_addr.disp() == 0, "cas must take a zero displacement"); // At this point we know that the header has the bias pattern and @@ -3185,7 +3172,7 @@ // FIXME: due to a lack of registers we currently blow away the age // bits in this situation. Should attempt to preserve them. load_klass(obj_reg, temp_reg); - ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); + ld_ptr(Address(temp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); or3(G2_thread, temp_reg, temp_reg); casn(mark_addr.base(), mark_reg, temp_reg); // If the biasing toward our thread failed, this means that @@ -3216,7 +3203,7 @@ // FIXME: due to a lack of registers we currently blow away the age // bits in this situation. Should attempt to preserve them. load_klass(obj_reg, temp_reg); - ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); + ld_ptr(Address(temp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); casn(mark_addr.base(), mark_reg, temp_reg); // Fall through to the normal CAS-based lock, because no matter what // the result of the above CAS, some thread must have succeeded in @@ -3283,7 +3270,7 @@ Register Rbox, Register Rscratch, BiasedLockingCounters* counters, bool try_bias) { - Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes()); + Address mark_addr(Roop, oopDesc::mark_offset_in_bytes()); verify_oop(Roop); Label done ; @@ -3386,7 +3373,7 @@ // If m->owner != null goto IsLocked // Pessimistic form: Test-and-CAS vs CAS // The optimistic form avoids RTS->RTO cache line upgrades. - ld_ptr (Address (Rmark, 0, ObjectMonitor::owner_offset_in_bytes()-2), Rscratch) ; + ld_ptr (Rmark, ObjectMonitor::owner_offset_in_bytes() - 2, Rscratch); andcc (Rscratch, Rscratch, G0) ; brx (Assembler::notZero, false, Assembler::pn, done) ; delayed()->nop() ; @@ -3482,7 +3469,7 @@ // Test-and-CAS vs CAS // Pessimistic form avoids futile (doomed) CAS attempts // The optimistic form avoids RTS->RTO cache line upgrades. - ld_ptr (Address (Rmark, 0, ObjectMonitor::owner_offset_in_bytes()-2), Rscratch) ; + ld_ptr (Rmark, ObjectMonitor::owner_offset_in_bytes() - 2, Rscratch); andcc (Rscratch, Rscratch, G0) ; brx (Assembler::notZero, false, Assembler::pn, done) ; delayed()->nop() ; @@ -3508,7 +3495,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch, bool try_bias) { - Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes()); + Address mark_addr(Roop, oopDesc::mark_offset_in_bytes()); Label done ; @@ -3568,14 +3555,14 @@ // Note that we use 1-0 locking by default for the inflated case. We // close the resultant (and rare) race by having contented threads in // monitorenter periodically poll _owner. - ld_ptr (Address(Rmark, 0, ObjectMonitor::owner_offset_in_bytes()-2), Rscratch) ; - ld_ptr (Address(Rmark, 0, ObjectMonitor::recursions_offset_in_bytes()-2), Rbox) ; + ld_ptr (Rmark, ObjectMonitor::owner_offset_in_bytes() - 2, Rscratch); + ld_ptr (Rmark, ObjectMonitor::recursions_offset_in_bytes() - 2, Rbox); xor3 (Rscratch, G2_thread, Rscratch) ; orcc (Rbox, Rscratch, Rbox) ; brx (Assembler::notZero, false, Assembler::pn, done) ; delayed()-> - ld_ptr (Address (Rmark, 0, ObjectMonitor::EntryList_offset_in_bytes()-2), Rscratch) ; - ld_ptr (Address (Rmark, 0, ObjectMonitor::cxq_offset_in_bytes()-2), Rbox) ; + ld_ptr (Rmark, ObjectMonitor::EntryList_offset_in_bytes() - 2, Rscratch); + ld_ptr (Rmark, ObjectMonitor::cxq_offset_in_bytes() - 2, Rbox); orcc (Rbox, Rscratch, G0) ; if (EmitSync & 65536) { Label LSucc ; @@ -3583,12 +3570,12 @@ delayed()->nop() ; br (Assembler::always, false, Assembler::pt, done) ; delayed()-> - st_ptr (G0, Address (Rmark, 0, ObjectMonitor::owner_offset_in_bytes()-2)) ; + st_ptr (G0, Rmark, ObjectMonitor::owner_offset_in_bytes() - 2); bind (LSucc) ; - st_ptr (G0, Address (Rmark, 0, ObjectMonitor::owner_offset_in_bytes()-2)) ; + st_ptr (G0, Rmark, ObjectMonitor::owner_offset_in_bytes() - 2); if (os::is_MP()) { membar (StoreLoad) ; } - ld_ptr (Address (Rmark, 0, ObjectMonitor::succ_offset_in_bytes()-2), Rscratch) ; + ld_ptr (Rmark, ObjectMonitor::succ_offset_in_bytes() - 2, Rscratch); andcc (Rscratch, Rscratch, G0) ; brx (Assembler::notZero, false, Assembler::pt, done) ; delayed()-> andcc (G0, G0, G0) ; @@ -3606,7 +3593,7 @@ delayed()->nop() ; br (Assembler::always, false, Assembler::pt, done) ; delayed()-> - st_ptr (G0, Address (Rmark, 0, ObjectMonitor::owner_offset_in_bytes()-2)) ; + st_ptr (G0, Rmark, ObjectMonitor::owner_offset_in_bytes() - 2); } bind (LStacked) ; @@ -4005,20 +3992,26 @@ bind(L); } -void MacroAssembler::inc_counter(address counter_ptr, Register Rtmp1, Register Rtmp2) { - Address counter_addr(Rtmp1, counter_ptr); - load_contents(counter_addr, Rtmp2); +void MacroAssembler::inc_counter(address counter_addr, Register Rtmp1, Register Rtmp2) { + AddressLiteral addrlit(counter_addr); + sethi(addrlit, Rtmp1); // Move hi22 bits into temporary register. + Address addr(Rtmp1, addrlit.low10()); // Build an address with low10 bits. + ld(addr, Rtmp2); inc(Rtmp2); - store_contents(Rtmp2, counter_addr); + st(Rtmp2, addr); +} + +void MacroAssembler::inc_counter(int* counter_addr, Register Rtmp1, Register Rtmp2) { + inc_counter((address) counter_addr, Rtmp1, Rtmp2); } SkipIfEqual::SkipIfEqual( MacroAssembler* masm, Register temp, const bool* flag_addr, Assembler::Condition condition) { _masm = masm; - Address flag(temp, (address)flag_addr, relocInfo::none); - _masm->sethi(flag); - _masm->ldub(flag, temp); + AddressLiteral flag(flag_addr); + _masm->sethi(flag, temp); + _masm->ldub(temp, flag.low10(), temp); _masm->tst(temp); _masm->br(condition, false, Assembler::pt, _label); _masm->delayed()->nop(); @@ -4333,8 +4326,8 @@ #else masm.srl(O0, CardTableModRefBS::card_shift, O0); #endif - Address rs(O1, (address)byte_map_base); - masm.load_address(rs); // O1 := <card table base> + AddressLiteral addrlit(byte_map_base); + masm.set(addrlit, O1); // O1 := <card table base> masm.ldub(O0, O1, O2); // O2 := [O0 + O1] masm.br_on_reg_cond(Assembler::rc_nz, /*annul*/false, Assembler::pt, @@ -4494,10 +4487,9 @@ #else post_filter_masm->srl(store_addr, CardTableModRefBS::card_shift, store_addr); #endif - assert( tmp != store_addr, "need separate temp reg"); - Address rs(tmp, (address)bs->byte_map_base); - load_address(rs); - stb(G0, rs.base(), store_addr); + assert(tmp != store_addr, "need separate temp reg"); + set(bs->byte_map_base, tmp); + stb(G0, tmp, store_addr); } bind(filtered); @@ -4516,24 +4508,6 @@ card_table_write(bs->byte_map_base, tmp, store_addr); } -// Loading values by size and signed-ness -void MacroAssembler::load_sized_value(Register s1, RegisterOrConstant s2, Register d, - int size_in_bytes, bool is_signed) { - switch (size_in_bytes ^ (is_signed ? -1 : 0)) { - case ~8: // fall through: - case 8: ld_long( s1, s2, d ); break; - case ~4: ldsw( s1, s2, d ); break; - case 4: lduw( s1, s2, d ); break; - case ~2: ldsh( s1, s2, d ); break; - case 2: lduh( s1, s2, d ); break; - case ~1: ldsb( s1, s2, d ); break; - case 1: ldub( s1, s2, d ); break; - default: ShouldNotReachHere(); - } -} - - - void MacroAssembler::load_klass(Register src_oop, Register klass) { // The number of bytes in this code is used by // MachCallDynamicJavaNode::ret_addr_offset() @@ -4563,12 +4537,12 @@ } } -void MacroAssembler::load_heap_oop(const Address& s, Register d, int offset) { +void MacroAssembler::load_heap_oop(const Address& s, Register d) { if (UseCompressedOops) { - lduw(s, d, offset); + lduw(s, d); decode_heap_oop(d); } else { - ld_ptr(s, d, offset); + ld_ptr(s, d); } } @@ -4714,7 +4688,7 @@ void MacroAssembler::reinit_heapbase() { if (UseCompressedOops) { // call indirectly to solve generation ordering problem - Address base(G6_heapbase, (address)Universe::narrow_oop_base_addr()); + AddressLiteral base(Universe::narrow_oop_base_addr()); load_ptr_contents(base, G6_heapbase); } }