RFR(M): 8024344: PPC64 (part 112): C argument in register AND stack slot.

Lindenmaier, Goetz goetz.lindenmaier at sap.com
Wed Sep 11 08:40:17 PDT 2013

Hi Chris,

we also did a small experiment, showing that the xlc compiler copies the
values on the stack, see below. We have tests for these calls, but they don’t
show errors if we remove copying to the stack.  But that only proves that
the compiler we use does not rely on these stack fields, other code could
do so.

Best regards,

See this small C-program calling a function with floats.  Gcc moves the constants to
the 13 floating point registers, xlC in addition copies f9-f13 to the stack.
Thanks to Axel for this!

extern "C" void foo(float, float, float, float, float, float, float, float, float, float, float, float, float, float);

int main(){
  foo(0.1, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.3, 1.4);

gcc -m64 -O3 -S test.cpp

        mflr 0
        lfs 1,.LC0 at toc(2)
        lfs 0,.LC12 at toc(2)
        std 0,16(1)
        stdu 1,-160(1)
        fmr 2,1
        lfs 3,.LC1 at toc(2)
        lfs 4,.LC2 at toc(2)
        lfs 5,.LC3 at toc(2)
        lfs 6,.LC4 at toc(2)
        lfs 7,.LC5 at toc(2)
        lfs 8,.LC6 at toc(2)
        stfs 0,156(1)
        lfs 9,.LC7 at toc(2)
        lfs 10,.LC8 at toc(2)
        lfs 11,.LC9 at toc(2)
        lfs 12,.LC10 at toc(2)
        lfs 13,.LC11 at toc(2)
        bl foo

xlC -q64 -S -O3 test.cpp

.main:                                  # 0x0000000000000000 (H.4.NO_SYMBOL)
        mfspr   r0,LR
        ld      r3,T.10.NO_SYMBOL(RTOC)
        stdu    SP,-160(SP)
        lfs     fp9,0(r3)
        lfs     fp10,4(r3)
        std     r0,176(SP)
        stfs    fp9,112(SP)
        lfs     fp11,8(r3)
        lfs     fp12,12(r3)
        stfs    fp10,120(SP)
        stfs    fp11,128(SP)
        lfs     fp13,16(r3)
        lfs     fp0,20(r3)
        stfs    fp12,136(SP)
        stfs    fp13,144(SP)
        lfs     fp1,24(r3)
        fmr     fp2,fp1
        lfs     fp3,28(r3)
        lfs     fp4,32(r3)
        lfs     fp5,36(r3)
        lfs     fp6,40(r3)
        lfs     fp7,44(r3)
        stfs    fp0,152(SP)
        lfs     fp8,48(r3)
        bl      .foo{PR}

From: Chris Plummer [mailto:chris.plummer at oracle.com]
Sent: Dienstag, 10. September 2013 20:39
To: Volker Simonis
Cc: Lindenmaier, Goetz; ppc-aix-port-dev at openjdk.java.net; hotspot-dev at openjdk.java.net
Subject: Re: RFR(M): 8024344: PPC64 (part 112): C argument in register AND stack slot.

Hi Volker,

Thanks for the explanation. Seems like you may need it for AIX but not linux, but it's fine if you want it always in place. It won't impact any existing ports, except for the needed mods to the c_calling_conventions() prototype.



On 9/10/13 8:25 AM, Volker Simonis wrote:
Hi Chris,

I think it is hard to find a real authoritative documentation for this convention. But GCC itself provides the option ' -mxl-compat/-mno-xl-compat' [1]) (was '-mxl-call/-mno-xl-call in older GCC versions prior to 3.4 [2]) which state:

Produce code that conforms more closely to IBM XL compiler semantics when using AIX-compatible ABI.  Pass floating-point arguments to prototyped functions beyond the register save area (RSA) on the stack in addition to argument FPRs. Do not assume that most significant double in 128-bit long double value is properly rounded when comparing values and converting to double.  Use XL symbol names for long double support routines.

The AIX calling convention was extended but not initially documented to handle an obscure K&R C case of calling a function that takes the address of its arguments with fewer arguments than declared.  IBM XL compilers access floating point arguments which do not fit in the RSA from the stack when a subroutine is compiled without optimization. Because always storing floating-point arguments on the stack is inefficient and rarely needed, this option is not enabled by default and only is necessary when calling subroutines compiled by IBM XL compilers without optimization.
I think that's basically the reason why we've adapted the calling conventions as well in order to be on the safe side:)

[1] http://gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/RS_002f6000-and-PowerPC-Options.html
[2] http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/RS_002f6000-and-PowerPC-Options.html

On Mon, Sep 9, 2013 at 9:26 PM, Chris Plummer <chris.plummer at oracle.com<mailto:chris.plummer at oracle.com>> wrote:
Hi Goetz,

From what I've read of both 32-bit and 64-bit PPC calling conventions, arguments passed in registers are not also placed on the stack.


Can you please explain when you think an FP argument can end up both in a register and on the stack? Is there some supporting documentation for this?



On 9/9/13 2:41 AM, Lindenmaier, Goetz wrote:

On PPC, the first 13 floating point arguments are passed in
floating point registers. Also, all but the first 8 arguments
are passed on the stack. So there can be floating point
arguments that are passed on the stack and in a register.

This change adapts the c_calling_conventions() to this.
We duplicate the regs datastructure passed to c_calling_convention().
This change adapts all the signatures of this function, which is
defined in a shared file, but implemented platform dependent.
How we use this can be seen in the ppc64 sharedRuntime file in
function c_calling_convention() and the stub generators.

Please review and test this change.

Best regards,

More information about the hotspot-dev mailing list