Соглашения о вызовах с составными типами дат
Я понимаю соглашения о вызовах для передачи 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 ответ:
Некоторые стандарты существуют. Например, документSystemV AMD64 ABI довольно подробно описывает передачу параметров для агрегатов (начиная со страницы 17). Я не буду копировать соответствующую часть текста здесь, так как есть несколько страниц.
Не все платформы, вероятно, будут так хорошо документированы.