Есть 3 тесты
bench_internal
bench_verify
bench_sign
которые построены ./configure --enable-бенчмарка
Что касается разницы в скорости испытания, возможно, придется делать с некоторыми линиями в tests.c, которые указывают на разное количество раундов (плюс тесты для эндоморфизму), если Эндоморфизм включен.
Встроенная программу с эндоморфизмом (./configure --enable-эндоморфизмы) и доложить с результатами, должно быть быстрее.
Хорошо - я сделал.
bench_verify показывает ускорение с эндоморфизму
ecdsa_verify: мин 42.0us / ср / макс 42.2us 43.0us (с)
ecdsa_verify: мин 57.7us / ср / макс 57.8us 58.4us (без)
bench_internal не показывает никаких улучшений (в пределах допуска меры), за исключением одного:
wnaf_const: мин 0.0887us / ср / макс 0.0920us 0.102us (с)
wnaf_const: мин 0.155us / ср / макс 0.161us 0.171us (без)
Я сомневаюсь, что это вызовет ускорение сверху.
Рико
Я выложу здесь 2 версии /src/field_5x52_asm_impl.h что я вроде взломаны, один с использованием памяти, другие регистры XMM.
Комментарий не хорошо, потому что это не уровень производства - просто дурачиться * с потоком данных, так что данные получают от одного конца к другому быстрее, с меньшим количеством отпечатком кода. Я никогда не был им работать на что-нибудь рядом с моим Q8200, и я задаюсь вопросом о поведении современных процессоров. Я был бы признателен, если вы (или кто-либо другой) можно запустить тест (базовый) + эти 2, и, возможно, время ./tests как более реальной производительности.
Если я делаю ./time тестов, как работать быстрее с помощью второго (58.2 секунд с базовым эндоморфизмом до 57,2 секунд в моем пониженном Q8200 @ 1.86gz), хотя версия памяти кажется быстрее в тестах. У меня есть теория о том, почему версия XMM засасывает в тестах (контекст OS переключается является более дорогим и сохранение набора XMM рег?), Но нижняя линия, кажется, быстрее, чем базовый, делая приуроченный испытательный пробег (более реальных приложения ) ... с точки зрения безопасности, я бы не хотел, чтобы данные торчать на XMM регистров, хотя.
(* То, что я хотел сделать, это уменьшить размер опкод, количество команд и обращений к памяти за счет сокращения числа временных переменных от 3 до 2 или 1, в то время как перемежения мулов с добавляет).
Версия 1 - нормальный / память:
/ ************************************************* *********************
* Copyright (с) 2013-2014 Diederik Хьюс, Pieter Wuille *
* Распространяется под лицензией MIT, см сопутствующая *
* Файл КОПИРОВАНИЕ или http://www.opensource.org/licenses/mit-license.php.*
************************************************** ******************** /
/ **
* Changelog:
* - март 2013, Diederik Хьюс: оригинальная версия
* - ноябрь 2014, Питер Wuille: обновлен для использования параллельного алгоритма умножения Питера Dettman в
* - декабрь 2014, Питер Wuille: преобразован из Yasm в GCC встроенного ассемблера
* /
#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_
#define _SECP256K1_FIELD_INNER5X52_IMPL_H_
SECP256K1_INLINE статической силы secp256k1_fe_mul_inner (uint64_t * г, Const uint64_t * а, Const uint64_t * SECP256K1_RESTRICT б) ТХ (%% r15) * /
"shlq $ 4, %% RDX \ п"
"ORQ %% Ракс, %% RDX \ п"
/ * С + = и0 * (R >> 4) * /
"MOVQ $ 0x1000003d1, %% Ракс \ п"
"mulq %% RDX \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% RCX \ п"
/ * R [0] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Ракс, 0 (%% RDI) \ п"
/ * С >>= 52 * /
"MOVQ 0 (%% RBX) %% Ракс \ п"
"shrdq $ 52, RCX %%, %% r8 \ п"
"исключающее %% ECX, %% ECX \ п"
/ * С + = a1 * b0 * /
"mulq %% r11 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ 8 (%% RBX), %% Rax \ п"
"adcq %% RDX, %% RCX \ п"
/ * С + = а0 * b1 * /
"mulq %% r10 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ 16 (%% RBX), %% Rax \ п"
"adcq %% RDX, %% RCX \ п"
/ * D + = а4 * b2 * /
"mulq %% r14 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ 24 (%% RBX), %% Rax \ п"
"adcq %% RDX, %% рши \ п"
/ * = D + а3 * b3 * /
"mulq %% r13 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ 32 (%% RBX), %% Rax \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = а2 * b4 * /
"mulq %% r12 \ п"
"addq %% Ракс, %% г9 \ п"
"adcq %% RDX, %% рши \ п"
/ * С + = (г & МИСТЕР */
"MOVQ %% г9, %% Ракс \ п"
"MOVQ $ 0x1000003d10, %% RDX \ п"
"andq %% r15, %% Ракс \ п"
"mulq %% RDX \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% RCX \ п"
/ * Д >>= 52 * /
"shrdq $ 52, риши %%, %% г9 \ п"
/ * R [1] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Rax, 8 (%% RDI) \ п"
/ * С >>= 52 * /
"MOVQ 0 (%% RBX) %% Ракс \ п"
"shrdq $ 52, RCX %%, %% r8 \ п"
"исключающее %% ECX, %% ECX \ п"
/ * С + = а2 * b0 * /
"mulq %% r12 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ 8 (%% RBX), %% Rax \ п"
"adcq %% RDX, %% RCX \ п"
/ * С + = a1 * b1 * /
"mulq %% r11 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ 16 (%% RBX), %% Rax \ п"
"adcq %% RDX, %% RCX \ п"
/ * С + = а0 * б2 (последнее использование %% r10 = а0) * /
"mulq %% r10 \ п"
"addq %% Ракс, %% r8 \ п"
/ * Получить t3 (%% r10, перезаписывает а0), t4 (%% r15) * /
"MOVQ 24 (%% RBX), %% Rax \ п"
"adcq %% RDX, %% RCX \ п"
/ * D + = а4 * b3 * /
"mulq %% r14 \ п"
"MOVQ% q1, %% r10 \ п"
"исключающее %% еси, %% еси \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ 32 (%% RBX), %% Rax \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = а3 * b4 * /
"mulq %% r13 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ $ 0x1000003d10, %% r11 \ п"
"adcq %% RDX, %% рши \ п"
/ * С + = (г & МИСТЕР */
"MOVQ %% г9, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"mulq %% r11 \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% RCX \ п"
/ * Д >>= 52 (%% г9 только) * /
"shrdq $ 52, риши %%, %% г9 \ п"
/ * R [2] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ% q2, %% рши \ п"
"MOVQ %% Rax, 16 (%% RDI) \ п"
/ * С >>= 52 * /
"shrdq $ 52, RCX %%, %% r8 \ п"
/ * С + = t3 * /
"исключающее %% ECX, %% ECX \ п"
"MOVQ %% г9, %% Ракс \ п"
"addq %% r10, %% r8 \ п"
/ * = С + d * R * /
"mulq %% r11 \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% RCX \ п"
/ * R [3] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Rax, 24 (%% RDI) \ п"
/ * С >>= 52 (%% r8 только) * /
"shrdq $ 52, RCX %%, %% r8 \ п"
/ * С + = t4 (только %% r8) * /
"addq %% риши, %% r8 \ п"
/ * Г [4] = C * /
"MOVQ %% r8,32 (%% RDI) \ п"
: "+ S"(А), "= м"(Tmp1), "= м"(Tmp2)
: "б"(Б), "D"(р)
: "% Ракс", "% RCX", "% RDX", "% r8", "% г9", "% r10", "% r11", "% r12", "% r13", "% r14", "% r15", "куб.см", "Память");
SECP256K1_INLINE статической силы secp256k1_fe_sqr_inner (uint64_t * г, Const uint64_t * а) ТХ (%% рши) * /
"shlq $ 4, %% RDX \ п"
"ORQ %% r15, %% RDX \ п" / * Q3 - R15 ВОЗВРАЩАЕТСЯ * /
/ * С + = и0 * (R >> 4) * /
"MOVQ $ 0x1000003d1, %% Ракс \ п"
"MOVQ $ 0xfffffffffffff, %% r15 \ п" / * R15 на место * /
"mulq %% RDX \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% г9 \ п"
/ * R [0] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Ракс, 0 (%% RDI) \ п"
/ * С >>= 52 * /
"shrdq $ 52, %% г9, %% r8 \ п"
"xorq %% г9, %% г9 \ п"
/ * * А0 = 2 * /
"addq %% r10, %% r10 \ п"
/ * С + = a0 * a1 * /
"MOVQ %% r10, %% Ракс \ п"
"mulq %% r11 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ %% r12, %% Ракс \ п"
"adcq %% RDX, %% г9 \ п"
/ * D + = а2 * а4 * /
"mulq %% r14 \ п"
"addq %% Ракс, %% RBX \ п"
"MOVQ %% r13, %% Ракс \ п"
"adcq %% RDX, %% RCX \ п"
/ * = D + а3 * a3 * /
"mulq %% r13 \ п"
"addq %% Ракс, %% RBX \ п"
"adcq %% RDX, %% RCX \ п"
/ * С + = (г & МИСТЕР */
"MOVQ %% RBX, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ $ 0x1000003d10, %% RDX \ п"
"mulq %% RDX \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% г9 \ п"
/ * Д >>= 52 * /
"shrdq $ 52, %% RCX, %% RBX \ п"
"исключающее %% ECX, %% ECX \ п"
/ * R [1] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Rax, 8 (%% RDI) \ п"
/ * С >>= 52 * /
"MOVQ %% r10, %% Ракс \ п"
"shrdq $ 52, %% г9, %% r8 \ п"
"xorq %% г9, %% г9 \ п"
/ * С + = а0 * а2 (в прошлом использование %% r10) * /
"mulq %% r12 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ %% r11, %% Ракс \ п"
"MOVQ% q1, %% r12 \ п" / * Q2 ВОЗВРАТ * /
"adcq %% RDX, %% г9 \ п"
/ * Получить t3 (%% r10, перезаписывает а0), t4 (%% RSi) * /
/ *"MOVQ% q1, %% r10 \ п" * /
/ * С + = a1 * a1 * /
"mulq %% r11 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ %% r13, %% Ракс \ п"
"adcq %% RDX, %% г9 \ п"
/ * D + = а3 * а4 * /
"mulq %% r14 \ п"
"addq %% Ракс, %% RBX \ п"
"adcq %% RDX, %% RCX \ п"
/ * С + = (г & МИСТЕР */
"MOVQ %% RBX, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ $ 0x1000003d10, %% r13 \ п"
"mulq %% r13 \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% г9 \ п"
/ * Д >>= 52 (%% только RBX) * /
"shrdq $ 52, %% RCX, %% RBX \ п"
/ * R [2] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Rax, 16 (%% RDI) \ п"
/ * С >>= 52 * /
"shrdq $ 52, %% г9, %% r8 \ п"
"xorq %% r14, %% r14 \ п"
/ * С + = t3 * /
"MOVQ %% RBX, %% Ракс \ п"
"addq %% риши, %% r8 \ п" / * RSI = Q1 * /
/ * = С + d * R * /
"mulq %% r13 \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% r14 \ п"
/ * R [3] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Rax, 24 (%% RDI) \ п"
/ * С >>= 52 (%% r8 только) * /
"shrdq $ 52, %% r14, %% r8 \ п"
/ * С + = t4 (только %% r8) * /
"addq %% r12, %% r8 \ п"
/ * Г [4] = C * /
"MOVQ %% r8,32 (%% RDI) \ п"
: "+ S"(А), "= м"(Tmp1a)
: "D"(р)
: "% Ракс", "% RBX", "% RCX", "% RDX", "% r8", "% г9", "% r10", "% r11", "% r12", "% r13", "% r14", "% r15", "куб.см", "Память");
#endif
Версия 2 - более XMM использование рег
/ ************************************************* *********************
* Copyright (с) 2013-2014 Diederik Хьюс, Pieter Wuille *
* Распространяется под лицензией MIT, см сопутствующая *
* Файл КОПИРОВАНИЕ или http://www.opensource.org/licenses/mit-license.php.*
************************************************** ******************** /
/ **
* Changelog:
* - март 2013, Diederik Хьюс: оригинальная версия
* - ноябрь 2014, Питер Wuille: обновлен для использования параллельного алгоритма умножения Питера Dettman в
* - декабрь 2014, Питер Wuille: преобразован из Yasm в GCC встроенного ассемблера
* /
#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_
#define _SECP256K1_FIELD_INNER5X52_IMPL_H_
SECP256K1_INLINE статической силы secp256k1_fe_mul_inner (uint64_t * г, Const uint64_t * а, Const uint64_t * SECP256K1_RESTRICT б)
/ **
* Регистры: RDX: Ракс = Умножение аккумулятор
* Г9: r8 = с
* R15: RCX = д
* R10-r14 = a0-a4
* RBX = Ь
* RDI = г
* Рши = а / т?
* /
/ * XMM0 = q1 = q2 xmm6 * /
/ * Это 17 мем доступ + 17 XMM использует против 35 доступа Мем и не использовать XMM * /
__asm__ __volatile __ (
"нажмите %% RBX \ п"
"MOVQ %% RSP, %% XMM1 \ п"
"MOVQ %% КПБ, %% xmm2 \ п"
"MOVQ %% RDI, %% XMM3 \ п"
"MOVQ 0 (%% RBX) %% RDI \ п"
"MOVQ 8 (%% RBX), %% RBP \ п"
"MOVQ 16 (%% RBX), %% RSP \ п"
"MOVQ %% RDI, %% xmm4 \ п"
"MOVQ 24 (%% рши), %% R13 \ п"
"MOVQ %% RDI, %% Ракс \ п"
"MOVQ 32 (%% рши), %% R14 \ п"
/ * D + = а3 * b0 * /
"mulq %% r13 \ п"
"MOVQ 0 (%% риши), %% r10 \ п"
"MOVQ %% Ракс, %% г9 \ п"
"MOVQ 8 (%% рши), %% r11 \ п"
"MOVQ 16 (%% рши), %% r12 \ п"
"MOVQ %% КПБ, %% Ракс \ п"
"MOVQ %% RDX, %% рши \ п"
/ * D + = а2 * b1 * /
"mulq %% r12 \ п"
"MOVQ 24 (%% RBX), %% RCX \ п"
"MOVQ 32 (%% RBX), %% RBX \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% RSP, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = a1 * b2 * /
"mulq %% r11 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% RCX, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * Д = а0 * b3 * /
"mulq %% r10 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% RBX, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * С = а4 * b4 * /
"mulq %% r14 \ п"
"MOVQ $ 0xfffffffffffff, %% r15 \ п"
"MOVQ %% Ракс, %% r8 \ п"
/ * D + = (с & МИСТЕР */
"andq %% r15, %% Ракс \ п"
"shrdq $ 52, RDX %%, %% r8 \ п" / * С >>= 52 (%% r8 только) * /
"MOVQ $ 0x1000003d10, %% RDX \ п"
"mulq %% RDX \ п"
"addq %% Ракс, %% г9 \ п"
"adcq %% RDX, %% рши \ п"
/ * T3 (tmp1) = д & M * /
"MOVQ %% г9, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Ракс, %% XMM0 \ п"
/ * Д >>= 52 * /
"MOVQ %% RDI, %% Ракс \ п"
"shrdq $ 52, риши %%, %% г9 \ п"
"исключающее %% еси, %% еси \ п"
/ * D + = а4 * b0 * /
"mulq %% r14 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% КПБ, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = а3 * b1 * /
"mulq %% r13 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% RSP, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = а2 * b2 * /
"mulq %% r12 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% RCX, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = а1 * b3 * /
"mulq %% r11 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% RBX, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = а0 * b4 * /
"mulq %% r10 \ п"
"addq %% Ракс, %% г9 \ п"
/ * D + = C * R * /
"MOVQ $ 0x1000003d10, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
"mulq %% r8 \ п"
"addq %% Ракс, %% г9 \ п"
"adcq %% RDX, %% рши \ п"
/ * T4 = д & М (%% r15) * /
"MOVQ %% г9, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
/ * Д >>= 52 * /
"shrdq $ 52, риши %%, %% г9 \ п"
"исключающее %% еси, %% еси \ п"
/ * ТЕ = t4 >> 48 (tmp3) * /
"MOVQ %% Ракс, %% r15 \ п"
"shrq $ 48, %% r15 \ п" / * Q3 * /
/ * T4 &= (М >> 4) (tmp2) * /
"MOVQ $ 0xffffffffffff, %% RDX \ п"
"andq %% RDX, %% Ракс \ п"
"MOVQ %% Ракс, %% xmm6 \ п"
/ *"MOVQ% q2, %% r15 \ п" * /
"MOVQ %% RDI, %% Ракс \ п"
/ * С = а0 * b0 * /
"mulq %% r10 \ п"
"MOVQ %% RCX, %% xmm5 \ п"
"MOVQ %% Ракс, %% r8 \ п"
"MOVQ %% КПБ, %% Ракс \ п"
"MOVQ %% RDX, %% RCX \ п"
/ * D + = а4 * b1 * /
"mulq %% r14 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% RSP, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = а3 * b2 * /
"mulq %% r13 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% xmm5, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = а2 * b3 * /
"mulq %% r12 \ п"
"addq %% Ракс, %% г9 \ п"
"MOVQ %% RBX, %% Ракс \ п"
"adcq %% RDX, %% рши \ п"
/ * D + = a1 * b4 * /
"mulq %% r11 \ п"
"addq %% Ракс, %% г9 \ п"
"adcq %% RDX, %% рши \ п"
"MOVQ %% r15, %% Ракс \ п" / * Q3 * переданы /
/ * И0 = д & М (%% r15) * /
"MOVQ %% г9, %% RDX \ п"
"shrdq $ 52, риши %%, %% г9 \ п"
"MOVQ $ 0xfffffffffffff, %% r15 \ п"
"исключающее %% еси, %% еси \ п"
"andq %% r15, %% RDX \ п"
/ * Д >>= 52 * /
/ * = И0 (и0 << 4)
SECP256K1_INLINE статической силы secp256k1_fe_sqr_inner (uint64_t * г, Const uint64_t * а) ТХ (%% рши) * /
"shlq $ 4, %% RDX \ п"
"ORQ %% КПБ, %% RDX \ п" / * Q3 ВОЗВРАТ * /
/ * С + = и0 * (R >> 4) * /
"MOVQ $ 0x1000003d1, %% Ракс \ п"
"mulq %% RDX \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% г9 \ п"
/ * R [0] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Ракс, 0 (%% RDI) \ п"
/ * С >>= 52 * /
"shrdq $ 52, %% г9, %% r8 \ п"
"xorq %% г9, %% г9 \ п"
/ * * А0 = 2 * /
"addq %% r10, %% r10 \ п"
/ * С + = a0 * a1 * /
"MOVQ %% r10, %% Ракс \ п"
"mulq %% r11 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ %% r12, %% Ракс \ п"
"adcq %% RDX, %% г9 \ п"
/ * D + = а2 * а4 * /
"mulq %% r14 \ п"
"addq %% Ракс, %% RBX \ п"
"MOVQ %% r13, %% Ракс \ п"
"adcq %% RDX, %% RCX \ п"
/ * = D + а3 * a3 * /
"mulq %% r13 \ п"
"addq %% Ракс, %% RBX \ п"
"adcq %% RDX, %% RCX \ п"
/ * С + = (г & МИСТЕР */
"MOVQ %% RBX, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"mulq %% RSP \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% г9 \ п"
/ * Д >>= 52 * /
"shrdq $ 52, %% RCX, %% RBX \ п"
"исключающее %% ECX, %% ECX \ п"
/ * R [1] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Rax, 8 (%% RDI) \ п"
/ * С >>= 52 * /
"MOVQ %% r10, %% Ракс \ п"
"shrdq $ 52, %% г9, %% r8 \ п"
"xorq %% г9, %% г9 \ п"
/ * С + = а0 * а2 (в прошлом использование %% r10) * /
"mulq %% r12 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ %% r11, %% Ракс \ п"
"MOVQ %% XMM0, %% r12 \ п" / * Q2 ВОЗВРАТ * /
"adcq %% RDX, %% г9 \ п"
/ * Получить t3 (%% r10, перезаписывает а0), t4 (%% RSi) * /
/ *"MOVQ% q1, %% r10 \ п" * /
/ * С + = a1 * a1 * /
"mulq %% r11 \ п"
"addq %% Ракс, %% r8 \ п"
"MOVQ %% r13, %% Ракс \ п"
"adcq %% RDX, %% г9 \ п"
/ * D + = а3 * а4 * /
"mulq %% r14 \ п"
"addq %% Ракс, %% RBX \ п"
"adcq %% RDX, %% RCX \ п"
/ * С + = (г & МИСТЕР */
"MOVQ %% RBX, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"mulq %% RSP \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% г9 \ п"
/ * Д >>= 52 (%% только RBX) * /
"shrdq $ 52, %% RCX, %% RBX \ п"
/ * R [2] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Rax, 16 (%% RDI) \ п"
/ * С >>= 52 * /
"shrdq $ 52, %% г9, %% r8 \ п"
"xorq %% r14, %% r14 \ п"
/ * С + = t3 * /
"MOVQ %% RBX, %% Ракс \ п"
"addq %% риши, %% r8 \ п" / * RSI = Q1 ВОЗВРАЩАЕТСЯ * /
/ * = С + d * R * /
"mulq %% RSP \ п"
"MOVQ %% XMM1, %% RSP \ п"
"MOVQ %% xmm2, %% РБП \ п"
"addq %% Ракс, %% r8 \ п"
"adcq %% RDX, %% r14 \ п"
/ * R [3] = с & M * /
"MOVQ %% r8, %% Ракс \ п"
"andq %% r15, %% Ракс \ п"
"MOVQ %% Rax, 24 (%% RDI) \ п"
/ * С >>= 52 (%% r8 только) * /
"shrdq $ 52, %% r14, %% r8 \ п"
/ * С + = t4 (только %% r8) * /
"addq %% r12, %% r8 \ п"
/ * Г [4] = C * /
"MOVQ %% r8,32 (%% RDI) \ п"
: "+ S"(А)
: "D"(р)
: "% Ракс", "% RBX", "% RCX", "% RDX", "% r8", "% г9", "% r10", "% r11", "% r12", "% r13", "% r14", "% r15", "куб.см", "Память");
#endif