7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
authortwisti
Mon, 14 Feb 2011 03:21:18 -0800
changeset 8328 478a1d29e5a3
parent 8327 f5a13a17d5f3
child 8329 96eacc5e391f
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC Reviewed-by: kvn
hotspot/src/cpu/sparc/vm/assembler_sparc.cpp
hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp
hotspot/src/cpu/x86/vm/assembler_x86.cpp
hotspot/src/cpu/x86/vm/assembler_x86.hpp
hotspot/src/cpu/x86/vm/methodHandles_x86.cpp
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Fri Feb 11 12:05:43 2011 -0800
+++ b/hotspot/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();
   }
 }
 
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Feb 11 12:05:43 2011 -0800
+++ b/hotspot/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,
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Feb 11 12:05:43 2011 -0800
+++ b/hotspot/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:
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Fri Feb 11 12:05:43 2011 -0800
+++ b/hotspot/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();
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Fri Feb 11 12:05:43 2011 -0800
+++ b/hotspot/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
 
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Feb 11 12:05:43 2011 -0800
+++ b/hotspot/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) {