mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 06:14:49 +02:00
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
Reviewed-by: kvn
This commit is contained in:
parent
add4b5bf69
commit
c2b37037c6
6 changed files with 63 additions and 48 deletions
|
@ -2407,14 +2407,23 @@ void MacroAssembler::lcmp( Register Ra, Register Rb, Register Rresult) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void MacroAssembler::load_sized_value(Address src, Register dst,
|
void MacroAssembler::load_sized_value(Address src, Register dst, size_t size_in_bytes, bool is_signed) {
|
||||||
size_t size_in_bytes, bool is_signed) {
|
|
||||||
switch (size_in_bytes) {
|
switch (size_in_bytes) {
|
||||||
case 8: ldx(src, dst); break;
|
case 8: ld_long(src, dst); break;
|
||||||
case 4: ld( src, dst); break;
|
case 4: ld( src, dst); break;
|
||||||
case 2: is_signed ? ldsh(src, dst) : lduh(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;
|
case 1: is_signed ? ldsb(src, dst) : ldub(src, dst); break;
|
||||||
default: ShouldNotReachHere();
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2330,8 +2330,9 @@ public:
|
||||||
void lcmp( Register Ra, Register Rb, Register Rresult);
|
void lcmp( Register Ra, Register Rb, Register Rresult);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Loading values by size and signed-ness
|
// 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 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,
|
void float_cmp( bool is_float, int unordered_result,
|
||||||
FloatRegister Fa, FloatRegister Fb,
|
FloatRegister Fa, FloatRegister Fb,
|
||||||
|
|
|
@ -596,16 +596,9 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||||
__ st_ptr(O1_scratch, Address(O0_argslot, 0));
|
__ st_ptr(O1_scratch, Address(O0_argslot, 0));
|
||||||
} else {
|
} else {
|
||||||
Address prim_value_addr(O1_scratch, java_lang_boxing_object::value_offset_in_bytes(arg_type));
|
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));
|
const int arg_size = type2aelembytes(arg_type);
|
||||||
if (arg_slots == 2) {
|
__ load_sized_value(prim_value_addr, O2_scratch, arg_size, is_signed_subword_type(arg_type));
|
||||||
__ unimplemented("not yet tested");
|
__ store_sized_value(O2_scratch, Address(O0_argslot, 0), arg_size); // long store uses O2/O3 on !_LP64
|
||||||
#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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direct_to_method) {
|
if (direct_to_method) {
|
||||||
|
@ -784,11 +777,9 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||||
switch (ek) {
|
switch (ek) {
|
||||||
case _adapter_opt_i2l:
|
case _adapter_opt_i2l:
|
||||||
{
|
{
|
||||||
__ ldsw(arg_lsw, O2_scratch); // Load LSW
|
__ ldsw(arg_lsw, O2_scratch); // Load LSW
|
||||||
#ifndef _LP64
|
NOT_LP64(__ srlx(O2_scratch, BitsPerInt, O3_scratch)); // Move high bits to lower bits for std
|
||||||
__ signx(O2_scratch, O3_scratch); // Sign extend
|
__ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64
|
||||||
#endif
|
|
||||||
__ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _adapter_opt_unboxl:
|
case _adapter_opt_unboxl:
|
||||||
|
|
|
@ -6528,20 +6528,39 @@ int MacroAssembler::load_unsigned_short(Register dst, Address src) {
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::load_sized_value(Register dst, Address src,
|
void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2) {
|
||||||
size_t size_in_bytes, bool is_signed) {
|
|
||||||
switch (size_in_bytes) {
|
switch (size_in_bytes) {
|
||||||
#ifndef _LP64
|
#ifndef _LP64
|
||||||
// For case 8, caller is responsible for manually loading
|
case 8:
|
||||||
// the second word into another register.
|
assert(dst2 != noreg, "second dest register required");
|
||||||
case 8: movl(dst, src); break;
|
movl(dst, src);
|
||||||
|
movl(dst2, src.plus_disp(BytesPerInt));
|
||||||
|
break;
|
||||||
#else
|
#else
|
||||||
case 8: movq(dst, src); break;
|
case 8: movq(dst, src); break;
|
||||||
#endif
|
#endif
|
||||||
case 4: movl(dst, src); break;
|
case 4: movl(dst, src); break;
|
||||||
case 2: is_signed ? load_signed_short(dst, src) : load_unsigned_short(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;
|
case 1: is_signed ? load_signed_byte( dst, src) : load_unsigned_byte( dst, src); break;
|
||||||
default: ShouldNotReachHere();
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1522,8 +1522,9 @@ class MacroAssembler: public Assembler {
|
||||||
// Support for sign-extension (hi:lo = extend_sign(lo))
|
// Support for sign-extension (hi:lo = extend_sign(lo))
|
||||||
void extend_sign(Register hi, Register lo);
|
void extend_sign(Register hi, Register lo);
|
||||||
|
|
||||||
// Loading values by size and signed-ness
|
// 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);
|
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
|
// Support for inc/dec with optimal instruction selection depending on value
|
||||||
|
|
||||||
|
|
|
@ -602,24 +602,18 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||||
// make room for the new argument:
|
// make room for the new argument:
|
||||||
__ movl(rax_argslot, rcx_bmh_vmargslot);
|
__ movl(rax_argslot, rcx_bmh_vmargslot);
|
||||||
__ lea(rax_argslot, __ argument_address(rax_argslot));
|
__ 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:
|
// store bound argument into the new stack slot:
|
||||||
__ load_heap_oop(rbx_temp, rcx_bmh_argument);
|
__ 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) {
|
if (arg_type == T_OBJECT) {
|
||||||
__ movptr(Address(rax_argslot, 0), rbx_temp);
|
__ movptr(Address(rax_argslot, 0), rbx_temp);
|
||||||
} else {
|
} else {
|
||||||
__ load_sized_value(rdx_temp, prim_value_addr,
|
Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type));
|
||||||
type2aelembytes(arg_type), is_signed_subword_type(arg_type));
|
const int arg_size = type2aelembytes(arg_type);
|
||||||
__ movptr(Address(rax_argslot, 0), rdx_temp);
|
__ load_sized_value(rdx_temp, prim_value_addr, arg_size, is_signed_subword_type(arg_type), rbx_temp);
|
||||||
#ifndef _LP64
|
__ store_sized_value(Address(rax_argslot, 0), rdx_temp, arg_size, rbx_temp);
|
||||||
if (arg_slots == 2) {
|
|
||||||
__ movl(rdx_temp, prim_value_addr.plus_disp(wordSize));
|
|
||||||
__ movl(Address(rax_argslot, Interpreter::stackElementSize), rdx_temp);
|
|
||||||
}
|
|
||||||
#endif //_LP64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direct_to_method) {
|
if (direct_to_method) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue