以下代码:
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;
}
编译为
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
在 Linux 上,x86-64 和 GCC 9.2 和 -O3(Godbolt 链接)
为什么两个双精度 ( Double2
) 的结构通过寄存器xmm0
和传递xmm1
,而三个双精度 ( Double3
) 的结构通过堆栈传递?double_args()
证明编译器至少能够通过寄存器传递三个双精度数。
这是否指定为 C 调用约定的一部分?相关规则是什么?