packages feed

crypton-2.1.2: cbits/s2n/arm/bignum_sqr_p521.S

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0

// ----------------------------------------------------------------------------
// Square modulo p_521, z := (x^2) mod p_521, assuming x reduced
// Input x[9]; output z[9]
//
//    extern void bignum_sqr_p521(uint64_t z[static 9], const uint64_t x[static 9]);
//
// Standard ARM ABI: X0 = z, X1 = x
// ----------------------------------------------------------------------------

#include "_internal_s2n_bignum_arm.h"

// bignum_sqr_p521 is functionally equivalent to unopt/bignum_sqr_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]!
//        ldp x20, x19, [x1]
//        ldr q23, [x1]
//        ldr q1, [x1]
//        ldr q16, [x1]
//        ldp x14, x12, [x1, #16]
//        ldr q28, [x1, #16]
//        ldr q31, [x1, #16]
//        ldp x9, x2, [x1, #32]
//        ldr q29, [x1, #32]
//        ldr q4, [x1, #32]
//        ldr q5, [x1]
//        ldr q2, [x1, #32]
//        ldp x6, x13, [x1, #48]
//        ldr q24, [x1, #48]
//        ldr q27, [x1, #48]
//        ldr q0, [x1, #16]
//        ldr q30, [x1, #48]
//        mul x17, x9, x6
//        mul x10, x2, x13
//        umulh x24, x9, x6
//        subs x4, x9, x2
//        cneg x4, x4, cc
//        csetm x16, cc
//        subs x3, x13, x6
//        cneg x23, x3, cc
//        mul x3, x4, x23
//        umulh x4, x4, x23
//        cinv x22, x16, cc
//        eor x23, x3, x22
//        eor x16, x4, x22
//        adds x3, x17, x24
//        adc x24, x24, xzr
//        umulh x4, x2, x13
//        adds x3, x3, x10
//        adcs x24, x24, x4
//        adc x4, x4, xzr
//        adds x24, x24, x10
//        adc x10, x4, xzr
//        cmn x22, #0x1
//        adcs x4, x3, x23
//        adcs x24, x24, x16
//        adc x10, x10, x22
//        adds x8, x17, x17
//        adcs x22, x4, x4
//        adcs x5, x24, x24
//        adcs x11, x10, x10
//        adc x23, xzr, xzr
//        movi v25.2D, #0xffffffff
//        uzp2 v19.4S, v4.4S, v4.4S
//        xtn v26.2S, v29.2D
//        xtn v22.2S, v4.2D
//        rev64 v4.4S, v4.4S
//        umull v7.2D, v26.2S, v22.2S
//        umull v21.2D, v26.2S, v19.2S
//        uzp2 v17.4S, v29.4S, v29.4S
//        mul v4.4S, v4.4S, v29.4S
//        usra v21.2D, v7.2D, #32
//        umull v18.2D, v17.2S, v19.2S
//        uaddlp v4.2D, v4.4S
//        and v7.16B, v21.16B, v25.16B
//        umlal v7.2D, v17.2S, v22.2S
//        shl v4.2D, v4.2D, #32
//        usra v18.2D, v21.2D, #32
//        umlal v4.2D, v26.2S, v22.2S
//        usra v18.2D, v7.2D, #32
//        mov x15, v4.d[0]
//        mov x16, v4.d[1]
//        mul x3, x9, x2
//        mov x10, v18.d[0]
//        mov x17, v18.d[1]
//        umulh x4, x9, x2
//        adds x24, x10, x3
//        adcs x10, x16, x4
//        adc x17, x17, xzr
//        adds x7, x24, x3
//        adcs x10, x10, x4
//        adc x17, x17, xzr
//        adds x8, x8, x10
//        adcs x22, x22, x17
//        adcs x21, x5, xzr
//        adcs x5, x11, xzr
//        adc x11, x23, xzr
//        movi v25.2D, #0xffffffff
//        uzp2 v19.4S, v27.4S, v27.4S
//        xtn v26.2S, v24.2D
//        xtn v22.2S, v27.2D
//        rev64 v4.4S, v27.4S
//        umull v7.2D, v26.2S, v22.2S
//        umull v21.2D, v26.2S, v19.2S
//        uzp2 v17.4S, v24.4S, v24.4S
//        mul v4.4S, v4.4S, v24.4S
//        usra v21.2D, v7.2D, #32
//        umull v18.2D, v17.2S, v19.2S
//        uaddlp v4.2D, v4.4S
//        and v7.16B, v21.16B, v25.16B
//        umlal v7.2D, v17.2S, v22.2S
//        shl v4.2D, v4.2D, #32
//        usra v18.2D, v21.2D, #32
//        umlal v4.2D, v26.2S, v22.2S
//        usra v18.2D, v7.2D, #32
//        mov x23, v4.d[0]
//        mov x16, v4.d[1]
//        mul x3, x6, x13
//        mov x10, v18.d[0]
//        mov x17, v18.d[1]
//        umulh x4, x6, x13
//        adds x24, x10, x3
//        adcs x10, x16, x4
//        adc x17, x17, xzr
//        adds x24, x24, x3
//        adcs x10, x10, x4
//        adc x17, x17, xzr
//        adds x23, x23, x21
//        adcs x16, x24, x5
//        adcs x3, x10, x11
//        adc x21, x17, xzr
//        ldr x17, [x1, #64]
//        add x5, x17, x17
//        mul x11, x17, x17
//        and x17, x20, #0xfffffffffffff
//        mul x4, x5, x17
//        extr x17, x19, x20, #52
//        and x17, x17, #0xfffffffffffff
//        mul x10, x5, x17
//        lsr x17, x4, #52
//        add x24, x10, x17
//        lsl x17, x4, #12
//        extr x17, x24, x17, #12
//        adds x15, x15, x17
//        extr x17, x14, x19, #40
//        and x17, x17, #0xfffffffffffff
//        mul x10, x5, x17
//        lsr x17, x24, #52
//        add x4, x10, x17
//        lsl x17, x24, #12
//        extr x17, x4, x17, #24
//        adcs x7, x7, x17
//        extr x17, x12, x14, #28
//        and x17, x17, #0xfffffffffffff
//        mul x10, x5, x17
//        lsr x17, x4, #52
//        add x24, x10, x17
//        lsl x17, x4, #12
//        extr x17, x24, x17, #36
//        adcs x8, x8, x17
//        extr x17, x9, x12, #16
//        and x17, x17, #0xfffffffffffff
//        mul x10, x5, x17
//        lsr x17, x24, #52
//        add x4, x10, x17
//        lsl x17, x24, #12
//        extr x17, x4, x17, #48
//        adcs x22, x22, x17
//        lsr x17, x9, #4
//        and x17, x17, #0xfffffffffffff
//        mul x10, x5, x17
//        lsr x17, x4, #52
//        add x24, x10, x17
//        lsl x17, x4, #12
//        extr x4, x24, x17, #60
//        extr x17, x2, x9, #56
//        and x17, x17, #0xfffffffffffff
//        mul x10, x5, x17
//        lsr x17, x24, #52
//        add x24, x10, x17
//        lsl x17, x4, #8
//        extr x17, x24, x17, #8
//        adcs x23, x23, x17
//        extr x17, x6, x2, #44
//        and x17, x17, #0xfffffffffffff
//        mul x10, x5, x17
//        lsr x17, x24, #52
//        add x4, x10, x17
//        lsl x17, x24, #12
//        extr x17, x4, x17, #20
//        adcs x16, x16, x17
//        extr x17, x13, x6, #32
//        and x17, x17, #0xfffffffffffff
//        mul x10, x5, x17
//        lsr x17, x4, #52
//        add x24, x10, x17
//        lsl x17, x4, #12
//        extr x17, x24, x17, #32
//        adcs x3, x3, x17
//        lsr x17, x13, #20
//        mul x10, x5, x17
//        lsr x17, x24, #52
//        add x10, x10, x17
//        lsl x17, x24, #12
//        extr x17, x10, x17, #44
//        adcs x4, x21, x17
//        lsr x17, x10, #44
//        adc x24, x11, x17
//        extr x10, x7, x15, #9
//        extr x17, x8, x7, #9
//        stp x10, x17, [x0]                       // @slothy:writes=buffer0
//        extr x10, x22, x8, #9
//        extr x17, x23, x22, #9
//        stp x10, x17, [x0, #16]                  // @slothy:writes=buffer16
//        extr x10, x16, x23, #9
//        extr x17, x3, x16, #9
//        stp x10, x17, [x0, #32]                  // @slothy:writes=buffer32
//        extr x10, x4, x3, #9
//        extr x17, x24, x4, #9
//        stp x10, x17, [x0, #48]                  // @slothy:writes=buffer48
//        and x10, x15, #0x1ff
//        lsr x17, x24, #9
//        add x17, x10, x17
//        str x17, [x0, #64]                       // @slothy:writes=buffer64
//        uzp1 v17.4S, v28.4S, v23.4S
//        rev64 v4.4S, v28.4S
//        uzp1 v7.4S, v23.4S, v23.4S
//        mul v4.4S, v4.4S, v23.4S
//        uaddlp v4.2D, v4.4S
//        shl v4.2D, v4.2D, #32
//        umlal v4.2D, v7.2S, v17.2S
//        mov x8, v4.d[0]
//        mov x22, v4.d[1]
//        umulh x23, x20, x14
//        subs x17, x20, x19
//        cneg x4, x17, cc
//        csetm x24, cc
//        subs x17, x12, x14
//        cneg x17, x17, cc
//        mul x10, x4, x17
//        umulh x17, x4, x17
//        cinv x16, x24, cc
//        eor x3, x10, x16
//        eor x4, x17, x16
//        adds x24, x8, x23
//        adc x10, x23, xzr
//        umulh x17, x19, x12
//        adds x24, x24, x22
//        adcs x10, x10, x17
//        adc x17, x17, xzr
//        adds x10, x10, x22
//        adc x17, x17, xzr
//        cmn x16, #0x1
//        adcs x24, x24, x3
//        adcs x10, x10, x4
//        adc x17, x17, x16
//        adds x15, x8, x8
//        adcs x7, x24, x24
//        adcs x8, x10, x10
//        adcs x22, x17, x17
//        adc x23, xzr, xzr
//        movi v25.2D, #0xffffffff
//        uzp2 v19.4S, v16.4S, v16.4S
//        xtn v26.2S, v1.2D
//        xtn v22.2S, v16.2D
//        rev64 v4.4S, v16.4S
//        umull v7.2D, v26.2S, v22.2S
//        umull v21.2D, v26.2S, v19.2S
//        uzp2 v17.4S, v1.4S, v1.4S
//        mul v4.4S, v4.4S, v1.4S
//        usra v21.2D, v7.2D, #32
//        umull v18.2D, v17.2S, v19.2S
//        uaddlp v4.2D, v4.4S
//        and v7.16B, v21.16B, v25.16B
//        umlal v7.2D, v17.2S, v22.2S
//        shl v4.2D, v4.2D, #32
//        usra v18.2D, v21.2D, #32
//        umlal v4.2D, v26.2S, v22.2S
//        usra v18.2D, v7.2D, #32
//        mov x21, v4.d[0]
//        mov x16, v4.d[1]
//        mul x3, x20, x19
//        mov x10, v18.d[0]
//        mov x17, v18.d[1]
//        umulh x4, x20, x19
//        adds x24, x10, x3
//        adcs x10, x16, x4
//        adc x17, x17, xzr
//        adds x5, x24, x3
//        adcs x10, x10, x4
//        adc x17, x17, xzr
//        adds x11, x15, x10
//        adcs x15, x7, x17
//        adcs x7, x8, xzr
//        adcs x8, x22, xzr
//        adc x22, x23, xzr
//        xtn v7.2S, v31.2D
//        shrn v4.2S, v31.2D, #32
//        umull v4.2D, v7.2S, v4.2S
//        shl v4.2D, v4.2D, #33
//        umlal v4.2D, v7.2S, v7.2S
//        mov x23, v4.d[0]
//        mov x16, v4.d[1]
//        mul x3, x14, x12
//        umulh x10, x14, x14
//        umulh x17, x12, x12
//        umulh x4, x14, x12
//        adds x24, x10, x3
//        adcs x10, x16, x4
//        adc x17, x17, xzr
//        adds x24, x24, x3
//        adcs x10, x10, x4
//        adc x17, x17, xzr
//        adds x16, x23, x7
//        adcs x3, x24, x8
//        adcs x4, x10, x22
//        adc x24, x17, xzr
//        ldp x10, x17, [x0]                       // @slothy:reads=buffer0
//        adds x10, x10, x21
//        adcs x17, x17, x5
//        stp x10, x17, [x0]                       // @slothy:writes=buffer0
//        ldp x10, x17, [x0, #16]                  // @slothy:reads=buffer16
//        adcs x10, x10, x11
//        adcs x17, x17, x15
//        stp x10, x17, [x0, #16]                  // @slothy:writes=buffer16
//        ldp x10, x17, [x0, #32]                  // @slothy:reads=buffer32
//        adcs x10, x10, x16
//        adcs x17, x17, x3
//        stp x10, x17, [x0, #32]                  // @slothy:writes=buffer32
//        ldp x10, x17, [x0, #48]                  // @slothy:reads=buffer48
//        adcs x10, x10, x4
//        adcs x17, x17, x24
//        stp x10, x17, [x0, #48]                  // @slothy:writes=buffer48
//        ldr x17, [x0, #64]                       // @slothy:reads=buffer64
//        adc x17, x17, xzr
//        str x17, [x0, #64]                       // @slothy:writes=buffer64
//        movi v25.2D, #0xffffffff
//        uzp2 v19.4S, v2.4S, v2.4S
//        xtn v26.2S, v5.2D
//        xtn v22.2S, v2.2D
//        rev64 v4.4S, v2.4S
//        umull v7.2D, v26.2S, v22.2S
//        umull v21.2D, v26.2S, v19.2S
//        uzp2 v17.4S, v5.4S, v5.4S
//        mul v4.4S, v4.4S, v5.4S
//        usra v21.2D, v7.2D, #32
//        umull v18.2D, v17.2S, v19.2S
//        uaddlp v4.2D, v4.4S
//        and v7.16B, v21.16B, v25.16B
//        umlal v7.2D, v17.2S, v22.2S
//        shl v4.2D, v4.2D, #32
//        usra v18.2D, v21.2D, #32
//        umlal v4.2D, v26.2S, v22.2S
//        usra v18.2D, v7.2D, #32
//        mov x5, v4.d[0]
//        mov x4, v4.d[1]
//        movi v25.2D, #0xffffffff
//        uzp2 v17.4S, v30.4S, v30.4S
//        xtn v19.2S, v0.2D
//        xtn v26.2S, v30.2D
//        rev64 v4.4S, v30.4S
//        umull v7.2D, v19.2S, v26.2S
//        umull v22.2D, v19.2S, v17.2S
//        uzp2 v21.4S, v0.4S, v0.4S
//        mul v4.4S, v4.4S, v0.4S
//        usra v22.2D, v7.2D, #32
//        umull v17.2D, v21.2S, v17.2S
//        uaddlp v4.2D, v4.4S
//        and v7.16B, v22.16B, v25.16B
//        umlal v7.2D, v21.2S, v26.2S
//        shl v4.2D, v4.2D, #32
//        usra v17.2D, v22.2D, #32
//        umlal v4.2D, v19.2S, v26.2S
//        usra v17.2D, v7.2D, #32
//        mov x24, v4.d[0]
//        mov x10, v4.d[1]
//        mov x17, v18.d[0]
//        adds x4, x4, x17
//        mov x17, v18.d[1]
//        adcs x24, x24, x17
//        mov x17, v17.d[0]
//        adcs x10, x10, x17
//        mov x17, v17.d[1]
//        adc x17, x17, xzr
//        adds x15, x4, x5
//        adcs x4, x24, x4
//        adcs x24, x10, x24
//        adcs x10, x17, x10
//        adc x17, xzr, x17
//        adds x7, x4, x5
//        adcs x8, x24, x15
//        adcs x22, x10, x4
//        adcs x23, x17, x24
//        adcs x16, xzr, x10
//        adc x3, xzr, x17
//        subs x17, x14, x12
//        cneg x24, x17, cc
//        csetm x4, cc
//        subs x17, x13, x6
//        cneg x10, x17, cc
//        mul x17, x24, x10
//        umulh x24, x24, x10
//        cinv x10, x4, cc
//        cmn x10, #0x1
//        eor x17, x17, x10
//        adcs x23, x23, x17
//        eor x17, x24, x10
//        adcs x16, x16, x17
//        adc x3, x3, x10
//        subs x17, x20, x19
//        cneg x24, x17, cc
//        csetm x4, cc
//        subs x17, x2, x9
//        cneg x10, x17, cc
//        mul x17, x24, x10
//        umulh x24, x24, x10
//        cinv x10, x4, cc
//        cmn x10, #0x1
//        eor x17, x17, x10
//        adcs x11, x15, x17
//        eor x17, x24, x10
//        adcs x15, x7, x17
//        adcs x7, x8, x10
//        adcs x22, x22, x10
//        adcs x23, x23, x10
//        adcs x16, x16, x10
//        adc x3, x3, x10
//        subs x17, x19, x12
//        cneg x24, x17, cc
//        csetm x4, cc
//        subs x17, x13, x2
//        cneg x10, x17, cc
//        mul x17, x24, x10
//        umulh x24, x24, x10
//        cinv x10, x4, cc
//        cmn x10, #0x1
//        eor x17, x17, x10
//        adcs x8, x22, x17
//        eor x17, x24, x10
//        adcs x23, x23, x17
//        adcs x16, x16, x10
//        adc x3, x3, x10
//        subs x17, x20, x14
//        cneg x24, x17, cc
//        csetm x4, cc
//        subs x17, x6, x9
//        cneg x10, x17, cc
//        mul x17, x24, x10
//        umulh x24, x24, x10
//        cinv x10, x4, cc
//        cmn x10, #0x1
//        eor x17, x17, x10
//        adcs x22, x15, x17
//        eor x17, x24, x10
//        adcs x4, x7, x17
//        adcs x24, x8, x10
//        adcs x23, x23, x10
//        adcs x16, x16, x10
//        adc x3, x3, x10
//        subs x12, x20, x12
//        cneg x10, x12, cc
//        csetm x17, cc
//        subs x12, x13, x9
//        cneg x9, x12, cc
//        mul x12, x10, x9
//        umulh x13, x10, x9
//        cinv x9, x17, cc
//        cmn x9, #0x1
//        eor x12, x12, x9
//        adcs x4, x4, x12
//        eor x12, x13, x9
//        adcs x24, x24, x12
//        adcs x10, x23, x9
//        adcs x17, x16, x9
//        adc x13, x3, x9
//        subs x19, x19, x14
//        cneg x12, x19, cc
//        csetm x9, cc
//        subs x6, x6, x2
//        cneg x14, x6, cc
//        mul x19, x12, x14
//        umulh x12, x12, x14
//        cinv x14, x9, cc
//        cmn x14, #0x1
//        eor x19, x19, x14
//        adcs x23, x4, x19
//        eor x19, x12, x14
//        adcs x16, x24, x19
//        adcs x6, x10, x14
//        adcs x2, x17, x14
//        adc x9, x13, x14
//        ldp x12, x14, [x0]                       // @slothy:reads=buffer0
//        extr x19, x6, x16, #8
//        adds x10, x19, x12
//        extr x19, x2, x6, #8
//        adcs x17, x19, x14
//        ldp x14, x12, [x0, #16]                  // @slothy:reads=buffer16
//        extr x19, x9, x2, #8
//        adcs x13, x19, x14
//        and x14, x17, x13
//        lsr x19, x9, #8
//        adcs x6, x19, x12
//        and x9, x14, x6
//        ldp x14, x12, [x0, #32]                  // @slothy:reads=buffer32
//        lsl x19, x5, #1
//        adcs x2, x19, x14
//        and x14, x9, x2
//        extr x19, x11, x5, #63
//        adcs x3, x19, x12
//        and x9, x14, x3
//        ldp x14, x12, [x0, #48]                  // @slothy:reads=buffer48
//        extr x19, x22, x11, #63
//        adcs x4, x19, x14
//        and x14, x9, x4
//        extr x19, x23, x22, #63
//        adcs x24, x19, x12
//        and x12, x14, x24
//        ldr x14, [x0, #64]                       // @slothy:reads=buffer64
//        extr x19, x16, x23, #63
//        and x19, x19, #0x1ff
//        adc x19, x14, x19
//        lsr x14, x19, #9
//        orr x19, x19, #0xfffffffffffffe00
//        cmp xzr, xzr
//        adcs xzr, x10, x14
//        adcs xzr, x12, xzr
//        adcs xzr, x19, xzr
//        adcs x10, x10, x14
//        adcs x17, x17, xzr
//        adcs x13, x13, xzr
//        adcs x6, x6, xzr
//        adcs x2, x2, xzr
//        adcs x9, x3, xzr
//        adcs x12, x4, xzr
//        adcs x14, x24, xzr
//        adc x19, x19, xzr
//        and x19, x19, #0x1ff
//        stp x10, x17, [x0]                       // @slothy:writes=buffer0
//        stp x13, x6, [x0, #16]                   // @slothy:writes=buffer16
//        stp x2, x9, [x0, #32]                    // @slothy:writes=buffer32
//        stp x12, x14, [x0, #48]                  // @slothy:writes=buffer48
//        str x19, [x0, #64]                       // @slothy:writes=buffer64
//        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 as, say, 'input.S'.
//        export OUTPUTS="[hint_buffer0,hint_buffer16,hint_buffer32,hint_buffer48,hint_buffer64]"
//        export RESERVED_REGS="[x18,x25,x26,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_sqr_p521)
        S2N_BN_FUNCTION_TYPE_DIRECTIVE(bignum_sqr_p521)
        S2N_BN_SYM_PRIVACY_DIRECTIVE(bignum_sqr_p521)
        .text
        .balign 4

