Mon, 14 Feb 2011 03:21:18 -0800
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
Reviewed-by: kvn
1.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp Fri Feb 11 12:05:43 2011 -0800 1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp Mon Feb 14 03:21:18 2011 -0800 1.3 @@ -2407,14 +2407,23 @@ 1.4 #endif 1.5 1.6 1.7 -void MacroAssembler::load_sized_value(Address src, Register dst, 1.8 - size_t size_in_bytes, bool is_signed) { 1.9 +void MacroAssembler::load_sized_value(Address src, Register dst, size_t size_in_bytes, bool is_signed) { 1.10 switch (size_in_bytes) { 1.11 - case 8: ldx(src, dst); break; 1.12 - case 4: ld( src, dst); break; 1.13 - case 2: is_signed ? ldsh(src, dst) : lduh(src, dst); break; 1.14 - case 1: is_signed ? ldsb(src, dst) : ldub(src, dst); break; 1.15 - default: ShouldNotReachHere(); 1.16 + case 8: ld_long(src, dst); break; 1.17 + case 4: ld( src, dst); break; 1.18 + case 2: is_signed ? ldsh(src, dst) : lduh(src, dst); break; 1.19 + case 1: is_signed ? ldsb(src, dst) : ldub(src, dst); break; 1.20 + default: ShouldNotReachHere(); 1.21 + } 1.22 +} 1.23 + 1.24 +void MacroAssembler::store_sized_value(Register src, Address dst, size_t size_in_bytes) { 1.25 + switch (size_in_bytes) { 1.26 + case 8: st_long(src, dst); break; 1.27 + case 4: st( src, dst); break; 1.28 + case 2: sth( src, dst); break; 1.29 + case 1: stb( src, dst); break; 1.30 + default: ShouldNotReachHere(); 1.31 } 1.32 } 1.33
2.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp Fri Feb 11 12:05:43 2011 -0800 2.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Mon Feb 14 03:21:18 2011 -0800 2.3 @@ -2330,8 +2330,9 @@ 2.4 void lcmp( Register Ra, Register Rb, Register Rresult); 2.5 #endif 2.6 2.7 - // Loading values by size and signed-ness 2.8 - void load_sized_value(Address src, Register dst, size_t size_in_bytes, bool is_signed); 2.9 + // Load and store values by size and signed-ness 2.10 + void load_sized_value( Address src, Register dst, size_t size_in_bytes, bool is_signed); 2.11 + void store_sized_value(Register src, Address dst, size_t size_in_bytes); 2.12 2.13 void float_cmp( bool is_float, int unordered_result, 2.14 FloatRegister Fa, FloatRegister Fb,
3.1 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Feb 11 12:05:43 2011 -0800 3.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp Mon Feb 14 03:21:18 2011 -0800 3.3 @@ -596,16 +596,9 @@ 3.4 __ st_ptr(O1_scratch, Address(O0_argslot, 0)); 3.5 } else { 3.6 Address prim_value_addr(O1_scratch, java_lang_boxing_object::value_offset_in_bytes(arg_type)); 3.7 - __ load_sized_value(prim_value_addr, O2_scratch, type2aelembytes(arg_type), is_signed_subword_type(arg_type)); 3.8 - if (arg_slots == 2) { 3.9 - __ unimplemented("not yet tested"); 3.10 -#ifndef _LP64 3.11 - __ signx(O2_scratch, O3_scratch); // Sign extend 3.12 -#endif 3.13 - __ st_long(O2_scratch, Address(O0_argslot, 0)); // Uses O2/O3 on !_LP64 3.14 - } else { 3.15 - __ st_ptr( O2_scratch, Address(O0_argslot, 0)); 3.16 - } 3.17 + const int arg_size = type2aelembytes(arg_type); 3.18 + __ load_sized_value(prim_value_addr, O2_scratch, arg_size, is_signed_subword_type(arg_type)); 3.19 + __ store_sized_value(O2_scratch, Address(O0_argslot, 0), arg_size); // long store uses O2/O3 on !_LP64 3.20 } 3.21 3.22 if (direct_to_method) { 3.23 @@ -784,11 +777,9 @@ 3.24 switch (ek) { 3.25 case _adapter_opt_i2l: 3.26 { 3.27 - __ ldsw(arg_lsw, O2_scratch); // Load LSW 3.28 -#ifndef _LP64 3.29 - __ signx(O2_scratch, O3_scratch); // Sign extend 3.30 -#endif 3.31 - __ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64 3.32 + __ ldsw(arg_lsw, O2_scratch); // Load LSW 3.33 + NOT_LP64(__ srlx(O2_scratch, BitsPerInt, O3_scratch)); // Move high bits to lower bits for std 3.34 + __ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64 3.35 } 3.36 break; 3.37 case _adapter_opt_unboxl:
4.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Fri Feb 11 12:05:43 2011 -0800 4.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Mon Feb 14 03:21:18 2011 -0800 4.3 @@ -6528,20 +6528,39 @@ 4.4 return off; 4.5 } 4.6 4.7 -void MacroAssembler::load_sized_value(Register dst, Address src, 4.8 - size_t size_in_bytes, bool is_signed) { 4.9 +void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2) { 4.10 switch (size_in_bytes) { 4.11 #ifndef _LP64 4.12 - // For case 8, caller is responsible for manually loading 4.13 - // the second word into another register. 4.14 - case 8: movl(dst, src); break; 4.15 + case 8: 4.16 + assert(dst2 != noreg, "second dest register required"); 4.17 + movl(dst, src); 4.18 + movl(dst2, src.plus_disp(BytesPerInt)); 4.19 + break; 4.20 #else 4.21 - case 8: movq(dst, src); break; 4.22 + case 8: movq(dst, src); break; 4.23 #endif 4.24 - case 4: movl(dst, src); break; 4.25 - case 2: is_signed ? load_signed_short(dst, src) : load_unsigned_short(dst, src); break; 4.26 - case 1: is_signed ? load_signed_byte( dst, src) : load_unsigned_byte( dst, src); break; 4.27 - default: ShouldNotReachHere(); 4.28 + case 4: movl(dst, src); break; 4.29 + case 2: is_signed ? load_signed_short(dst, src) : load_unsigned_short(dst, src); break; 4.30 + case 1: is_signed ? load_signed_byte( dst, src) : load_unsigned_byte( dst, src); break; 4.31 + default: ShouldNotReachHere(); 4.32 + } 4.33 +} 4.34 + 4.35 +void MacroAssembler::store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2) { 4.36 + switch (size_in_bytes) { 4.37 +#ifndef _LP64 4.38 + case 8: 4.39 + assert(src2 != noreg, "second source register required"); 4.40 + movl(dst, src); 4.41 + movl(dst.plus_disp(BytesPerInt), src2); 4.42 + break; 4.43 +#else 4.44 + case 8: movq(dst, src); break; 4.45 +#endif 4.46 + case 4: movl(dst, src); break; 4.47 + case 2: movw(dst, src); break; 4.48 + case 1: movb(dst, src); break; 4.49 + default: ShouldNotReachHere(); 4.50 } 4.51 } 4.52
5.1 --- a/src/cpu/x86/vm/assembler_x86.hpp Fri Feb 11 12:05:43 2011 -0800 5.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp Mon Feb 14 03:21:18 2011 -0800 5.3 @@ -1522,8 +1522,9 @@ 5.4 // Support for sign-extension (hi:lo = extend_sign(lo)) 5.5 void extend_sign(Register hi, Register lo); 5.6 5.7 - // Loading values by size and signed-ness 5.8 - void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed); 5.9 + // Load and store values by size and signed-ness 5.10 + void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg); 5.11 + void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg); 5.12 5.13 // Support for inc/dec with optimal instruction selection depending on value 5.14
6.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp Fri Feb 11 12:05:43 2011 -0800 6.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Mon Feb 14 03:21:18 2011 -0800 6.3 @@ -602,24 +602,18 @@ 6.4 // make room for the new argument: 6.5 __ movl(rax_argslot, rcx_bmh_vmargslot); 6.6 __ lea(rax_argslot, __ argument_address(rax_argslot)); 6.7 - insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, 6.8 - rax_argslot, rbx_temp, rdx_temp); 6.9 + 6.10 + insert_arg_slots(_masm, arg_slots * stack_move_unit(), arg_mask, rax_argslot, rbx_temp, rdx_temp); 6.11 6.12 // store bound argument into the new stack slot: 6.13 __ load_heap_oop(rbx_temp, rcx_bmh_argument); 6.14 - Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type)); 6.15 if (arg_type == T_OBJECT) { 6.16 __ movptr(Address(rax_argslot, 0), rbx_temp); 6.17 } else { 6.18 - __ load_sized_value(rdx_temp, prim_value_addr, 6.19 - type2aelembytes(arg_type), is_signed_subword_type(arg_type)); 6.20 - __ movptr(Address(rax_argslot, 0), rdx_temp); 6.21 -#ifndef _LP64 6.22 - if (arg_slots == 2) { 6.23 - __ movl(rdx_temp, prim_value_addr.plus_disp(wordSize)); 6.24 - __ movl(Address(rax_argslot, Interpreter::stackElementSize), rdx_temp); 6.25 - } 6.26 -#endif //_LP64 6.27 + Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type)); 6.28 + const int arg_size = type2aelembytes(arg_type); 6.29 + __ load_sized_value(rdx_temp, prim_value_addr, arg_size, is_signed_subword_type(arg_type), rbx_temp); 6.30 + __ store_sized_value(Address(rax_argslot, 0), rdx_temp, arg_size, rbx_temp); 6.31 } 6.32 6.33 if (direct_to_method) {