# HG changeset patch # User twisti # Date 1297682478 28800 # Node ID 28bf941f445eb77827dd06fa7b1b67e248017dda # Parent 34457f6ac8184060dd2d2b66b9955eccd88fd65f 7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC Reviewed-by: kvn diff -r 34457f6ac818 -r 28bf941f445e src/cpu/sparc/vm/assembler_sparc.cpp --- a/src/cpu/sparc/vm/assembler_sparc.cpp Fri Feb 11 12:05:43 2011 -0800 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp Mon Feb 14 03:21:18 2011 -0800 @@ -2407,14 +2407,23 @@ #endif -void MacroAssembler::load_sized_value(Address src, Register dst, - size_t size_in_bytes, bool is_signed) { +void MacroAssembler::load_sized_value(Address src, Register dst, size_t size_in_bytes, bool is_signed) { switch (size_in_bytes) { - case 8: ldx(src, dst); break; - case 4: ld( src, dst); break; - case 2: is_signed ? ldsh(src, dst) : lduh(src, dst); break; - case 1: is_signed ? ldsb(src, dst) : ldub(src, dst); break; - default: ShouldNotReachHere(); + case 8: ld_long(src, dst); break; + case 4: ld( src, dst); break; + case 2: is_signed ? ldsh(src, dst) : lduh(src, dst); break; + case 1: is_signed ? ldsb(src, dst) : ldub(src, dst); break; + default: ShouldNotReachHere(); + } +} + +void MacroAssembler::store_sized_value(Register src, Address dst, size_t size_in_bytes) { + switch (size_in_bytes) { + case 8: st_long(src, dst); break; + case 4: st( src, dst); break; + case 2: sth( src, dst); break; + case 1: stb( src, dst); break; + default: ShouldNotReachHere(); } } diff -r 34457f6ac818 -r 28bf941f445e src/cpu/sparc/vm/assembler_sparc.hpp --- a/src/cpu/sparc/vm/assembler_sparc.hpp Fri Feb 11 12:05:43 2011 -0800 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Mon Feb 14 03:21:18 2011 -0800 @@ -2330,8 +2330,9 @@ void lcmp( Register Ra, Register Rb, Register Rresult); #endif - // Loading values by size and signed-ness - void load_sized_value(Address src, Register dst, size_t size_in_bytes, bool is_signed); + // Load and store values by size and signed-ness + void load_sized_value( Address src, Register dst, size_t size_in_bytes, bool is_signed); + void store_sized_value(Register src, Address dst, size_t size_in_bytes); void float_cmp( bool is_float, int unordered_result, FloatRegister Fa, FloatRegister Fb, diff -r 34457f6ac818 -r 28bf941f445e src/cpu/sparc/vm/methodHandles_sparc.cpp --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Feb 11 12:05:43 2011 -0800 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp Mon Feb 14 03:21:18 2011 -0800 @@ -596,16 +596,9 @@ __ st_ptr(O1_scratch, Address(O0_argslot, 0)); } else { Address prim_value_addr(O1_scratch, java_lang_boxing_object::value_offset_in_bytes(arg_type)); - __ load_sized_value(prim_value_addr, O2_scratch, type2aelembytes(arg_type), is_signed_subword_type(arg_type)); - if (arg_slots == 2) { - __ unimplemented("not yet tested"); -#ifndef _LP64 - __ signx(O2_scratch, O3_scratch); // Sign extend -#endif - __ st_long(O2_scratch, Address(O0_argslot, 0)); // Uses O2/O3 on !_LP64 - } else { - __ st_ptr( O2_scratch, Address(O0_argslot, 0)); - } + const int arg_size = type2aelembytes(arg_type); + __ load_sized_value(prim_value_addr, O2_scratch, arg_size, is_signed_subword_type(arg_type)); + __ store_sized_value(O2_scratch, Address(O0_argslot, 0), arg_size); // long store uses O2/O3 on !_LP64 } if (direct_to_method) { @@ -784,11 +777,9 @@ switch (ek) { case _adapter_opt_i2l: { - __ ldsw(arg_lsw, O2_scratch); // Load LSW -#ifndef _LP64 - __ signx(O2_scratch, O3_scratch); // Sign extend -#endif - __ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64 + __ ldsw(arg_lsw, O2_scratch); // Load LSW + NOT_LP64(__ srlx(O2_scratch, BitsPerInt, O3_scratch)); // Move high bits to lower bits for std + __ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64 } break; case _adapter_opt_unboxl: diff -r 34457f6ac818 -r 28bf941f445e src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Fri Feb 11 12:05:43 2011 -0800 +++ b/src/cpu/x86/vm/assembler_x86.cpp Mon Feb 14 03:21:18 2011 -0800 @@ -6528,20 +6528,39 @@ return off; } -void MacroAssembler::load_sized_value(Register dst, Address src, - size_t size_in_bytes, bool is_signed) { +void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2) { switch (size_in_bytes) { #ifndef _LP64 - // For case 8, caller is responsible for manually loading - // the second word into another register. - case 8: movl(dst, src); break; + case 8: + assert(dst2 != noreg, "second dest register required"); + movl(dst, src); + movl(dst2, src.plus_disp(BytesPerInt)); + break; #else - case 8: movq(dst, src); break; + case 8: movq(dst, src); break; #endif - case 4: movl(dst, src); break; - case 2: is_signed ? load_signed_short(dst, src) : load_unsigned_short(dst, src); break; - case 1: is_signed ? load_signed_byte( dst, src) : load_unsigned_byte( dst, src); break; - default: ShouldNotReachHere(); + case 4: movl(dst, src); break; + case 2: is_signed ? load_signed_short(dst, src) : load_unsigned_short(dst, src); break; + case 1: is_signed ? load_signed_byte( dst, src) : load_unsigned_byte( dst, src); break; + default: ShouldNotReachHere(); + } +} + +void MacroAssembler::store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2) { + switch (size_in_bytes) { +#ifndef _LP64 + case 8: + assert(src2 != noreg, "second source register required"); + movl(dst, src); + movl(dst.plus_disp(BytesPerInt), src2); + break; +#else + case 8: movq(dst, src); break; +#endif + case 4: movl(dst, src); break; + case 2: movw(dst, src); break; + case 1: movb(dst, src); break; + default: ShouldNotReachHere(); } } diff -r 34457f6ac818 -r 28bf941f445e src/cpu/x86/vm/assembler_x86.hpp --- a/src/cpu/x86/vm/assembler_x86.hpp Fri Feb 11 12:05:43 2011 -0800 +++ b/src/cpu/x86/vm/assembler_x86.hpp Mon Feb 14 03:21:18 2011 -0800 @@ -1522,8 +1522,9 @@ // Support for sign-extension (hi:lo = extend_sign(lo)) void extend_sign(Register hi, Register lo); - // Loading values by size and signed-ness - void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed); + // Load and store values by size and signed-ness + void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg); + void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg); // Support for inc/dec with optimal instruction selection depending on value diff -r 34457f6ac818 -r 28bf941f445e src/cpu/x86/vm/methodHandles_x86.cpp --- a/src/cpu/x86/vm/methodHandles_x86.cpp Fri Feb 11 12:05:43 2011 -0800 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Mon Feb 14 03:21:18 2011 -0800 @@ -602,24 +602,18 @@ // make room for the new argument: __ movl(rax_argslot, rcx_bmh_vmargslot); __ lea(rax_argslot, __ argument_address(rax_argslot)); - insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, - rax_argslot, rbx_temp, rdx_temp); + + insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, rax_argslot, rbx_temp, rdx_temp); // store bound argument into the new stack slot: __ load_heap_oop(rbx_temp, rcx_bmh_argument); - Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type)); if (arg_type == T_OBJECT) { __ movptr(Address(rax_argslot, 0), rbx_temp); } else { - __ load_sized_value(rdx_temp, prim_value_addr, - type2aelembytes(arg_type), is_signed_subword_type(arg_type)); - __ movptr(Address(rax_argslot, 0), rdx_temp); -#ifndef _LP64 - if (arg_slots == 2) { - __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize)); - __ movl(Address(rax_argslot, Interpreter::stackElementSize), rdx_temp); - } -#endif //_LP64 + Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type)); + const int arg_size = type2aelembytes(arg_type); + __ load_sized_value(rdx_temp, prim_value_addr, arg_size, is_signed_subword_type(arg_type), rbx_temp); + __ store_sized_value(Address(rax_argslot, 0), rdx_temp, arg_size, rbx_temp); } if (direct_to_method) {