复合日期类型的调用约定

Calling conventions with composite date types

我了解为 Micrsoft 和 System V AMD64 ABI 传递 32 位和 64 位整数(和指针)、浮点数和双精度数的 64 位代码的调用约定。但是我不清楚复合数据类型的调用约定是什么。

更清楚的是,在具有外部链接的函数(即不是 static inline 函数)中,传递结构、classes 和按值联合的调用约定是什么?我对简单的结构特别感兴趣,例如

typedef struct doublefloat { float hi; float lo; } doublefloat;
typedef struct doubledouble { double hi; double lo; } doubledouble;
typedef struct int128 { int64_t hi; int64_t lo; } int128; 

doublefloat foof(float a, float b);    
doubledouble food(double a, double b);
float foo3(doubledouble a, doubledouble b);    
int128 fooi(int64_t a, int64_t b);

这是我在 GCC 中观察到的(使用 -O3)

Agner Fog 描述了每个编译器的详细信息(与观察结果一致) http://www.agner.org/optimize/calling_conventions.pdf

参见Table 6.传递结构、class和联合对象的方法Table 7. 返回结构、class和联合对象的方法.

对于 64 位代码,他的表分为 Windows 和 Linux/BSD/Mac,而不是每个编译器,所以这对我来说意味着复合数据类型有一些标准。这是正确的还是复合数据类型的传递和返回可能由每个编译器或每个版本的编译器定义(即可能随下一个版本而改变)。

请注意,我知道在实践中,在许多情况下,static inline 可能是最好的选择。另请注意,即使 C 没有 classes,我仍然对 C 中的结构和联合如何按值传递感兴趣,而不仅仅是 C++,这就是我包含 C 标记的原因。

确实存在一些标准。例如,SystemV AMD64 ABI document 详细描述了聚合的参数传递(从第 17 页开始)。由于有几页,我不会在这里复制相关部分的文本。

并非所有平台都有如此详尽的文档记录。