8139258: PPC64LE: argument passing problem when passing 15 floats in native call
Reviewed-by: mdoerr, goetz
Contributed-by: asmundak@google.com
--- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Mon Nov 16 20:57:49 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Tue Nov 17 08:59:21 2015 +0100
@@ -297,8 +297,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/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Mon Nov 16 20:57:49 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Tue Nov 17 08:59:21 2015 +0100
@@ -753,6 +753,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];
@@ -766,14 +781,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);