Угол проверки также имеет два других вопросы, которые вы не рассматриваете: консенсусную последовательность. Использование GMP валидация бы точное поведение GMP консенсуса критического, что является проблемой, так как разные системы работают разные коды. (GMP также имеет лицензию, которая является более ограничительным, чем программное обеспечение Bitcoin).
Я никогда бы не подумал, консистенция, возможно, были проблемы с целыми значениями, пока я вроде не узнал об этом на собственном горьком опыте, теряя день, получая избили двух умножений в конце поля 10x26 при преобразовании все это в SSE2 работать на регистры MMX для моего 12yr старый Пентиум-м ноутбук ...
D + =
с * (R1 >> 4) + t1
а также
д =
с * (R0 >> 4) + t0;
где R1 представл ет >>4 = 64, R0 >>4 = 977 ... не было никакого способа, чтобы получить его вычислить с с * 64 / с * 977, как это: "PMULUDQ (регистр с 64 или 977 в качестве источника) и (регистрироваться в) в качестве мишени.
Я до сих пор не знаю, почему сдвиг влево на 6 не то же самое, как умножение с 64 - если перелива и обтекание не в игре (или, может быть, это я не знаю, - но от того, что я вижу, количество бит должен быть 53 и 56, вдали от переполненности).
D = C * (R 0 >> 4) + t0;
VERIFY_BITS (д,
56);
D + = C * (R 1 >> 4) + t1;
VERIFY_BITS (д,
53);
Во всяком случае, мой ум все еще недоумевал по этому поводу, но я должен был работать вокруг него, пока тест не не сломается.
Для * 64 Я сделал это с сворачивает налево на 6.
Для * 977 Я сделал это с уродством, где с были скопированы в нескольких регистров, а затем каждый экземпляр был сдвинут соответствующим образом, а затем сдвинутый гр получил добавленное.
Во всяком случае, несмотря на это дорогой обходного пути, родные 64-разрядные арифметические регистры MMX разнести ССАГПЗ / лязг / ICC скомпилированных версии для более -m32 сборки. размер Опкод также был уменьшен (1900 против 2800 байт для field_mul, 1300 против 2200+ байт для field_sqr).
Если вы не имели в виду, используя GMP, но только с помощью различных операций для не sidechannel чувствительной paths-- библиотеки уже делает, что во многих places--, хотя и не для FE мул / добавить. FE нормализует делать принимать переменное время проверки. Если у вас есть ускорение, основанное на том, что вы можете отправить его!
Сейчас только массивный убыстрение я достиг в 32-битной версии, где компиляторы используют 32-битные регистры (вместо 64-битных MMX / SSE регистров). Для 64-битной версии, с не AVX использования, я на ~ 10% прибыли в не-комментировал код (который, кажется, плохо для обзора), из которых 3-5% был недавнее увеличение, за счет уменьшения параметров затирания на ассемблере и вручную перемежении начальных толчков и конечные хлопки в удобных этапах (например, умножение и сложение киосков).
Чем быстрее 32-разрядная версия ниже (я сделал комментарии о том, что делает каждая строка, в случае, если это будет полезно для других, но я не рассматривал его "представление" за счет использования массива, который не sidechannel устойчивостью (и я думал, что это было "требование"). По существу массив используется в начале для хранения результатов умножений и дополнений, которые являются нелинейными и, таким образом, может быть вычислено на старте.)
На моем ноутбуке (Пентиум-м 2,13) bench_verify (с endomoprhism) вниз к 350us от 570us.
На моем рабочем столе (Q8200 @ 1,86) это в 404us вниз от 652us. Это, вероятно, может пойти вниз еще на 5-10%, если код читаемость страдает много (это уже страдает от некоторого ручного чередования операций памяти с мулами и добавляет, чтобы получить ~ 7-10%).
C версии (-m32 / поле 10x26):
field_sqr: мин 0.187us / ср / макс 0.188us 0.189us
field_mul: мин 0.275us / ср / макс 0.277us 0.278us
field_inverse: мин 55.4us / ср / макс 55.6us 55.8us
field_inverse_var: мин 55.4us / ср / макс 55.6us 55.9us
field_sqrt: мин 53.8us / ср / макс 54.1us 54.5us
...
context_verify: мин 77649us / ср / макс 77741us 77891us
context_sign: мин 267us / ср / макс 268us 269us
...
версия ASM (-m32 / поле 10x26) (sse2 на MMX * регистры):
field_sqr: мин 0.101us / ср / макс 0.101us 0.102us
field_mul: мин 0.135us / ср / макс 0.135us 0.135us
field_inverse: мин 28.3us / ср / макс 28.3us 28.4us
field_inverse_var: мин 28.3us / ср / макс 28.3us 28.4us
field_sqrt: мин 28.0us / ср / макс 28.0us 28.0us
...
context_verify: мин 42876us / ср / макс 43099us 43391us
context_sign: мин 170us / ср / макс 170us 170us
* В Core2, это не делает разницы, если это XMM или регистры мм (за исключением 2-3% ускорения с удалением EMMS в конце концов). На Пентиуме-м, операции XMM регистров очень медленно, чтобы начать с того, я подозреваю, что они эмулируются с точкой зрения ширины, что приводит к удвоенным операциям внутренне, но MMX регистров отображаются на регистрах 80bit ФПА, которые имеют хорошую фактическую ширину и собственно скорость.
SECP256K1_INLINE статической силы secp256k1_fe_mul_inner (uint32_t * г, Const uint32_t * а, Const uint32_t * SECP256K1_RESTRICT б) {
/ * Uint64_t с, д; * /
uint64_t результат [19]; / * Температура хранения массива * /
uint32_t tempstor [2]; / * Температура хранения массива * /
Const uint32_t М = 0x3FFFFFFUL, R0 = 0x3D10UL / *, R 1 = 0x400UL * /;
tempstor [0] = М;
tempstor [1] = R0;
/ * Tempstor [2] для R1 не требуется. Это 1024, так сворачивает налево на 10 вместо * /
__asm__ __volatile __ (
/ * Часть # 1: Умножения и дополнения
*
* D = (uint64_t) (uint64_t) а [0] * б [9]
+ (Uint64_t) а [1] * б [8]
+ (Uint64_t) а [2] * б [7]
+ (Uint64_t) а [3] * б [6]
+ (Uint64_t) а [4] * б [5]
+ (Uint64_t) а [5] * б [4]
+ (Uint64_t) а [6] * б [3]
+ (Uint64_t) а [7] * б [2]
+ (Uint64_t) а [8] * б [1]
+ (Uint64_t) а [9] * б [0]; * /
"MOVD 0 (% 0), %% MM0 \ п" / * A0 * /
"MOVD 36 (% 1), %% ММ2 \ п" / * B9 * /
"MOVD 4 (% 0), %% ММ1 \ п" / * A1 * /
"MOVD 32 (% 1), %% ММ3 \ п" / * B8 * /
"PMULUDQ %% MM0, %% MM2 \ п" / * A0 * b9 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A1 * b8 * /
"MOVD 8 (% 0), %% ММ4 \ п" / * A2 * /
"MOVD 28 (% 1), %% ММ6 \ п" / * B7 * /
"MOVD 12 (% 0), %% ММ5 \ п" / * A3 * /
"MOVD 24 (% 1), %% MM7 \ п" / * B6 * /
"PMULUDQ %% MM4, %% MM6 \ п" / * A2 * b7 * /
"PMULUDQ %% ММ5, %% MM7 \ п" / * A3 * b6 * /
"MOVD 16 (% 0), %% MM0 \ п" / * A4 * /
"MOVD 20 (% 0), %% ММ1 \ п" / * A5 * /
"PADDQ %% MM2, %% MM3 \ п"
"PADDQ %% MM6, %% MM7 \ п"
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 20 (% 1), %% ММ2 \ п" / * B5 * /
"MOVD 16 (% 1), %% ММ3 \ п" / * B4 * /
"PMULUDQ %% MM0, %% MM2 \ п" / * A4 * b5 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A5 * b4 * /
"MOVD 24 (% 0), %% MM0 \ п" / * A6 * /
"PADDQ %% MM2, %% MM3 \ п"
"MOVD 28 (% 0), %% ММ1 \ п" / * A7 * /
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 12 (% 1), %% ММ2 \ п" / * B3 * /
"MOVD 8 (% 1), %% ММ3 \ п" /* Би 2 */
"PMULUDQ %% MM0, %% MM2 \ п" / * A6 * b3 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A7 * b2 * /
"PADDQ %% MM2, %% MM3 \ п"
"MOVD 32 (% 0), %% MM0 \ п" / * A8 * /
"MOVD 36 (% 0), %% ММ1 \ п" / * A9 * /
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 4 (% 1), %% ММ2 \ п" / * B1 * /
"MOVD 0 (% 1), %% ММ3 \ п" / * B0 * /
"PMULUDQ %% MM0, %% MM2 \ п" / * A8 * b1 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A9 * b0 * /
"PADDQ %% MM2, %% MM3 \ п"
"MOVD 4 (% 1), %% ММ2 \ п" / * B1 * /
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 8 (% 1), %% ММ3 \ п" /* Би 2 */
"MOVQ %% MM7, 0 (% 2) \ п" / * Экстракт результат [0] * /
/ * Часть # 2: Умножения и дополнения
*
*
D + = (uint64_t) а [1] * б [9]
+ (Uint64_t) а [2] * б [8]
+ (Uint64_t) а [3] * б [7]
+ (Uint64_t) а [4] * б [6]
+ (Uint64_t) а [5] * б [5]
+ (Uint64_t) а [6] * б [4]
+ (Uint64_t) а [7] * б [3]
+ (Uint64_t) а [8] * б [2]
+ (Uint64_t) а [9] * б [1]; * /
"PMULUDQ %% MM1, %% MM2 \ п" / * A9 * b1 * /
"PMULUDQ %% MM0, %% MM3 \ п" / * A8 * b2 * /
"MOVD 28 (% 1), %% ММ6 \ п" / * B7 * /
"MOVD 32 (% 1), %% MM7 \ п" / * B8 * /
"PMULUDQ %% ММ5, %% MM6 \ п" / * A3 * b7 * /
"PMULUDQ %% MM4, %% MM7 \ п" / * A2 * b8 * /
"PADDQ %% MM2, %% MM3 \ п"
"MOVD 4 (% 0), %% MM0 \ п" / * A1 * /
"MOVD 36 (% 1), %% ММ2 \ п" / * B9 * /
"PADDQ %% MM3, %% MM6 \ п"
"MOVD 16 (% 0), %% ММ1 \ п" / * A4 * /
"PADDQ %% MM6, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 24 (% 1), %% ММ3 \ п" / * B6 * /
"PMULUDQ %% MM0, %% MM2 \ п" / * A1 * b9 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A4 * b6 * /
"MOVD 28 (% 0), %% ММ4 \ п" / * A7 * /
"MOVD 12 (% 1), %% ММ5 \ п" / * B3 * /
"PADDQ %% MM2, %% MM7 \ п"
"MOVD 20 (% 0), %% MM0 \ п" / * A5 * /
"MOVD 24 (% 0), %% ММ1 \ п" / * A6 * /
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 20 (% 1), %% ММ2 \ п" / * B5 * /
"MOVD 16 (% 1), %% ММ3 \ п" / * B4 * /
"PMULUDQ %% MM0, %% MM2 \ п" / * A5 * b5 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A6 * b4 * /
"PMULUDQ %% MM4, %% ММ5 \ п" / * A7 * b3 * /
"MOVD 20 (% 1), %% ММ6 \ п" / * B5 * /
"PADDQ %% MM2, %% MM7 \ п"
"MOVD 16 (% 0), %% ММ2 \ п" / * A4 * /
"PADDQ %% ММ5, %% MM7 \ п"
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 24 (% 1), %% ММ5 \ п" / * B6 * /
"MOVQ %% MM7, 8 (% 2) \ п" / * Экстракт результат [1] * /
/ * Часть # 3: Умножения и дополнения
*
* = D + (uint64_t) а [2] * б [9]
+ (Uint64_t) а [3] * б [8]
+ (Uint64_t) а [4] * б [7]
+ (Uint64_t) а [5] * б [6]
+ (Uint64_t) а [6] * б [5]
+ (Uint64_t) а [7] * б [4]
+ (Uint64_t) а [8] * б [3]
+ (Uint64_t) а [9] * б [2]; * /
"PMULUDQ %% MM1, %% MM6 \ п" / * A6 * b5 * /
"MOVD 16 (% 1), %% MM7 \ п" / * B4 * /
"PMULUDQ %% MM0, %% ММ5 \ п" / * A5 * b6 * /
"PMULUDQ %% MM4, %% MM7 \ п" / * A7 * b4 * /
"MOVD 36 (% 1), %% ММ3 \ п" / * B9 * /
"MOVD 12 (% 0), %% ММ1 \ п" / * A3 * /
"PADDQ %% MM6, %% ММ5 \ п"
"MOVD 32 (% 1), %% ММ4 \ п" / * B8 * /
"PADDQ %% ММ5, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 8 (% 0), %% MM0 \ п" / * A2 * /
"MOVD 28 (% 1), %% ММ5 \ п" / * B7 * /
"PMULUDQ %% MM1, %% MM4 \ п" / * A3 * b8 * /
"PMULUDQ %% MM2, %% ММ5 \ п" / * A4 * b7 * /
"PMULUDQ %% MM0, %% MM3 \ п" / * A2 * b9 * /
"MOVD 12 (% 1), %% ММ6 \ п" / * B3 * /
"PADDQ %% MM4, %% MM7 \ п"
"PADDQ %% ММ5, %% MM7 \ п"
"MOVD 36 (% 0), %% ММ4 \ п" / * A9 * /
"MOVD 32 (% 0), %% ММ5 \ п" / * A8 * /
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 8 (% 1), %% ММ3 \ п" /*Би 2 */
"PMULUDQ %% ММ5, %% MM6 \ п" / * A8 * b3 * /
"PMULUDQ %% MM4, %% MM3 \ п" / * A9 * b2 - (порядок b2 * a9) * /
"MOVD 12 (% 1), %% MM0 \ п" / * B3 * /
"PADDQ %% MM6, %% MM7 \ п"
"MOVD 32 (% 1), %% ММ6 \ п" / * B8 * /
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 16 (% 1), %% ММ3 \ п" / * B4 * /
"MOVQ %% MM7, 16 (% 2) \ п" / * Экстракт результат [2] * /
/ * Часть # 4: Умножения и дополнения
*
*
* = D + (uint64_t) а [3] * б [9]
+ (Uint64_t) а [4] * б [8]
+ (Uint64_t) а [5] * б [7]
+ (Uint64_t) а [6] * б [6]
+ (Uint64_t) а [7] * б [5]
+ (Uint64_t) а [8] * б [4]
+ (Uint64_t) а [9] * б [3]; * /
"PMULUDQ %% MM4, %% MM0 \ п" / * A9 * b3 * /
"MOVD 36 (% 1), %% MM7 \ п" / * B9 * /
"PMULUDQ %% ММ5, %% MM3 \ п" / * A8 * b4 * /
"PMULUDQ %% MM2, %% MM6 \ п" / * A4 * b8 * /
"PMULUDQ %% MM1, %% MM7 \ п" / * A3 * b9 * /
"PADDQ %% MM0, %% MM3 \ п"
"MOVD 24 (% 1), %% ММ4 \ п" / * B6 * /
"MOVD 20 (% 1), %% ММ5 \ п" / * B5 * /
"PADDQ %% MM3, %% MM6 \ п"
"MOVD 20 (% 0), %% MM0 \ п" / * A5 * /
"MOVD 28 (% 0), %% ММ2 \ п" / * A7 * /
"PADDQ %% MM6, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 24 (% 0), %% ММ6 \ п" / * A6 * /
"MOVD 28 (% 1), %% ММ3 \ п" / * B7 * /
"PMULUDQ %% MM2, %% ММ5 \ п" / * A7 * b5 * /
"PMULUDQ %% MM6, %% MM4 \ п" / * A6 * b6 * /
"PMULUDQ %% MM0, %% MM3 \ п" / * A5 * b7 * /
"PADDQ %% ММ5, %% MM7 \ п"
"MOVD 16 (% 0), %% ММ1 \ п" / * A4 * /
"PADDQ %% MM4, %% MM7 \ п"
"MOVD 32 (% 1), %% ММ5 \ п" / * B8 * /
"PADDQ %% MM3, %% MM7 \ п"
"MOVD 28 (% 1), %% ММ4 \ п" / * B7 * /
"MOVQ %% MM7, 24 (% 2) \ п" / * Экстракт результат [3] * /
/ * Часть # 5: Умножения и дополнения
*
D + = (uint64_t) а [4] * б [9]
+ (Uint64_t) а [5] * б [8]
+ (Uint64_t) а [6] * б [7]
+ (Uint64_t) а [7] * б [6]
+ (Uint64_t) а [8] * б [5]
+ (Uint64_t) а [9] * б [4]; * /
"PMULUDQ %% MM6, %% MM4 \ п" / * A6 * b7 * /
"MOVD 24 (% 1), %% ММ3 \ п" / * B6 * /
"MOVD 36 (% 1), %% MM7 \ п" / * B9 * /
"PMULUDQ %% MM0, %% ММ5 \ п" / * A5 * b8 * /
"PMULUDQ %% MM2, %% MM3 \ п" / * A7 * b6 * /
"PMULUDQ %% MM1, %% MM7 \ п" / * A4 * b9 * /
"PADDQ %% MM4, %% ММ5 \ п"
"MOVD 36 (% 0), %% ММ4 \ п" / * A9 * /
"PADDQ %% ММ5, %% MM3 \ п"
"MOVD 20 (% 1), %% ММ5 \ п" / * B5 * /
"PADDQ %% MM3, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"MOVD 32 (% 0), %% ММ3 \ п" / * A8 * /
"MOVD 16 (% 1), %% ММ1 \ п" / * B4 * /
"PMULUDQ %% MM3, %% ММ5 \ п" / * A8 * b5 * /
"PMULUDQ %% MM4, %% MM1 \ п" / * A9 * b4 * /
"PADDQ %% ММ5, %% MM7 \ п"
"MOVD 28 (% 1), %% ММ3 \ п" / * B7 * /
"MOVD 32 (% 1), %% ММ5 \ п" / * B8 * /
"PADDQ %% MM1, %% MM7 \ п"
"MOVQ %% MM7, 32 (% 2) \ п" / * Экстракт результат [4] * /
/ * Часть # 6: Умножения и дополнения
*
*
* = D + (uint64_t) а [5] * б [9]
+ (Uint64_t) а [6] * б [8]
+ (Uint64_t) а [7] * б [7]
+ (Uint64_t) а [8] * б [6]
+ (Uint64_t) а [9] * б [5];
* /
"PMULUDQ %% MM2, %% MM3 \ п" / * A7 * b7 * /
"MOVD 20 (% 1), %% ММ1 \ п" / * B5 * /
"MOVD 36 (% 1), %% MM7 \ п" / * B9 * /
"PMULUDQ %% MM6, %% ММ5 \ п" / * A6 * b8 * /
"PMULUDQ %% MM4, %% MM1 \ п" / * A9 * b5 * /
"PMULUDQ %% MM0, %% MM7 \ п" / * A5 * b9 * /
"PADDQ %% MM3, %% ММ5 \ п"
"MOVD 24 (% 1), %% ММ3 \ п" / * B6 * /
"PADDQ %% MM1, %% ММ5 \ п"
"MOVD 32 (% 0), %% ММ1 \ п" / * A8 * /
"PADDQ %% ММ5, %% MM7 \ п" / * Результат учета дополнений в mm7 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A8 * b6 * /
"MOVD 24 (% 1), %% MM0 \ п" / * B6 * /
"MOVD 32 (% 1), %% ММ5 \ п" / * B8 * /
"PADDQ %% MM3, %% MM7 \ п"
"MOVQ %% MM7, 40 (% 2) \ п" / * Экстракт результат [5] * /
/ * Часть # 7: Умножения и дополнения
*
*
* = D + (uint64_t) а [6] * б [9]
+ (Uint64_t) а [7] * б [8]
+ (Uint64_t) а [8] * б [7]
+ (Uint64_t) а [9] * б [6]; * /
"PMULUDQ %% MM4, %% MM0 \ п" / * A9 * b6 * /
"MOVD 28 (% 1), %% ММ3 \ п" / * B7 * /
"MOVD 36 (% 1), %% MM7 \ п" / * B9 * /
"PMULUDQ %% MM2, %% ММ5 \ п" / * A7 * b8 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A8 * b7 * /
"PMULUDQ %% MM6, %% MM7 \ п" / * A6 * b9 * /
"PADDQ %% MM0, %% ММ5 \ п"
"PADDQ %% MM3, %% MM7 \ п"
"MOVD 24 (% 1), %% MM0 \ п" / * B6 * /
"PADDQ %% ММ5, %% MM7 \ п" / * Добавление результатов mm7 * /
"MOVQ %% MM7, 48 (% 2) \ п" / * Экстракт результат [6] * /
/ * Часть # 8: Умножения и дополнение 3 отдельных результатов
*
*
D + = (uint64_t) а [7] * б [9]
+ (Uint64_t) а [8] * б [8]
+ (Uint64_t) а [9] * б [7]; результат 7
D + = (uint64_t) а [8] * б [9]
+ (Uint64_t) а [9] * б [8]; результат 8
D + = (uint64_t) а [9] * б [9]; Результат 9 * /
"MOVD 28 (% 1), %% ММ3 \ п" / * B7 * /
"MOVD 32 (% 1), %% ММ5 \ п" / * B8 * /
"MOVD 36 (% 1), %% MM7 \ п" / * B9 * /
"PMULUDQ %% MM4, %% MM3 \ п" / * A9 * b7 * /
"PMULUDQ %% MM1, %% ММ5 \ п" / * A8 * b8 * /
"MOVQ %% MM7, %% MM6 \ п" / * B9 * /
"PMULUDQ %% MM2, %% MM7 \ п" / * A7 * b9 * /
"PADDQ %% MM3, %% ММ5 \ п"
"PADDQ %% ММ5, %% MM7 \ п"
"MOVQ %% MM6, %% MM3 \ п" / * B9 * /
"MOVD 32 (% 1), %% ММ5 \ п" / * B8 * /
"MOVQ %% MM7, 56 (% 2) \ п" / * Экстракт результат [7] * /
"PMULUDQ %% MM1, %% MM6 \ п" / * A8 * b9 * /
"PMULUDQ %% MM4, %% ММ5 \ п" / * A9 * b8 * /
"PMULUDQ %% MM4, %% MM3 \ п" / * A9 * b9 * /
"MOVD 8 (% 0), %% MM7 \ п" / * A2 * /
"PADDQ %% ММ5, %% MM6 \ п"
"MOVQ %% ММ3, 72 (% 2) \ п" / * Экстракт результат [9] * /
"MOVQ %% ММ6, 64 (% 2) \ п" / * Экстракт результат [8] * /
/ * Часть # 9: Умножения и дополнения
*
* С + = (uint64_t) а [0] * б [8]
+ (Uint64_t) а [1] * б [7]
+ (Uint64_t) а [2] * б [6]
+ (Uint64_t) а [3] * б [5]
+ (Uint64_t) а [4] * б [4]
+ (Uint64_t) а [5] * б [3]
+ (Uint64_t) а [6] * б [2]
+ (Uint64_t) а [7] * б [1]
+ (Uint64_t) а [8] * б [0]; * /
"PMULUDQ %% MM7, %% MM0 \ п" / * A2 * b6 * /
"MOVD 0 (% 1), %% ММ3 \ п" / * B0 * /
"PMULUDQ %% MM1, %% MM3 \ п" / * A8 * b0 * /
"MOVD 4 (% 1), %% MM7 \ п" / * B1 * /
"PMULUDQ %% MM2, %% MM7 \ п" / * A7 * b1 * /
"MOVD 4 (% 0), %% ММ1 \ п" / * A1 * /
"PADDQ %% MM0, %% MM3 \ п"
"MOVD 20 (% 1), %% ММ4 \ п" / * B5 * /
"PADDQ %% MM3, %% MM7 \ п"
"MOVD 12 (% 0), %% ММ2 \ п" / * A3 * /
"MOVD 28 (% 1), %% ММ5 \ п" / * B7 * /
"PMULUDQ %% MM2, %% MM4 \ п" / * A3 * b5 * /
"MOVD 16 (% 0), %% ММ3 \ п" / * A4 * /
"MOVD 16 (% 1), %% ММ6 \ п" / * B4 * /
"PMULUDQ %% MM1, %% ММ5 \ п" / * A1 * b7 * /
"MOVD 0 (% 0), %% MM0 \ п" / * A0 * /
"PMULUDQ %% MM6, %% MM3 \ п" / * B4 * a4 * /
"MOVD 32 (% 1), %% ММ6 \ п" / * B8 * /
"PMULUDQ %% MM0, %% MM6 \ п" / * A0 * b8 * /
"PADDQ %% MM4, %% ММ5 \ п"
"MOVD 24 (% 0), %% ММ4 \ п" / * A6 * /
"PADDQ %% MM6, %% MM3 \ п"
"PADDQ %% ММ5, %% MM7 \ п"
"MOVD 8 (% 1), %% ММ6 \ п" /*Би 2*/
"PADDQ %% MM3, %% MM7 \ п"
"MOVD 12 (% 1), %% ММ5 \ п" / * B3 * /
"MOVD 20 (% 0), %% ММ3 \ п" / * A5 * /
"PMULUDQ %% MM4, %% MM6 \ п" / * A6 * b2 * /
"PMULUDQ %% MM3, %% ММ5 \ п" / * A5 * b3 * /
"PADDQ %% MM6, %% MM7 \ п"
"MOVD 0 (% 1), %% ММ4 \ п" / * B0 * /
"PADDQ %% ММ5, %% MM7 \ п" / * Аддитивные результаты по mm7 * /
"MOVD 8 (% 0), %% ММ3 \ п" / * A2 * /
"MOVD 4 (% 1), %% ММ5 \ п" / * B1 * /
"MOVQ %% MM7, 80 (% 2) \ п" / * Результат экстракта [10] * /
/ * Часть # 10: Умножения и дополнения
*
* С + = (uint64_t) а [0] * б [3]
+ (Uint64_t) а [1] * б [2]
+ (Uint64_t) а [2] * б [1]
+ (Uint64_t) а [3] * б [0]; result11
с + = (uint64_t) а [0] * б [1]
+ (Uint64_t) а [1] * б [0]; result12
с = (uint64_t) а [0] * б [0]; result13
с + = (uint64_t) а [0] * б [2]
+ (Uint64_t) а [1] * б [1]
+ (Uint64_t) а [2] * б [0]; result14 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * B0 * a3 * /
"PMULUDQ %% ММ5, %% MM3 \ п" / * B1 * a2 * /
"MOVD 8 (% 1), %% MM7 \ п" /*Би 2*/
"MOVD 12 (% 1), %% ММ6 \ п" / * B3 * /
"PMULUDQ %% MM7, %% MM1 \ п" / * B2 * a1 * /
"PMULUDQ %% MM6, %% MM0 \ п" / * B3 * a0 * /
"PADDQ %% MM2, %% MM3 \ п"
"MOVD 8 (% 1), %% ММ2 \ п" /*Би 2*/
"PADDQ %% MM1, %% MM0 \ п"
"MOVD 4 (% 1), %% ММ1 \ п" / * B1 * /
"PADDQ %% MM0, %% MM3 \ п"
"MOVD 0 (% 1), %% MM0 \ п" / * B0 * /
"MOVQ %% MM3, 88 (% 2) \ п" / * Результат экстракта [11] * /
"MOVD 0 (% 0), %% ММ4 \ п" / * A0 * /
"MOVQ %% MM0, %% MM3 \ п" / * B0 * /
"MOVD 4 (% 0), %% ММ5 \ п" / * A1 * /
"MOVD 8 (% 0), %% MM7 \ п" / * A2 * /
"MOVQ %% MM1, %% MM6 \ п" / * B1 * /
"PMULUDQ %% ММ5, %% MM3 \ п" / * A1 * b0 * /
"PMULUDQ %% MM4, %% MM6 \ п" / * A0 * b1 * /
"PADDQ %% MM3, %% MM6 \ п"
"MOVQ %% MM0, %% MM3 \ п" / * B0 * /
"MOVQ %% ММ6, 96 (% 2) \ п" / * Результат экстракта [12] * /
"PMULUDQ %% MM4, %% MM3 \ п" / * A0 * b0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * A0 * b2 * /
"MOVQ %% мм3 104 (% 2) \ п" / * Результат экстракта [13] * /
"MOVQ %% MM1, %% MM6 \ п" / * B1 * /
"PMULUDQ %% ММ5, %% MM6 \ п" / * A1 * b1 * /
"MOVQ %% MM0, %% MM3 \ п" / * B0 * /
"PMULUDQ %% MM7, %% MM3 \ п" / * A2 * b0 * /
"PADDQ %% MM2, %% MM6 \ п"
"PADDQ %% MM6, %% MM3 \ п"
"MOVD 16 (% 1), %% ММ2 \ п" / * B4 * /
"MOVQ %% ММ3, 112 (% 2) \ п" / * Результат экстракта [14] * /
/ * Часть # 11: Умножения и дополнения
*
*
с + = (uint64_t) а [0] * б [4]
+ (Uint64_t) а [1] * б [3]
+ (Uint64_t) а [2] * б [2]
+ (Uint64_t) а [3] * б [1]
+ (Uint64_t) а [4] * б [0] * /
"PMULUDQ %% MM4, %% MM2 \ п" / * A0 * b4 * /
"MOVD 16 (% 0), %% ММ3 \ п" / * A4 * /
"MOVD 12 (% 0), %% ММ6 \ п" / * A3 * /
"PMULUDQ %% MM0, %% MM3 \ п" / * B0 * a4 * /
"PMULUDQ %% MM1, %% MM6 \ п" / * B1 * a3 * /
"PADDQ %% MM2, %% MM3 \ п"
"MOVD 12 (% 1), %% ММ2 \ п" / * B3 * /
"PADDQ %% MM3, %% MM6 \ п"
"MOVD 8 (% 1), %% ММ3 \ п" /*Би 2*/
"PMULUDQ %% ММ5, %% MM2 \ п" / * A1 * b3 * /
"PMULUDQ %% MM7, %% MM3 \ п" / * A2 * b2 * /
"PADDQ %% MM2, %% MM6 \ п"
"MOVD 20 (% 1), %% ММ2 \ п" / * B5 * /
"PADDQ %% MM3, %% MM6 \ п"
"MOVD 20 (% 0), %% ММ3 \ п" / * A5 * /
"MOVQ %% ММ6, 120 (% 2) \ п" / * Результат экстракта [15] * /
/ * Часть # 12: Умножения и дополнения
*
* С + = (uint64_t) а [0] * б [5]
+ (Uint64_t) а [1] * б [4]
+ (Uint64_t) а [2] * б [3]
+ (Uint64_t) а [3] * б [2]
+ (Uint64_t) а [4] * б [1]
+ (Uint64_t) а [5] * б [0] * /
"PMULUDQ %% MM4, %% MM2 \ п" / * A0 * b5 * /
"MOVD 16 (% 0), %% ММ6 \ п" / * A4 * /
"PMULUDQ %% MM0, %% MM3 \ п" / * B0 * a5 * /
"PMULUDQ %% MM1, %% MM6 \ п" / * B1 * a4 * /
"PADDQ %% MM2, %% MM3 \ п"
"MOVD 16 (% 1), %% ММ2 \ п" / * B4 * /
"PADDQ %% MM3, %% MM6 \ п" / * Добавление результатов MM6 * /
"MOVD 12 (% 1), %% ММ3 \ п" / * B3 * /
"PMULUDQ %% ММ5, %% MM2 \ п" / * A1 * b4 * /
"PMULUDQ %% MM7, %% MM3 \ п" / * A2 * b3 * /
"MOVD 8 (% 1), %% MM0 \ п" /*Би 2*/
"PADDQ %% MM2, %% MM6 \ п"
"MOVD 12 (% 0), %% ММ2 \ п" / * A3 * /
"PADDQ %% MM3, %% MM6 \ п"
"PMULUDQ %% MM0, %% MM2 \ п" / * B2 * a3 * /
"MOVD 24 (% 0), %% ММ3 \ п" / * A6 * /
"MOVD 0 (% 1), %% MM0 \ п" / * B0 * /
"PADDQ %% MM2, %% MM6 \ п" / * Все дополнения в конечном итоге в MM6 * /
"MOVD 24 (% 1), %% ММ2 \ п" / * B6 * /
"MOVQ %% ММ6, 128 (% 2) \ п" / * Результат экстракта [16] * /
/ * Часть # 13: Умножения и дополнения
*
* С + = (uint64_t) а [0] * б [6]
+ (Uint64_t) а [1] * б [5]
+ (Uint64_t) а [2] * б [4]
+ (Uint64_t) а [3] * б [3]
+ (Uint64_t) а [4] * б [2]
+ (Uint64_t) а [5] * б [1]
+ (Uint64_t) а [6] * б [0]; * /
"PMULUDQ %% MM0, %% MM3 \ п" / * A6 * b0 * /
"MOVD 20 (% 0), %% ММ6 \ п" / * A5 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * B6 * a0 * /
"PMULUDQ %% MM1, %% MM6 \ п" / * A5 * b1 * /
"PADDQ %% MM2, %% MM3 \ п"
"PADDQ %% MM3, %% MM6 \ п" / * Добавление всех результатов на MM6 * /
"MOVD 20 (% 1), %% ММ2 \ п" / * B5 * /
"MOVD 16 (% 1), %% ММ3 \ п" / * B4 * /
"PMULUDQ %% ММ5, %% MM2 \ п" / * A1 * b5 * /
"PMULUDQ %% MM7, %% MM3 \ п" / * A2 * b4 * /
"MOVD 8 (% 1), %% ММ4 \ п" /*Би 2*/
"MOVD 12 (% 1), %% ММ1 \ п" / * B3 * /
"PADDQ %% MM2, %% MM6 \ п"
"MOVD 12 (% 0), %% ММ2 \ п" / * A3 * /
"PADDQ %% MM3, %% MM6 \ п"
"MOVD 16 (% 0), %% ММ3 \ п" / * A4 * /
"PMULUDQ %% MM1, %% MM2 \ п" / * B3 * a3 * /
"PMULUDQ %% MM4, %% MM3 \ п" / * B2 * a4 * /
"PADDQ %% MM2, %% MM6 \ п"
"MOVD 4 (% 1), %% ММ1 \ п" / * B1 * /
"MOVD 24 (% 0), %% ММ2 \ п" / * A6 * /
"PADDQ %% MM3, %% MM6 \ п"
"MOVD 0 (% 0), %% ММ4 \ п" / * A0 * /
"MOVQ %% ММ6, 136 (% 2) \ п" / * Результат экстракта [17] * /
/ * Часть # 14: Умножения и дополнения
*
* С + = (uint64_t) а [0] * б [7]
+ (Uint64_t) а [1] * б [6]
+ (Uint64_t) а [2] * б [5]
+ (Uint64_t) а [3] * б [4]
+ (Uint64_t) а [4] * б [3]
+ (Uint64_t) а [5] * б [2]
+ (Uint64_t) а [6] * б [1]
+ (Uint64_t) а [7] * б [0]; * /
"PMULUDQ %% MM2, %% MM1 \ п" / * A6 * b1 * /
"MOVD 28 (% 0), %% ММ6 \ п" / * A7 * /
"MOVD 28 (% 1), %% ММ3 \ п" / * B7 * /
"PMULUDQ %% MM6, %% MM0 \ п" / * A7 * b0 * /
"PMULUDQ %% MM3, %% MM4 \ п" / * B7 * a0 * /
"MOVD 24 (% 1), %% ММ6 \ п" / * B6 * /
"MOVD 20 (% 1), %% ММ2 \ п" / * B5 * /
"PMULUDQ %% MM6, %% ММ5 \ п" / * B6 * a1 * /
"PMULUDQ %% MM2, %% MM7 \ п" / * B5 * a2 * /
"PADDQ %% MM0, %% MM1 \ п"
"MOVQ 8 (% 2), %% ММ3 \ п"/ * Упреждающей result1 * /
"PADDQ %% MM4, %% ММ5 \ п"
"MOVD 12 (% 0), %% MM0 \ п" / * A3 * /
"MOVD 8 (% 1), %% ММ6 \ п" /*Би 2*/
"PADDQ %% MM1, %% ММ5 \ п"
"MOVD 20 (% 0), %% ММ2 \ п" / * A5 * /
"MOVD 12 (% 1), %% ММ4 \ п" / * B3 * /
"PADDQ %% ММ5, %% MM7 \ п"
"PMULUDQ %% MM2, %% MM6 \ п" / * A5 * b2 * /
"MOVD 16 (% 0), %% ММ1 \ п" / * A4 * /
"MOVD 16 (% 1), %% ММ5 \ п" / * B4 * /
"PMULUDQ %% MM1, %% MM4 \ п" / * A4 * b3 * /
"PMULUDQ %% MM0, %% ММ5 \ п" / * A3 * b4 * /
"PADDQ %% MM6, %% MM4 \ п"
"MOVD 0 (% 4), %% ММ2 \ п" / * Упреждающей M в MM2 * /
"PADDQ %% MM4, %% ММ5 \ п"
"PADDQ %% MM7, %% ММ5 \ п"
"MOVQ 0 (% 2), %% ММ6 \ п" / * Предвыборки д в результате из [0] * /
"MOVQ %% MM2, %% MM0 \ п" / * М вторичного хранения * /
"MOVQ %% ММ5, 144 (% 2) \ п" / * Результат экстракта [18] * /
"MOVQ 104 (% 2), %% MM7 \ п" / * С в результате из [13] * /
"PAND %% MM6, %% MM2 \ п" / * Г [9] = d & M; * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"MOVD 4 (% 4), %% ММ4 \ п" / * R0 до MM4 * /
"MOVD %% ММ2, 36 (% 3) \ п" / * Экстракт г [9] = d & M; * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) результат [1] * /
"MOVQ %% MM0, %% MM2 \ п" / * M назад в мм2 * /
"MOVQ 16 (% 2), %% ММ3 \ п" / * Упреждающей result2 * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) Результат [2] * /
"MOVQ 96 (% 2), %% ММ5 \ п" / * Упреждающей result12 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 0 (% 3) \ п" / * Экспорт t0 / г [0] = с & M * /
"MOVQ %% MM0, %% MM2 \ п" / * M * /
"PADDQ %% ММ5, %% MM7 \ п" / * = С + (uint64_t) Результат [12] * /
"MOVQ 24 (% 2), %% ММ3 \ п"/ * Упреждающей result3 * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) Результат [3] * /
"MOVQ 112 (% 2), %% ММ5 \ п" / * Упреждающей result14 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 4 (% 3) \ п" / * Экспорт t1 / г [1] = с & M * /
"MOVQ %% MM0, %% MM2 \ п" / * M * /
"PADDQ %% ММ5, %% MM7 \ п" / * = С + (uint64_t) Результат [14] * /
"MOVQ 32 (% 2), %% ММ3 \ п"/ * Упреждающей result4 * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) результат [4] * /
"MOVQ 88 (% 2), %% ММ5 \ п" / * Упреждающей result11 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 8 (% 3) \ п" / * Экспорт t2 / г [2] = с & M * /
"MOVQ %% MM0, %% MM2 \ п" / * M * /
"PADDQ %% ММ5, %% MM7 \ п" / * = С + (uint64_t) Результат [11] * /
"MOVQ 40 (% 2), %% ММ3 \ п"/ * Упреждающей result5 * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) Результат [5] * /
"MOVQ 120 (% 2), %% ММ5 \ п" / * Упреждающей result15 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 12 (% 3) \ п" / * Экспорт t3 / г [3] = с & M * /
"MOVQ %% MM0, %% MM2 \ п" / * M * /
"PADDQ %% ММ5, %% MM7 \ п" / * = С + (uint64_t) Результат [15] * /
"MOVQ 48 (% 2), %% ММ3 \ п"/ * Упреждающей result6 * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) результат [6] * /
"MOVQ 128 (% 2), %% ММ5 \ п" / * Упреждающей result16 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 16 (% 3) \ п" / * Экспорт t4 / г [4] = с & M * /
"MOVQ %% MM0, %% MM2 \ п" / * M * /
"PADDQ %% ММ5, %% MM7 \ п" / * = С + (uint64_t) Результат [16] * /
"MOVQ 56 (% 2), %% ММ3 \ п"/ * Упреждающей result7 * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) результат [7] * /
"MOVQ 136 (% 2), %% ММ5 \ п" / * Упреждающей result16 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 20 (% 3) \ п" / * Экспорт t5 / г [5] = с & M * /
"MOVQ %% MM0, %% MM2 \ п" / * M * /
"PADDQ %% ММ5, %% MM7 \ п" / * = С + (uint64_t) Результат [16] * /
"MOVQ 64 (% 2), %% ММ3 \ п"/ * Упреждающей result8 * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) Результат [8] * /
"MOVQ 144 (% 2), %% ММ5 \ п" / * Упреждающей result18 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 24 (% 3) \ п" / * Экспорт t6 / г [6] = с & M * /
"MOVQ %% MM0, %% MM2 \ п" / * M * /
"PADDQ %% ММ5, %% MM7 \ п" / * = С + (uint64_t) Результат [18] * /
"MOVQ 72 (% 2), %% ММ3 \ п"/ * Упреждающей result9 * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM3, %% MM6 \ п" / * D + = (uint64_t) Результат [9] * /
"MOVQ 80 (% 2), %% ММ5 \ п" / * Упреждающей result10 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 28 (% 3) \ п" / * Экспорт T7 / г [7] = с & M * /
"MOVQ %% MM0, %% MM2 \ п" / * M * /
"PADDQ %% ММ5, %% MM7 \ п" / * = С + (uint64_t) Результат [10] * /
"PAND %% MM6, %% MM2 \ п" / * И0 = д & M; * /
"MOVQ %% MM2, %% MM1 \ п" / * U0, чтобы температура mm1 * /
"PSRLQ $ 26, %% MM6 \ п" / * Д >>= 26; * /
"PSLLQ $ 10, %% MM1 \ п" / * R1 * u0 - с R1 равен 1024, это сдвиг влево на 10 для u0 * /
"PMULUDQ %% MM4, %% MM2 \ п" / * R0 * u0 * /
"PADDQ %% MM2, %% MM7 \ п" / * С = (результат от R0 * u0) + с * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с для операции AND * /
"PAND %% MM0, %% MM3 \ п" / * С & M * /
"PSRLQ $ 26, %% MM7 \ п" / * С >>= 26; * /
"MOVQ %% MM0, %% MM2 \ п" / * Клонирование M в мм2 * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = и0 * R1 * /
"MOVD %% ММ3, 32 (% 3) \ п" / * Экспорт t8 / г [8] = с & M * /
"PMULUDQ %% MM6, %% MM4 \ п" / * D * R 0 * /
"PSRLQ $ 4, %% MM0 \ п" / * M >>= 4 * /
"MOVD 36 (% 3), %% ММ1 \ п" / * R [9] * /
"PADDQ %% MM4, %% MM7 \ п" / * = С + d * R0 * /
"PADDQ %% MM1, %% MM7 \ п" / * С + = г [9] ===> с + = d * R 0 + г [9] * /
"PAND %% MM7, %% MM0 \ п" / * С & (M >> 4) * /
"MOVD %% MM0, 36 (% 3) \ п" / * R [9] = с & (M >> 4) * /
"PSRLQ $ 22, %% MM7 \ п" / * С >>= 22 * /
"PSLLQ $ 14, %% MM6 \ п" / * Д * (R1 << 4). Так как (R1 << 4) равен 16384, это по существу левый сдвиг на 14 * /
"PADDQ %% MM6, %% MM7 \ п" / * = С + d * (R1 << 4) * /
"MOVQ %% MM7, %% MM3 \ п" / * Клонирование с * /
"PSLLQ $ 6, %% MM7 \ п" / * Результат с * (R 1 >> 4), которая равна с сдвигается влево на 6, так как (R1 >> 4) = 64 * /
"MOVQ %% MM3, %% MM0 \ п" / * Это ручная попытка умножения C с x3D1 или 977 десятичными, путем сдвига и добавления копий с ... * /
"MOVQ %% MM3, %% MM1 \ п" / * Все это сегмент, это, на самом деле, просто (с * 977) одиночная линия умножения * /
"MOVQ %% MM3, %% MM6 \ п" / *, Которые по каким-то причинам не хочет работать иначе с простой PMULUDQ с * 977 * константой /
"MOVQ %% MM3, %% MM4 \ п"
"MOVQ %% MM3, %% ММ5 \ п"
"PSLLQ $ 9, %% MM0 \ п" / * X512 * /
"PSLLQ $ 8, %% MM1 \ п" / * X256 * /
"PSLLQ $ 7, %% MM6 \ п" / * X128 * /
"PSLLQ $ 6, %% MM4 \ п" / * 64 * /
"PSLLQ $ 4, %% ММ5 \ п" / * Х16 * / / * 512 + 256 + 128 + 64 = 976x, так что +1 добавить сверху = 977 или 0x3D1 * /
"PADDQ %% MM3, %% MM0 \ п"
"PADDQ %% MM1, %% MM6 \ п"
"MOVD 0 (% 3), %% ММ3 \ п" / * Предвыборки г [0] для MM3 * /
"PADDQ %% MM4, %% MM0 \ п"
"PADDQ %% MM6, %% MM0 \ п"
"PADDQ %% MM0, %% ММ5 \ п" / * Результат с * (R0 >> 4) * /
"PADDQ %% MM3, %% ММ5 \ п" / * Д = г [0] + с (R 0 >> 4) * /
"MOVD 4 (% 3), %% ММ4 \ п" / * Г [1] ММ4 * /
"MOVD 8 (% 3), %% MM0 \ п" / * Г [2], чтобы ММ5 * /
"MOVQ %% ММ5, %% MM3 \ п" / * * Клонирование д /
"PAND %% MM2, %% ММ5 \ п" / * Д&M * /
"PSRLQ $ 26, %% MM3 \ п" / * Д >>= 26 * /
"PADDQ %% MM7, %% MM4 \ п" / * C * (R 1 >> 4) + г [1] * /
"PADDQ %% MM4, %% MM3 \ п" / * D + = C * (R 1 >> 4) + г [1]; * /
"MOVD %% ММ5, 0 (% 3) \ п" / * Экспорт д к г [0] * /
"MOVQ %% MM3, %% MM7 \ п" / * * Клонирование д /
"PAND %% MM2, %% MM7 \ п" / * Д&M * /
"PSRLQ $ 26, %% MM3 \ п" / * Д >>= 26 * /
"PADDQ %% MM0, %% MM3 \ п" / * Й + = г [2]; * /
"MOVD %% MM7, 4 (% 3) \ п" / * Г [1] = d & M; * /
"MOVD %% ММ3, 8 (% 3) \ п" / * Г [2] = д; * /
"EMMS \ п"
:
: "Q"(А), "Q"(Б), "Q"(Результат), "Q"(р), "S"(Tempstor)
: "Память", "% mm0", "% mm1", "% мм2", "% мм3", "% mm4", "% ММ5", "% MM6", "% MM7"
);
}