使用复合日期类型调用约定

时间:2015-05-18 10:43:38

标签: c++ c gcc x86 calling-convention

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

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

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)

  • foof返回hilo打包到XMM0的前64位。
  • foodhilo返回XMM0XMM1
  • foo3hiloabXMM0XMM1传递XMM2XMM3fooi
  • hilostatic inline返回到rda和rdx

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

参见表6.传递结构,类和联合对象的方法表7.返回结构,类和联合对象的方法

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

请注意,我了解到在实践中,在许多情况下{{1}}最好使用{{1}}。还要注意,即使C没有类,我仍然对如何通过C中的值传递结构和联合感兴趣,而不仅仅是C ++,这就是我包含C标记的原因。

1 个答案:

答案 0 :(得分:2)

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

并非所有平台都有可能记录得很好。