Вариативность
Инструкции vastart и vaarg предоставляют простой способ доступа к дополнительным параметрам вариацитивной функции.
The vastart and vaarg instructions provide a portable way to access the extra parameters of a variadic function.
vastart -- (m) vaarg -- T(mmmm)
Инструкция vastart инициализирует список аргументов, используемый для доступа к дополнительным параметрам вызванной вариацитивной функции. Её можно безопасно вызвать несколько раз.
The vastart instruction initializes a variable argument list used to access the extra parameters of the enclosing variadic function. It is safe to call it multiple times.
Инструкция vaarg извлекает следующий аргумент из вышеназванного списка аргументов. В настоящее время он ограничен выборками, которые имеют базовый тип. Эта инструкция на самом деле эффективна: последовательно вызвав ее дважды возвращает два последовательных аргумента из списка аргументов.
The vaarg instruction fetches the next argument from a variable argument list. It is currently limited to fetching arguments that have a base type. This instruction is essentially effectful: calling it twice in a row will return two consecutive arguments from the argument list.
Обе инструкции принимают указатель на список аргументов как единственный аргумент. Размер и выравнивание списков аргументов зависит от цели использования. Тем не менее, можно консервативно использовать максимальные размер и выравнивание, необходимые для всех целей.
Both instructions take a pointer to a variable argument list as sole argument. The size and alignment of variable argument lists depend on the target used. However, it is possible to conservatively use the maximum size and alignment required by all the targets.
type :valist = align 8 { 24 } # For amd64_sysv type :valist = align 8 { 32 } # For arm64
В приведенном ниже примере определена вариацитивная функция, суммирующая три своих первых аргумента.
The following example defines a variadic function adding its first three arguments.
Пример. function s $add3(s %a, ...) { @start %ap =l alloc8 32 vastart %ap %r =s call $vadd(s %a, l %ap) ret %r } function s $vadd(s %a, l %ap) { @start %b =s vaarg %ap %c =s vaarg %ap %d =s add %a, %b %e =s add %d, %c ret %e }
Источник: c9x.me