Tue, 17 Nov 2015 08:59:21 +0100
8139258: PPC64LE: argument passing problem when passing 15 floats in native call
Reviewed-by: mdoerr, goetz
Contributed-by: asmundak@google.com
src/cpu/ppc/vm/interpreter_ppc.cpp | file | annotate | diff | comparison | revisions | |
src/cpu/ppc/vm/sharedRuntime_ppc.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/cpu/ppc/vm/interpreter_ppc.cpp Mon Oct 12 12:20:38 2015 +0200 1.2 +++ b/src/cpu/ppc/vm/interpreter_ppc.cpp Tue Nov 17 08:59:21 2015 +0100 1.3 @@ -296,8 +296,16 @@ 1.4 __ bind(do_float); 1.5 __ lfs(floatSlot, 0, arg_java); 1.6 #if defined(LINUX) 1.7 + // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float 1.8 + // in the least significant word of an argument slot. 1.9 +#if defined(VM_LITTLE_ENDIAN) 1.10 + __ stfs(floatSlot, 0, arg_c); 1.11 +#else 1.12 __ stfs(floatSlot, 4, arg_c); 1.13 +#endif 1.14 #elif defined(AIX) 1.15 + // Although AIX runs on big endian CPU, float is in most significant 1.16 + // word of an argument slot. 1.17 __ stfs(floatSlot, 0, arg_c); 1.18 #else 1.19 #error "unknown OS"
2.1 --- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Mon Oct 12 12:20:38 2015 +0200 2.2 +++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Tue Nov 17 08:59:21 2015 +0100 2.3 @@ -766,6 +766,21 @@ 2.4 // in farg_reg[j] if argument i is the j-th float argument of this call. 2.5 // 2.6 case T_FLOAT: 2.7 +#if defined(LINUX) 2.8 + // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float 2.9 + // in the least significant word of an argument slot. 2.10 +#if defined(VM_LITTLE_ENDIAN) 2.11 +#define FLOAT_WORD_OFFSET_IN_SLOT 0 2.12 +#else 2.13 +#define FLOAT_WORD_OFFSET_IN_SLOT 1 2.14 +#endif 2.15 +#elif defined(AIX) 2.16 + // Although AIX runs on big endian CPU, float is in the most 2.17 + // significant word of an argument slot. 2.18 +#define FLOAT_WORD_OFFSET_IN_SLOT 0 2.19 +#else 2.20 +#error "unknown OS" 2.21 +#endif 2.22 if (freg < Argument::n_float_register_parameters_c) { 2.23 // Put float in register ... 2.24 reg = farg_reg[freg]; 2.25 @@ -779,14 +794,14 @@ 2.26 if (arg >= Argument::n_regs_not_on_stack_c) { 2.27 // ... and on the stack. 2.28 guarantee(regs2 != NULL, "must pass float in register and stack slot"); 2.29 - VMReg reg2 = VMRegImpl::stack2reg(stk LINUX_ONLY(+1)); 2.30 + VMReg reg2 = VMRegImpl::stack2reg(stk + FLOAT_WORD_OFFSET_IN_SLOT); 2.31 regs2[i].set1(reg2); 2.32 stk += inc_stk_for_intfloat; 2.33 } 2.34 2.35 } else { 2.36 // Put float on stack. 2.37 - reg = VMRegImpl::stack2reg(stk LINUX_ONLY(+1)); 2.38 + reg = VMRegImpl::stack2reg(stk + FLOAT_WORD_OFFSET_IN_SLOT); 2.39 stk += inc_stk_for_intfloat; 2.40 } 2.41 regs[i].set1(reg);