From 9b6a0d340b4a5b93036d789cd5440586d007be09 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 26 Feb 2018 14:56:56 +0100 Subject: Add neon and remove 64-bit implementations --- Makefile | 2 +- curve25519-donna64.c | 414 ---------- curve25519-hacl64.c | 751 ------------------ curve25519-neon.S | 2110 ++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 38 +- 5 files changed, 2122 insertions(+), 1193 deletions(-) delete mode 100644 curve25519-donna64.c delete mode 100644 curve25519-hacl64.c create mode 100644 curve25519-neon.S diff --git a/Makefile b/Makefile index 0b5ecc0..8287c4a 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ ifneq ($(KERNELRELEASE),) -kbench9000-y := main.o curve25519-donna64.o curve25519-hacl64.o curve25519-donna32.o curve25519-fiat32.o +kbench9000-y := main.o curve25519-neon.o curve25519-donna32.o curve25519-fiat32.o obj-m := kbench9000.o ccflags-y += -O3 ccflags-y += -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt' diff --git a/curve25519-donna64.c b/curve25519-donna64.c deleted file mode 100644 index f294369..0000000 --- a/curve25519-donna64.c +++ /dev/null @@ -1,414 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2008 Google Inc. All Rights Reserved. - * Copyright (C) 2015-2018 Jason A. Donenfeld . All Rights Reserved. - * - * Original author: Adam Langley - */ - -#include -#include - -enum { CURVE25519_POINT_SIZE = 32 }; - -typedef u64 limb; -typedef limb felem[5]; -typedef __uint128_t u128; - -static __always_inline void normalize_secret(u8 secret[CURVE25519_POINT_SIZE]) -{ - secret[0] &= 248; - secret[31] &= 127; - secret[31] |= 64; -} - -/* Sum two numbers: output += in */ -static __always_inline void fsum(limb *output, const limb *in) -{ - output[0] += in[0]; - output[1] += in[1]; - output[2] += in[2]; - output[3] += in[3]; - output[4] += in[4]; -} - -/* Find the difference of two numbers: output = in - output - * (note the order of the arguments!) - * - * Assumes that out[i] < 2**52 - * On return, out[i] < 2**55 - */ -static __always_inline void fdifference_backwards(felem out, const felem in) -{ - /* 152 is 19 << 3 */ - static const limb two54m152 = (((limb)1) << 54) - 152; - static const limb two54m8 = (((limb)1) << 54) - 8; - - out[0] = in[0] + two54m152 - out[0]; - out[1] = in[1] + two54m8 - out[1]; - out[2] = in[2] + two54m8 - out[2]; - out[3] = in[3] + two54m8 - out[3]; - out[4] = in[4] + two54m8 - out[4]; -} - -/* Multiply a number by a scalar: output = in * scalar */ -static __always_inline void fscalar_product(felem output, const felem in, const limb scalar) -{ - u128 a; - - a = ((u128) in[0]) * scalar; - output[0] = ((limb)a) & 0x7ffffffffffffUL; - - a = ((u128) in[1]) * scalar + ((limb) (a >> 51)); - output[1] = ((limb)a) & 0x7ffffffffffffUL; - - a = ((u128) in[2]) * scalar + ((limb) (a >> 51)); - output[2] = ((limb)a) & 0x7ffffffffffffUL; - - a = ((u128) in[3]) * scalar + ((limb) (a >> 51)); - output[3] = ((limb)a) & 0x7ffffffffffffUL; - - a = ((u128) in[4]) * scalar + ((limb) (a >> 51)); - output[4] = ((limb)a) & 0x7ffffffffffffUL; - - output[0] += (a >> 51) * 19; -} - -/* Multiply two numbers: output = in2 * in - * - * output must be distinct to both inputs. The inputs are reduced coefficient - * form, the output is not. - * - * Assumes that in[i] < 2**55 and likewise for in2. - * On return, output[i] < 2**52 - */ -static __always_inline void fmul(felem output, const felem in2, const felem in) -{ - u128 t[5]; - limb r0, r1, r2, r3, r4, s0, s1, s2, s3, s4, c; - - r0 = in[0]; - r1 = in[1]; - r2 = in[2]; - r3 = in[3]; - r4 = in[4]; - - s0 = in2[0]; - s1 = in2[1]; - s2 = in2[2]; - s3 = in2[3]; - s4 = in2[4]; - - t[0] = ((u128) r0) * s0; - t[1] = ((u128) r0) * s1 + ((u128) r1) * s0; - t[2] = ((u128) r0) * s2 + ((u128) r2) * s0 + ((u128) r1) * s1; - t[3] = ((u128) r0) * s3 + ((u128) r3) * s0 + ((u128) r1) * s2 + ((u128) r2) * s1; - t[4] = ((u128) r0) * s4 + ((u128) r4) * s0 + ((u128) r3) * s1 + ((u128) r1) * s3 + ((u128) r2) * s2; - - r4 *= 19; - r1 *= 19; - r2 *= 19; - r3 *= 19; - - t[0] += ((u128) r4) * s1 + ((u128) r1) * s4 + ((u128) r2) * s3 + ((u128) r3) * s2; - t[1] += ((u128) r4) * s2 + ((u128) r2) * s4 + ((u128) r3) * s3; - t[2] += ((u128) r4) * s3 + ((u128) r3) * s4; - t[3] += ((u128) r4) * s4; - - r0 = (limb)t[0] & 0x7ffffffffffffUL; c = (limb)(t[0] >> 51); - t[1] += c; r1 = (limb)t[1] & 0x7ffffffffffffUL; c = (limb)(t[1] >> 51); - t[2] += c; r2 = (limb)t[2] & 0x7ffffffffffffUL; c = (limb)(t[2] >> 51); - t[3] += c; r3 = (limb)t[3] & 0x7ffffffffffffUL; c = (limb)(t[3] >> 51); - t[4] += c; r4 = (limb)t[4] & 0x7ffffffffffffUL; c = (limb)(t[4] >> 51); - r0 += c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffffUL; - r1 += c; c = r1 >> 51; r1 = r1 & 0x7ffffffffffffUL; - r2 += c; - - output[0] = r0; - output[1] = r1; - output[2] = r2; - output[3] = r3; - output[4] = r4; -} - -static __always_inline void fsquare_times(felem output, const felem in, limb count) -{ - u128 t[5]; - limb r0, r1, r2, r3, r4, c; - limb d0, d1, d2, d4, d419; - - r0 = in[0]; - r1 = in[1]; - r2 = in[2]; - r3 = in[3]; - r4 = in[4]; - - do { - d0 = r0 * 2; - d1 = r1 * 2; - d2 = r2 * 2 * 19; - d419 = r4 * 19; - d4 = d419 * 2; - - t[0] = ((u128) r0) * r0 + ((u128) d4) * r1 + (((u128) d2) * (r3 )); - t[1] = ((u128) d0) * r1 + ((u128) d4) * r2 + (((u128) r3) * (r3 * 19)); - t[2] = ((u128) d0) * r2 + ((u128) r1) * r1 + (((u128) d4) * (r3 )); - t[3] = ((u128) d0) * r3 + ((u128) d1) * r2 + (((u128) r4) * (d419 )); - t[4] = ((u128) d0) * r4 + ((u128) d1) * r3 + (((u128) r2) * (r2 )); - - r0 = (limb)t[0] & 0x7ffffffffffffUL; c = (limb)(t[0] >> 51); - t[1] += c; r1 = (limb)t[1] & 0x7ffffffffffffUL; c = (limb)(t[1] >> 51); - t[2] += c; r2 = (limb)t[2] & 0x7ffffffffffffUL; c = (limb)(t[2] >> 51); - t[3] += c; r3 = (limb)t[3] & 0x7ffffffffffffUL; c = (limb)(t[3] >> 51); - t[4] += c; r4 = (limb)t[4] & 0x7ffffffffffffUL; c = (limb)(t[4] >> 51); - r0 += c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffffUL; - r1 += c; c = r1 >> 51; r1 = r1 & 0x7ffffffffffffUL; - r2 += c; - } while (--count); - - output[0] = r0; - output[1] = r1; - output[2] = r2; - output[3] = r3; - output[4] = r4; -} - -/* Load a little-endian 64-bit number */ -static inline limb load_limb(const u8 *in) -{ - return le64_to_cpu(*(__le64 *)in); -} - -static inline void store_limb(u8 *out, limb in) -{ - *(__le64 *)out = cpu_to_le64(in); -} - -/* Take a little-endian, 32-byte number and expand it into polynomial form */ -static inline void fexpand(limb *output, const u8 *in) -{ - output[0] = load_limb(in) & 0x7ffffffffffffUL; - output[1] = (load_limb(in + 6) >> 3) & 0x7ffffffffffffUL; - output[2] = (load_limb(in + 12) >> 6) & 0x7ffffffffffffUL; - output[3] = (load_limb(in + 19) >> 1) & 0x7ffffffffffffUL; - output[4] = (load_limb(in + 24) >> 12) & 0x7ffffffffffffUL; -} - -/* Take a fully reduced polynomial form number and contract it into a - * little-endian, 32-byte array - */ -static void fcontract(u8 *output, const felem input) -{ - u128 t[5]; - - t[0] = input[0]; - t[1] = input[1]; - t[2] = input[2]; - t[3] = input[3]; - t[4] = input[4]; - - t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffffUL; - t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffffUL; - t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffffUL; - t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffffUL; - t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffffUL; - - t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffffUL; - t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffffUL; - t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffffUL; - t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffffUL; - t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffffUL; - - /* now t is between 0 and 2^255-1, properly carried. */ - /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ - - t[0] += 19; - - t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffffUL; - t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffffUL; - t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffffUL; - t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffffUL; - t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffffUL; - - /* now between 19 and 2^255-1 in both cases, and offset by 19. */ - - t[0] += 0x8000000000000UL - 19; - t[1] += 0x8000000000000UL - 1; - t[2] += 0x8000000000000UL - 1; - t[3] += 0x8000000000000UL - 1; - t[4] += 0x8000000000000UL - 1; - - /* now between 2^255 and 2^256-20, and offset by 2^255. */ - - t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffffUL; - t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffffUL; - t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffffUL; - t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffffUL; - t[4] &= 0x7ffffffffffffUL; - - store_limb(output, t[0] | (t[1] << 51)); - store_limb(output+8, (t[1] >> 13) | (t[2] << 38)); - store_limb(output+16, (t[2] >> 26) | (t[3] << 25)); - store_limb(output+24, (t[3] >> 39) | (t[4] << 12)); -} - -/* Input: Q, Q', Q-Q' - * Output: 2Q, Q+Q' - * - * x2 z3: long form - * x3 z3: long form - * x z: short form, destroyed - * xprime zprime: short form, destroyed - * qmqp: short form, preserved - */ -static void fmonty(limb *x2, limb *z2, /* output 2Q */ - limb *x3, limb *z3, /* output Q + Q' */ - limb *x, limb *z, /* input Q */ - limb *xprime, limb *zprime, /* input Q' */ - - const limb *qmqp /* input Q - Q' */) -{ - limb origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5], zzprime[5], zzzprime[5]; - - memcpy(origx, x, 5 * sizeof(limb)); - fsum(x, z); - fdifference_backwards(z, origx); // does x - z - - memcpy(origxprime, xprime, sizeof(limb) * 5); - fsum(xprime, zprime); - fdifference_backwards(zprime, origxprime); - fmul(xxprime, xprime, z); - fmul(zzprime, x, zprime); - memcpy(origxprime, xxprime, sizeof(limb) * 5); - fsum(xxprime, zzprime); - fdifference_backwards(zzprime, origxprime); - fsquare_times(x3, xxprime, 1); - fsquare_times(zzzprime, zzprime, 1); - fmul(z3, zzzprime, qmqp); - - fsquare_times(xx, x, 1); - fsquare_times(zz, z, 1); - fmul(x2, xx, zz); - fdifference_backwards(zz, xx); // does zz = xx - zz - fscalar_product(zzz, zz, 121665); - fsum(zzz, xx); - fmul(z2, zz, zzz); -} - -/* Maybe swap the contents of two limb arrays (@a and @b), each @len elements - * long. Perform the swap iff @swap is non-zero. - * - * This function performs the swap without leaking any side-channel - * information. - */ -static void swap_conditional(limb a[5], limb b[5], limb iswap) -{ - unsigned int i; - const limb swap = -iswap; - - for (i = 0; i < 5; ++i) { - const limb x = swap & (a[i] ^ b[i]); - - a[i] ^= x; - b[i] ^= x; - } -} - -/* Calculates nQ where Q is the x-coordinate of a point on the curve - * - * resultx/resultz: the x coordinate of the resulting curve point (short form) - * n: a little endian, 32-byte number - * q: a point of the curve (short form) - */ -static void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) -{ - limb a[5] = {0}, b[5] = {1}, c[5] = {1}, d[5] = {0}; - limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; - limb e[5] = {0}, f[5] = {1}, g[5] = {0}, h[5] = {1}; - limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; - - unsigned int i, j; - - memcpy(nqpqx, q, sizeof(limb) * 5); - - for (i = 0; i < 32; ++i) { - u8 byte = n[31 - i]; - - for (j = 0; j < 8; ++j) { - const limb bit = byte >> 7; - - swap_conditional(nqx, nqpqx, bit); - swap_conditional(nqz, nqpqz, bit); - fmonty(nqx2, nqz2, - nqpqx2, nqpqz2, - nqx, nqz, - nqpqx, nqpqz, - q); - swap_conditional(nqx2, nqpqx2, bit); - swap_conditional(nqz2, nqpqz2, bit); - - t = nqx; - nqx = nqx2; - nqx2 = t; - t = nqz; - nqz = nqz2; - nqz2 = t; - t = nqpqx; - nqpqx = nqpqx2; - nqpqx2 = t; - t = nqpqz; - nqpqz = nqpqz2; - nqpqz2 = t; - - byte <<= 1; - } - } - - memcpy(resultx, nqx, sizeof(limb) * 5); - memcpy(resultz, nqz, sizeof(limb) * 5); -} - -static void crecip(felem out, const felem z) -{ - felem a, t0, b, c; - - /* 2 */ fsquare_times(a, z, 1); // a = 2 - /* 8 */ fsquare_times(t0, a, 2); - /* 9 */ fmul(b, t0, z); // b = 9 - /* 11 */ fmul(a, b, a); // a = 11 - /* 22 */ fsquare_times(t0, a, 1); - /* 2^5 - 2^0 = 31 */ fmul(b, t0, b); - /* 2^10 - 2^5 */ fsquare_times(t0, b, 5); - /* 2^10 - 2^0 */ fmul(b, t0, b); - /* 2^20 - 2^10 */ fsquare_times(t0, b, 10); - /* 2^20 - 2^0 */ fmul(c, t0, b); - /* 2^40 - 2^20 */ fsquare_times(t0, c, 20); - /* 2^40 - 2^0 */ fmul(t0, t0, c); - /* 2^50 - 2^10 */ fsquare_times(t0, t0, 10); - /* 2^50 - 2^0 */ fmul(b, t0, b); - /* 2^100 - 2^50 */ fsquare_times(t0, b, 50); - /* 2^100 - 2^0 */ fmul(c, t0, b); - /* 2^200 - 2^100 */ fsquare_times(t0, c, 100); - /* 2^200 - 2^0 */ fmul(t0, t0, c); - /* 2^250 - 2^50 */ fsquare_times(t0, t0, 50); - /* 2^250 - 2^0 */ fmul(t0, t0, b); - /* 2^255 - 2^5 */ fsquare_times(t0, t0, 5); - /* 2^255 - 21 */ fmul(out, t0, a); -} - -bool curve25519_donna64(u8 mypublic[CURVE25519_POINT_SIZE], const u8 secret[CURVE25519_POINT_SIZE], const u8 basepoint[CURVE25519_POINT_SIZE]) -{ - limb bp[5], x[5], z[5], zmone[5]; - u8 e[32]; - - memcpy(e, secret, 32); - normalize_secret(e); - - fexpand(bp, basepoint); - cmult(x, z, e, bp); - crecip(zmone, z); - fmul(z, x, zmone); - fcontract(mypublic, z); - - return true; -} diff --git a/curve25519-hacl64.c b/curve25519-hacl64.c deleted file mode 100644 index af2460b..0000000 --- a/curve25519-hacl64.c +++ /dev/null @@ -1,751 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2016-2017 INRIA and Microsoft Corporation. - * Copyright (C) 2018 Jason A. Donenfeld . All Rights Reserved. - * - * This is a machine-generated formally verified implementation of curve25519 DH from: - * https://github.com/mitls/hacl-star - */ - -#include -#include - -enum { CURVE25519_POINT_SIZE = 32 }; - -static __always_inline void normalize_secret(u8 secret[CURVE25519_POINT_SIZE]) -{ - secret[0] &= 248; - secret[31] &= 127; - secret[31] |= 64; -} - -typedef __uint128_t u128; - -static __always_inline u64 u64_eq_mask(u64 x, u64 y) -{ - x = ~(x ^ y); - x &= x << 32; - x &= x << 16; - x &= x << 8; - x &= x << 4; - x &= x << 2; - x &= x << 1; - return ((s64)x) >> 63; -} - -static __always_inline u64 u64_gte_mask(u64 x, u64 y) -{ - u64 low63 = ~((u64)((s64)((s64)(x & 0x7fffffffffffffffLLU) - (s64)(y & 0x7fffffffffffffffLLU)) >> 63)); - u64 high_bit = ~((u64)((s64)((s64)(x & 0x8000000000000000LLU) - (s64)(y & 0x8000000000000000LLU)) >> 63)); - return low63 & high_bit; -} - -static __always_inline void modulo_carry_top(u64 *b) -{ - u64 b4 = b[4]; - u64 b0 = b[0]; - u64 b4_ = b4 & 0x7ffffffffffffLLU; - u64 b0_ = b0 + 19 * (b4 >> 51); - b[4] = b4_; - b[0] = b0_; -} - -static __always_inline void fproduct_copy_from_wide_(u64 *output, u128 *input) -{ - { - u128 xi = input[0]; - output[0] = ((u64)(xi)); - } - { - u128 xi = input[1]; - output[1] = ((u64)(xi)); - } - { - u128 xi = input[2]; - output[2] = ((u64)(xi)); - } - { - u128 xi = input[3]; - output[3] = ((u64)(xi)); - } - { - u128 xi = input[4]; - output[4] = ((u64)(xi)); - } -} - -static __always_inline void fproduct_sum_scalar_multiplication_(u128 *output, u64 *input, u64 s) -{ - u32 i; - for (i = 0; i < 5; ++i) { - u128 xi = output[i]; - u64 yi = input[i]; - output[i] = ((xi) + (((u128)(yi) * (s)))); - } -} - -static __always_inline void fproduct_carry_wide_(u128 *tmp) -{ - u32 i; - for (i = 0; i < 4; ++i) { - u32 ctr = i; - u128 tctr = tmp[ctr]; - u128 tctrp1 = tmp[ctr + 1]; - u64 r0 = ((u64)(tctr)) & 0x7ffffffffffffLLU; - u128 c = ((tctr) >> (51)); - tmp[ctr] = ((u128)(r0)); - tmp[ctr + 1] = ((tctrp1) + (c)); - } -} - -static __always_inline void fmul_shift_reduce(u64 *output) -{ - u64 tmp = output[4]; - u64 b0; - { - u32 ctr = 5 - 0 - 1; - u64 z = output[ctr - 1]; - output[ctr] = z; - } - { - u32 ctr = 5 - 1 - 1; - u64 z = output[ctr - 1]; - output[ctr] = z; - } - { - u32 ctr = 5 - 2 - 1; - u64 z = output[ctr - 1]; - output[ctr] = z; - } - { - u32 ctr = 5 - 3 - 1; - u64 z = output[ctr - 1]; - output[ctr] = z; - } - output[0] = tmp; - b0 = output[0]; - output[0] = 19 * b0; -} - -static __always_inline void fmul_mul_shift_reduce_(u128 *output, u64 *input, u64 *input21) -{ - u32 i; - u64 input2i; - { - u64 input2i = input21[0]; - fproduct_sum_scalar_multiplication_(output, input, input2i); - fmul_shift_reduce(input); - } - { - u64 input2i = input21[1]; - fproduct_sum_scalar_multiplication_(output, input, input2i); - fmul_shift_reduce(input); - } - { - u64 input2i = input21[2]; - fproduct_sum_scalar_multiplication_(output, input, input2i); - fmul_shift_reduce(input); - } - { - u64 input2i = input21[3]; - fproduct_sum_scalar_multiplication_(output, input, input2i); - fmul_shift_reduce(input); - } - i = 4; - input2i = input21[i]; - fproduct_sum_scalar_multiplication_(output, input, input2i); -} - -static __always_inline void fmul_fmul(u64 *output, u64 *input, u64 *input21) -{ - u64 tmp[5]; - memcpy(tmp, input, 5 * sizeof(*input)); - { - u128 b4; - u128 b0; - u128 b4_; - u128 b0_; - u64 i0; - u64 i1; - u64 i0_; - u64 i1_; - u128 t[5]; - { - u32 _i; - for (_i = 0; _i < 5; ++_i) - t[_i] = ((u128)(0)); - } - fmul_mul_shift_reduce_(t, tmp, input21); - fproduct_carry_wide_(t); - b4 = t[4]; - b0 = t[0]; - b4_ = ((b4) & (((u128)(0x7ffffffffffffLLU)))); - b0_ = ((b0) + (((u128)(19) * (((u64)(((b4) >> (51)))))))); - t[4] = b4_; - t[0] = b0_; - fproduct_copy_from_wide_(output, t); - i0 = output[0]; - i1 = output[1]; - i0_ = i0 & 0x7ffffffffffffLLU; - i1_ = i1 + (i0 >> 51); - output[0] = i0_; - output[1] = i1_; - } -} - -static __always_inline void fsquare_fsquare__(u128 *tmp, u64 *output) -{ - u64 r0 = output[0]; - u64 r1 = output[1]; - u64 r2 = output[2]; - u64 r3 = output[3]; - u64 r4 = output[4]; - u64 d0 = r0 * 2; - u64 d1 = r1 * 2; - u64 d2 = r2 * 2 * 19; - u64 d419 = r4 * 19; - u64 d4 = d419 * 2; - u128 s0 = ((((((u128)(r0) * (r0))) + (((u128)(d4) * (r1))))) + (((u128)(d2) * (r3)))); - u128 s1 = ((((((u128)(d0) * (r1))) + (((u128)(d4) * (r2))))) + (((u128)(r3 * 19) * (r3)))); - u128 s2 = ((((((u128)(d0) * (r2))) + (((u128)(r1) * (r1))))) + (((u128)(d4) * (r3)))); - u128 s3 = ((((((u128)(d0) * (r3))) + (((u128)(d1) * (r2))))) + (((u128)(r4) * (d419)))); - u128 s4 = ((((((u128)(d0) * (r4))) + (((u128)(d1) * (r3))))) + (((u128)(r2) * (r2)))); - tmp[0] = s0; - tmp[1] = s1; - tmp[2] = s2; - tmp[3] = s3; - tmp[4] = s4; -} - -static __always_inline void fsquare_fsquare_(u128 *tmp, u64 *output) -{ - u128 b4; - u128 b0; - u128 b4_; - u128 b0_; - u64 i0; - u64 i1; - u64 i0_; - u64 i1_; - fsquare_fsquare__(tmp, output); - fproduct_carry_wide_(tmp); - b4 = tmp[4]; - b0 = tmp[0]; - b4_ = ((b4) & (((u128)(0x7ffffffffffffLLU)))); - b0_ = ((b0) + (((u128)(19) * (((u64)(((b4) >> (51)))))))); - tmp[4] = b4_; - tmp[0] = b0_; - fproduct_copy_from_wide_(output, tmp); - i0 = output[0]; - i1 = output[1]; - i0_ = i0 & 0x7ffffffffffffLLU; - i1_ = i1 + (i0 >> 51); - output[0] = i0_; - output[1] = i1_; -} - -static __always_inline void fsquare_fsquare_times_(u64 *input, u128 *tmp, u32 count1) -{ - u32 i; - fsquare_fsquare_(tmp, input); - for (i = 1; i < count1; ++i) - fsquare_fsquare_(tmp, input); -} - -static __always_inline void fsquare_fsquare_times(u64 *output, u64 *input, u32 count1) -{ - u128 t[5]; - { - u32 _i; - for (_i = 0; _i < 5; ++_i) - t[_i] = ((u128)(0)); - } - memcpy(output, input, 5 * sizeof(*input)); - fsquare_fsquare_times_(output, t, count1); -} - -static __always_inline void fsquare_fsquare_times_inplace(u64 *output, u32 count1) -{ - u128 t[5]; - { - u32 _i; - for (_i = 0; _i < 5; ++_i) - t[_i] = ((u128)(0)); - } - fsquare_fsquare_times_(output, t, count1); -} - -static __always_inline void crecip_crecip(u64 *out, u64 *z) -{ - u64 buf[20] = { 0 }; - u64 *a0 = buf; - u64 *t00 = buf + 5; - u64 *b0 = buf + 10; - u64 *t01; - u64 *b1; - u64 *c0; - u64 *a; - u64 *t0; - u64 *b; - u64 *c; - fsquare_fsquare_times(a0, z, 1); - fsquare_fsquare_times(t00, a0, 2); - fmul_fmul(b0, t00, z); - fmul_fmul(a0, b0, a0); - fsquare_fsquare_times(t00, a0, 1); - fmul_fmul(b0, t00, b0); - fsquare_fsquare_times(t00, b0, 5); - t01 = buf + 5; - b1 = buf + 10; - c0 = buf + 15; - fmul_fmul(b1, t01, b1); - fsquare_fsquare_times(t01, b1, 10); - fmul_fmul(c0, t01, b1); - fsquare_fsquare_times(t01, c0, 20); - fmul_fmul(t01, t01, c0); - fsquare_fsquare_times_inplace(t01, 10); - fmul_fmul(b1, t01, b1); - fsquare_fsquare_times(t01, b1, 50); - a = buf; - t0 = buf + 5; - b = buf + 10; - c = buf + 15; - fmul_fmul(c, t0, b); - fsquare_fsquare_times(t0, c, 100); - fmul_fmul(t0, t0, c); - fsquare_fsquare_times_inplace(t0, 50); - fmul_fmul(t0, t0, b); - fsquare_fsquare_times_inplace(t0, 5); - fmul_fmul(out, t0, a); -} - -static __always_inline void fsum(u64 *a, u64 *b) -{ - u32 i; - for (i = 0; i < 5; ++i) { - u64 xi = a[i]; - u64 yi = b[i]; - a[i] = xi + yi; - } -} - -static __always_inline void fdifference(u64 *a, u64 *b) -{ - u64 tmp[5] = { 0 }; - u64 b0; - u64 b1; - u64 b2; - u64 b3; - u64 b4; - memcpy(tmp, b, 5 * sizeof(*b)); - b0 = tmp[0]; - b1 = tmp[1]; - b2 = tmp[2]; - b3 = tmp[3]; - b4 = tmp[4]; - tmp[0] = b0 + 0x3fffffffffff68LLU; - tmp[1] = b1 + 0x3ffffffffffff8LLU; - tmp[2] = b2 + 0x3ffffffffffff8LLU; - tmp[3] = b3 + 0x3ffffffffffff8LLU; - tmp[4] = b4 + 0x3ffffffffffff8LLU; - { - u64 xi = a[0]; - u64 yi = tmp[0]; - a[0] = yi - xi; - } - { - u64 xi = a[1]; - u64 yi = tmp[1]; - a[1] = yi - xi; - } - { - u64 xi = a[2]; - u64 yi = tmp[2]; - a[2] = yi - xi; - } - { - u64 xi = a[3]; - u64 yi = tmp[3]; - a[3] = yi - xi; - } - { - u64 xi = a[4]; - u64 yi = tmp[4]; - a[4] = yi - xi; - } -} - -static __always_inline void fscalar(u64 *output, u64 *b, u64 s) -{ - u128 tmp[5]; - u128 b4; - u128 b0; - u128 b4_; - u128 b0_; - { - u64 xi = b[0]; - tmp[0] = ((u128)(xi) * (s)); - } - { - u64 xi = b[1]; - tmp[1] = ((u128)(xi) * (s)); - } - { - u64 xi = b[2]; - tmp[2] = ((u128)(xi) * (s)); - } - { - u64 xi = b[3]; - tmp[3] = ((u128)(xi) * (s)); - } - { - u64 xi = b[4]; - tmp[4] = ((u128)(xi) * (s)); - } - fproduct_carry_wide_(tmp); - b4 = tmp[4]; - b0 = tmp[0]; - b4_ = ((b4) & (((u128)(0x7ffffffffffffLLU)))); - b0_ = ((b0) + (((u128)(19) * (((u64)(((b4) >> (51)))))))); - tmp[4] = b4_; - tmp[0] = b0_; - fproduct_copy_from_wide_(output, tmp); -} - -static __always_inline void fmul(u64 *output, u64 *a, u64 *b) -{ - fmul_fmul(output, a, b); -} - -static __always_inline void crecip(u64 *output, u64 *input) -{ - crecip_crecip(output, input); -} - -static __always_inline void point_swap_conditional_step(u64 *a, u64 *b, u64 swap1, u32 ctr) -{ - u32 i = ctr - 1; - u64 ai = a[i]; - u64 bi = b[i]; - u64 x = swap1 & (ai ^ bi); - u64 ai1 = ai ^ x; - u64 bi1 = bi ^ x; - a[i] = ai1; - b[i] = bi1; -} - -static __always_inline void point_swap_conditional_(u64 *a, u64 *b, u64 swap1, u32 ctr) -{ - u32 i; - for (i = ctr; i > 0; --i) - point_swap_conditional_step(a, b, swap1, i); -} - -static __always_inline void point_swap_conditional(u64 *a, u64 *b, u64 iswap) -{ - u64 swap1 = 0 - iswap; - point_swap_conditional_(a, b, swap1, 5); - point_swap_conditional_(a + 5, b + 5, swap1, 5); -} - -static __always_inline void point_copy(u64 *output, u64 *input) -{ - memcpy(output, input, 5 * sizeof(*input)); - memcpy(output + 5, input + 5, 5 * sizeof(*input)); -} - -static __always_inline void addanddouble_fmonty(u64 *pp, u64 *ppq, u64 *p, u64 *pq, u64 *qmqp) -{ - u64 *qx = qmqp; - u64 *x2 = pp; - u64 *z2 = pp + 5; - u64 *x3 = ppq; - u64 *z3 = ppq + 5; - u64 *x = p; - u64 *z = p + 5; - u64 *xprime = pq; - u64 *zprime = pq + 5; - u64 buf[40] = { 0 }; - u64 *origx = buf; - u64 *origxprime0 = buf + 5; - u64 *xxprime0; - u64 *zzprime0; - u64 *origxprime; - xxprime0 = buf + 25; - zzprime0 = buf + 30; - memcpy(origx, x, 5 * sizeof(*x)); - fsum(x, z); - fdifference(z, origx); - memcpy(origxprime0, xprime, 5 * sizeof(*xprime)); - fsum(xprime, zprime); - fdifference(zprime, origxprime0); - fmul(xxprime0, xprime, z); - fmul(zzprime0, x, zprime); - origxprime = buf + 5; - { - u64 *xx0; - u64 *zz0; - u64 *xxprime; - u64 *zzprime; - u64 *zzzprime; - xx0 = buf + 15; - zz0 = buf + 20; - xxprime = buf + 25; - zzprime = buf + 30; - zzzprime = buf + 35; - memcpy(origxprime, xxprime, 5 * sizeof(*xxprime)); - fsum(xxprime, zzprime); - fdifference(zzprime, origxprime); - fsquare_fsquare_times(x3, xxprime, 1); - fsquare_fsquare_times(zzzprime, zzprime, 1); - fmul(z3, zzzprime, qx); - fsquare_fsquare_times(xx0, x, 1); - fsquare_fsquare_times(zz0, z, 1); - { - u64 *zzz; - u64 *xx; - u64 *zz; - u64 scalar; - zzz = buf + 10; - xx = buf + 15; - zz = buf + 20; - fmul(x2, xx, zz); - fdifference(zz, xx); - scalar = 121665; - fscalar(zzz, zz, scalar); - fsum(zzz, xx); - fmul(z2, zzz, zz); - } - } -} - -static __always_inline void ladder_smallloop_cmult_small_loop_step(u64 *nq, u64 *nqpq, u64 *nq2, u64 *nqpq2, u64 *q, u8 byt) -{ - u64 bit0 = (u64)(byt >> 7); - u64 bit; - point_swap_conditional(nq, nqpq, bit0); - addanddouble_fmonty(nq2, nqpq2, nq, nqpq, q); - bit = (u64)(byt >> 7); - point_swap_conditional(nq2, nqpq2, bit); -} - -static __always_inline void ladder_smallloop_cmult_small_loop_double_step(u64 *nq, u64 *nqpq, u64 *nq2, u64 *nqpq2, u64 *q, u8 byt) -{ - u8 byt1; - ladder_smallloop_cmult_small_loop_step(nq, nqpq, nq2, nqpq2, q, byt); - byt1 = byt << 1; - ladder_smallloop_cmult_small_loop_step(nq2, nqpq2, nq, nqpq, q, byt1); -} - -static __always_inline void ladder_smallloop_cmult_small_loop(u64 *nq, u64 *nqpq, u64 *nq2, u64 *nqpq2, u64 *q, u8 byt, u32 i) -{ - while (i--) { - ladder_smallloop_cmult_small_loop_double_step(nq, nqpq, nq2, nqpq2, q, byt); - byt <<= 2; - } -} - -static __always_inline void ladder_bigloop_cmult_big_loop(u8 *n1, u64 *nq, u64 *nqpq, u64 *nq2, u64 *nqpq2, u64 *q, u32 i) -{ - while (i--) { - u8 byte = n1[i]; - ladder_smallloop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byte, 4); - } -} - -static __always_inline void ladder_cmult(u64 *result, u8 *n1, u64 *q) -{ - u64 point_buf[40] = { 0 }; - u64 *nq = point_buf; - u64 *nqpq = point_buf + 10; - u64 *nq2 = point_buf + 20; - u64 *nqpq2 = point_buf + 30; - point_copy(nqpq, q); - nq[0] = 1; - ladder_bigloop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, 32); - point_copy(result, nq); -} - -static __always_inline void format_fexpand(u64 *output, const u8 *input) -{ - const u8 *x00 = input + 6; - const u8 *x01 = input + 12; - const u8 *x02 = input + 19; - const u8 *x0 = input + 24; - u64 i0, i1, i2, i3, i4, output0, output1, output2, output3, output4; - i0 = le64_to_cpup((__force __le64 *)input); - i1 = le64_to_cpup((__force __le64 *)x00); - i2 = le64_to_cpup((__force __le64 *)x01); - i3 = le64_to_cpup((__force __le64 *)x02); - i4 = le64_to_cpup((__force __le64 *)x0); - output0 = i0 & 0x7ffffffffffffLLU; - output1 = i1 >> 3 & 0x7ffffffffffffLLU; - output2 = i2 >> 6 & 0x7ffffffffffffLLU; - output3 = i3 >> 1 & 0x7ffffffffffffLLU; - output4 = i4 >> 12 & 0x7ffffffffffffLLU; - output[0] = output0; - output[1] = output1; - output[2] = output2; - output[3] = output3; - output[4] = output4; -} - -static __always_inline void format_fcontract_first_carry_pass(u64 *input) -{ - u64 t0 = input[0]; - u64 t1 = input[1]; - u64 t2 = input[2]; - u64 t3 = input[3]; - u64 t4 = input[4]; - u64 t1_ = t1 + (t0 >> 51); - u64 t0_ = t0 & 0x7ffffffffffffLLU; - u64 t2_ = t2 + (t1_ >> 51); - u64 t1__ = t1_ & 0x7ffffffffffffLLU; - u64 t3_ = t3 + (t2_ >> 51); - u64 t2__ = t2_ & 0x7ffffffffffffLLU; - u64 t4_ = t4 + (t3_ >> 51); - u64 t3__ = t3_ & 0x7ffffffffffffLLU; - input[0] = t0_; - input[1] = t1__; - input[2] = t2__; - input[3] = t3__; - input[4] = t4_; -} - -static __always_inline void format_fcontract_first_carry_full(u64 *input) -{ - format_fcontract_first_carry_pass(input); - modulo_carry_top(input); -} - -static __always_inline void format_fcontract_second_carry_pass(u64 *input) -{ - u64 t0 = input[0]; - u64 t1 = input[1]; - u64 t2 = input[2]; - u64 t3 = input[3]; - u64 t4 = input[4]; - u64 t1_ = t1 + (t0 >> 51); - u64 t0_ = t0 & 0x7ffffffffffffLLU; - u64 t2_ = t2 + (t1_ >> 51); - u64 t1__ = t1_ & 0x7ffffffffffffLLU; - u64 t3_ = t3 + (t2_ >> 51); - u64 t2__ = t2_ & 0x7ffffffffffffLLU; - u64 t4_ = t4 + (t3_ >> 51); - u64 t3__ = t3_ & 0x7ffffffffffffLLU; - input[0] = t0_; - input[1] = t1__; - input[2] = t2__; - input[3] = t3__; - input[4] = t4_; -} - -static __always_inline void format_fcontract_second_carry_full(u64 *input) -{ - u64 i0; - u64 i1; - u64 i0_; - u64 i1_; - format_fcontract_second_carry_pass(input); - modulo_carry_top(input); - i0 = input[0]; - i1 = input[1]; - i0_ = i0 & 0x7ffffffffffffLLU; - i1_ = i1 + (i0 >> 51); - input[0] = i0_; - input[1] = i1_; -} - -static __always_inline void format_fcontract_trim(u64 *input) -{ - u64 a0 = input[0]; - u64 a1 = input[1]; - u64 a2 = input[2]; - u64 a3 = input[3]; - u64 a4 = input[4]; - u64 mask0 = u64_gte_mask(a0, 0x7ffffffffffedLLU); - u64 mask1 = u64_eq_mask(a1, 0x7ffffffffffffLLU); - u64 mask2 = u64_eq_mask(a2, 0x7ffffffffffffLLU); - u64 mask3 = u64_eq_mask(a3, 0x7ffffffffffffLLU); - u64 mask4 = u64_eq_mask(a4, 0x7ffffffffffffLLU); - u64 mask = (((mask0 & mask1) & mask2) & mask3) & mask4; - u64 a0_ = a0 - (0x7ffffffffffedLLU & mask); - u64 a1_ = a1 - (0x7ffffffffffffLLU & mask); - u64 a2_ = a2 - (0x7ffffffffffffLLU & mask); - u64 a3_ = a3 - (0x7ffffffffffffLLU & mask); - u64 a4_ = a4 - (0x7ffffffffffffLLU & mask); - input[0] = a0_; - input[1] = a1_; - input[2] = a2_; - input[3] = a3_; - input[4] = a4_; -} - -static __always_inline void format_fcontract_store(u8 *output, u64 *input) -{ - u64 t0 = input[0]; - u64 t1 = input[1]; - u64 t2 = input[2]; - u64 t3 = input[3]; - u64 t4 = input[4]; - u64 o0 = t1 << 51 | t0; - u64 o1 = t2 << 38 | t1 >> 13; - u64 o2 = t3 << 25 | t2 >> 26; - u64 o3 = t4 << 12 | t3 >> 39; - u8 *b0 = output; - u8 *b1 = output + 8; - u8 *b2 = output + 16; - u8 *b3 = output + 24; - *(__force __le64 *)b0 = cpu_to_le64(o0); - *(__force __le64 *)b1 = cpu_to_le64(o1); - *(__force __le64 *)b2 = cpu_to_le64(o2); - *(__force __le64 *)b3 = cpu_to_le64(o3); -} - -static __always_inline void format_fcontract(u8 *output, u64 *input) -{ - format_fcontract_first_carry_full(input); - format_fcontract_second_carry_full(input); - format_fcontract_trim(input); - format_fcontract_store(output, input); -} - -static __always_inline void format_scalar_of_point(u8 *scalar, u64 *point) -{ - u64 *x = point; - u64 *z = point + 5; - u64 buf[10] __aligned(32) = { 0 }; - u64 *zmone = buf; - u64 *sc = buf + 5; - crecip(zmone, z); - fmul(sc, x, zmone); - format_fcontract(scalar, sc); -} - -bool curve25519_hacl64(u8 mypublic[CURVE25519_POINT_SIZE], const u8 secret[CURVE25519_POINT_SIZE], const u8 basepoint[CURVE25519_POINT_SIZE]) -{ - u64 buf0[10] __aligned(32) = { 0 }; - u64 *x0 = buf0; - u64 *z = buf0 + 5; - u64 *q; - format_fexpand(x0, basepoint); - z[0] = 1; - q = buf0; - { - u8 e[32] __aligned(32) = { 0 }; - u8 *scalar; - memcpy(e, secret, 32); - normalize_secret(e); - scalar = e; - { - u64 buf[15] = { 0 }; - u64 *nq = buf; - u64 *x = nq; - x[0] = 1; - ladder_cmult(nq, scalar, q); - format_scalar_of_point(mypublic, nq); - } - } - - return true; -} diff --git a/curve25519-neon.S b/curve25519-neon.S new file mode 100644 index 0000000..b8e2c1d --- /dev/null +++ b/curve25519-neon.S @@ -0,0 +1,2110 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2015-2018 Jason A. Donenfeld . All Rights Reserved. + * + * Based on algorithms from Daniel J. Bernstein and Peter Schwabe. + */ + +#if IS_ENABLED(CONFIG_KERNEL_MODE_NEON) + +#include + + .text + .fpu neon + .align 4 + +ENTRY(curve25519_neon) + vpush {q4,q5,q6,q7} + mov r12,sp + sub r3,sp,#736 + and r3,r3,#0xffffffe0 + mov sp,r3 + strd r4,[sp,#0] + strd r6,[sp,#8] + strd r8,[sp,#16] + strd r10,[sp,#24] + str r12,[sp,#480] + str r14,[sp,#484] + mov r0,r0 + mov r1,r1 + mov r2,r2 + add r3,sp,#32 + ldr r4,=0 + ldr r5,=254 + vmov.i32 q0,#1 + vshr.u64 q1,q0,#7 + vshr.u64 q0,q0,#8 + vmov.i32 d4,#19 + vmov.i32 d5,#38 + add r6,sp,#512 + vst1.8 {d2-d3},[r6,: 128] + add r6,sp,#528 + vst1.8 {d0-d1},[r6,: 128] + add r6,sp,#544 + vst1.8 {d4-d5},[r6,: 128] + add r6,r3,#0 + vmov.i32 q2,#0 + vst1.8 {d4-d5},[r6,: 128]! + vst1.8 {d4-d5},[r6,: 128]! + vst1.8 d4,[r6,: 64] + add r6,r3,#0 + ldr r7,=960 + sub r7,r7,#2 + neg r7,r7 + sub r7,r7,r7,LSL #7 + str r7,[r6] + add r6,sp,#704 + vld1.8 {d4-d5},[r1]! + vld1.8 {d6-d7},[r1] + vst1.8 {d4-d5},[r6,: 128]! + vst1.8 {d6-d7},[r6,: 128] + sub r1,r6,#16 + ldrb r6,[r1] + and r6,r6,#248 + strb r6,[r1] + ldrb r6,[r1,#31] + and r6,r6,#127 + orr r6,r6,#64 + strb r6,[r1,#31] + vmov.i64 q2,#0xffffffff + vshr.u64 q3,q2,#7 + vshr.u64 q2,q2,#6 + vld1.8 {d8},[r2] + vld1.8 {d10},[r2] + add r2,r2,#6 + vld1.8 {d12},[r2] + vld1.8 {d14},[r2] + add r2,r2,#6 + vld1.8 {d16},[r2] + add r2,r2,#4 + vld1.8 {d18},[r2] + vld1.8 {d20},[r2] + add r2,r2,#6 + vld1.8 {d22},[r2] + add r2,r2,#2 + vld1.8 {d24},[r2] + vld1.8 {d26},[r2] + vshr.u64 q5,q5,#26 + vshr.u64 q6,q6,#3 + vshr.u64 q7,q7,#29 + vshr.u64 q8,q8,#6 + vshr.u64 q10,q10,#25 + vshr.u64 q11,q11,#3 + vshr.u64 q12,q12,#12 + vshr.u64 q13,q13,#38 + vand q4,q4,q2 + vand q6,q6,q2 + vand q8,q8,q2 + vand q10,q10,q2 + vand q2,q12,q2 + vand q5,q5,q3 + vand q7,q7,q3 + vand q9,q9,q3 + vand q11,q11,q3 + vand q3,q13,q3 + add r2,r3,#48 + vadd.i64 q12,q4,q1 + vadd.i64 q13,q10,q1 + vshr.s64 q12,q12,#26 + vshr.s64 q13,q13,#26 + vadd.i64 q5,q5,q12 + vshl.i64 q12,q12,#26 + vadd.i64 q14,q5,q0 + vadd.i64 q11,q11,q13 + vshl.i64 q13,q13,#26 + vadd.i64 q15,q11,q0 + vsub.i64 q4,q4,q12 + vshr.s64 q12,q14,#25 + vsub.i64 q10,q10,q13 + vshr.s64 q13,q15,#25 + vadd.i64 q6,q6,q12 + vshl.i64 q12,q12,#25 + vadd.i64 q14,q6,q1 + vadd.i64 q2,q2,q13 + vsub.i64 q5,q5,q12 + vshr.s64 q12,q14,#26 + vshl.i64 q13,q13,#25 + vadd.i64 q14,q2,q1 + vadd.i64 q7,q7,q12 + vshl.i64 q12,q12,#26 + vadd.i64 q15,q7,q0 + vsub.i64 q11,q11,q13 + vshr.s64 q13,q14,#26 + vsub.i64 q6,q6,q12 + vshr.s64 q12,q15,#25 + vadd.i64 q3,q3,q13 + vshl.i64 q13,q13,#26 + vadd.i64 q14,q3,q0 + vadd.i64 q8,q8,q12 + vshl.i64 q12,q12,#25 + vadd.i64 q15,q8,q1 + add r2,r2,#8 + vsub.i64 q2,q2,q13 + vshr.s64 q13,q14,#25 + vsub.i64 q7,q7,q12 + vshr.s64 q12,q15,#26 + vadd.i64 q14,q13,q13 + vadd.i64 q9,q9,q12 + vtrn.32 d12,d14 + vshl.i64 q12,q12,#26 + vtrn.32 d13,d15 + vadd.i64 q0,q9,q0 + vadd.i64 q4,q4,q14 + vst1.8 d12,[r2,: 64]! + vshl.i64 q6,q13,#4 + vsub.i64 q7,q8,q12 + vshr.s64 q0,q0,#25 + vadd.i64 q4,q4,q6 + vadd.i64 q6,q10,q0 + vshl.i64 q0,q0,#25 + vadd.i64 q8,q6,q1 + vadd.i64 q4,q4,q13 + vshl.i64 q10,q13,#25 + vadd.i64 q1,q4,q1 + vsub.i64 q0,q9,q0 + vshr.s64 q8,q8,#26 + vsub.i64 q3,q3,q10 + vtrn.32 d14,d0 + vshr.s64 q1,q1,#26 + vtrn.32 d15,d1 + vadd.i64 q0,q11,q8 + vst1.8 d14,[r2,: 64] + vshl.i64 q7,q8,#26 + vadd.i64 q5,q5,q1 + vtrn.32 d4,d6 + vshl.i64 q1,q1,#26 + vtrn.32 d5,d7 + vsub.i64 q3,q6,q7 + add r2,r2,#16 + vsub.i64 q1,q4,q1 + vst1.8 d4,[r2,: 64] + vtrn.32 d6,d0 + vtrn.32 d7,d1 + sub r2,r2,#8 + vtrn.32 d2,d10 + vtrn.32 d3,d11 + vst1.8 d6,[r2,: 64] + sub r2,r2,#24 + vst1.8 d2,[r2,: 64] + add r2,r3,#96 + vmov.i32 q0,#0 + vmov.i64 d2,#0xff + vmov.i64 d3,#0 + vshr.u32 q1,q1,#7 + vst1.8 {d2-d3},[r2,: 128]! + vst1.8 {d0-d1},[r2,: 128]! + vst1.8 d0,[r2,: 64] + add r2,r3,#144 + vmov.i32 q0,#0 + vst1.8 {d0-d1},[r2,: 128]! + vst1.8 {d0-d1},[r2,: 128]! + vst1.8 d0,[r2,: 64] + add r2,r3,#240 + vmov.i32 q0,#0 + vmov.i64 d2,#0xff + vmov.i64 d3,#0 + vshr.u32 q1,q1,#7 + vst1.8 {d2-d3},[r2,: 128]! + vst1.8 {d0-d1},[r2,: 128]! + vst1.8 d0,[r2,: 64] + add r2,r3,#48 + add r6,r3,#192 + vld1.8 {d0-d1},[r2,: 128]! + vld1.8 {d2-d3},[r2,: 128]! + vld1.8 {d4},[r2,: 64] + vst1.8 {d0-d1},[r6,: 128]! + vst1.8 {d2-d3},[r6,: 128]! + vst1.8 d4,[r6,: 64] + .Lmainloop: + mov r2,r5,LSR #3 + and r6,r5,#7 + ldrb r2,[r1,r2] + mov r2,r2,LSR r6 + and r2,r2,#1 + str r5,[sp,#488] + eor r4,r4,r2 + str r2,[sp,#492] + neg r2,r4 + add r4,r3,#96 + add r5,r3,#192 + add r6,r3,#144 + vld1.8 {d8-d9},[r4,: 128]! + add r7,r3,#240 + vld1.8 {d10-d11},[r5,: 128]! + veor q6,q4,q5 + vld1.8 {d14-d15},[r6,: 128]! + vdup.i32 q8,r2 + vld1.8 {d18-d19},[r7,: 128]! + veor q10,q7,q9 + vld1.8 {d22-d23},[r4,: 128]! + vand q6,q6,q8 + vld1.8 {d24-d25},[r5,: 128]! + vand q10,q10,q8 + vld1.8 {d26-d27},[r6,: 128]! + veor q4,q4,q6 + vld1.8 {d28-d29},[r7,: 128]! + veor q5,q5,q6 + vld1.8 {d0},[r4,: 64] + veor q6,q7,q10 + vld1.8 {d2},[r5,: 64] + veor q7,q9,q10 + vld1.8 {d4},[r6,: 64] + veor q9,q11,q12 + vld1.8 {d6},[r7,: 64] + veor q10,q0,q1 + sub r2,r4,#32 + vand q9,q9,q8 + sub r4,r5,#32 + vand q10,q10,q8 + sub r5,r6,#32 + veor q11,q11,q9 + sub r6,r7,#32 + veor q0,q0,q10 + veor q9,q12,q9 + veor q1,q1,q10 + veor q10,q13,q14 + veor q12,q2,q3 + vand q10,q10,q8 + vand q8,q12,q8 + veor q12,q13,q10 + veor q2,q2,q8 + veor q10,q14,q10 + veor q3,q3,q8 + vadd.i32 q8,q4,q6 + vsub.i32 q4,q4,q6 + vst1.8 {d16-d17},[r2,: 128]! + vadd.i32 q6,q11,q12 + vst1.8 {d8-d9},[r5,: 128]! + vsub.i32 q4,q11,q12 + vst1.8 {d12-d13},[r2,: 128]! + vadd.i32 q6,q0,q2 + vst1.8 {d8-d9},[r5,: 128]! + vsub.i32 q0,q0,q2 + vst1.8 d12,[r2,: 64] + vadd.i32 q2,q5,q7 + vst1.8 d0,[r5,: 64] + vsub.i32 q0,q5,q7 + vst1.8 {d4-d5},[r4,: 128]! + vadd.i32 q2,q9,q10 + vst1.8 {d0-d1},[r6,: 128]! + vsub.i32 q0,q9,q10 + vst1.8 {d4-d5},[r4,: 128]! + vadd.i32 q2,q1,q3 + vst1.8 {d0-d1},[r6,: 128]! + vsub.i32 q0,q1,q3 + vst1.8 d4,[r4,: 64] + vst1.8 d0,[r6,: 64] + add r2,sp,#544 + add r4,r3,#96 + add r5,r3,#144 + vld1.8 {d0-d1},[r2,: 128] + vld1.8 {d2-d3},[r4,: 128]! + vld1.8 {d4-d5},[r5,: 128]! + vzip.i32 q1,q2 + vld1.8 {d6-d7},[r4,: 128]! + vld1.8 {d8-d9},[r5,: 128]! + vshl.i32 q5,q1,#1 + vzip.i32 q3,q4 + vshl.i32 q6,q2,#1 + vld1.8 {d14},[r4,: 64] + vshl.i32 q8,q3,#1 + vld1.8 {d15},[r5,: 64] + vshl.i32 q9,q4,#1 + vmul.i32 d21,d7,d1 + vtrn.32 d14,d15 + vmul.i32 q11,q4,q0 + vmul.i32 q0,q7,q0 + vmull.s32 q12,d2,d2 + vmlal.s32 q12,d11,d1 + vmlal.s32 q12,d12,d0 + vmlal.s32 q12,d13,d23 + vmlal.s32 q12,d16,d22 + vmlal.s32 q12,d7,d21 + vmull.s32 q10,d2,d11 + vmlal.s32 q10,d4,d1 + vmlal.s32 q10,d13,d0 + vmlal.s32 q10,d6,d23 + vmlal.s32 q10,d17,d22 + vmull.s32 q13,d10,d4 + vmlal.s32 q13,d11,d3 + vmlal.s32 q13,d13,d1 + vmlal.s32 q13,d16,d0 + vmlal.s32 q13,d17,d23 + vmlal.s32 q13,d8,d22 + vmull.s32 q1,d10,d5 + vmlal.s32 q1,d11,d4 + vmlal.s32 q1,d6,d1 + vmlal.s32 q1,d17,d0 + vmlal.s32 q1,d8,d23 + vmull.s32 q14,d10,d6 + vmlal.s32 q14,d11,d13 + vmlal.s32 q14,d4,d4 + vmlal.s32 q14,d17,d1 + vmlal.s32 q14,d18,d0 + vmlal.s32 q14,d9,d23 + vmull.s32 q11,d10,d7 + vmlal.s32 q11,d11,d6 + vmlal.s32 q11,d12,d5 + vmlal.s32 q11,d8,d1 + vmlal.s32 q11,d19,d0 + vmull.s32 q15,d10,d8 + vmlal.s32 q15,d11,d17 + vmlal.s32 q15,d12,d6 + vmlal.s32 q15,d13,d5 + vmlal.s32 q15,d19,d1 + vmlal.s32 q15,d14,d0 + vmull.s32 q2,d10,d9 + vmlal.s32 q2,d11,d8 + vmlal.s32 q2,d12,d7 + vmlal.s32 q2,d13,d6 + vmlal.s32 q2,d14,d1 + vmull.s32 q0,d15,d1 + vmlal.s32 q0,d10,d14 + vmlal.s32 q0,d11,d19 + vmlal.s32 q0,d12,d8 + vmlal.s32 q0,d13,d17 + vmlal.s32 q0,d6,d6 + add r2,sp,#512 + vld1.8 {d18-d19},[r2,: 128] + vmull.s32 q3,d16,d7 + vmlal.s32 q3,d10,d15 + vmlal.s32 q3,d11,d14 + vmlal.s32 q3,d12,d9 + vmlal.s32 q3,d13,d8 + add r2,sp,#528 + vld1.8 {d8-d9},[r2,: 128] + vadd.i64 q5,q12,q9 + vadd.i64 q6,q15,q9 + vshr.s64 q5,q5,#26 + vshr.s64 q6,q6,#26 + vadd.i64 q7,q10,q5 + vshl.i64 q5,q5,#26 + vadd.i64 q8,q7,q4 + vadd.i64 q2,q2,q6 + vshl.i64 q6,q6,#26 + vadd.i64 q10,q2,q4 + vsub.i64 q5,q12,q5 + vshr.s64 q8,q8,#25 + vsub.i64 q6,q15,q6 + vshr.s64 q10,q10,#25 + vadd.i64 q12,q13,q8 + vshl.i64 q8,q8,#25 + vadd.i64 q13,q12,q9 + vadd.i64 q0,q0,q10 + vsub.i64 q7,q7,q8 + vshr.s64 q8,q13,#26 + vshl.i64 q10,q10,#25 + vadd.i64 q13,q0,q9 + vadd.i64 q1,q1,q8 + vshl.i64 q8,q8,#26 + vadd.i64 q15,q1,q4 + vsub.i64 q2,q2,q10 + vshr.s64 q10,q13,#26 + vsub.i64 q8,q12,q8 + vshr.s64 q12,q15,#25 + vadd.i64 q3,q3,q10 + vshl.i64 q10,q10,#26 + vadd.i64 q13,q3,q4 + vadd.i64 q14,q14,q12 + add r2,r3,#288 + vshl.i64 q12,q12,#25 + add r4,r3,#336 + vadd.i64 q15,q14,q9 + add r2,r2,#8 + vsub.i64 q0,q0,q10 + add r4,r4,#8 + vshr.s64 q10,q13,#25 + vsub.i64 q1,q1,q12 + vshr.s64 q12,q15,#26 + vadd.i64 q13,q10,q10 + vadd.i64 q11,q11,q12 + vtrn.32 d16,d2 + vshl.i64 q12,q12,#26 + vtrn.32 d17,d3 + vadd.i64 q1,q11,q4 + vadd.i64 q4,q5,q13 + vst1.8 d16,[r2,: 64]! + vshl.i64 q5,q10,#4 + vst1.8 d17,[r4,: 64]! + vsub.i64 q8,q14,q12 + vshr.s64 q1,q1,#25 + vadd.i64 q4,q4,q5 + vadd.i64 q5,q6,q1 + vshl.i64 q1,q1,#25 + vadd.i64 q6,q5,q9 + vadd.i64 q4,q4,q10 + vshl.i64 q10,q10,#25 + vadd.i64 q9,q4,q9 + vsub.i64 q1,q11,q1 + vshr.s64 q6,q6,#26 + vsub.i64 q3,q3,q10 + vtrn.32 d16,d2 + vshr.s64 q9,q9,#26 + vtrn.32 d17,d3 + vadd.i64 q1,q2,q6 + vst1.8 d16,[r2,: 64] + vshl.i64 q2,q6,#26 + vst1.8 d17,[r4,: 64] + vadd.i64 q6,q7,q9 + vtrn.32 d0,d6 + vshl.i64 q7,q9,#26 + vtrn.32 d1,d7 + vsub.i64 q2,q5,q2 + add r2,r2,#16 + vsub.i64 q3,q4,q7 + vst1.8 d0,[r2,: 64] + add r4,r4,#16 + vst1.8 d1,[r4,: 64] + vtrn.32 d4,d2 + vtrn.32 d5,d3 + sub r2,r2,#8 + sub r4,r4,#8 + vtrn.32 d6,d12 + vtrn.32 d7,d13 + vst1.8 d4,[r2,: 64] + vst1.8 d5,[r4,: 64] + sub r2,r2,#24 + sub r4,r4,#24 + vst1.8 d6,[r2,: 64] + vst1.8 d7,[r4,: 64] + add r2,r3,#240 + add r4,r3,#96 + vld1.8 {d0-d1},[r4,: 128]! + vld1.8 {d2-d3},[r4,: 128]! + vld1.8 {d4},[r4,: 64] + add r4,r3,#144 + vld1.8 {d6-d7},[r4,: 128]! + vtrn.32 q0,q3 + vld1.8 {d8-d9},[r4,: 128]! + vshl.i32 q5,q0,#4 + vtrn.32 q1,q4 + vshl.i32 q6,q3,#4 + vadd.i32 q5,q5,q0 + vadd.i32 q6,q6,q3 + vshl.i32 q7,q1,#4 + vld1.8 {d5},[r4,: 64] + vshl.i32 q8,q4,#4 + vtrn.32 d4,d5 + vadd.i32 q7,q7,q1 + vadd.i32 q8,q8,q4 + vld1.8 {d18-d19},[r2,: 128]! + vshl.i32 q10,q2,#4 + vld1.8 {d22-d23},[r2,: 128]! + vadd.i32 q10,q10,q2 + vld1.8 {d24},[r2,: 64] + vadd.i32 q5,q5,q0 + add r2,r3,#192 + vld1.8 {d26-d27},[r2,: 128]! + vadd.i32 q6,q6,q3 + vld1.8 {d28-d29},[r2,: 128]! + vadd.i32 q8,q8,q4 + vld1.8 {d25},[r2,: 64] + vadd.i32 q10,q10,q2 + vtrn.32 q9,q13 + vadd.i32 q7,q7,q1 + vadd.i32 q5,q5,q0 + vtrn.32 q11,q14 + vadd.i32 q6,q6,q3 + add r2,sp,#560 + vadd.i32 q10,q10,q2 + vtrn.32 d24,d25 + vst1.8 {d12-d13},[r2,: 128] + vshl.i32 q6,q13,#1 + add r2,sp,#576 + vst1.8 {d20-d21},[r2,: 128] + vshl.i32 q10,q14,#1 + add r2,sp,#592 + vst1.8 {d12-d13},[r2,: 128] + vshl.i32 q15,q12,#1 + vadd.i32 q8,q8,q4 + vext.32 d10,d31,d30,#0 + vadd.i32 q7,q7,q1 + add r2,sp,#608 + vst1.8 {d16-d17},[r2,: 128] + vmull.s32 q8,d18,d5 + vmlal.s32 q8,d26,d4 + vmlal.s32 q8,d19,d9 + vmlal.s32 q8,d27,d3 + vmlal.s32 q8,d22,d8 + vmlal.s32 q8,d28,d2 + vmlal.s32 q8,d23,d7 + vmlal.s32 q8,d29,d1 + vmlal.s32 q8,d24,d6 + vmlal.s32 q8,d25,d0 + add r2,sp,#624 + vst1.8 {d14-d15},[r2,: 128] + vmull.s32 q2,d18,d4 + vmlal.s32 q2,d12,d9 + vmlal.s32 q2,d13,d8 + vmlal.s32 q2,d19,d3 + vmlal.s32 q2,d22,d2 + vmlal.s32 q2,d23,d1 + vmlal.s32 q2,d24,d0 + add r2,sp,#640 + vst1.8 {d20-d21},[r2,: 128] + vmull.s32 q7,d18,d9 + vmlal.s32 q7,d26,d3 + vmlal.s32 q7,d19,d8 + vmlal.s32 q7,d27,d2 + vmlal.s32 q7,d22,d7 + vmlal.s32 q7,d28,d1 + vmlal.s32 q7,d23,d6 + vmlal.s32 q7,d29,d0 + add r2,sp,#656 + vst1.8 {d10-d11},[r2,: 128] + vmull.s32 q5,d18,d3 + vmlal.s32 q5,d19,d2 + vmlal.s32 q5,d22,d1 + vmlal.s32 q5,d23,d0 + vmlal.s32 q5,d12,d8 + add r2,sp,#672 + vst1.8 {d16-d17},[r2,: 128] + vmull.s32 q4,d18,d8 + vmlal.s32 q4,d26,d2 + vmlal.s32 q4,d19,d7 + vmlal.s32 q4,d27,d1 + vmlal.s32 q4,d22,d6 + vmlal.s32 q4,d28,d0 + vmull.s32 q8,d18,d7 + vmlal.s32 q8,d26,d1 + vmlal.s32 q8,d19,d6 + vmlal.s32 q8,d27,d0 + add r2,sp,#576 + vld1.8 {d20-d21},[r2,: 128] + vmlal.s32 q7,d24,d21 + vmlal.s32 q7,d25,d20 + vmlal.s32 q4,d23,d21 + vmlal.s32 q4,d29,d20 + vmlal.s32 q8,d22,d21 + vmlal.s32 q8,d28,d20 + vmlal.s32 q5,d24,d20 + add r2,sp,#576 + vst1.8 {d14-d15},[r2,: 128] + vmull.s32 q7,d18,d6 + vmlal.s32 q7,d26,d0 + add r2,sp,#656 + vld1.8 {d30-d31},[r2,: 128] + vmlal.s32 q2,d30,d21 + vmlal.s32 q7,d19,d21 + vmlal.s32 q7,d27,d20 + add r2,sp,#624 + vld1.8 {d26-d27},[r2,: 128] + vmlal.s32 q4,d25,d27 + vmlal.s32 q8,d29,d27 + vmlal.s32 q8,d25,d26 + vmlal.s32 q7,d28,d27 + vmlal.s32 q7,d29,d26 + add r2,sp,#608 + vld1.8 {d28-d29},[r2,: 128] + vmlal.s32 q4,d24,d29 + vmlal.s32 q8,d23,d29 + vmlal.s32 q8,d24,d28 + vmlal.s32 q7,d22,d29 + vmlal.s32 q7,d23,d28 + add r2,sp,#608 + vst1.8 {d8-d9},[r2,: 128] + add r2,sp,#560 + vld1.8 {d8-d9},[r2,: 128] + vmlal.s32 q7,d24,d9 + vmlal.s32 q7,d25,d31 + vmull.s32 q1,d18,d2 + vmlal.s32 q1,d19,d1 + vmlal.s32 q1,d22,d0 + vmlal.s32 q1,d24,d27 + vmlal.s32 q1,d23,d20 + vmlal.s32 q1,d12,d7 + vmlal.s32 q1,d13,d6 + vmull.s32 q6,d18,d1 + vmlal.s32 q6,d19,d0 + vmlal.s32 q6,d23,d27 + vmlal.s32 q6,d22,d20 + vmlal.s32 q6,d24,d26 + vmull.s32 q0,d18,d0 + vmlal.s32 q0,d22,d27 + vmlal.s32 q0,d23,d26 + vmlal.s32 q0,d24,d31 + vmlal.s32 q0,d19,d20 + add r2,sp,#640 + vld1.8 {d18-d19},[r2,: 128] + vmlal.s32 q2,d18,d7 + vmlal.s32 q2,d19,d6 + vmlal.s32 q5,d18,d6 + vmlal.s32 q5,d19,d21 + vmlal.s32 q1,d18,d21 + vmlal.s32 q1,d19,d29 + vmlal.s32 q0,d18,d28 + vmlal.s32 q0,d19,d9 + vmlal.s32 q6,d18,d29 + vmlal.s32 q6,d19,d28 + add r2,sp,#592 + vld1.8 {d18-d19},[r2,: 128] + add r2,sp,#512 + vld1.8 {d22-d23},[r2,: 128] + vmlal.s32 q5,d19,d7 + vmlal.s32 q0,d18,d21 + vmlal.s32 q0,d19,d29 + vmlal.s32 q6,d18,d6 + add r2,sp,#528 + vld1.8 {d6-d7},[r2,: 128] + vmlal.s32 q6,d19,d21 + add r2,sp,#576 + vld1.8 {d18-d19},[r2,: 128] + vmlal.s32 q0,d30,d8 + add r2,sp,#672 + vld1.8 {d20-d21},[r2,: 128] + vmlal.s32 q5,d30,d29 + add r2,sp,#608 + vld1.8 {d24-d25},[r2,: 128] + vmlal.s32 q1,d30,d28 + vadd.i64 q13,q0,q11 + vadd.i64 q14,q5,q11 + vmlal.s32 q6,d30,d9 + vshr.s64 q4,q13,#26 + vshr.s64 q13,q14,#26 + vadd.i64 q7,q7,q4 + vshl.i64 q4,q4,#26 + vadd.i64 q14,q7,q3 + vadd.i64 q9,q9,q13 + vshl.i64 q13,q13,#26 + vadd.i64 q15,q9,q3 + vsub.i64 q0,q0,q4 + vshr.s64 q4,q14,#25 + vsub.i64 q5,q5,q13 + vshr.s64 q13,q15,#25 + vadd.i64 q6,q6,q4 + vshl.i64 q4,q4,#25 + vadd.i64 q14,q6,q11 + vadd.i64 q2,q2,q13 + vsub.i64 q4,q7,q4 + vshr.s64 q7,q14,#26 + vshl.i64 q13,q13,#25 + vadd.i64 q14,q2,q11 + vadd.i64 q8,q8,q7 + vshl.i64 q7,q7,#26 + vadd.i64 q15,q8,q3 + vsub.i64 q9,q9,q13 + vshr.s64 q13,q14,#26 + vsub.i64 q6,q6,q7 + vshr.s64 q7,q15,#25 + vadd.i64 q10,q10,q13 + vshl.i64 q13,q13,#26 + vadd.i64 q14,q10,q3 + vadd.i64 q1,q1,q7 + add r2,r3,#144 + vshl.i64 q7,q7,#25 + add r4,r3,#96 + vadd.i64 q15,q1,q11 + add r2,r2,#8 + vsub.i64 q2,q2,q13 + add r4,r4,#8 + vshr.s64 q13,q14,#25 + vsub.i64 q7,q8,q7 + vshr.s64 q8,q15,#26 + vadd.i64 q14,q13,q13 + vadd.i64 q12,q12,q8 + vtrn.32 d12,d14 + vshl.i64 q8,q8,#26 + vtrn.32 d13,d15 + vadd.i64 q3,q12,q3 + vadd.i64 q0,q0,q14 + vst1.8 d12,[r2,: 64]! + vshl.i64 q7,q13,#4 + vst1.8 d13,[r4,: 64]! + vsub.i64 q1,q1,q8 + vshr.s64 q3,q3,#25 + vadd.i64 q0,q0,q7 + vadd.i64 q5,q5,q3 + vshl.i64 q3,q3,#25 + vadd.i64 q6,q5,q11 + vadd.i64 q0,q0,q13 + vshl.i64 q7,q13,#25 + vadd.i64 q8,q0,q11 + vsub.i64 q3,q12,q3 + vshr.s64 q6,q6,#26 + vsub.i64 q7,q10,q7 + vtrn.32 d2,d6 + vshr.s64 q8,q8,#26 + vtrn.32 d3,d7 + vadd.i64 q3,q9,q6 + vst1.8 d2,[r2,: 64] + vshl.i64 q6,q6,#26 + vst1.8 d3,[r4,: 64] + vadd.i64 q1,q4,q8 + vtrn.32 d4,d14 + vshl.i64 q4,q8,#26 + vtrn.32 d5,d15 + vsub.i64 q5,q5,q6 + add r2,r2,#16 + vsub.i64 q0,q0,q4 + vst1.8 d4,[r2,: 64] + add r4,r4,#16 + vst1.8 d5,[r4,: 64] + vtrn.32 d10,d6 + vtrn.32 d11,d7 + sub r2,r2,#8 + sub r4,r4,#8 + vtrn.32 d0,d2 + vtrn.32 d1,d3 + vst1.8 d10,[r2,: 64] + vst1.8 d11,[r4,: 64] + sub r2,r2,#24 + sub r4,r4,#24 + vst1.8 d0,[r2,: 64] + vst1.8 d1,[r4,: 64] + add r2,r3,#288 + add r4,r3,#336 + vld1.8 {d0-d1},[r2,: 128]! + vld1.8 {d2-d3},[r4,: 128]! + vsub.i32 q0,q0,q1 + vld1.8 {d2-d3},[r2,: 128]! + vld1.8 {d4-d5},[r4,: 128]! + vsub.i32 q1,q1,q2 + add r5,r3,#240 + vld1.8 {d4},[r2,: 64] + vld1.8 {d6},[r4,: 64] + vsub.i32 q2,q2,q3 + vst1.8 {d0-d1},[r5,: 128]! + vst1.8 {d2-d3},[r5,: 128]! + vst1.8 d4,[r5,: 64] + add r2,r3,#144 + add r4,r3,#96 + add r5,r3,#144 + add r6,r3,#192 + vld1.8 {d0-d1},[r2,: 128]! + vld1.8 {d2-d3},[r4,: 128]! + vsub.i32 q2,q0,q1 + vadd.i32 q0,q0,q1 + vld1.8 {d2-d3},[r2,: 128]! + vld1.8 {d6-d7},[r4,: 128]! + vsub.i32 q4,q1,q3 + vadd.i32 q1,q1,q3 + vld1.8 {d6},[r2,: 64] + vld1.8 {d10},[r4,: 64] + vsub.i32 q6,q3,q5 + vadd.i32 q3,q3,q5 + vst1.8 {d4-d5},[r5,: 128]! + vst1.8 {d0-d1},[r6,: 128]! + vst1.8 {d8-d9},[r5,: 128]! + vst1.8 {d2-d3},[r6,: 128]! + vst1.8 d12,[r5,: 64] + vst1.8 d6,[r6,: 64] + add r2,r3,#0 + add r4,r3,#240 + vld1.8 {d0-d1},[r4,: 128]! + vld1.8 {d2-d3},[r4,: 128]! + vld1.8 {d4},[r4,: 64] + add r4,r3,#336 + vld1.8 {d6-d7},[r4,: 128]! + vtrn.32 q0,q3 + vld1.8 {d8-d9},[r4,: 128]! + vshl.i32 q5,q0,#4 + vtrn.32 q1,q4 + vshl.i32 q6,q3,#4 + vadd.i32 q5,q5,q0 + vadd.i32 q6,q6,q3 + vshl.i32 q7,q1,#4 + vld1.8 {d5},[r4,: 64] + vshl.i32 q8,q4,#4 + vtrn.32 d4,d5 + vadd.i32 q7,q7,q1 + vadd.i32 q8,q8,q4 + vld1.8 {d18-d19},[r2,: 128]! + vshl.i32 q10,q2,#4 + vld1.8 {d22-d23},[r2,: 128]! + vadd.i32 q10,q10,q2 + vld1.8 {d24},[r2,: 64] + vadd.i32 q5,q5,q0 + add r2,r3,#288 + vld1.8 {d26-d27},[r2,: 128]! + vadd.i32 q6,q6,q3 + vld1.8 {d28-d29},[r2,: 128]! + vadd.i32 q8,q8,q4 + vld1.8 {d25},[r2,: 64] + vadd.i32 q10,q10,q2 + vtrn.32 q9,q13 + vadd.i32 q7,q7,q1 + vadd.i32 q5,q5,q0 + vtrn.32 q11,q14 + vadd.i32 q6,q6,q3 + add r2,sp,#560 + vadd.i32 q10,q10,q2 + vtrn.32 d24,d25 + vst1.8 {d12-d13},[r2,: 128] + vshl.i32 q6,q13,#1 + add r2,sp,#576 + vst1.8 {d20-d21},[r2,: 128] + vshl.i32 q10,q14,#1 + add r2,sp,#592 + vst1.8 {d12-d13},[r2,: 128] + vshl.i32 q15,q12,#1 + vadd.i32 q8,q8,q4 + vext.32 d10,d31,d30,#0 + vadd.i32 q7,q7,q1 + add r2,sp,#608 + vst1.8 {d16-d17},[r2,: 128] + vmull.s32 q8,d18,d5 + vmlal.s32 q8,d26,d4 + vmlal.s32 q8,d19,d9 + vmlal.s32 q8,d27,d3 + vmlal.s32 q8,d22,d8 + vmlal.s32 q8,d28,d2 + vmlal.s32 q8,d23,d7 + vmlal.s32 q8,d29,d1 + vmlal.s32 q8,d24,d6 + vmlal.s32 q8,d25,d0 + add r2,sp,#624 + vst1.8 {d14-d15},[r2,: 128] + vmull.s32 q2,d18,d4 + vmlal.s32 q2,d12,d9 + vmlal.s32 q2,d13,d8 + vmlal.s32 q2,d19,d3 + vmlal.s32 q2,d22,d2 + vmlal.s32 q2,d23,d1 + vmlal.s32 q2,d24,d0 + add r2,sp,#640 + vst1.8 {d20-d21},[r2,: 128] + vmull.s32 q7,d18,d9 + vmlal.s32 q7,d26,d3 + vmlal.s32 q7,d19,d8 + vmlal.s32 q7,d27,d2 + vmlal.s32 q7,d22,d7 + vmlal.s32 q7,d28,d1 + vmlal.s32 q7,d23,d6 + vmlal.s32 q7,d29,d0 + add r2,sp,#656 + vst1.8 {d10-d11},[r2,: 128] + vmull.s32 q5,d18,d3 + vmlal.s32 q5,d19,d2 + vmlal.s32 q5,d22,d1 + vmlal.s32 q5,d23,d0 + vmlal.s32 q5,d12,d8 + add r2,sp,#672 + vst1.8 {d16-d17},[r2,: 128] + vmull.s32 q4,d18,d8 + vmlal.s32 q4,d26,d2 + vmlal.s32 q4,d19,d7 + vmlal.s32 q4,d27,d1 + vmlal.s32 q4,d22,d6 + vmlal.s32 q4,d28,d0 + vmull.s32 q8,d18,d7 + vmlal.s32 q8,d26,d1 + vmlal.s32 q8,d19,d6 + vmlal.s32 q8,d27,d0 + add r2,sp,#576 + vld1.8 {d20-d21},[r2,: 128] + vmlal.s32 q7,d24,d21 + vmlal.s32 q7,d25,d20 + vmlal.s32 q4,d23,d21 + vmlal.s32 q4,d29,d20 + vmlal.s32 q8,d22,d21 + vmlal.s32 q8,d28,d20 + vmlal.s32 q5,d24,d20 + add r2,sp,#576 + vst1.8 {d14-d15},[r2,: 128] + vmull.s32 q7,d18,d6 + vmlal.s32 q7,d26,d0 + add r2,sp,#656 + vld1.8 {d30-d31},[r2,: 128] + vmlal.s32 q2,d30,d21 + vmlal.s32 q7,d19,d21 + vmlal.s32 q7,d27,d20 + add r2,sp,#624 + vld1.8 {d26-d27},[r2,: 128] + vmlal.s32 q4,d25,d27 + vmlal.s32 q8,d29,d27 + vmlal.s32 q8,d25,d26 + vmlal.s32 q7,d28,d27 + vmlal.s32 q7,d29,d26 + add r2,sp,#608 + vld1.8 {d28-d29},[r2,: 128] + vmlal.s32 q4,d24,d29 + vmlal.s32 q8,d23,d29 + vmlal.s32 q8,d24,d28 + vmlal.s32 q7,d22,d29 + vmlal.s32 q7,d23,d28 + add r2,sp,#608 + vst1.8 {d8-d9},[r2,: 128] + add r2,sp,#560 + vld1.8 {d8-d9},[r2,: 128] + vmlal.s32 q7,d24,d9 + vmlal.s32 q7,d25,d31 + vmull.s32 q1,d18,d2 + vmlal.s32 q1,d19,d1 + vmlal.s32 q1,d22,d0 + vmlal.s32 q1,d24,d27 + vmlal.s32 q1,d23,d20 + vmlal.s32 q1,d12,d7 + vmlal.s32 q1,d13,d6 + vmull.s32 q6,d18,d1 + vmlal.s32 q6,d19,d0 + vmlal.s32 q6,d23,d27 + vmlal.s32 q6,d22,d20 + vmlal.s32 q6,d24,d26 + vmull.s32 q0,d18,d0 + vmlal.s32 q0,d22,d27 + vmlal.s32 q0,d23,d26 + vmlal.s32 q0,d24,d31 + vmlal.s32 q0,d19,d20 + add r2,sp,#640 + vld1.8 {d18-d19},[r2,: 128] + vmlal.s32 q2,d18,d7 + vmlal.s32 q2,d19,d6 + vmlal.s32 q5,d18,d6 + vmlal.s32 q5,d19,d21 + vmlal.s32 q1,d18,d21 + vmlal.s32 q1,d19,d29 + vmlal.s32 q0,d18,d28 + vmlal.s32 q0,d19,d9 + vmlal.s32 q6,d18,d29 + vmlal.s32 q6,d19,d28 + add r2,sp,#592 + vld1.8 {d18-d19},[r2,: 128] + add r2,sp,#512 + vld1.8 {d22-d23},[r2,: 128] + vmlal.s32 q5,d19,d7 + vmlal.s32 q0,d18,d21 + vmlal.s32 q0,d19,d29 + vmlal.s32 q6,d18,d6 + add r2,sp,#528 + vld1.8 {d6-d7},[r2,: 128] + vmlal.s32 q6,d19,d21 + add r2,sp,#576 + vld1.8 {d18-d19},[r2,: 128] + vmlal.s32 q0,d30,d8 + add r2,sp,#672 + vld1.8 {d20-d21},[r2,: 128] + vmlal.s32 q5,d30,d29 + add r2,sp,#608 + vld1.8 {d24-d25},[r2,: 128] + vmlal.s32 q1,d30,d28 + vadd.i64 q13,q0,q11 + vadd.i64 q14,q5,q11 + vmlal.s32 q6,d30,d9 + vshr.s64 q4,q13,#26 + vshr.s64 q13,q14,#26 + vadd.i64 q7,q7,q4 + vshl.i64 q4,q4,#26 + vadd.i64 q14,q7,q3 + vadd.i64 q9,q9,q13 + vshl.i64 q13,q13,#26 + vadd.i64 q15,q9,q3 + vsub.i64 q0,q0,q4 + vshr.s64 q4,q14,#25 + vsub.i64 q5,q5,q13 + vshr.s64 q13,q15,#25 + vadd.i64 q6,q6,q4 + vshl.i64 q4,q4,#25 + vadd.i64 q14,q6,q11 + vadd.i64 q2,q2,q13 + vsub.i64 q4,q7,q4 + vshr.s64 q7,q14,#26 + vshl.i64 q13,q13,#25 + vadd.i64 q14,q2,q11 + vadd.i64 q8,q8,q7 + vshl.i64 q7,q7,#26 + vadd.i64 q15,q8,q3 + vsub.i64 q9,q9,q13 + vshr.s64 q13,q14,#26 + vsub.i64 q6,q6,q7 + vshr.s64 q7,q15,#25 + vadd.i64 q10,q10,q13 + vshl.i64 q13,q13,#26 + vadd.i64 q14,q10,q3 + vadd.i64 q1,q1,q7 + add r2,r3,#288 + vshl.i64 q7,q7,#25 + add r4,r3,#96 + vadd.i64 q15,q1,q11 + add r2,r2,#8 + vsub.i64 q2,q2,q13 + add r4,r4,#8 + vshr.s64 q13,q14,#25 + vsub.i64 q7,q8,q7 + vshr.s64 q8,q15,#26 + vadd.i64 q14,q13,q13 + vadd.i64 q12,q12,q8 + vtrn.32 d12,d14 + vshl.i64 q8,q8,#26 + vtrn.32 d13,d15 + vadd.i64 q3,q12,q3 + vadd.i64 q0,q0,q14 + vst1.8 d12,[r2,: 64]! + vshl.i64 q7,q13,#4 + vst1.8 d13,[r4,: 64]! + vsub.i64 q1,q1,q8 + vshr.s64 q3,q3,#25 + vadd.i64 q0,q0,q7 + vadd.i64 q5,q5,q3 + vshl.i64 q3,q3,#25 + vadd.i64 q6,q5,q11 + vadd.i64 q0,q0,q13 + vshl.i64 q7,q13,#25 + vadd.i64 q8,q0,q11 + vsub.i64 q3,q12,q3 + vshr.s64 q6,q6,#26 + vsub.i64 q7,q10,q7 + vtrn.32 d2,d6 + vshr.s64 q8,q8,#26 + vtrn.32 d3,d7 + vadd.i64 q3,q9,q6 + vst1.8 d2,[r2,: 64] + vshl.i64 q6,q6,#26 + vst1.8 d3,[r4,: 64] + vadd.i64 q1,q4,q8 + vtrn.32 d4,d14 + vshl.i64 q4,q8,#26 + vtrn.32 d5,d15 + vsub.i64 q5,q5,q6 + add r2,r2,#16 + vsub.i64 q0,q0,q4 + vst1.8 d4,[r2,: 64] + add r4,r4,#16 + vst1.8 d5,[r4,: 64] + vtrn.32 d10,d6 + vtrn.32 d11,d7 + sub r2,r2,#8 + sub r4,r4,#8 + vtrn.32 d0,d2 + vtrn.32 d1,d3 + vst1.8 d10,[r2,: 64] + vst1.8 d11,[r4,: 64] + sub r2,r2,#24 + sub r4,r4,#24 + vst1.8 d0,[r2,: 64] + vst1.8 d1,[r4,: 64] + add r2,sp,#544 + add r4,r3,#144 + add r5,r3,#192 + vld1.8 {d0-d1},[r2,: 128] + vld1.8 {d2-d3},[r4,: 128]! + vld1.8 {d4-d5},[r5,: 128]! + vzip.i32 q1,q2 + vld1.8 {d6-d7},[r4,: 128]! + vld1.8 {d8-d9},[r5,: 128]! + vshl.i32 q5,q1,#1 + vzip.i32 q3,q4 + vshl.i32 q6,q2,#1 + vld1.8 {d14},[r4,: 64] + vshl.i32 q8,q3,#1 + vld1.8 {d15},[r5,: 64] + vshl.i32 q9,q4,#1 + vmul.i32 d21,d7,d1 + vtrn.32 d14,d15 + vmul.i32 q11,q4,q0 + vmul.i32 q0,q7,q0 + vmull.s32 q12,d2,d2 + vmlal.s32 q12,d11,d1 + vmlal.s32 q12,d12,d0 + vmlal.s32 q12,d13,d23 + vmlal.s32 q12,d16,d22 + vmlal.s32 q12,d7,d21 + vmull.s32 q10,d2,d11 + vmlal.s32 q10,d4,d1 + vmlal.s32 q10,d13,d0 + vmlal.s32 q10,d6,d23 + vmlal.s32 q10,d17,d22 + vmull.s32 q13,d10,d4 + vmlal.s32 q13,d11,d3 + vmlal.s32 q13,d13,d1 + vmlal.s32 q13,d16,d0 + vmlal.s32 q13,d17,d23 + vmlal.s32 q13,d8,d22 + vmull.s32 q1,d10,d5 + vmlal.s32 q1,d11,d4 + vmlal.s32 q1,d6,d1 + vmlal.s32 q1,d17,d0 + vmlal.s32 q1,d8,d23 + vmull.s32 q14,d10,d6 + vmlal.s32 q14,d11,d13 + vmlal.s32 q14,d4,d4 + vmlal.s32 q14,d17,d1 + vmlal.s32 q14,d18,d0 + vmlal.s32 q14,d9,d23 + vmull.s32 q11,d10,d7 + vmlal.s32 q11,d11,d6 + vmlal.s32 q11,d12,d5 + vmlal.s32 q11,d8,d1 + vmlal.s32 q11,d19,d0 + vmull.s32 q15,d10,d8 + vmlal.s32 q15,d11,d17 + vmlal.s32 q15,d12,d6 + vmlal.s32 q15,d13,d5 + vmlal.s32 q15,d19,d1 + vmlal.s32 q15,d14,d0 + vmull.s32 q2,d10,d9 + vmlal.s32 q2,d11,d8 + vmlal.s32 q2,d12,d7 + vmlal.s32 q2,d13,d6 + vmlal.s32 q2,d14,d1 + vmull.s32 q0,d15,d1 + vmlal.s32 q0,d10,d14 + vmlal.s32 q0,d11,d19 + vmlal.s32 q0,d12,d8 + vmlal.s32 q0,d13,d17 + vmlal.s32 q0,d6,d6 + add r2,sp,#512 + vld1.8 {d18-d19},[r2,: 128] + vmull.s32 q3,d16,d7 + vmlal.s32 q3,d10,d15 + vmlal.s32 q3,d11,d14 + vmlal.s32 q3,d12,d9 + vmlal.s32 q3,d13,d8 + add r2,sp,#528 + vld1.8 {d8-d9},[r2,: 128] + vadd.i64 q5,q12,q9 + vadd.i64 q6,q15,q9 + vshr.s64 q5,q5,#26 + vshr.s64 q6,q6,#26 + vadd.i64 q7,q10,q5 + vshl.i64 q5,q5,#26 + vadd.i64 q8,q7,q4 + vadd.i64 q2,q2,q6 + vshl.i64 q6,q6,#26 + vadd.i64 q10,q2,q4 + vsub.i64 q5,q12,q5 + vshr.s64 q8,q8,#25 + vsub.i64 q6,q15,q6 + vshr.s64 q10,q10,#25 + vadd.i64 q12,q13,q8 + vshl.i64 q8,q8,#25 + vadd.i64 q13,q12,q9 + vadd.i64 q0,q0,q10 + vsub.i64 q7,q7,q8 + vshr.s64 q8,q13,#26 + vshl.i64 q10,q10,#25 + vadd.i64 q13,q0,q9 + vadd.i64 q1,q1,q8 + vshl.i64 q8,q8,#26 + vadd.i64 q15,q1,q4 + vsub.i64 q2,q2,q10 + vshr.s64 q10,q13,#26 + vsub.i64 q8,q12,q8 + vshr.s64 q12,q15,#25 + vadd.i64 q3,q3,q10 + vshl.i64 q10,q10,#26 + vadd.i64 q13,q3,q4 + vadd.i64 q14,q14,q12 + add r2,r3,#144 + vshl.i64 q12,q12,#25 + add r4,r3,#192 + vadd.i64 q15,q14,q9 + add r2,r2,#8 + vsub.i64 q0,q0,q10 + add r4,r4,#8 + vshr.s64 q10,q13,#25 + vsub.i64 q1,q1,q12 + vshr.s64 q12,q15,#26 + vadd.i64 q13,q10,q10 + vadd.i64 q11,q11,q12 + vtrn.32 d16,d2 + vshl.i64 q12,q12,#26 + vtrn.32 d17,d3 + vadd.i64 q1,q11,q4 + vadd.i64 q4,q5,q13 + vst1.8 d16,[r2,: 64]! + vshl.i64 q5,q10,#4 + vst1.8 d17,[r4,: 64]! + vsub.i64 q8,q14,q12 + vshr.s64 q1,q1,#25 + vadd.i64 q4,q4,q5 + vadd.i64 q5,q6,q1 + vshl.i64 q1,q1,#25 + vadd.i64 q6,q5,q9 + vadd.i64 q4,q4,q10 + vshl.i64 q10,q10,#25 + vadd.i64 q9,q4,q9 + vsub.i64 q1,q11,q1 + vshr.s64 q6,q6,#26 + vsub.i64 q3,q3,q10 + vtrn.32 d16,d2 + vshr.s64 q9,q9,#26 + vtrn.32 d17,d3 + vadd.i64 q1,q2,q6 + vst1.8 d16,[r2,: 64] + vshl.i64 q2,q6,#26 + vst1.8 d17,[r4,: 64] + vadd.i64 q6,q7,q9 + vtrn.32 d0,d6 + vshl.i64 q7,q9,#26 + vtrn.32 d1,d7 + vsub.i64 q2,q5,q2 + add r2,r2,#16 + vsub.i64 q3,q4,q7 + vst1.8 d0,[r2,: 64] + add r4,r4,#16 + vst1.8 d1,[r4,: 64] + vtrn.32 d4,d2 + vtrn.32 d5,d3 + sub r2,r2,#8 + sub r4,r4,#8 + vtrn.32 d6,d12 + vtrn.32 d7,d13 + vst1.8 d4,[r2,: 64] + vst1.8 d5,[r4,: 64] + sub r2,r2,#24 + sub r4,r4,#24 + vst1.8 d6,[r2,: 64] + vst1.8 d7,[r4,: 64] + add r2,r3,#336 + add r4,r3,#288 + vld1.8 {d0-d1},[r2,: 128]! + vld1.8 {d2-d3},[r4,: 128]! + vadd.i32 q0,q0,q1 + vld1.8 {d2-d3},[r2,: 128]! + vld1.8 {d4-d5},[r4,: 128]! + vadd.i32 q1,q1,q2 + add r5,r3,#288 + vld1.8 {d4},[r2,: 64] + vld1.8 {d6},[r4,: 64] + vadd.i32 q2,q2,q3 + vst1.8 {d0-d1},[r5,: 128]! + vst1.8 {d2-d3},[r5,: 128]! + vst1.8 d4,[r5,: 64] + add r2,r3,#48 + add r4,r3,#144 + vld1.8 {d0-d1},[r4,: 128]! + vld1.8 {d2-d3},[r4,: 128]! + vld1.8 {d4},[r4,: 64] + add r4,r3,#288 + vld1.8 {d6-d7},[r4,: 128]! + vtrn.32 q0,q3 + vld1.8 {d8-d9},[r4,: 128]! + vshl.i32 q5,q0,#4 + vtrn.32 q1,q4 + vshl.i32 q6,q3,#4 + vadd.i32 q5,q5,q0 + vadd.i32 q6,q6,q3 + vshl.i32 q7,q1,#4 + vld1.8 {d5},[r4,: 64] + vshl.i32 q8,q4,#4 + vtrn.32 d4,d5 + vadd.i32 q7,q7,q1 + vadd.i32 q8,q8,q4 + vld1.8 {d18-d19},[r2,: 128]! + vshl.i32 q10,q2,#4 + vld1.8 {d22-d23},[r2,: 128]! + vadd.i32 q10,q10,q2 + vld1.8 {d24},[r2,: 64] + vadd.i32 q5,q5,q0 + add r2,r3,#240 + vld1.8 {d26-d27},[r2,: 128]! + vadd.i32 q6,q6,q3 + vld1.8 {d28-d29},[r2,: 128]! + vadd.i32 q8,q8,q4 + vld1.8 {d25},[r2,: 64] + vadd.i32 q10,q10,q2 + vtrn.32 q9,q13 + vadd.i32 q7,q7,q1 + vadd.i32 q5,q5,q0 + vtrn.32 q11,q14 + vadd.i32 q6,q6,q3 + add r2,sp,#560 + vadd.i32 q10,q10,q2 + vtrn.32 d24,d25 + vst1.8 {d12-d13},[r2,: 128] + vshl.i32 q6,q13,#1 + add r2,sp,#576 + vst1.8 {d20-d21},[r2,: 128] + vshl.i32 q10,q14,#1 + add r2,sp,#592 + vst1.8 {d12-d13},[r2,: 128] + vshl.i32 q15,q12,#1 + vadd.i32 q8,q8,q4 + vext.32 d10,d31,d30,#0 + vadd.i32 q7,q7,q1 + add r2,sp,#608 + vst1.8 {d16-d17},[r2,: 128] + vmull.s32 q8,d18,d5 + vmlal.s32 q8,d26,d4 + vmlal.s32 q8,d19,d9 + vmlal.s32 q8,d27,d3 + vmlal.s32 q8,d22,d8 + vmlal.s32 q8,d28,d2 + vmlal.s32 q8,d23,d7 + vmlal.s32 q8,d29,d1 + vmlal.s32 q8,d24,d6 + vmlal.s32 q8,d25,d0 + add r2,sp,#624 + vst1.8 {d14-d15},[r2,: 128] + vmull.s32 q2,d18,d4 + vmlal.s32 q2,d12,d9 + vmlal.s32 q2,d13,d8 + vmlal.s32 q2,d19,d3 + vmlal.s32 q2,d22,d2 + vmlal.s32 q2,d23,d1 + vmlal.s32 q2,d24,d0 + add r2,sp,#640 + vst1.8 {d20-d21},[r2,: 128] + vmull.s32 q7,d18,d9 + vmlal.s32 q7,d26,d3 + vmlal.s32 q7,d19,d8 + vmlal.s32 q7,d27,d2 + vmlal.s32 q7,d22,d7 + vmlal.s32 q7,d28,d1 + vmlal.s32 q7,d23,d6 + vmlal.s32 q7,d29,d0 + add r2,sp,#656 + vst1.8 {d10-d11},[r2,: 128] + vmull.s32 q5,d18,d3 + vmlal.s32 q5,d19,d2 + vmlal.s32 q5,d22,d1 + vmlal.s32 q5,d23,d0 + vmlal.s32 q5,d12,d8 + add r2,sp,#672 + vst1.8 {d16-d17},[r2,: 128] + vmull.s32 q4,d18,d8 + vmlal.s32 q4,d26,d2 + vmlal.s32 q4,d19,d7 + vmlal.s32 q4,d27,d1 + vmlal.s32 q4,d22,d6 + vmlal.s32 q4,d28,d0 + vmull.s32 q8,d18,d7 + vmlal.s32 q8,d26,d1 + vmlal.s32 q8,d19,d6 + vmlal.s32 q8,d27,d0 + add r2,sp,#576 + vld1.8 {d20-d21},[r2,: 128] + vmlal.s32 q7,d24,d21 + vmlal.s32 q7,d25,d20 + vmlal.s32 q4,d23,d21 + vmlal.s32 q4,d29,d20 + vmlal.s32 q8,d22,d21 + vmlal.s32 q8,d28,d20 + vmlal.s32 q5,d24,d20 + add r2,sp,#576 + vst1.8 {d14-d15},[r2,: 128] + vmull.s32 q7,d18,d6 + vmlal.s32 q7,d26,d0 + add r2,sp,#656 + vld1.8 {d30-d31},[r2,: 128] + vmlal.s32 q2,d30,d21 + vmlal.s32 q7,d19,d21 + vmlal.s32 q7,d27,d20 + add r2,sp,#624 + vld1.8 {d26-d27},[r2,: 128] + vmlal.s32 q4,d25,d27 + vmlal.s32 q8,d29,d27 + vmlal.s32 q8,d25,d26 + vmlal.s32 q7,d28,d27 + vmlal.s32 q7,d29,d26 + add r2,sp,#608 + vld1.8 {d28-d29},[r2,: 128] + vmlal.s32 q4,d24,d29 + vmlal.s32 q8,d23,d29 + vmlal.s32 q8,d24,d28 + vmlal.s32 q7,d22,d29 + vmlal.s32 q7,d23,d28 + add r2,sp,#608 + vst1.8 {d8-d9},[r2,: 128] + add r2,sp,#560 + vld1.8 {d8-d9},[r2,: 128] + vmlal.s32 q7,d24,d9 + vmlal.s32 q7,d25,d31 + vmull.s32 q1,d18,d2 + vmlal.s32 q1,d19,d1 + vmlal.s32 q1,d22,d0 + vmlal.s32 q1,d24,d27 + vmlal.s32 q1,d23,d20 + vmlal.s32 q1,d12,d7 + vmlal.s32 q1,d13,d6 + vmull.s32 q6,d18,d1 + vmlal.s32 q6,d19,d0 + vmlal.s32 q6,d23,d27 + vmlal.s32 q6,d22,d20 + vmlal.s32 q6,d24,d26 + vmull.s32 q0,d18,d0 + vmlal.s32 q0,d22,d27 + vmlal.s32 q0,d23,d26 + vmlal.s32 q0,d24,d31 + vmlal.s32 q0,d19,d20 + add r2,sp,#640 + vld1.8 {d18-d19},[r2,: 128] + vmlal.s32 q2,d18,d7 + vmlal.s32 q2,d19,d6 + vmlal.s32 q5,d18,d6 + vmlal.s32 q5,d19,d21 + vmlal.s32 q1,d18,d21 + vmlal.s32 q1,d19,d29 + vmlal.s32 q0,d18,d28 + vmlal.s32 q0,d19,d9 + vmlal.s32 q6,d18,d29 + vmlal.s32 q6,d19,d28 + add r2,sp,#592 + vld1.8 {d18-d19},[r2,: 128] + add r2,sp,#512 + vld1.8 {d22-d23},[r2,: 128] + vmlal.s32 q5,d19,d7 + vmlal.s32 q0,d18,d21 + vmlal.s32 q0,d19,d29 + vmlal.s32 q6,d18,d6 + add r2,sp,#528 + vld1.8 {d6-d7},[r2,: 128] + vmlal.s32 q6,d19,d21 + add r2,sp,#576 + vld1.8 {d18-d19},[r2,: 128] + vmlal.s32 q0,d30,d8 + add r2,sp,#672 + vld1.8 {d20-d21},[r2,: 128] + vmlal.s32 q5,d30,d29 + add r2,sp,#608 + vld1.8 {d24-d25},[r2,: 128] + vmlal.s32 q1,d30,d28 + vadd.i64 q13,q0,q11 + vadd.i64 q14,q5,q11 + vmlal.s32 q6,d30,d9 + vshr.s64 q4,q13,#26 + vshr.s64 q13,q14,#26 + vadd.i64 q7,q7,q4 + vshl.i64 q4,q4,#26 + vadd.i64 q14,q7,q3 + vadd.i64 q9,q9,q13 + vshl.i64 q13,q13,#26 + vadd.i64 q15,q9,q3 + vsub.i64 q0,q0,q4 + vshr.s64 q4,q14,#25 + vsub.i64 q5,q5,q13 + vshr.s64 q13,q15,#25 + vadd.i64 q6,q6,q4 + vshl.i64 q4,q4,#25 + vadd.i64 q14,q6,q11 + vadd.i64 q2,q2,q13 + vsub.i64 q4,q7,q4 + vshr.s64 q7,q14,#26 + vshl.i64 q13,q13,#25 + vadd.i64 q14,q2,q11 + vadd.i64 q8,q8,q7 + vshl.i64 q7,q7,#26 + vadd.i64 q15,q8,q3 + vsub.i64 q9,q9,q13 + vshr.s64 q13,q14,#26 + vsub.i64 q6,q6,q7 + vshr.s64 q7,q15,#25 + vadd.i64 q10,q10,q13 + vshl.i64 q13,q13,#26 + vadd.i64 q14,q10,q3 + vadd.i64 q1,q1,q7 + add r2,r3,#240 + vshl.i64 q7,q7,#25 + add r4,r3,#144 + vadd.i64 q15,q1,q11 + add r2,r2,#8 + vsub.i64 q2,q2,q13 + add r4,r4,#8 + vshr.s64 q13,q14,#25 + vsub.i64 q7,q8,q7 + vshr.s64 q8,q15,#26 + vadd.i64 q14,q13,q13 + vadd.i64 q12,q12,q8 + vtrn.32 d12,d14 + vshl.i64 q8,q8,#26 + vtrn.32 d13,d15 + vadd.i64 q3,q12,q3 + vadd.i64 q0,q0,q14 + vst1.8 d12,[r2,: 64]! + vshl.i64 q7,q13,#4 + vst1.8 d13,[r4,: 64]! + vsub.i64 q1,q1,q8 + vshr.s64 q3,q3,#25 + vadd.i64 q0,q0,q7 + vadd.i64 q5,q5,q3 + vshl.i64 q3,q3,#25 + vadd.i64 q6,q5,q11 + vadd.i64 q0,q0,q13 + vshl.i64 q7,q13,#25 + vadd.i64 q8,q0,q11 + vsub.i64 q3,q12,q3 + vshr.s64 q6,q6,#26 + vsub.i64 q7,q10,q7 + vtrn.32 d2,d6 + vshr.s64 q8,q8,#26 + vtrn.32 d3,d7 + vadd.i64 q3,q9,q6 + vst1.8 d2,[r2,: 64] + vshl.i64 q6,q6,#26 + vst1.8 d3,[r4,: 64] + vadd.i64 q1,q4,q8 + vtrn.32 d4,d14 + vshl.i64 q4,q8,#26 + vtrn.32 d5,d15 + vsub.i64 q5,q5,q6 + add r2,r2,#16 + vsub.i64 q0,q0,q4 + vst1.8 d4,[r2,: 64] + add r4,r4,#16 + vst1.8 d5,[r4,: 64] + vtrn.32 d10,d6 + vtrn.32 d11,d7 + sub r2,r2,#8 + sub r4,r4,#8 + vtrn.32 d0,d2 + vtrn.32 d1,d3 + vst1.8 d10,[r2,: 64] + vst1.8 d11,[r4,: 64] + sub r2,r2,#24 + sub r4,r4,#24 + vst1.8 d0,[r2,: 64] + vst1.8 d1,[r4,: 64] + ldr r2,[sp,#488] + ldr r4,[sp,#492] + subs r5,r2,#1 + bge .Lmainloop + add r1,r3,#144 + add r2,r3,#336 + vld1.8 {d0-d1},[r1,: 128]! + vld1.8 {d2-d3},[r1,: 128]! + vld1.8 {d4},[r1,: 64] + vst1.8 {d0-d1},[r2,: 128]! + vst1.8 {d2-d3},[r2,: 128]! + vst1.8 d4,[r2,: 64] + ldr r1,=0 + .Linvertloop: + add r2,r3,#144 + ldr r4,=0 + ldr r5,=2 + cmp r1,#1 + ldreq r5,=1 + addeq r2,r3,#336 + addeq r4,r3,#48 + cmp r1,#2 + ldreq r5,=1 + addeq r2,r3,#48 + cmp r1,#3 + ldreq r5,=5 + addeq r4,r3,#336 + cmp r1,#4 + ldreq r5,=10 + cmp r1,#5 + ldreq r5,=20 + cmp r1,#6 + ldreq r5,=10 + addeq r2,r3,#336 + addeq r4,r3,#336 + cmp r1,#7 + ldreq r5,=50 + cmp r1,#8 + ldreq r5,=100 + cmp r1,#9 + ldreq r5,=50 + addeq r2,r3,#336 + cmp r1,#10 + ldreq r5,=5 + addeq r2,r3,#48 + cmp r1,#11 + ldreq r5,=0 + addeq r2,r3,#96 + add r6,r3,#144 + add r7,r3,#288 + vld1.8 {d0-d1},[r6,: 128]! + vld1.8 {d2-d3},[r6,: 128]! + vld1.8 {d4},[r6,: 64] + vst1.8 {d0-d1},[r7,: 128]! + vst1.8 {d2-d3},[r7,: 128]! + vst1.8 d4,[r7,: 64] + cmp r5,#0 + beq .Lskipsquaringloop + .Lsquaringloop: + add r6,r3,#288 + add r7,r3,#288 + add r8,r3,#288 + vmov.i32 q0,#19 + vmov.i32 q1,#0 + vmov.i32 q2,#1 + vzip.i32 q1,q2 + vld1.8 {d4-d5},[r7,: 128]! + vld1.8 {d6-d7},[r7,: 128]! + vld1.8 {d9},[r7,: 64] + vld1.8 {d10-d11},[r6,: 128]! + add r7,sp,#416 + vld1.8 {d12-d13},[r6,: 128]! + vmul.i32 q7,q2,q0 + vld1.8 {d8},[r6,: 64] + vext.32 d17,d11,d10,#1 + vmul.i32 q9,q3,q0 + vext.32 d16,d10,d8,#1 + vshl.u32 q10,q5,q1 + vext.32 d22,d14,d4,#1 + vext.32 d24,d18,d6,#1 + vshl.u32 q13,q6,q1 + vshl.u32 d28,d8,d2 + vrev64.i32 d22,d22 + vmul.i32 d1,d9,d1 + vrev64.i32 d24,d24 + vext.32 d29,d8,d13,#1 + vext.32 d0,d1,d9,#1 + vrev64.i32 d0,d0 + vext.32 d2,d9,d1,#1 + vext.32 d23,d15,d5,#1 + vmull.s32 q4,d20,d4 + vrev64.i32 d23,d23 + vmlal.s32 q4,d21,d1 + vrev64.i32 d2,d2 + vmlal.s32 q4,d26,d19 + vext.32 d3,d5,d15,#1 + vmlal.s32 q4,d27,d18 + vrev64.i32 d3,d3 + vmlal.s32 q4,d28,d15 + vext.32 d14,d12,d11,#1 + vmull.s32 q5,d16,d23 + vext.32 d15,d13,d12,#1 + vmlal.s32 q5,d17,d4 + vst1.8 d8,[r7,: 64]! + vmlal.s32 q5,d14,d1 + vext.32 d12,d9,d8,#0 + vmlal.s32 q5,d15,d19 + vmov.i64 d13,#0 + vmlal.s32 q5,d29,d18 + vext.32 d25,d19,d7,#1 + vmlal.s32 q6,d20,d5 + vrev64.i32 d25,d25 + vmlal.s32 q6,d21,d4 + vst1.8 d11,[r7,: 64]! + vmlal.s32 q6,d26,d1 + vext.32 d9,d10,d10,#0 + vmlal.s32 q6,d27,d19 + vmov.i64 d8,#0 + vmlal.s32 q6,d28,d18 + vmlal.s32 q4,d16,d24 + vmlal.s32 q4,d17,d5 + vmlal.s32 q4,d14,d4 + vst1.8 d12,[r7,: 64]! + vmlal.s32 q4,d15,d1 + vext.32 d10,d13,d12,#0 + vmlal.s32 q4,d29,d19 + vmov.i64 d11,#0 + vmlal.s32 q5,d20,d6 + vmlal.s32 q5,d21,d5 + vmlal.s32 q5,d26,d4 + vext.32 d13,d8,d8,#0 + vmlal.s32 q5,d27,d1 + vmov.i64 d12,#0 + vmlal.s32 q5,d28,d19 + vst1.8 d9,[r7,: 64]! + vmlal.s32 q6,d16,d25 + vmlal.s32 q6,d17,d6 + vst1.8 d10,[r7,: 64] + vmlal.s32 q6,d14,d5 + vext.32 d8,d11,d10,#0 + vmlal.s32 q6,d15,d4 + vmov.i64 d9,#0 + vmlal.s32 q6,d29,d1 + vmlal.s32 q4,d20,d7 + vmlal.s32 q4,d21,d6 + vmlal.s32 q4,d26,d5 + vext.32 d11,d12,d12,#0 + vmlal.s32 q4,d27,d4 + vmov.i64 d10,#0 + vmlal.s32 q4,d28,d1 + vmlal.s32 q5,d16,d0 + sub r6,r7,#32 + vmlal.s32 q5,d17,d7 + vmlal.s32 q5,d14,d6 + vext.32 d30,d9,d8,#0 + vmlal.s32 q5,d15,d5 + vld1.8 {d31},[r6,: 64]! + vmlal.s32 q5,d29,d4 + vmlal.s32 q15,d20,d0 + vext.32 d0,d6,d18,#1 + vmlal.s32 q15,d21,d25 + vrev64.i32 d0,d0 + vmlal.s32 q15,d26,d24 + vext.32 d1,d7,d19,#1 + vext.32 d7,d10,d10,#0 + vmlal.s32 q15,d27,d23 + vrev64.i32 d1,d1 + vld1.8 {d6},[r6,: 64] + vmlal.s32 q15,d28,d22 + vmlal.s32 q3,d16,d4 + add r6,r6,#24 + vmlal.s32 q3,d17,d2 + vext.32 d4,d31,d30,#0 + vmov d17,d11 + vmlal.s32 q3,d14,d1 + vext.32 d11,d13,d13,#0 + vext.32 d13,d30,d30,#0 + vmlal.s32 q3,d15,d0 + vext.32 d1,d8,d8,#0 + vmlal.s32 q3,d29,d3 + vld1.8 {d5},[r6,: 64] + sub r6,r6,#16 + vext.32 d10,d6,d6,#0 + vmov.i32 q1,#0xffffffff + vshl.i64 q4,q1,#25 + add r7,sp,#512 + vld1.8 {d14-d15},[r7,: 128] + vadd.i64 q9,q2,q7 + vshl.i64 q1,q1,#26 + vshr.s64 q10,q9,#26 + vld1.8 {d0},[r6,: 64]! + vadd.i64 q5,q5,q10 + vand q9,q9,q1 + vld1.8 {d16},[r6,: 64]! + add r6,sp,#528 + vld1.8 {d20-d21},[r6,: 128] + vadd.i64 q11,q5,q10 + vsub.i64 q2,q2,q9 + vshr.s64 q9,q11,#25 + vext.32 d12,d5,d4,#0 + vand q11,q11,q4 + vadd.i64 q0,q0,q9 + vmov d19,d7 + vadd.i64 q3,q0,q7 + vsub.i64 q5,q5,q11 + vshr.s64 q11,q3,#26 + vext.32 d18,d11,d10,#0 + vand q3,q3,q1 + vadd.i64 q8,q8,q11 + vadd.i64 q11,q8,q10 + vsub.i64 q0,q0,q3 + vshr.s64 q3,q11,#25 + vand q11,q11,q4 + vadd.i64 q3,q6,q3 + vadd.i64 q6,q3,q7 + vsub.i64 q8,q8,q11 + vshr.s64 q11,q6,#26 + vand q6,q6,q1 + vadd.i64 q9,q9,q11 + vadd.i64 d25,d19,d21 + vsub.i64 q3,q3,q6 + vshr.s64 d23,d25,#25 + vand q4,q12,q4 + vadd.i64 d21,d23,d23 + vshl.i64 d25,d23,#4 + vadd.i64 d21,d21,d23 + vadd.i64 d25,d25,d21 + vadd.i64 d4,d4,d25 + vzip.i32 q0,q8 + vadd.i64 d12,d4,d14 + add r6,r8,#8 + vst1.8 d0,[r6,: 64] + vsub.i64 d19,d19,d9 + add r6,r6,#16 + vst1.8 d16,[r6,: 64] + vshr.s64 d22,d12,#26 + vand q0,q6,q1 + vadd.i64 d10,d10,d22 + vzip.i32 q3,q9 + vsub.i64 d4,d4,d0 + sub r6,r6,#8 + vst1.8 d6,[r6,: 64] + add r6,r6,#16 + vst1.8 d18,[r6,: 64] + vzip.i32 q2,q5 + sub r6,r6,#32 + vst1.8 d4,[r6,: 64] + subs r5,r5,#1 + bhi .Lsquaringloop + .Lskipsquaringloop: + mov r2,r2 + add r5,r3,#288 + add r6,r3,#144 + vmov.i32 q0,#19 + vmov.i32 q1,#0 + vmov.i32 q2,#1 + vzip.i32 q1,q2 + vld1.8 {d4-d5},[r5,: 128]! + vld1.8 {d6-d7},[r5,: 128]! + vld1.8 {d9},[r5,: 64] + vld1.8 {d10-d11},[r2,: 128]! + add r5,sp,#416 + vld1.8 {d12-d13},[r2,: 128]! + vmul.i32 q7,q2,q0 + vld1.8 {d8},[r2,: 64] + vext.32 d17,d11,d10,#1 + vmul.i32 q9,q3,q0 + vext.32 d16,d10,d8,#1 + vshl.u32 q10,q5,q1 + vext.32 d22,d14,d4,#1 + vext.32 d24,d18,d6,#1 + vshl.u32 q13,q6,q1 + vshl.u32 d28,d8,d2 + vrev64.i32 d22,d22 + vmul.i32 d1,d9,d1 + vrev64.i32 d24,d24 + vext.32 d29,d8,d13,#1 + vext.32 d0,d1,d9,#1 + vrev64.i32 d0,d0 + vext.32 d2,d9,d1,#1 + vext.32 d23,d15,d5,#1 + vmull.s32 q4,d20,d4 + vrev64.i32 d23,d23 + vmlal.s32 q4,d21,d1 + vrev64.i32 d2,d2 + vmlal.s32 q4,d26,d19 + vext.32 d3,d5,d15,#1 + vmlal.s32 q4,d27,d18 + vrev64.i32 d3,d3 + vmlal.s32 q4,d28,d15 + vext.32 d14,d12,d11,#1 + vmull.s32 q5,d16,d23 + vext.32 d15,d13,d12,#1 + vmlal.s32 q5,d17,d4 + vst1.8 d8,[r5,: 64]! + vmlal.s32 q5,d14,d1 + vext.32 d12,d9,d8,#0 + vmlal.s32 q5,d15,d19 + vmov.i64 d13,#0 + vmlal.s32 q5,d29,d18 + vext.32 d25,d19,d7,#1 + vmlal.s32 q6,d20,d5 + vrev64.i32 d25,d25 + vmlal.s32 q6,d21,d4 + vst1.8 d11,[r5,: 64]! + vmlal.s32 q6,d26,d1 + vext.32 d9,d10,d10,#0 + vmlal.s32 q6,d27,d19 + vmov.i64 d8,#0 + vmlal.s32 q6,d28,d18 + vmlal.s32 q4,d16,d24 + vmlal.s32 q4,d17,d5 + vmlal.s32 q4,d14,d4 + vst1.8 d12,[r5,: 64]! + vmlal.s32 q4,d15,d1 + vext.32 d10,d13,d12,#0 + vmlal.s32 q4,d29,d19 + vmov.i64 d11,#0 + vmlal.s32 q5,d20,d6 + vmlal.s32 q5,d21,d5 + vmlal.s32 q5,d26,d4 + vext.32 d13,d8,d8,#0 + vmlal.s32 q5,d27,d1 + vmov.i64 d12,#0 + vmlal.s32 q5,d28,d19 + vst1.8 d9,[r5,: 64]! + vmlal.s32 q6,d16,d25 + vmlal.s32 q6,d17,d6 + vst1.8 d10,[r5,: 64] + vmlal.s32 q6,d14,d5 + vext.32 d8,d11,d10,#0 + vmlal.s32 q6,d15,d4 + vmov.i64 d9,#0 + vmlal.s32 q6,d29,d1 + vmlal.s32 q4,d20,d7 + vmlal.s32 q4,d21,d6 + vmlal.s32 q4,d26,d5 + vext.32 d11,d12,d12,#0 + vmlal.s32 q4,d27,d4 + vmov.i64 d10,#0 + vmlal.s32 q4,d28,d1 + vmlal.s32 q5,d16,d0 + sub r2,r5,#32 + vmlal.s32 q5,d17,d7 + vmlal.s32 q5,d14,d6 + vext.32 d30,d9,d8,#0 + vmlal.s32 q5,d15,d5 + vld1.8 {d31},[r2,: 64]! + vmlal.s32 q5,d29,d4 + vmlal.s32 q15,d20,d0 + vext.32 d0,d6,d18,#1 + vmlal.s32 q15,d21,d25 + vrev64.i32 d0,d0 + vmlal.s32 q15,d26,d24 + vext.32 d1,d7,d19,#1 + vext.32 d7,d10,d10,#0 + vmlal.s32 q15,d27,d23 + vrev64.i32 d1,d1 + vld1.8 {d6},[r2,: 64] + vmlal.s32 q15,d28,d22 + vmlal.s32 q3,d16,d4 + add r2,r2,#24 + vmlal.s32 q3,d17,d2 + vext.32 d4,d31,d30,#0 + vmov d17,d11 + vmlal.s32 q3,d14,d1 + vext.32 d11,d13,d13,#0 + vext.32 d13,d30,d30,#0 + vmlal.s32 q3,d15,d0 + vext.32 d1,d8,d8,#0 + vmlal.s32 q3,d29,d3 + vld1.8 {d5},[r2,: 64] + sub r2,r2,#16 + vext.32 d10,d6,d6,#0 + vmov.i32 q1,#0xffffffff + vshl.i64 q4,q1,#25 + add r5,sp,#512 + vld1.8 {d14-d15},[r5,: 128] + vadd.i64 q9,q2,q7 + vshl.i64 q1,q1,#26 + vshr.s64 q10,q9,#26 + vld1.8 {d0},[r2,: 64]! + vadd.i64 q5,q5,q10 + vand q9,q9,q1 + vld1.8 {d16},[r2,: 64]! + add r2,sp,#528 + vld1.8 {d20-d21},[r2,: 128] + vadd.i64 q11,q5,q10 + vsub.i64 q2,q2,q9 + vshr.s64 q9,q11,#25 + vext.32 d12,d5,d4,#0 + vand q11,q11,q4 + vadd.i64 q0,q0,q9 + vmov d19,d7 + vadd.i64 q3,q0,q7 + vsub.i64 q5,q5,q11 + vshr.s64 q11,q3,#26 + vext.32 d18,d11,d10,#0 + vand q3,q3,q1 + vadd.i64 q8,q8,q11 + vadd.i64 q11,q8,q10 + vsub.i64 q0,q0,q3 + vshr.s64 q3,q11,#25 + vand q11,q11,q4 + vadd.i64 q3,q6,q3 + vadd.i64 q6,q3,q7 + vsub.i64 q8,q8,q11 + vshr.s64 q11,q6,#26 + vand q6,q6,q1 + vadd.i64 q9,q9,q11 + vadd.i64 d25,d19,d21 + vsub.i64 q3,q3,q6 + vshr.s64 d23,d25,#25 + vand q4,q12,q4 + vadd.i64 d21,d23,d23 + vshl.i64 d25,d23,#4 + vadd.i64 d21,d21,d23 + vadd.i64 d25,d25,d21 + vadd.i64 d4,d4,d25 + vzip.i32 q0,q8 + vadd.i64 d12,d4,d14 + add r2,r6,#8 + vst1.8 d0,[r2,: 64] + vsub.i64 d19,d19,d9 + add r2,r2,#16 + vst1.8 d16,[r2,: 64] + vshr.s64 d22,d12,#26 + vand q0,q6,q1 + vadd.i64 d10,d10,d22 + vzip.i32 q3,q9 + vsub.i64 d4,d4,d0 + sub r2,r2,#8 + vst1.8 d6,[r2,: 64] + add r2,r2,#16 + vst1.8 d18,[r2,: 64] + vzip.i32 q2,q5 + sub r2,r2,#32 + vst1.8 d4,[r2,: 64] + cmp r4,#0 + beq .Lskippostcopy + add r2,r3,#144 + mov r4,r4 + vld1.8 {d0-d1},[r2,: 128]! + vld1.8 {d2-d3},[r2,: 128]! + vld1.8 {d4},[r2,: 64] + vst1.8 {d0-d1},[r4,: 128]! + vst1.8 {d2-d3},[r4,: 128]! + vst1.8 d4,[r4,: 64] + .Lskippostcopy: + cmp r1,#1 + bne .Lskipfinalcopy + add r2,r3,#288 + add r4,r3,#144 + vld1.8 {d0-d1},[r2,: 128]! + vld1.8 {d2-d3},[r2,: 128]! + vld1.8 {d4},[r2,: 64] + vst1.8 {d0-d1},[r4,: 128]! + vst1.8 {d2-d3},[r4,: 128]! + vst1.8 d4,[r4,: 64] + .Lskipfinalcopy: + add r1,r1,#1 + cmp r1,#12 + blo .Linvertloop + add r1,r3,#144 + ldr r2,[r1],#4 + ldr r3,[r1],#4 + ldr r4,[r1],#4 + ldr r5,[r1],#4 + ldr r6,[r1],#4 + ldr r7,[r1],#4 + ldr r8,[r1],#4 + ldr r9,[r1],#4 + ldr r10,[r1],#4 + ldr r1,[r1] + add r11,r1,r1,LSL #4 + add r11,r11,r1,LSL #1 + add r11,r11,#16777216 + mov r11,r11,ASR #25 + add r11,r11,r2 + mov r11,r11,ASR #26 + add r11,r11,r3 + mov r11,r11,ASR #25 + add r11,r11,r4 + mov r11,r11,ASR #26 + add r11,r11,r5 + mov r11,r11,ASR #25 + add r11,r11,r6 + mov r11,r11,ASR #26 + add r11,r11,r7 + mov r11,r11,ASR #25 + add r11,r11,r8 + mov r11,r11,ASR #26 + add r11,r11,r9 + mov r11,r11,ASR #25 + add r11,r11,r10 + mov r11,r11,ASR #26 + add r11,r11,r1 + mov r11,r11,ASR #25 + add r2,r2,r11 + add r2,r2,r11,LSL #1 + add r2,r2,r11,LSL #4 + mov r11,r2,ASR #26 + add r3,r3,r11 + sub r2,r2,r11,LSL #26 + mov r11,r3,ASR #25 + add r4,r4,r11 + sub r3,r3,r11,LSL #25 + mov r11,r4,ASR #26 + add r5,r5,r11 + sub r4,r4,r11,LSL #26 + mov r11,r5,ASR #25 + add r6,r6,r11 + sub r5,r5,r11,LSL #25 + mov r11,r6,ASR #26 + add r7,r7,r11 + sub r6,r6,r11,LSL #26 + mov r11,r7,ASR #25 + add r8,r8,r11 + sub r7,r7,r11,LSL #25 + mov r11,r8,ASR #26 + add r9,r9,r11 + sub r8,r8,r11,LSL #26 + mov r11,r9,ASR #25 + add r10,r10,r11 + sub r9,r9,r11,LSL #25 + mov r11,r10,ASR #26 + add r1,r1,r11 + sub r10,r10,r11,LSL #26 + mov r11,r1,ASR #25 + sub r1,r1,r11,LSL #25 + add r2,r2,r3,LSL #26 + mov r3,r3,LSR #6 + add r3,r3,r4,LSL #19 + mov r4,r4,LSR #13 + add r4,r4,r5,LSL #13 + mov r5,r5,LSR #19 + add r5,r5,r6,LSL #6 + add r6,r7,r8,LSL #25 + mov r7,r8,LSR #7 + add r7,r7,r9,LSL #19 + mov r8,r9,LSR #13 + add r8,r8,r10,LSL #12 + mov r9,r10,LSR #20 + add r1,r9,r1,LSL #6 + str r2,[r0],#4 + str r3,[r0],#4 + str r4,[r0],#4 + str r5,[r0],#4 + str r6,[r0],#4 + str r7,[r0],#4 + str r8,[r0],#4 + str r1,[r0] + ldrd r4,[sp,#0] + ldrd r6,[sp,#8] + ldrd r8,[sp,#16] + ldrd r10,[sp,#24] + ldr r12,[sp,#480] + ldr r14,[sp,#484] + ldr r0,=0 + mov sp,r12 + vpop {q4,q5,q6,q7} + bx lr +ENDPROC(curve25519_neon) +#endif diff --git a/main.c b/main.c index 8c33f84..ce5f496 100644 --- a/main.c +++ b/main.c @@ -6,6 +6,7 @@ #include #include #include +#include static unsigned long stamp = 0; module_param(stamp, ulong, 0); @@ -16,20 +17,6 @@ enum { CURVE25519_POINT_SIZE = 32 }; u8 dummy_out[CURVE25519_POINT_SIZE]; #include "test_vectors.h" -static inline cycles_t get_arm_cycles(void) -{ - cycles_t cycles; - asm volatile("isb;mrs %0, cntpct_el0" : "=r"(cycles)); - return cycles; -} - -static inline cycles_t get_arm_freq(void) -{ - cycles_t cycles; - asm volatile("isb;mrs %0, cntfrq_el0" : "=r"(cycles)); - return cycles; -} - #define declare_it(name) \ bool curve25519_ ## name(u8 mypublic[CURVE25519_POINT_SIZE], const u8 secret[CURVE25519_POINT_SIZE], const u8 basepoint[CURVE25519_POINT_SIZE]); \ static __always_inline int name(void) \ @@ -40,10 +27,10 @@ static __always_inline int name(void) \ #define do_it(name) do { \ for (i = 0; i < WARMUP; ++i) \ ret |= name(); \ - start_ ## name = get_arm_cycles(); \ + start_ ## name = get_cycles(); \ for (i = 0; i < TRIALS; ++i) \ ret |= name(); \ - end_ ## name = get_arm_cycles(); \ + end_ ## name = get_cycles(); \ } while (0) #define test_it(name, before, after) do { \ @@ -58,12 +45,11 @@ static __always_inline int name(void) \ } while (0) #define report_it(name) do { \ - pr_err("%lu: %7s: %lu cycles per call\n", stamp, #name, (end_ ## name - start_ ## name) * get_arm_freq() / TRIALS / 1000000); \ + pr_err("%lu: %7s: %lu cycles per call\n", stamp, #name, (end_ ## name - start_ ## name) / TRIALS); \ } while (0) -declare_it(donna64) -declare_it(hacl64) +declare_it(neon) declare_it(fiat32) declare_it(donna32) @@ -74,8 +60,7 @@ static bool verify(void) u8 out[CURVE25519_POINT_SIZE]; for (i = 0; i < ARRAY_SIZE(curve25519_test_vectors); ++i) { - test_it(donna64, {}, {}); - test_it(hacl64, {}, {}); + test_it(neon, { kernel_neon_begin(); }, { kernel_neon_end(); }); test_it(fiat32, {}, {}); test_it(donna32, {}, {}); } @@ -86,8 +71,7 @@ static int __init mod_init(void) { enum { WARMUP = 5000, TRIALS = 10000, IDLE = 1 * 1000 }; int ret = 0, i; - cycles_t start_donna64, end_donna64; - cycles_t start_hacl64, end_hacl64; + cycles_t start_neon, end_neon; cycles_t start_fiat32, end_fiat32; cycles_t start_donna32, end_donna32; unsigned long flags; @@ -100,15 +84,15 @@ static int __init mod_init(void) spin_lock_irqsave(&lock, flags); - do_it(donna64); - do_it(hacl64); + kernel_neon_begin(); + do_it(neon); + kernel_neon_end(); do_it(fiat32); do_it(donna32); spin_unlock_irqrestore(&lock, flags); - report_it(donna64); - report_it(hacl64); + report_it(neon); report_it(fiat32); report_it(donna32); -- cgit v1.2.3-59-g8ed1b