in FourQ_ARM_NEON/ARM/fp2_1271_NEON.c [149:250]
void v2sqr1271_a(uint32_t* a, uint32_t* c)
{ // Squaring over GF((2^127-1)^2) using NEON instructions
// Operation: c = a^2 in GF((2^127-1)^2)
// Representation: 23/23/26/26/26/26/26/26/26/26-bit
asm volatile(
// q0-q2[0] <- A0|A1
"vld1.8 {d0,d1}, [%0]! \n\t"
"vld1.8 {d2,d3}, [%0]! \n\t"
#if defined(INTERLEAVE)
"vshr.u64 q3, q0, #32 \n\t" // q3-q5[0] = (0|a9->0|a5)
"vld1.8 {d4}, [%0]! \n\t"
"vpush {q4-q7} \n\t"
"vmov.i64 q8, 0xFFFFFFFF \n\t" // mask_26
#else
"vld1.8 {d4}, [%0]! \n\t"
"vpush {q4-q7} \n\t"
"vmov.i64 q8, 0xFFFFFFFF \n\t" // mask_26
"vshr.u64 q3, q0, #32 \n\t" // q3-q5[0] = (0|a9->0|a5)
#endif
"vshr.u64 q4, q1, #32 \n\t"
"vshr.u64 d10, d4, #32 \n\t"
"vsub.s32 q13, q0, q3 \n\t" // q13-q15[0] = (a9|a4-a9->a5|a0-a5)
"vsub.s32 q14, q1, q4 \n\t"
"vsub.s32 d30, d4, d10 \n\t"
"vadd.s32 q3, q0, q3 \n\t" // q3-q5[0] = (a9|a4+a9->a5|a0+a5)
"vadd.s32 q4, q1, q4 \n\t"
"vadd.s32 d10, d4, d10 \n\t"
"vshl.i64 q0, q0, #33 \n\t" // q0-q2[0] = (2*a4|0->2*a0|0)
"vshl.i64 q1, q1, #33 \n\t"
"vshl.i64 d4, d4, #33 \n\t"
"vbit q0, q13, q8 \n\t" // q0-q2[0] = (2*a4|a4-a9->2*a0|a0-a5)
"vbit q1, q14, q8 \n\t"
"vbit d4, d30, d16 \n\t"
"vshl.i32 q6, q0, #3 \n\t" // 8*(2*a4|a4-a9->2*a0|a0-a5)
"vshl.i32 q7, q1, #3 \n\t"
"vshl.i32 d5, d4, #3 \n\t"
// q11-q15 <- 2*A0*B0|(A0+A1)*(A0-A1)
"vmull.s32 q11, d6, d0 \n\t" // q11 = a0*b0 | a0*b5
"vmlal.s32 q11, d10, d13 \n\t" // q11 = a0*b0 + 8*(a1*b4) | a0*b5 + 8*(a1*b9)
"vmlal.s32 q11, d7, d5 \n\t" // q11 = a0*b0 + 8*(a1*b4 + a4*b1) | a0*b5 + 8*(a1*b9 + a4*b6)
"vmlal.s32 q11, d9, d14 \n\t" // q11 = a0*b0 + 8*(a1*b4 + a4*b1 + a2*b3) | a0*b5 + 8*(a1*b9 + a4*b6 + a2*b8)
"vmlal.s32 q11, d8, d15 \n\t" // q11 = a0*b0 + 8*(a1*b4 + a4*b1 + a2*b3 + a3*b2) | a0*b5 + 8*(a1*b9 + a4*b6 + a2*b8 + a3*b7)
"vmull.s32 q12, d7, d0 \n\t" // q12 = a0*b1 | a0*b6
"vmlal.s32 q12, d6, d1 \n\t" // q12 = a0*b1 + a1*b0 | a0*b6 + a1*b5
"vmlal.s32 q12, d10, d14 \n\t" // q12 = a0*b1 + a1*b0 + 8*(a2*b4) | a0*b6 + a1*b5 + 8*(a2*b9)
"vmlal.s32 q12, d8, d5 \n\t" // q12 = a0*b1 + a1*b0 + 8*(a2*b4 + a4*b2) | a0*b6 + a1*b5 + 8*(a2*b9 + a4*b7)
"vmlal.s32 q12, d9, d15 \n\t" // q12 = a0*b1 + a1*b0 + 8*(a2*b4 + a4*b2 + a3*b3) | a0*b6 + a1*b5 + 8*(a2*b9 + a4*b7 + a3*b8)
"vmull.s32 q13, d8, d0 \n\t" // q13 = a0*b2 | a0*b7
"vmlal.s32 q13, d6, d2 \n\t" // q13 = a0*b2 + a2*b0 | a0*b7 + a2*b5
"vmlal.s32 q13, d7, d1 \n\t" // q13 = a0*b2 + a2*b0 + a1*b1 | a0*b7 + a2*b5 + a1*b6
"vmlal.s32 q13, d10, d15 \n\t" // q13 = a0*b2 + a2*b0 + a1*b1 + 8*(a3*b4) | a0*b7 + a2*b5 + a1*b6 + 8*(a3*b9)
"vmlal.s32 q13, d9, d5 \n\t" // q13 = a0*b2 + a2*b0 + a1*b1 + 8*(a3*b4 + a4*b3) | a0*b7 + a2*b5 + a1*b6 + 8*(a3*b9 + a4*b8)
"vshr.s64 q10, q11, #26 \n\t" ///
"vmull.s32 q14, d9, d0 \n\t" // q14 = a0*b3 | a0*b8
"vadd.s64 q10, q12, q10 \n\t" ///
"vmlal.s32 q14, d6, d3 \n\t" // q14 = a0*b3 + a3*b0 | a0*b8 + a3*b5
"vmlal.s32 q14, d8, d1 \n\t" // q14 = a0*b3 + a3*b0 + a1*b2 | a0*b8 + a3*b5 + a1*b7
"vmlal.s32 q14, d7, d2 \n\t" // q14 = a0*b3 + a3*b0 + a1*b2 + a2*b1 | a0*b8 + a3*b5 + a1*b7 + a2*b6
"vmlal.s32 q14, d10, d5 \n\t" // q14 = a0*b3 + a3*b0 + a1*b2 + a2*b1 + 8*(a4*b4) | a0*b8 + a3*b5 + a1*b7 + a2*b6 + 8*(a4*b9)
"vmull.s32 q15, d10, d0 \n\t" // q15 = a0*b4 | a0*b9
"vshr.s64 q5, q10, #26 \n\t" ///
"vmlal.s32 q15, d6, d4 \n\t" // q15 = a0*b4 + a4*b0 | a0*b9 + a4*b5
"vadd.s64 q5, q13, q5 \n\t" ///
"vmlal.s32 q15, d9, d1 \n\t" // q15 = a0*b4 + a4*b0 + a1*b3 | a0*b9 + a4*b5 + a1*b8
"vmlal.s32 q15, d7, d3 \n\t" // q15 = a0*b4 + a4*b0 + a1*b3 + a3*b1 | a0*b9 + a4*b5 + a1*b8 + a3*b6
"vmlal.s32 q15, d8, d2 \n\t" // q15 = a0*b4 + a4*b0 + a1*b3 + a3*b1 + a2*b2 | a0*b9 + a4*b5 + a1*b8 + a3*b6 + a2*b7
// Reduction
"vshr.s64 q9, q5, #26 \n\t"
"vshr.u64 q8, q8, #6 \n\t"
"vadd.s64 q9, q14, q9 \n\t"
"vand.u64 q1, q10, q8 \n\t"
"vand.u64 q0, q11, q8 \n\t"
"vshr.s64 q10, q9, #26 \n\t"
"vand.u64 q2, q5, q8 \n\t"
"vadd.s64 q10, q15, q10 \n\t"
"vshr.u64 q6, q8, #3 \n\t" // mask_23
"vshr.s64 q5, q10, #23 \n\t"
"vand.u64 q3, q9, q8 \n\t"
"vand.u64 q11, q10, q6 \n\t"
"vand.u64 q12, q5, q8 \n\t"
"vshr.s64 q6, q5, #26 \n\t"
"vadd.s64 q0, q0, q12 \n\t"
"vadd.s64 q1, q1, q6 \n\t"
"vst2.32 {d0[0],d1[0]}, [%1]! \n\t"
"vst2.32 {d2[0],d3[0]}, [%1]! \n\t"
#if defined(INTERLEAVE)
"vpop {q4-q7} \n\t"
#endif
"vst2.32 {d4[0],d5[0]}, [%1]! \n\t"
"vst2.32 {d6[0],d7[0]}, [%1]! \n\t"
"vst2.32 {d22[0],d23[0]}, [%1]! \n\t"
#if !defined(INTERLEAVE)
"vpop {q4-q7} \n\t"
#endif
:
:"r"(&a[0]), "r"(&c[0])
);
return;
}