Why is a struct of two doubles passed via registers but a struct of three doubles passed on the stack?

100 Views Asked by At

The following code:

struct Double2 {
    double a;
    double b;
};

struct Double3 {
    double a;
    double b;
    double c;
};

double double2(struct Double2 x) {
    return x.a + x.b;
}

double double3(struct Double3 x) {
    return x.a + x.b + x.c;
}

double double_args(double a, double b, double c) {
    return a + b + c;
}

compiles to

double2:
        addsd   xmm0, xmm1
        ret
double3:
        movsd   xmm0, QWORD PTR [rsp+8]
        addsd   xmm0, QWORD PTR [rsp+16]
        addsd   xmm0, QWORD PTR [rsp+24]
        ret
double_args:
        addsd   xmm0, xmm1
        addsd   xmm0, xmm2
        ret

on Linux, x86-64 with GCC 9.2 with -O3 (Godbolt link)

Why is a struct of two doubles (Double2) passed via the registers xmm0 and xmm1, but a struct of three doubles (Double3) is passed via the stack? double_args() demonstrates that the compiler is at least capable of passing three doubles via registers.

Is this specified as part of the C calling convention? What is the relevant rule?

0

There are 0 best solutions below