Почему соглашение о вызовах Windows x64 не использует регистры XMM для передачи более 4 целочисленных аргументов? - PullRequest
4 голосов
/ 08 июня 2011

(Microsoft) x64 соглашение о вызовах заявляет:

Аргументы передаются в регистрах RCX, RDX, R8 и R9. Если аргументы имеют тип float / double, они передаются в XMM0L, XMM1L, XMM2L и XMM3L.

Это здорово, но почему просто плавает / удваивается? Почему целые числа (и, возможно, указатели) также не передаются через регистры XMM?
Кажется, это пустая трата свободного места, не так ли?

Ответы [ 2 ]

6 голосов
/ 08 июня 2011

Поскольку большинство операций со значениями не-FP (то есть целыми числами и адресами) предназначены для использования регистров общего назначения.

Существуют целочисленные операции SSE, но они только арифметические.

Таким образом, если соглашение о вызовах поддерживает передачу целых чисел и адресов через регистры SSE, почти всегда необходимо копировать значение в регистры общего назначения.

2 голосов
/ 25 февраля 2019

Функции часто хотят использовать целочисленные аргументы с указателями (в качестве индексов или для вычисления указателя конца как границы цикла) или с другими целочисленными аргументами в регистрах GP. Или с другими целыми числами, загруженными из памяти, с которой они хотят работать в регистрах GP

Вы не можете эффективно использовать целое число в регистре XMM в качестве счетчика цикла или связанного, потому что нет сравнения упакованных целых чисел, которое устанавливает целочисленные флаги для инструкций ветвления. (pcmpgtd создает маску из 0 / -1 элементов).

См. Также Почему бы не сохранить параметры функции в векторных регистрах XMM? и другой ответ здесь для получения дополнительной информации.


Но даже более того, эта идея дизайна даже не подходит для Windows x64 fastcall / vectorcall.

Windows x64 решает тратить пространство нарочно, чтобы упростить различные функции. Аргументы регистров могут быть сброшены в 32-байтовое «теневое пространство» / «домашнее пространство» над адресом возврата, чтобы сформировать массив аргументов.

Вот почему (например) Windows x64 передает 3-й аргумент в R8 или XMM2 независимо от типов предыдущих аргументов. И почему вызовы функций с переменными значениями требуют, чтобы аргументы FP также копировались в соответствующий регистр целых чисел, поэтому пролог функции может выводить регистры arg, не выясняя, какие аргументы с переменными числами были FP, а какие были целыми.

Чтобы заставить работать массив массива arg, в регистрах можно передать только 4 полных аргумента, независимо от того, есть ли у вас комбинация целочисленных и FP-аргументов. Достаточно целочисленных регистров GP для хранения Максимальное количество аргументов регистра уже, даже если они все целые.


(В отличие от x86-64 System V, где первые до 8 аргументов FP передаются в xmm0..7 независимо от количества используемых регистров передачи целочисленных значений / указателей.)

Почему Windows64 использует соглашение о вызовах, отличное от всех других ОС на x86-64?

...