Соглашения о вызовах с составными типами дат


Я понимаю соглашения о вызовах для передачи 32-битных и 64-битных целых чисел (и указателей), плавающих и двойных чисел для 64-битного кода для Micrsoft и System V AMD64 ABI. Но мне не ясно, какие соглашения о вызовах существуют для составных типов данных.

Чтобы быть более ясным, каковы соглашения о вызовах для передачи структур, классов и объединений по значению в функциях с внешней связью (т. е. не 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 возвращает hi и lo, упакованные в первые 64 бита XMM0.
  • food возвращает hi и lo в XMM0 и XMM1.
  • foo3 проходит hi и lo из a и b в XMM0, XMM1, XMM2, и XMM3.
  • fooi возвращает hi и lo в rda и rdx

Agner Fog описывает детали (которые согласуются с наблюдениями) для каждого компилятора около http://www.agner.org/optimize/calling_conventions.pdf

См Таблица 6. Методы передачи объектов структуры, класса и объединения и Таблица 7. Методы для возврата объектов структуры, класса и объединения .

Для 64-битного кода его таблицы разделены на Windows и Linux/BSD / Mac, а не на компилятор, поэтому для меня это означает, что существует некоторый стандарт для составных типов данных. Правильно ли это или передача и возврат составного типа данных потенциально определяется каждым компилятором или каждой версией компилятора (т. е. может изменяться со следующей версией).

Обратите внимание, что я понимаю, что на практике во многих из этих случаев static inline, вероятно, было бы лучше всего использовать в любом случае. Также обратите внимание, что, хотя C не имеет классов, мне все еще интересно, как структуры и союзы передаются по значению в C, а не только в C++, поэтому я включил тег C.
1 3

1 ответ:

Некоторые стандарты существуют. Например, документSystemV AMD64 ABI довольно подробно описывает передачу параметров для агрегатов (начиная со страницы 17). Я не буду копировать соответствующую часть текста здесь, так как есть несколько страниц.

Не все платформы, вероятно, будут так хорошо документированы.