changeset 6502:237e197452b9

8139258: PPC64LE: argument passing problem when passing 15 floats in native call Reviewed-by: mdoerr, goetz Contributed-by: asmundak@google.com
author goetz
date Tue, 17 Nov 2015 08:59:21 +0100
parents e806d32ca07a
children dcbd95fc5cc6
files src/cpu/ppc/vm/interpreter_ppc.cpp src/cpu/ppc/vm/sharedRuntime_ppc.cpp
diffstat 2 files changed, 25 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/ppc/vm/interpreter_ppc.cpp	Mon Oct 12 12:20:38 2015 +0200
+++ b/src/cpu/ppc/vm/interpreter_ppc.cpp	Tue Nov 17 08:59:21 2015 +0100
@@ -312,8 +312,16 @@
   __ bind(do_float);
   __ lfs(floatSlot, 0, arg_java);
 #if defined(LINUX)
+  // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float
+  // in the least significant word of an argument slot.
+#if defined(VM_LITTLE_ENDIAN)
+  __ stfs(floatSlot, 0, arg_c);
+#else
   __ stfs(floatSlot, 4, arg_c);
+#endif
 #elif defined(AIX)
+  // Although AIX runs on big endian CPU, float is in most significant
+  // word of an argument slot.
   __ stfs(floatSlot, 0, arg_c);
 #else
 #error "unknown OS"
--- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Mon Oct 12 12:20:38 2015 +0200
+++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Nov 17 08:59:21 2015 +0100
@@ -769,6 +769,21 @@
     // in farg_reg[j] if argument i is the j-th float argument of this call.
     //
     case T_FLOAT:
+#if defined(LINUX)
+      // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float
+      // in the least significant word of an argument slot.
+#if defined(VM_LITTLE_ENDIAN)
+#define FLOAT_WORD_OFFSET_IN_SLOT 0
+#else
+#define FLOAT_WORD_OFFSET_IN_SLOT 1
+#endif
+#elif defined(AIX)
+      // Although AIX runs on big endian CPU, float is in the most
+      // significant word of an argument slot.
+#define FLOAT_WORD_OFFSET_IN_SLOT 0
+#else
+#error "unknown OS"
+#endif
       if (freg < Argument::n_float_register_parameters_c) {
         // Put float in register ...
         reg = farg_reg[freg];
@@ -782,14 +797,14 @@
         if (arg >= Argument::n_regs_not_on_stack_c) {
           // ... and on the stack.
           guarantee(regs2 != NULL, "must pass float in register and stack slot");
-          VMReg reg2 = VMRegImpl::stack2reg(stk LINUX_ONLY(+1));
+          VMReg reg2 = VMRegImpl::stack2reg(stk + FLOAT_WORD_OFFSET_IN_SLOT);
           regs2[i].set1(reg2);
           stk += inc_stk_for_intfloat;
         }
 
       } else {
         // Put float on stack.
-        reg = VMRegImpl::stack2reg(stk LINUX_ONLY(+1));
+        reg = VMRegImpl::stack2reg(stk + FLOAT_WORD_OFFSET_IN_SLOT);
         stk += inc_stk_for_intfloat;
       }
       regs[i].set1(reg);