S2N_BN_SYMBOL(bignum_sqr_p521):
        CFI_START

// Save registers

        CFI_PUSH2(x19,x20)
        CFI_PUSH2(x21,x22)
        CFI_PUSH2(x23,x24)

        ldr q23, [x1, #32]
        ldp x9, x2, [x1, #32]
        ldr q16, [x1, #32]
        ldr q20, [x1, #48]
        ldp x6, x13, [x1, #48]
        rev64 v2.4S, v23.4S
        mul x14, x9, x2
        ldr q31, [x1, #48]
        subs x22, x9, x2
        uzp2 v26.4S, v23.4S, v23.4S
        mul v30.4S, v2.4S, v16.4S
        xtn v0.2S, v20.2D
        csetm x12, cc
        xtn v21.2S, v16.2D
        xtn v23.2S, v23.2D
        umulh x10, x9, x6
        rev64 v27.4S, v31.4S
        umull v2.2D, v21.2S, v26.2S
        cneg x23, x22, cc
        uaddlp v25.2D, v30.4S
        umull v18.2D, v21.2S, v23.2S
        mul x22, x9, x6
        mul v6.4S, v27.4S, v20.4S
        uzp2 v17.4S, v20.4S, v20.4S
        shl v20.2D, v25.2D, #32
        uzp2 v27.4S, v31.4S, v31.4S
        mul x16, x2, x13
        umlal v20.2D, v21.2S, v23.2S
        usra v2.2D, v18.2D, #32
        adds x8, x22, x10
        umull v25.2D, v17.2S, v27.2S
        xtn v31.2S, v31.2D
        movi v1.2D, #0xffffffff
        adc x3, x10, xzr
        umulh x21, x2, x13
        uzp2 v21.4S, v16.4S, v16.4S
        umull v18.2D, v0.2S, v27.2S
        subs x19, x13, x6
        and v7.16B, v2.16B, v1.16B
        umull v27.2D, v0.2S, v31.2S
        cneg x20, x19, cc
        movi v30.2D, #0xffffffff
        umull v16.2D, v21.2S, v26.2S
        umlal v7.2D, v21.2S, v23.2S
        mul x19, x23, x20
        cinv x7, x12, cc
        uaddlp v6.2D, v6.4S
        eor x12, x19, x7
        adds x11, x8, x16
        umulh x10, x23, x20
        ldr q1, [x1]
        usra v16.2D, v2.2D, #32
        adcs x19, x3, x21
        shl v2.2D, v6.2D, #32
        adc x20, x21, xzr
        adds x17, x19, x16
        usra v18.2D, v27.2D, #32
        adc x19, x20, xzr
        cmn x7, #0x1
        umlal v2.2D, v0.2S, v31.2S
        umulh x16, x9, x2
        adcs x8, x11, x12
        usra v16.2D, v7.2D, #32
        ldr x12, [x1, #64]
        eor x20, x10, x7
        umulh x10, x6, x13
        mov x23, v2.d[0]
        mov x3, v2.d[1]
        adcs x21, x17, x20
        usra v25.2D, v18.2D, #32
        and v23.16B, v18.16B, v30.16B
        adc x7, x19, x7
        adds x22, x22, x22
        ldr q7, [x1, #16]
        adcs x17, x8, x8
        umlal v23.2D, v17.2S, v31.2S
        mov x19, v16.d[0]
        mul x11, x12, x12
        ldr q4, [x1]
        usra v25.2D, v23.2D, #32
        add x5, x12, x12
        adcs x15, x21, x21
        ldr q28, [x1]
        mov x12, v20.d[1]
        adcs x24, x7, x7
        mov x21, v16.d[1]
        adc x4, xzr, xzr
        adds x19, x19, x14
        ldr q18, [x1, #16]
        xtn v26.2S, v1.2D
        adcs x8, x12, x16
        adc x21, x21, xzr
        adds x7, x19, x14
        xtn v23.2S, v7.2D
        rev64 v21.4S, v28.4S
        adcs x12, x8, x16
        ldp x20, x19, [x1]
        mov x16, v25.d[1]
        xtn v22.2S, v28.2D
        adc x14, x21, xzr
        adds x8, x22, x12
        uzp2 v24.4S, v28.4S, v28.4S
        rev64 v28.4S, v18.4S
        mul x12, x6, x13
        mul v16.4S, v21.4S, v1.4S
        shrn v31.2S, v7.2D, #32
        adcs x22, x17, x14
        mov x14, v25.d[0]
        and x21, x20, #0xfffffffffffff
        umull v17.2D, v26.2S, v24.2S
        ldr q2, [x1, #32]
        adcs x17, x15, xzr
        ldr q30, [x1, #48]
        umull v7.2D, v26.2S, v22.2S
        adcs x15, x24, xzr
        ldr q0, [x1, #16]
        movi v6.2D, #0xffffffff
        adc x4, x4, xzr
        adds x14, x14, x12
        uzp1 v27.4S, v18.4S, v4.4S
        uzp2 v19.4S, v1.4S, v1.4S
        adcs x24, x3, x10
        mul x3, x5, x21
        umull v29.2D, v23.2S, v31.2S
        ldr q5, [x1]
        adc x21, x16, xzr
        adds x16, x14, x12
        extr x12, x19, x20, #52
        umull v18.2D, v19.2S, v24.2S
        adcs x24, x24, x10
        and x10, x12, #0xfffffffffffff
        ldp x14, x12, [x1, #16]
        usra v17.2D, v7.2D, #32
        adc x21, x21, xzr
        adds x23, x23, x17
        mul x17, x5, x10
        shl v21.2D, v29.2D, #33
        lsl x10, x3, #12
        lsr x1, x3, #52
        rev64 v29.4S, v2.4S
        uaddlp v25.2D, v16.4S
        add x17, x17, x1
        adcs x16, x16, x15
        extr x3, x14, x19, #40
        mov x15, v20.d[0]
        extr x10, x17, x10, #12
        and x3, x3, #0xfffffffffffff
        shl v3.2D, v25.2D, #32
        and v6.16B, v17.16B, v6.16B
        mul x1, x5, x3
        usra v18.2D, v17.2D, #32
        adcs x3, x24, x4
        extr x4, x12, x14, #28
        umlal v6.2D, v19.2S, v22.2S
        xtn v20.2S, v2.2D
        umlal v3.2D, v26.2S, v22.2S
        movi v26.2D, #0xffffffff
        lsr x24, x17, #52
        and x4, x4, #0xfffffffffffff
        uzp2 v19.4S, v2.4S, v2.4S
        add x1, x1, x24
        mul x24, x5, x4
        lsl x4, x17, #12
        xtn v24.2S, v5.2D
        extr x17, x1, x4, #24
        adc x21, x21, xzr
        umlal v21.2D, v23.2S, v23.2S
        adds x4, x15, x10
        lsl x10, x1, #12
        adcs x15, x7, x17
        mul v23.4S, v28.4S, v4.4S
        and x7, x4, #0x1ff
        lsr x17, x1, #52
        umulh x1, x19, x12
        uzp2 v17.4S, v5.4S, v5.4S
        extr x4, x15, x4, #9
        add x24, x24, x17
        mul v29.4S, v29.4S, v5.4S
        extr x17, x24, x10, #36
        extr x10, x9, x12, #16
        uzp1 v28.4S, v4.4S, v4.4S
        adcs x17, x8, x17
        and x8, x10, #0xfffffffffffff
        umull v16.2D, v24.2S, v20.2S
        extr x10, x17, x15, #9
        mul x15, x5, x8
        stp x4, x10, [x0]
        lsl x4, x24, #12
        lsr x8, x9, #4
        uaddlp v4.2D, v23.4S
        and x8, x8, #0xfffffffffffff
        umull v23.2D, v24.2S, v19.2S
        mul x8, x5, x8
        extr x10, x2, x9, #56
        lsr x24, x24, #52
        and x10, x10, #0xfffffffffffff
        add x15, x15, x24
        extr x4, x15, x4, #48
        mul x24, x5, x10
        lsr x10, x15, #52
        usra v23.2D, v16.2D, #32
        add x10, x8, x10
        shl v4.2D, v4.2D, #32
        adcs x22, x22, x4
        extr x4, x6, x2, #44
        lsl x15, x15, #12
        lsr x8, x10, #52
        extr x15, x10, x15, #60
        and x10, x4, #0xfffffffffffff
        umlal v4.2D, v28.2S, v27.2S
        add x8, x24, x8
        extr x4, x13, x6, #32
        mul x24, x5, x10
        uzp2 v16.4S, v30.4S, v30.4S
        lsl x10, x15, #8
        rev64 v28.4S, v30.4S
        and x15, x4, #0xfffffffffffff
        extr x4, x8, x10, #8
        mul x10, x5, x15
        lsl x15, x8, #12
        adcs x23, x23, x4
        lsr x4, x8, #52
        lsr x8, x13, #20
        add x4, x24, x4
        mul x8, x5, x8
        lsr x24, x4, #52
        extr x15, x4, x15, #20
        lsl x4, x4, #12
        add x10, x10, x24
        adcs x15, x16, x15
        extr x4, x10, x4, #32
        umulh x5, x20, x14
        adcs x3, x3, x4
        usra v18.2D, v6.2D, #32
        lsl x16, x10, #12
        extr x24, x15, x23, #9
        lsr x10, x10, #52
        uzp2 v27.4S, v0.4S, v0.4S
        add x8, x8, x10
        extr x10, x3, x15, #9
        extr x4, x22, x17, #9
        and v25.16B, v23.16B, v26.16B
        lsr x17, x8, #44
        extr x15, x8, x16, #44
        extr x16, x23, x22, #9
        xtn v7.2S, v30.2D
        mov x8, v4.d[0]
        stp x24, x10, [x0, #32]
        uaddlp v30.2D, v29.4S
        stp x4, x16, [x0, #16]
        umulh x24, x20, x19
        adcs x15, x21, x15
        adc x16, x11, x17
        subs x11, x20, x19
        xtn v5.2S, v0.2D
        csetm x17, cc
        extr x3, x15, x3, #9
        mov x22, v4.d[1]
        cneg x21, x11, cc
        subs x10, x12, x14
        mul v31.4S, v28.4S, v0.4S
        cneg x10, x10, cc
        cinv x11, x17, cc
        shl v4.2D, v30.2D, #32
        umull v28.2D, v5.2S, v16.2S
        extr x23, x16, x15, #9
        adds x4, x8, x5
        mul x17, x21, x10
        umull v22.2D, v5.2S, v7.2S
        adc x15, x5, xzr
        adds x4, x4, x22
        uaddlp v2.2D, v31.4S
        lsr x5, x16, #9
        adcs x16, x15, x1
        mov x15, v18.d[0]
        adc x1, x1, xzr
        umulh x10, x21, x10
        adds x22, x16, x22
        umlal v4.2D, v24.2S, v20.2S
        umull v30.2D, v27.2S, v16.2S
        stp x3, x23, [x0, #48]
        add x3, x7, x5
        adc x16, x1, xzr
        usra v28.2D, v22.2D, #32
        mul x23, x20, x19
        eor x1, x17, x11
        cmn x11, #0x1
        mov x17, v18.d[1]
        umull v18.2D, v17.2S, v19.2S
        adcs x7, x4, x1
        eor x1, x10, x11
        umlal v25.2D, v17.2S, v20.2S
        movi v16.2D, #0xffffffff
        adcs x22, x22, x1
        usra v18.2D, v23.2D, #32
        umulh x4, x14, x14
        adc x1, x16, x11
        adds x10, x8, x8
        shl v23.2D, v2.2D, #32
        str x3, [x0, #64]
        adcs x5, x7, x7
        and v16.16B, v28.16B, v16.16B
        usra v30.2D, v28.2D, #32
        adcs x7, x22, x22
        mov x21, v3.d[1]
        adcs x11, x1, x1
        umlal v16.2D, v27.2S, v7.2S
        adc x22, xzr, xzr
        adds x16, x15, x23
        mul x8, x14, x12
        umlal v23.2D, v5.2S, v7.2S
        usra v18.2D, v25.2D, #32
        umulh x15, x14, x12
        adcs x21, x21, x24
        usra v30.2D, v16.2D, #32
        adc x1, x17, xzr
        adds x3, x16, x23
        adcs x21, x21, x24
        adc x1, x1, xzr
        adds x24, x10, x21
        umulh x21, x12, x12
        adcs x16, x5, x1
        adcs x10, x7, xzr
        mov x17, v21.d[1]
        adcs x23, x11, xzr
        adc x5, x22, xzr
        adds x1, x4, x8
        adcs x22, x17, x15
        ldp x17, x4, [x0]
        mov x11, v21.d[0]
        adc x21, x21, xzr
        adds x1, x1, x8
        adcs x15, x22, x15
        adc x8, x21, xzr
        adds x22, x11, x10
        mov x21, v3.d[0]
        adcs x11, x1, x23
        ldp x1, x10, [x0, #16]
        adcs x15, x15, x5
        adc x7, x8, xzr
        adds x8, x17, x21
        mov x23, v4.d[1]
        ldp x5, x21, [x0, #32]
        adcs x17, x4, x3
        ldr x4, [x0, #64]
        mov x3, v18.d[0]
        adcs x24, x1, x24
        stp x8, x17, [x0]
        adcs x17, x10, x16
        ldp x1, x16, [x0, #48]
        adcs x5, x5, x22
        adcs x8, x21, x11
        stp x5, x8, [x0, #32]
        adcs x1, x1, x15
        mov x15, v23.d[1]
        adcs x21, x16, x7
        stp x1, x21, [x0, #48]
        adc x10, x4, xzr
        subs x7, x14, x12
        mov x16, v18.d[1]
        cneg x5, x7, cc
        csetm x4, cc
        subs x11, x13, x6
        mov x8, v23.d[0]
        cneg x7, x11, cc
        cinv x21, x4, cc
        mov x11, v30.d[0]
        adds x4, x23, x3
        mul x22, x5, x7
        mov x23, v30.d[1]
        adcs x8, x8, x16
        adcs x16, x15, x11
        adc x11, x23, xzr
        umulh x3, x5, x7
        stp x24, x17, [x0, #16]
        mov x5, v4.d[0]
        subs x15, x20, x19
        cneg x7, x15, cc
        str x10, [x0, #64]
        csetm x1, cc
        subs x24, x2, x9
        cneg x17, x24, cc
        cinv x15, x1, cc
        adds x23, x4, x5
        umulh x1, x7, x17
        adcs x24, x8, x4
        adcs x10, x16, x8
        eor x8, x22, x21
        adcs x16, x11, x16
        mul x22, x7, x17
        eor x17, x1, x15
        adc x1, xzr, x11
        adds x11, x24, x5
        eor x7, x3, x21
        adcs x3, x10, x23
        adcs x24, x16, x24
        adcs x4, x1, x10
        eor x10, x22, x15
        adcs x16, xzr, x16
        adc x1, xzr, x1
        cmn x21, #0x1
        adcs x8, x4, x8
        adcs x22, x16, x7
        adc x7, x1, x21
        subs x21, x19, x12
        csetm x4, cc
        cneg x1, x21, cc
        subs x21, x13, x2
        cinv x16, x4, cc
        cneg x4, x21, cc
        cmn x15, #0x1
        adcs x21, x23, x10
        mul x23, x1, x4
        adcs x11, x11, x17
        adcs x3, x3, x15
        umulh x1, x1, x4
        adcs x24, x24, x15
        adcs x8, x8, x15
        adcs x22, x22, x15
        eor x17, x23, x16
        adc x15, x7, x15
        subs x7, x20, x14
        cneg x7, x7, cc
        csetm x4, cc
        subs x10, x20, x12
        cneg x23, x10, cc
        csetm x10, cc
        subs x12, x6, x9
        cinv x20, x4, cc
        cneg x12, x12, cc
        cmn x16, #0x1
        eor x1, x1, x16
        adcs x17, x24, x17
        mul x4, x7, x12
        adcs x8, x8, x1
        umulh x1, x7, x12
        adcs x24, x22, x16
        adc x7, x15, x16
        subs x12, x13, x9
        cneg x12, x12, cc
        cinv x13, x10, cc
        subs x19, x19, x14
        mul x9, x23, x12
        cneg x19, x19, cc
        csetm x10, cc
        eor x16, x1, x20
        subs x22, x6, x2
        umulh x12, x23, x12
        eor x1, x4, x20
        cinv x4, x10, cc
        cneg x22, x22, cc
        cmn x20, #0x1
        adcs x15, x11, x1
        eor x6, x12, x13
        adcs x10, x3, x16
        adcs x17, x17, x20
        eor x23, x9, x13
        adcs x2, x8, x20
        mul x11, x19, x22
        adcs x24, x24, x20
        adc x7, x7, x20
        cmn x13, #0x1
        adcs x3, x10, x23
        umulh x22, x19, x22
        adcs x17, x17, x6
        eor x12, x22, x4
        extr x22, x15, x21, #63
        adcs x8, x2, x13
        extr x21, x21, x5, #63
        ldp x16, x23, [x0]
        adcs x20, x24, x13
        eor x1, x11, x4
        adc x6, x7, x13
        cmn x4, #0x1
        ldp x2, x7, [x0, #16]
        adcs x1, x3, x1
        extr x19, x1, x15, #63
        adcs x14, x17, x12
        extr x1, x14, x1, #63
        lsl x17, x5, #1
        adcs x8, x8, x4
        extr x12, x8, x14, #8
        ldp x15, x11, [x0, #32]
        adcs x9, x20, x4
        adc x3, x6, x4
        adds x16, x12, x16
        extr x6, x9, x8, #8
        ldp x14, x12, [x0, #48]
        extr x8, x3, x9, #8
        adcs x20, x6, x23
        ldr x24, [x0, #64]
        lsr x6, x3, #8
        adcs x8, x8, x2
        and x2, x1, #0x1ff
        and x1, x20, x8
        adcs x4, x6, x7
        adcs x3, x17, x15
        and x1, x1, x4
        adcs x9, x21, x11
        and x1, x1, x3
        adcs x6, x22, x14
        and x1, x1, x9
        and x21, x1, x6
        adcs x14, x19, x12
        adc x1, x24, x2
        cmp xzr, xzr
        orr x12, x1, #0xfffffffffffffe00
        lsr x1, x1, #9
        adcs xzr, x16, x1
        and x21, x21, x14
        adcs xzr, x21, xzr
        adcs xzr, x12, xzr
        adcs x21, x16, x1
        adcs x1, x20, xzr
        adcs x19, x8, xzr
        stp x21, x1, [x0]
        adcs x1, x4, xzr
        adcs x21, x3, xzr
        stp x19, x1, [x0, #16]
        adcs x1, x9, xzr
        stp x21, x1, [x0, #32]
        adcs x21, x6, xzr
        adcs x1, x14, xzr
        stp x21, x1, [x0, #48]
        adc x1, x12, xzr
        and x1, x1, #0x1ff
        str x1, [x0, #64]

// Restore regs and return

        CFI_POP2(x23,x24)
        CFI_POP2(x21,x22)
        CFI_POP2(x19,x20)

        CFI_RET

S2N_BN_SIZE_DIRECTIVE(bignum_sqr_p521)

#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif