crypton-2.1.2: cbits/s2n/arm/bignum_mul_p521.S
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0
// ----------------------------------------------------------------------------
// Multiply modulo p_521, z := (x * y) mod p_521, assuming x and y reduced
// Inputs x[9], y[9]; output z[9]
//
// extern void bignum_mul_p521(uint64_t z[static 9], const uint64_t x[static 9],
// const uint64_t y[static 9]);
//
// Standard ARM ABI: X0 = z, X1 = x, X2 = y
// ----------------------------------------------------------------------------
#include "_internal_s2n_bignum_arm.h"
// bignum_mul_p521 is functionally equivalent to unopt/bignum_mul_p521_base.
// It is written in a way that
// 1. A subset of scalar multiplications in bignum_montmul_p384 are carefully
// chosen and vectorized
// 2. The vectorized assembly is rescheduled using the SLOTHY superoptimizer.
// https://github.com/slothy-optimizer/slothy
//
// The output program of step 1. is as follows:
//
// stp x19, x20, [sp, #-16]!
// stp x21, x22, [sp, #-16]!
// stp x23, x24, [sp, #-16]!
// stp x25, x26, [sp, #-16]!
// sub sp, sp, #80
// ldp x15, x21, [x1]
// ldp x10, x17, [x1, #16]
// ldp x13, x16, [x2]
// ldr q18, [x1]
// ldr q28, [x2]
// ldp x5, x20, [x2, #16]
// movi v16.2D, #0x00000000ffffffff
// uzp2 v7.4S, v28.4S, v28.4S
// xtn v4.2S, v18.2D
// xtn v1.2S, v28.2D
// rev64 v27.4S, v28.4S
// umull v21.2D, v4.2S, v1.2S
// umull v28.2D, v4.2S, v7.2S
// uzp2 v5.4S, v18.4S, v18.4S
// mul v18.4S, v27.4S, v18.4S
// usra v28.2D, v21.2D, #32
// umull v29.2D, v5.2S, v7.2S
// uaddlp v18.2D, v18.4S
// and v16.16B, v28.16B, v16.16B
// umlal v16.2D, v5.2S, v1.2S
// shl v18.2D, v18.2D, #32
// usra v29.2D, v28.2D, #32
// umlal v18.2D, v4.2S, v1.2S
// usra v29.2D, v16.2D, #32
// mov x8, v18.d[0]
// mov x9, v18.d[1]
// mul x6, x10, x5
// mul x19, x17, x20
// mov x14, v29.d[0]
// adds x9, x9, x14
// mov x14, v29.d[1]
// adcs x6, x6, x14
// umulh x14, x10, x5
// adcs x19, x19, x14
// umulh x14, x17, x20
// adc x14, x14, xzr
// adds x11, x9, x8
// adcs x9, x6, x9
// adcs x6, x19, x6
// adcs x19, x14, x19
// adc x14, xzr, x14
// adds x3, x9, x8
// adcs x24, x6, x11
// adcs x9, x19, x9
// adcs x6, x14, x6
// adcs x19, xzr, x19
// adc x14, xzr, x14
// subs x4, x10, x17
// cneg x4, x4, cc
// csetm x7, cc
// subs x23, x20, x5
// cneg x23, x23, cc
// mul x22, x4, x23
// umulh x4, x4, x23
// cinv x7, x7, cc
// cmn x7, #0x1
// eor x23, x22, x7
// adcs x6, x6, x23
// eor x4, x4, x7
// adcs x19, x19, x4
// adc x14, x14, x7
// subs x4, x15, x21
// cneg x4, x4, cc
// csetm x7, cc
// subs x23, x16, x13
// cneg x23, x23, cc
// mul x22, x4, x23
// umulh x4, x4, x23
// cinv x7, x7, cc
// cmn x7, #0x1
// eor x23, x22, x7
// adcs x11, x11, x23
// eor x4, x4, x7
// adcs x3, x3, x4
// adcs x24, x24, x7
// adcs x9, x9, x7
// adcs x6, x6, x7
// adcs x19, x19, x7
// adc x14, x14, x7
// subs x4, x21, x17
// cneg x4, x4, cc
// csetm x7, cc
// subs x23, x20, x16
// cneg x23, x23, cc
// mul x22, x4, x23
// umulh x4, x4, x23
// cinv x7, x7, cc
// cmn x7, #0x1
// eor x23, x22, x7
// adcs x9, x9, x23
// eor x4, x4, x7
// adcs x6, x6, x4
// adcs x19, x19, x7
// adc x14, x14, x7
// subs x4, x15, x10
// cneg x4, x4, cc
// csetm x7, cc
// subs x23, x5, x13
// cneg x23, x23, cc
// mul x22, x4, x23
// umulh x4, x4, x23
// cinv x7, x7, cc
// cmn x7, #0x1
// eor x23, x22, x7
// adcs x3, x3, x23
// eor x4, x4, x7
// adcs x24, x24, x4
// adcs x9, x9, x7
// adcs x6, x6, x7
// adcs x19, x19, x7
// adc x14, x14, x7
// subs x17, x15, x17
// cneg x17, x17, cc
// csetm x4, cc
// subs x13, x20, x13
// cneg x13, x13, cc
// mul x20, x17, x13
// umulh x17, x17, x13
// cinv x13, x4, cc
// cmn x13, #0x1
// eor x20, x20, x13
// adcs x20, x24, x20
// eor x17, x17, x13
// adcs x17, x9, x17
// adcs x9, x6, x13
// adcs x6, x19, x13
// adc x13, x14, x13
// subs x21, x21, x10
// cneg x21, x21, cc
// csetm x10, cc
// subs x16, x5, x16
// cneg x16, x16, cc
// mul x5, x21, x16
// umulh x21, x21, x16
// cinv x10, x10, cc
// cmn x10, #0x1
// eor x16, x5, x10
// adcs x16, x20, x16
// eor x21, x21, x10
// adcs x21, x17, x21
// adcs x17, x9, x10
// adcs x5, x6, x10
// adc x10, x13, x10
// lsl x13, x8, #9
// extr x20, x11, x8, #55
// extr x8, x3, x11, #55
// extr x9, x16, x3, #55
// lsr x16, x16, #55
// stp x21, x17, [sp] // @slothy:writes=stack0
// stp x5, x10, [sp, #16] // @slothy:writes=stack16
// stp x13, x20, [sp, #32] // @slothy:writes=stack32
// stp x8, x9, [sp, #48] // @slothy:writes=stack48
// str x16, [sp, #64] // @slothy:writes=stack64
// ldp x21, x10, [x1, #32]
// ldp x17, x13, [x1, #48]
// ldp x16, x5, [x2, #32]
// ldr q18, [x1, #32]
// ldr q28, [x2, #32]
// ldp x20, x8, [x2, #48]
// movi v16.2D, #0x00000000ffffffff
// uzp2 v7.4S, v28.4S, v28.4S
// xtn v4.2S, v18.2D
// xtn v1.2S, v28.2D
// rev64 v28.4S, v28.4S
// umull v27.2D, v4.2S, v1.2S
// umull v29.2D, v4.2S, v7.2S
// uzp2 v21.4S, v18.4S, v18.4S
// mul v28.4S, v28.4S, v18.4S
// usra v29.2D, v27.2D, #32
// umull v18.2D, v21.2S, v7.2S
// uaddlp v28.2D, v28.4S
// and v16.16B, v29.16B, v16.16B
// umlal v16.2D, v21.2S, v1.2S
// shl v28.2D, v28.2D, #32
// usra v18.2D, v29.2D, #32
// umlal v28.2D, v4.2S, v1.2S
// usra v18.2D, v16.2D, #32
// mov x9, v28.d[0]
// mov x6, v28.d[1]
// mul x19, x17, x20
// mul x14, x13, x8
// mov x11, v18.d[0]
// adds x6, x6, x11
// mov x11, v18.d[1]
// adcs x19, x19, x11
// umulh x11, x17, x20
// adcs x14, x14, x11
// umulh x11, x13, x8
// adc x11, x11, xzr
// adds x3, x6, x9
// adcs x6, x19, x6
// adcs x19, x14, x19
// adcs x14, x11, x14
// adc x11, xzr, x11
// adds x24, x6, x9
// adcs x4, x19, x3
// adcs x6, x14, x6
// adcs x19, x11, x19
// adcs x14, xzr, x14
// adc x11, xzr, x11
// subs x7, x17, x13
// cneg x7, x7, cc
// csetm x23, cc
// subs x22, x8, x20
// cneg x22, x22, cc
// mul x12, x7, x22
// umulh x7, x7, x22
// cinv x23, x23, cc
// cmn x23, #0x1
// eor x22, x12, x23
// adcs x19, x19, x22
// eor x7, x7, x23
// adcs x14, x14, x7
// adc x11, x11, x23
// subs x7, x21, x10
// cneg x7, x7, cc
// csetm x23, cc
// subs x22, x5, x16
// cneg x22, x22, cc
// mul x12, x7, x22
// umulh x7, x7, x22
// cinv x23, x23, cc
// cmn x23, #0x1
// eor x22, x12, x23
// adcs x3, x3, x22
// eor x7, x7, x23
// adcs x24, x24, x7
// adcs x4, x4, x23
// adcs x6, x6, x23
// adcs x19, x19, x23
// adcs x14, x14, x23
// adc x11, x11, x23
// subs x7, x10, x13
// cneg x7, x7, cc
// csetm x23, cc
// subs x22, x8, x5
// cneg x22, x22, cc
// mul x12, x7, x22
// umulh x7, x7, x22
// cinv x23, x23, cc
// cmn x23, #0x1
// eor x22, x12, x23
// adcs x6, x6, x22
// eor x7, x7, x23
// adcs x19, x19, x7
// adcs x14, x14, x23
// adc x11, x11, x23
// subs x7, x21, x17
// cneg x7, x7, cc
// csetm x23, cc
// subs x22, x20, x16
// cneg x22, x22, cc
// mul x12, x7, x22
// umulh x7, x7, x22
// cinv x23, x23, cc
// cmn x23, #0x1
// eor x22, x12, x23
// adcs x24, x24, x22
// eor x7, x7, x23
// adcs x4, x4, x7
// adcs x6, x6, x23
// adcs x19, x19, x23
// adcs x14, x14, x23
// adc x11, x11, x23
// subs x7, x21, x13
// cneg x7, x7, cc
// csetm x23, cc
// subs x22, x8, x16
// cneg x22, x22, cc
// mul x12, x7, x22
// umulh x7, x7, x22
// cinv x23, x23, cc
// cmn x23, #0x1
// eor x22, x12, x23
// adcs x4, x4, x22
// eor x7, x7, x23
// adcs x6, x6, x7
// adcs x19, x19, x23
// adcs x14, x14, x23
// adc x11, x11, x23
// subs x7, x10, x17
// cneg x7, x7, cc
// csetm x23, cc
// subs x22, x20, x5
// cneg x22, x22, cc
// mul x12, x7, x22
// umulh x7, x7, x22
// cinv x23, x23, cc
// cmn x23, #0x1
// eor x22, x12, x23
// adcs x4, x4, x22
// eor x7, x7, x23
// adcs x6, x6, x7
// adcs x19, x19, x23
// adcs x14, x14, x23
// adc x11, x11, x23
// ldp x7, x23, [sp] // @slothy:reads=stack0
// adds x9, x9, x7
// adcs x3, x3, x23
// stp x9, x3, [sp] // @slothy:writes=stack0
// ldp x9, x3, [sp, #16] // @slothy:reads=stack16
// adcs x9, x24, x9
// adcs x3, x4, x3
// stp x9, x3, [sp, #16] // @slothy:writes=stack16
// ldp x9, x3, [sp, #32] // @slothy:reads=stack32
// adcs x9, x6, x9
// adcs x6, x19, x3
// stp x9, x6, [sp, #32] // @slothy:writes=stack32
// ldp x9, x6, [sp, #48] // @slothy:reads=stack48
// adcs x9, x14, x9
// adcs x6, x11, x6
// stp x9, x6, [sp, #48] // @slothy:writes=stack48
// ldr x9, [sp, #64] // @slothy:reads=stack64
// adc x9, x9, xzr
// str x9, [sp, #64] // @slothy:writes=stack64
// ldp x9, x6, [x1]
// subs x21, x21, x9
// sbcs x10, x10, x6
// ldp x9, x6, [x1, #16]
// sbcs x17, x17, x9
// sbcs x13, x13, x6
// csetm x9, cc
// ldp x6, x19, [x2]
// subs x16, x6, x16
// sbcs x5, x19, x5
// ldp x6, x19, [x2, #16]
// sbcs x20, x6, x20
// sbcs x8, x19, x8
// csetm x6, cc
// eor x21, x21, x9
// subs x21, x21, x9
// eor x10, x10, x9
// sbcs x10, x10, x9
// eor x17, x17, x9
// sbcs x17, x17, x9
// eor x13, x13, x9
// sbc x13, x13, x9
// eor x16, x16, x6
// subs x16, x16, x6
// eor x5, x5, x6
// sbcs x5, x5, x6
// eor x20, x20, x6
// sbcs x20, x20, x6
// eor x8, x8, x6
// sbc x8, x8, x6
// eor x9, x6, x9
// mul x6, x21, x16
// mul x19, x10, x5
// mul x14, x17, x20
// mul x11, x13, x8
// umulh x3, x21, x16
// adds x19, x19, x3
// umulh x3, x10, x5
// adcs x14, x14, x3
// umulh x3, x17, x20
// adcs x11, x11, x3
// umulh x3, x13, x8
// adc x3, x3, xzr
// adds x24, x19, x6
// adcs x19, x14, x19
// adcs x14, x11, x14
// adcs x11, x3, x11
// adc x3, xzr, x3
// adds x4, x19, x6
// adcs x7, x14, x24
// adcs x19, x11, x19
// adcs x14, x3, x14
// adcs x11, xzr, x11
// adc x3, xzr, x3
// subs x23, x17, x13
// cneg x23, x23, cc
// csetm x22, cc
// subs x12, x8, x20
// cneg x12, x12, cc
// mul x15, x23, x12
// umulh x23, x23, x12
// cinv x22, x22, cc
// cmn x22, #0x1
// eor x12, x15, x22
// adcs x14, x14, x12
// eor x23, x23, x22
// adcs x11, x11, x23
// adc x3, x3, x22
// subs x23, x21, x10
// cneg x23, x23, cc
// csetm x22, cc
// subs x12, x5, x16
// cneg x12, x12, cc
// mul x15, x23, x12
// umulh x23, x23, x12
// cinv x22, x22, cc
// cmn x22, #0x1
// eor x12, x15, x22
// adcs x24, x24, x12
// eor x23, x23, x22
// adcs x4, x4, x23
// adcs x7, x7, x22
// adcs x19, x19, x22
// adcs x14, x14, x22
// adcs x11, x11, x22
// adc x3, x3, x22
// subs x23, x10, x13
// cneg x23, x23, cc
// csetm x22, cc
// subs x12, x8, x5
// cneg x12, x12, cc
// mul x15, x23, x12
// umulh x23, x23, x12
// cinv x22, x22, cc
// cmn x22, #0x1
// eor x12, x15, x22
// adcs x19, x19, x12
// eor x23, x23, x22
// adcs x14, x14, x23
// adcs x11, x11, x22
// adc x3, x3, x22
// subs x23, x21, x17
// cneg x23, x23, cc
// csetm x22, cc
// subs x12, x20, x16
// cneg x12, x12, cc
// mul x15, x23, x12
// umulh x23, x23, x12
// cinv x22, x22, cc
// cmn x22, #0x1
// eor x12, x15, x22
// adcs x4, x4, x12
// eor x23, x23, x22
// adcs x7, x7, x23
// adcs x19, x19, x22
// adcs x14, x14, x22
// adcs x11, x11, x22
// adc x3, x3, x22
// subs x21, x21, x13
// cneg x21, x21, cc
// csetm x13, cc
// subs x16, x8, x16
// cneg x16, x16, cc
// mul x8, x21, x16
// umulh x21, x21, x16
// cinv x13, x13, cc
// cmn x13, #0x1
// eor x16, x8, x13
// adcs x16, x7, x16
// eor x21, x21, x13
// adcs x21, x19, x21
// adcs x8, x14, x13
// adcs x19, x11, x13
// adc x13, x3, x13
// subs x10, x10, x17
// cneg x10, x10, cc
// csetm x17, cc
// subs x5, x20, x5
// cneg x5, x5, cc
// mul x20, x10, x5
// umulh x10, x10, x5
// cinv x17, x17, cc
// cmn x17, #0x1
// eor x5, x20, x17
// adcs x16, x16, x5
// eor x10, x10, x17
// adcs x21, x21, x10
// adcs x10, x8, x17
// adcs x5, x19, x17
// adc x17, x13, x17
// ldp x13, x20, [sp] // @slothy:reads=stack0
// ldp x8, x19, [sp, #16] // @slothy:reads=stack16
// eor x6, x6, x9
// adds x6, x6, x13
// eor x14, x24, x9
// adcs x14, x14, x20
// eor x11, x4, x9
// adcs x11, x11, x8
// eor x16, x16, x9
// adcs x16, x16, x19
// eor x21, x21, x9
// ldp x3, x24, [sp, #32] // @slothy:reads=stack32
// ldp x4, x7, [sp, #48] // @slothy:reads=stack48
// ldr x23, [sp, #64] // @slothy:reads=stack64
// adcs x21, x21, x3
// eor x10, x10, x9
// adcs x10, x10, x24
// eor x5, x5, x9
// adcs x5, x5, x4
// eor x17, x17, x9
// adcs x17, x17, x7
// adc x22, x23, xzr
// adds x21, x21, x13
// adcs x10, x10, x20
// adcs x13, x5, x8
// adcs x17, x17, x19
// and x5, x9, #0x1ff
// lsl x20, x6, #9
// orr x5, x20, x5
// adcs x5, x3, x5
// extr x20, x14, x6, #55
// adcs x20, x24, x20
// extr x8, x11, x14, #55
// adcs x8, x4, x8
// extr x9, x16, x11, #55
// adcs x9, x7, x9
// lsr x16, x16, #55
// adc x16, x16, x23
// ldr x6, [x2, #64]
// ldp x19, x14, [x1]
// and x11, x19, #0xfffffffffffff
// mul x11, x6, x11
// ldr x3, [x1, #64]
// ldp x24, x4, [x2]
// and x7, x24, #0xfffffffffffff
// mul x7, x3, x7
// add x11, x11, x7
// extr x19, x14, x19, #52
// and x19, x19, #0xfffffffffffff
// mul x19, x6, x19
// extr x24, x4, x24, #52
// and x24, x24, #0xfffffffffffff
// mul x24, x3, x24
// add x19, x19, x24
// lsr x24, x11, #52
// add x19, x19, x24
// lsl x11, x11, #12
// extr x11, x19, x11, #12
// adds x21, x21, x11
// ldp x11, x24, [x1, #16]
// ldp x7, x23, [x2, #16]
// extr x14, x11, x14, #40
// and x14, x14, #0xfffffffffffff
// mul x14, x6, x14
// extr x4, x7, x4, #40
// and x4, x4, #0xfffffffffffff
// mul x4, x3, x4
// add x14, x14, x4
// lsr x4, x19, #52
// add x14, x14, x4
// lsl x19, x19, #12
// extr x19, x14, x19, #24
// adcs x10, x10, x19
// extr x19, x24, x11, #28
// and x19, x19, #0xfffffffffffff
// mul x19, x6, x19
// extr x11, x23, x7, #28
// and x11, x11, #0xfffffffffffff
// mul x11, x3, x11
// add x19, x19, x11
// lsr x11, x14, #52
// add x19, x19, x11
// lsl x14, x14, #12
// extr x14, x19, x14, #36
// adcs x13, x13, x14
// and x14, x10, x13
// ldp x11, x4, [x1, #32]
// ldp x7, x12, [x2, #32]
// extr x24, x11, x24, #16
// and x24, x24, #0xfffffffffffff
// mul x24, x6, x24
// extr x23, x7, x23, #16
// and x23, x23, #0xfffffffffffff
// mul x23, x3, x23
// add x24, x24, x23
// lsl x23, x22, #48
// add x24, x24, x23
// lsr x23, x19, #52
// add x24, x24, x23
// lsl x19, x19, #12
// extr x19, x24, x19, #48
// adcs x17, x17, x19
// and x19, x14, x17
// lsr x14, x11, #4
// and x14, x14, #0xfffffffffffff
// mul x14, x6, x14
// lsr x23, x7, #4
// and x23, x23, #0xfffffffffffff
// mul x23, x3, x23
// add x14, x14, x23
// lsr x23, x24, #52
// add x14, x14, x23
// lsl x24, x24, #12
// extr x24, x14, x24, #60
// extr x11, x4, x11, #56
// and x11, x11, #0xfffffffffffff
// mul x11, x6, x11
// extr x7, x12, x7, #56
// and x7, x7, #0xfffffffffffff
// mul x7, x3, x7
// add x11, x11, x7
// lsr x14, x14, #52
// add x14, x11, x14
// lsl x11, x24, #8
// extr x11, x14, x11, #8
// adcs x5, x5, x11
// and x19, x19, x5
// ldp x11, x24, [x1, #48]
// ldp x2, x7, [x2, #48]
// extr x4, x11, x4, #44
// and x4, x4, #0xfffffffffffff
// mul x4, x6, x4
// extr x23, x2, x12, #44
// and x23, x23, #0xfffffffffffff
// mul x23, x3, x23
// add x4, x4, x23
// lsr x23, x14, #52
// add x4, x4, x23
// lsl x14, x14, #12
// extr x14, x4, x14, #20
// adcs x20, x20, x14
// and x19, x19, x20
// extr x14, x24, x11, #32
// and x14, x14, #0xfffffffffffff
// mul x14, x6, x14
// extr x2, x7, x2, #32
// and x2, x2, #0xfffffffffffff
// mul x2, x3, x2
// add x2, x14, x2
// lsr x14, x4, #52
// add x2, x2, x14
// lsl x14, x4, #12
// extr x14, x2, x14, #32
// adcs x8, x8, x14
// and x19, x19, x8
// lsr x14, x24, #20
// mul x14, x6, x14
// lsr x11, x7, #20
// mul x11, x3, x11
// add x14, x14, x11
// lsr x11, x2, #52
// add x14, x14, x11
// lsl x2, x2, #12
// extr x2, x14, x2, #44
// adcs x9, x9, x2
// and x2, x19, x9
// mul x6, x6, x3
// lsr x19, x14, #44
// add x6, x6, x19
// adc x16, x16, x6
// lsr x6, x16, #9
// orr x16, x16, #0xfffffffffffffe00
// cmp xzr, xzr
// adcs xzr, x21, x6
// adcs xzr, x2, xzr
// adcs xzr, x16, xzr
// adcs x21, x21, x6
// adcs x10, x10, xzr
// adcs x13, x13, xzr
// adcs x17, x17, xzr
// adcs x5, x5, xzr
// adcs x20, x20, xzr
// adcs x8, x8, xzr
// adcs x9, x9, xzr
// adc x16, x16, xzr
// and x2, x21, #0x1ff
// extr x21, x10, x21, #9
// extr x10, x13, x10, #9
// stp x21, x10, [x0] // @slothy:writes=buffer0
// extr x21, x17, x13, #9
// extr x10, x5, x17, #9
// stp x21, x10, [x0, #16] // @slothy:writes=buffer16
// extr x21, x20, x5, #9
// extr x10, x8, x20, #9
// stp x21, x10, [x0, #32] // @slothy:writes=buffer32
// extr x21, x9, x8, #9
// extr x10, x16, x9, #9
// stp x21, x10, [x0, #48] // @slothy:writes=buffer48
// str x2, [x0, #64] // @slothy:writes=buffer64
// add sp, sp, #80
// ldp x25, x26, [sp], #16
// ldp x23, x24, [sp], #16
// ldp x21, x22, [sp], #16
// ldp x19, x20, [sp], #16
// ret
//
// The bash script used for step 2 is as follows:
//
// # Store the assembly instructions except the last 'ret',
// # callee-register store/loads and add/sub sp #80 as, say, 'input.S'.
// export OUTPUTS="[hint_buffer0,hint_buffer16,hint_buffer32,hint_buffer48,hint_buffer64]"
// export RESERVED_REGS="[x18,x27,x28,x29,x30,sp,q8,q9,q10,q11,q12,q13,q14,q15,v8,v9,v10,v11,v12,v13,v14,v15]"
// <s2n-bignum>/tools/external/slothy.sh input.S my_out_dir
// # my_out_dir/3.opt.s is the optimized assembly. Its output may differ
// # from this file since the sequence is non-deterministically chosen.
// # Please add 'ret' at the end of the output assembly.
S2N_BN_SYM_VISIBILITY_DIRECTIVE(bignum_mul_p521)
S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_mul_p521)
S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_mul_p521)
.text
.balign 4
S2N_BN_SYMBOL(bignum_mul_p521):
CFI_START
// Save registers and make space for the temporary buffer
CFI_PUSH2(x19,x20)
CFI_PUSH2(x21,x22)
CFI_PUSH2(x23,x24)
CFI_PUSH2(x25,x26)
CFI_DEC_SP(80)
ldr q6, [x2]
ldp x10, x17, [x1, #16]
ldr q4, [x1]
ldr q16, [x2, #32]
ldp x5, x20, [x2, #16]
ldr q2, [x1, #32]
movi v31.2D, #0x00000000ffffffff
uzp2 v17.4S, v6.4S, v6.4S
rev64 v7.4S, v6.4S
ldp x15, x21, [x1]
xtn v25.2S, v6.2D
xtn v22.2S, v4.2D
subs x14, x10, x17
mul v7.4S, v7.4S, v4.4S
csetm x8, cc
rev64 v3.4S, v16.4S
xtn v1.2S, v16.2D
ldp x13, x16, [x2]
mul x26, x10, x5
uzp2 v16.4S, v16.4S, v16.4S
uaddlp v26.2D, v7.4S
cneg x4, x14, cc
subs x24, x15, x21
xtn v5.2S, v2.2D
mul v28.4S, v3.4S, v2.4S
shl v26.2D, v26.2D, #32
mul x22, x17, x20
umull v20.2D, v22.2S, v25.2S
uzp2 v6.4S, v4.4S, v4.4S
umull v18.2D, v22.2S, v17.2S
uzp2 v4.4S, v2.4S, v2.4S
cneg x14, x24, cc
csetm x7, cc
umulh x11, x17, x20
usra v18.2D, v20.2D, #32
uaddlp v7.2D, v28.4S
subs x19, x16, x13
umlal v26.2D, v22.2S, v25.2S
cneg x19, x19, cc
shl v28.2D, v7.2D, #32
umull v7.2D, v5.2S, v1.2S
umull v30.2D, v5.2S, v16.2S
cinv x6, x7, cc
mul x25, x14, x19
umlal v28.2D, v5.2S, v1.2S
umull v21.2D, v6.2S, v17.2S
umulh x14, x14, x19
usra v30.2D, v7.2D, #32
subs x9, x20, x5
and v29.16B, v18.16B, v31.16B
cinv x23, x8, cc
mov x8, v26.d[1]
cneg x12, x9, cc
usra v21.2D, v18.2D, #32
umlal v29.2D, v6.2S, v25.2S
mul x24, x4, x12
umull v18.2D, v4.2S, v16.2S
movi v25.2D, #0x00000000ffffffff
eor x9, x14, x6
and v7.16B, v30.16B, v25.16B
usra v21.2D, v29.2D, #32
umulh x7, x10, x5
usra v18.2D, v30.2D, #32
umlal v7.2D, v4.2S, v1.2S
mov x19, v21.d[0]
umulh x3, x4, x12
mov x14, v21.d[1]
usra v18.2D, v7.2D, #32
adds x4, x8, x19
mov x8, v26.d[0]
adcs x19, x26, x14
adcs x14, x22, x7
adc x12, x11, xzr
adds x11, x4, x8
adcs x26, x19, x4
adcs x22, x14, x19
eor x4, x24, x23
adcs x14, x12, x14
eor x7, x25, x6
adc x25, xzr, x12
eor x19, x3, x23
adds x3, x26, x8
adcs x24, x22, x11
adcs x12, x14, x26
adcs x22, x25, x22
adcs x26, xzr, x14
adc x14, xzr, x25
cmn x23, #0x1
adcs x22, x22, x4
adcs x19, x26, x19
adc x25, x14, x23
subs x14, x21, x17
cneg x23, x14, cc
csetm x26, cc
subs x4, x20, x16
cneg x14, x4, cc
cinv x4, x26, cc
cmn x6, #0x1
adcs x11, x11, x7
mul x7, x23, x14
adcs x9, x3, x9
adcs x26, x24, x6
umulh x3, x23, x14
adcs x14, x12, x6
adcs x22, x22, x6
adcs x12, x19, x6
extr x24, x11, x8, #55
adc x6, x25, x6
subs x19, x15, x17
csetm x17, cc
cneg x23, x19, cc
subs x19, x20, x13
lsl x25, x8, #9
eor x8, x7, x4
cneg x20, x19, cc
umulh x7, x23, x20
cinv x19, x17, cc
subs x17, x15, x10
csetm x15, cc
stp x25, x24, [sp, #32]
cneg x24, x17, cc
mul x20, x23, x20
subs x25, x5, x13
cneg x13, x25, cc
cinv x15, x15, cc
mul x25, x24, x13
subs x21, x21, x10
csetm x23, cc
cneg x17, x21, cc
subs x21, x5, x16
umulh x13, x24, x13
cinv x10, x23, cc
cneg x23, x21, cc
cmn x4, #0x1
adcs x14, x14, x8
eor x21, x3, x4
adcs x21, x22, x21
eor x5, x20, x19
adcs x24, x12, x4
mul x12, x17, x23
eor x8, x25, x15
adc x25, x6, x4
cmn x15, #0x1
adcs x6, x9, x8
ldp x20, x8, [x2, #48]
eor x9, x13, x15
adcs x4, x26, x9
umulh x26, x17, x23
ldp x17, x13, [x1, #48]
adcs x9, x14, x15
adcs x16, x21, x15
adcs x14, x24, x15
eor x21, x7, x19
mul x23, x17, x20
adc x24, x25, x15
cmn x19, #0x1
adcs x7, x4, x5
adcs x9, x9, x21
umulh x3, x13, x8
adcs x16, x16, x19
adcs x22, x14, x19
eor x5, x12, x10
adc x12, x24, x19
cmn x10, #0x1
adcs x19, x7, x5
eor x14, x26, x10
mov x7, v28.d[1]
adcs x24, x9, x14
extr x4, x19, x6, #55
umulh x15, x17, x20
mov x14, v18.d[1]
lsr x9, x19, #55
adcs x5, x16, x10
mov x16, v18.d[0]
adcs x19, x22, x10
str x9, [sp, #64]
extr x25, x6, x11, #55
adc x21, x12, x10
subs x26, x17, x13
stp x25, x4, [sp, #48]
stp x19, x21, [sp, #16]
csetm x6, cc
cneg x4, x26, cc
mul x19, x13, x8
subs x11, x8, x20
stp x24, x5, [sp]
ldp x21, x10, [x1, #32]
cinv x12, x6, cc
cneg x6, x11, cc
mov x9, v28.d[0]
umulh x25, x4, x6
adds x22, x7, x16
ldp x16, x5, [x2, #32]
adcs x14, x23, x14
adcs x11, x19, x15
adc x24, x3, xzr
adds x3, x22, x9
adcs x15, x14, x22
mul x22, x4, x6
adcs x6, x11, x14
adcs x4, x24, x11
eor x14, x25, x12
adc x26, xzr, x24
subs x7, x21, x10
csetm x23, cc
cneg x19, x7, cc
subs x24, x5, x16
cneg x11, x24, cc
cinv x7, x23, cc
adds x25, x15, x9
eor x23, x22, x12
adcs x22, x6, x3
mul x24, x19, x11
adcs x15, x4, x15
adcs x6, x26, x6
umulh x19, x19, x11
adcs x11, xzr, x4
adc x26, xzr, x26
cmn x12, #0x1
adcs x4, x6, x23
eor x6, x24, x7
adcs x14, x11, x14
adc x26, x26, x12
subs x11, x10, x13
cneg x12, x11, cc
csetm x11, cc
eor x19, x19, x7
subs x24, x8, x5
cinv x11, x11, cc
cneg x24, x24, cc
cmn x7, #0x1
adcs x3, x3, x6
mul x23, x12, x24
adcs x25, x25, x19
adcs x6, x22, x7
umulh x19, x12, x24
adcs x22, x15, x7
adcs x12, x4, x7
eor x24, x23, x11
adcs x4, x14, x7
adc x26, x26, x7
eor x19, x19, x11
subs x14, x21, x17
cneg x7, x14, cc
csetm x14, cc
subs x23, x20, x16
cinv x14, x14, cc
cneg x23, x23, cc
cmn x11, #0x1
adcs x22, x22, x24
mul x24, x7, x23
adcs x15, x12, x19
adcs x4, x4, x11
adc x19, x26, x11
umulh x26, x7, x23
subs x7, x21, x13
eor x11, x24, x14
cneg x23, x7, cc
csetm x12, cc
subs x7, x8, x16
cneg x7, x7, cc
cinv x12, x12, cc
cmn x14, #0x1
eor x26, x26, x14
adcs x11, x25, x11
mul x25, x23, x7
adcs x26, x6, x26
adcs x6, x22, x14
adcs x24, x15, x14
umulh x23, x23, x7
adcs x4, x4, x14
adc x22, x19, x14
eor x14, x25, x12
eor x7, x23, x12
cmn x12, #0x1
adcs x14, x26, x14
ldp x19, x25, [x2]
ldp x15, x23, [x2, #16]
adcs x26, x6, x7
adcs x24, x24, x12
adcs x7, x4, x12
adc x4, x22, x12
subs x19, x19, x16
ldp x16, x22, [x1]
sbcs x6, x25, x5
ldp x12, x25, [x1, #16]
sbcs x15, x15, x20
sbcs x8, x23, x8
csetm x23, cc
subs x21, x21, x16
eor x16, x19, x23
sbcs x19, x10, x22
eor x22, x6, x23
eor x8, x8, x23
sbcs x6, x17, x12
sbcs x13, x13, x25
csetm x12, cc
subs x10, x10, x17
cneg x17, x10, cc
csetm x25, cc
subs x5, x20, x5
eor x10, x19, x12
cneg x19, x5, cc
eor x20, x15, x23
eor x21, x21, x12
cinv x15, x25, cc
mul x25, x17, x19
subs x16, x16, x23
sbcs x5, x22, x23
eor x6, x6, x12
sbcs x20, x20, x23
eor x22, x13, x12
sbc x8, x8, x23
subs x21, x21, x12
umulh x19, x17, x19
sbcs x10, x10, x12
sbcs x17, x6, x12
eor x6, x19, x15
eor x19, x25, x15
umulh x25, x17, x20
sbc x13, x22, x12
cmn x15, #0x1
adcs x22, x14, x19
adcs x19, x26, x6
ldp x6, x26, [sp]
adcs x14, x24, x15
umulh x24, x21, x16
adcs x7, x7, x15
adc x15, x4, x15
adds x4, x9, x6
eor x9, x23, x12
adcs x12, x3, x26
stp x4, x12, [sp]
ldp x4, x26, [sp, #16]
umulh x12, x10, x5
ldp x6, x23, [sp, #32]
adcs x3, x11, x4
mul x4, x13, x8
adcs x26, x22, x26
ldp x22, x11, [sp, #48]
adcs x6, x19, x6
stp x3, x26, [sp, #16]
mul x26, x10, x5
adcs x14, x14, x23
stp x6, x14, [sp, #32]
ldr x6, [sp, #64]
adcs x22, x7, x22
adcs x14, x15, x11
mul x11, x17, x20
adc x19, x6, xzr
stp x22, x14, [sp, #48]
adds x14, x26, x24
str x19, [sp, #64]
umulh x19, x13, x8
adcs x7, x11, x12
adcs x22, x4, x25
mul x6, x21, x16
adc x19, x19, xzr
subs x11, x17, x13
cneg x12, x11, cc
csetm x11, cc
subs x24, x8, x20
cinv x11, x11, cc
cneg x24, x24, cc
adds x4, x14, x6
adcs x14, x7, x14
mul x3, x12, x24
adcs x7, x22, x7
adcs x22, x19, x22
umulh x12, x12, x24
adc x24, xzr, x19
adds x19, x14, x6
eor x3, x3, x11
adcs x26, x7, x4
adcs x14, x22, x14
adcs x25, x24, x7
adcs x23, xzr, x22
eor x7, x12, x11
adc x12, xzr, x24
subs x22, x21, x10
cneg x24, x22, cc
csetm x22, cc
subs x15, x5, x16
cinv x22, x22, cc
cneg x15, x15, cc
cmn x11, #0x1
adcs x3, x25, x3
mul x25, x24, x15
adcs x23, x23, x7
adc x11, x12, x11
subs x7, x10, x13
umulh x15, x24, x15
cneg x12, x7, cc
csetm x7, cc
eor x24, x25, x22
eor x25, x15, x22
cmn x22, #0x1
adcs x24, x4, x24
adcs x19, x19, x25
adcs x15, x26, x22
adcs x4, x14, x22
adcs x26, x3, x22
adcs x25, x23, x22
adc x23, x11, x22
subs x14, x21, x17
cneg x3, x14, cc
csetm x11, cc
subs x14, x8, x5
cneg x14, x14, cc
cinv x7, x7, cc
subs x13, x21, x13
cneg x21, x13, cc
csetm x13, cc
mul x22, x12, x14
subs x8, x8, x16
cinv x13, x13, cc
umulh x14, x12, x14
cneg x12, x8, cc
subs x8, x20, x16
cneg x8, x8, cc
cinv x16, x11, cc
eor x22, x22, x7
cmn x7, #0x1
eor x14, x14, x7
adcs x4, x4, x22
mul x11, x3, x8
adcs x22, x26, x14
adcs x14, x25, x7
eor x25, x24, x9
adc x26, x23, x7
umulh x7, x3, x8
subs x17, x10, x17
cneg x24, x17, cc
eor x3, x11, x16
csetm x11, cc
subs x20, x20, x5
cneg x5, x20, cc
cinv x11, x11, cc
cmn x16, #0x1
mul x17, x21, x12
eor x8, x7, x16
adcs x10, x19, x3
and x19, x9, #0x1ff
adcs x20, x15, x8
umulh x15, x21, x12
eor x12, x10, x9
eor x8, x6, x9
adcs x6, x4, x16
adcs x4, x22, x16
adcs x21, x14, x16
adc x7, x26, x16
mul x10, x24, x5
cmn x13, #0x1
ldp x3, x14, [x1]
eor x17, x17, x13
umulh x5, x24, x5
adcs x20, x20, x17
eor x17, x15, x13
adcs x16, x6, x17
eor x22, x10, x11
adcs x23, x4, x13
extr x10, x14, x3, #52
and x26, x3, #0xfffffffffffff
adcs x24, x21, x13
and x15, x10, #0xfffffffffffff
adc x6, x7, x13
cmn x11, #0x1
adcs x17, x20, x22
eor x4, x5, x11
ldp x21, x10, [sp]
adcs x7, x16, x4
eor x16, x17, x9
eor x13, x7, x9
ldp x3, x17, [sp, #16]
adcs x7, x23, x11
eor x23, x7, x9
ldp x5, x22, [sp, #32]
adcs x7, x24, x11
adc x24, x6, x11
ldr x6, [x2, #64]
adds x20, x8, x21
lsl x11, x20, #9
eor x4, x7, x9
orr x7, x11, x19
eor x8, x24, x9
adcs x11, x25, x10
mul x26, x6, x26
ldp x19, x24, [sp, #48]
adcs x12, x12, x3
adcs x16, x16, x17
adcs x9, x13, x5
ldr x25, [sp, #64]
extr x20, x11, x20, #55
adcs x13, x23, x22
adcs x4, x4, x19
extr x23, x12, x11, #55
adcs x8, x8, x24
adc x11, x25, xzr
adds x21, x9, x21
extr x9, x16, x12, #55
lsr x12, x16, #55
adcs x10, x13, x10
mul x15, x6, x15
adcs x13, x4, x3
ldp x16, x4, [x2]
ldr x3, [x1, #64]
adcs x17, x8, x17
adcs x5, x5, x7
adcs x20, x22, x20
adcs x8, x19, x23
and x22, x16, #0xfffffffffffff
ldp x19, x7, [x1, #16]
adcs x9, x24, x9
extr x24, x4, x16, #52
adc x16, x12, x25
mul x22, x3, x22
and x25, x24, #0xfffffffffffff
extr x14, x19, x14, #40
and x12, x14, #0xfffffffffffff
extr x23, x7, x19, #28
ldp x19, x24, [x2, #16]
mul x14, x3, x25
and x23, x23, #0xfffffffffffff
add x22, x26, x22
lsl x11, x11, #48
lsr x26, x22, #52
lsl x25, x22, #12
mul x22, x6, x12
extr x12, x19, x4, #40
add x4, x15, x14
mul x15, x6, x23
add x4, x4, x26
extr x23, x24, x19, #28
ldp x14, x19, [x1, #32]
and x26, x12, #0xfffffffffffff
extr x12, x4, x25, #12
and x25, x23, #0xfffffffffffff
adds x21, x21, x12
mul x12, x3, x26
extr x23, x14, x7, #16
and x23, x23, #0xfffffffffffff
mul x7, x3, x25
ldp x25, x26, [x2, #32]
add x12, x22, x12
extr x22, x19, x14, #56
mul x23, x6, x23
lsr x14, x14, #4
extr x24, x25, x24, #16
add x7, x15, x7
and x15, x24, #0xfffffffffffff
and x22, x22, #0xfffffffffffff
lsr x24, x4, #52
mul x15, x3, x15
and x14, x14, #0xfffffffffffff
add x12, x12, x24
lsl x24, x4, #12
lsr x4, x12, #52
extr x24, x12, x24, #24
adcs x10, x10, x24
lsl x24, x12, #12
add x12, x7, x4
mul x22, x6, x22
add x4, x23, x15
extr x7, x12, x24, #36
adcs x13, x13, x7
lsl x15, x12, #12
add x7, x4, x11
lsr x24, x12, #52
ldp x23, x11, [x2, #48]
add x4, x7, x24
mul x12, x6, x14
extr x7, x26, x25, #56
extr x14, x4, x15, #48
and x2, x7, #0xfffffffffffff
extr x24, x11, x23, #32
ldp x15, x7, [x1, #48]
and x1, x24, #0xfffffffffffff
lsr x24, x4, #52
mul x2, x3, x2
extr x26, x23, x26, #44
lsr x23, x25, #4
and x23, x23, #0xfffffffffffff
and x25, x26, #0xfffffffffffff
extr x26, x7, x15, #32
extr x19, x15, x19, #44
mul x23, x3, x23
and x15, x26, #0xfffffffffffff
lsl x26, x4, #12
and x4, x19, #0xfffffffffffff
lsr x11, x11, #20
mul x19, x6, x4
adcs x17, x17, x14
add x14, x22, x2
add x22, x12, x23
lsr x7, x7, #20
add x22, x22, x24
extr x2, x22, x26, #60
mul x24, x3, x25
lsr x22, x22, #52
add x14, x14, x22
lsl x22, x2, #8
extr x22, x14, x22, #8
lsl x2, x14, #12
mul x1, x3, x1
adcs x12, x5, x22
mul x5, x6, x15
and x26, x10, x13
and x4, x26, x17
add x23, x19, x24
lsr x14, x14, #52
mul x22, x3, x11
add x11, x23, x14
extr x25, x11, x2, #20
lsl x19, x11, #12
adcs x25, x20, x25
and x14, x4, x12
add x1, x5, x1
and x14, x14, x25
mul x15, x6, x7
add x26, x15, x22
mul x6, x6, x3
lsr x22, x11, #52
add x4, x1, x22
lsr x1, x4, #52
extr x3, x4, x19, #32
lsl x15, x4, #12
add x7, x26, x1
adcs x23, x8, x3
extr x20, x7, x15, #44
and x3, x14, x23
lsr x19, x7, #44
adcs x7, x9, x20
add x11, x6, x19
adc x4, x16, x11
lsr x14, x4, #9
cmp xzr, xzr
and x15, x3, x7
orr x3, x4, #0xfffffffffffffe00
adcs xzr, x21, x14
adcs xzr, x15, xzr
adcs xzr, x3, xzr
adcs x11, x21, x14
and x14, x11, #0x1ff
adcs x1, x10, xzr
extr x10, x1, x11, #9
str x14, [x0, #64]
adcs x14, x13, xzr
extr x11, x14, x1, #9
adcs x1, x17, xzr
extr x4, x1, x14, #9
stp x10, x11, [x0]
adcs x11, x12, xzr
extr x14, x11, x1, #9
adcs x10, x25, xzr
extr x11, x10, x11, #9
stp x4, x14, [x0, #16]
adcs x14, x23, xzr
extr x10, x14, x10, #9
adcs x1, x7, xzr
stp x11, x10, [x0, #32]
extr x14, x1, x14, #9
adc x10, x3, xzr
extr x26, x10, x1, #9
stp x14, x26, [x0, #48]
// Restore regs and return
CFI_INC_SP(80)
CFI_POP2(x25,x26)
CFI_POP2(x23,x24)
CFI_POP2(x21,x22)
CFI_POP2(x19,x20)
CFI_RET
S2N_BN_SIZE_DIRECTIVE(bignum_mul_p521)
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif