void v2sqradd1271_a()

in FourQ_ARM_NEON/ARM/fp2_1271_NEON.c [928:1055]


void v2sqradd1271_a(uint32_t* a, uint32_t* c, uint32_t* d, uint32_t* e, uint32_t* f) 
{ // Squaring/addition over GF((2^127-1)^2) combining ARM and NEON instructions
  // Operation: c = a^2, f = d + e 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"
    "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 
    "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"    
    
    "push         {r5-r8}                 	\n\t"
    "ldm          %2!, {r5,r6}              \n\t"    //***** 
    "ldm          %3!, {r7,r8}              \n\t"    //***** 
    "add          r5, r7                    \n\t"    //***** 
    "add          r6, r8                    \n\t"    //***** 
    "stm          %4!, {r5,r6}              \n\t"    //*****
        
    // q11-q15 <- 2*A0*B0|(A0+A1)*(A0-A1)  
	"vshr.u64     q8, q8, #6                \n\t"    
    "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 
    "ldm          %2!, {r5,r6}              \n\t"    //***** 
    "ldm          %3!, {r7,r8}              \n\t"    //***** 
    "add          r5, r7                    \n\t"    //***** 
    "add          r6, r8                    \n\t"    //***** 
    "stm          %4!, {r5,r6}              \n\t"    //*****
    "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)
    "vmull.s32    q14, d9, d0               \n\t"    // q14 = a0*b3 | a0*b8 
    "ldm          %2!, {r5,r6}              \n\t"    //***** 
    "ldm          %3!, {r7,r8}              \n\t"    //***** 
    "add          r5, r7                    \n\t"    //***** 
    "add          r6, r8                    \n\t"    //***** 
    "stm          %4!, {r5,r6}              \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
    "vmlal.s32    q15, d6, d4               \n\t"    // q15 = a0*b4 + a4*b0 | a0*b9 + a4*b5
    "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
     
    "ldm          %2!, {r5,r6}              \n\t"    //***** 
    "ldm          %3!, {r7,r8}              \n\t"    //***** 
    "add          r5, r7                    \n\t"    //***** 
    "add          r6, r8                    \n\t"    //***** 
    "stm          %4!, {r5,r6}              \n\t"    //*****

    // Reduction   
	"vshr.u64     q6, q8, #3                \n\t"    // mask_23
    "vshr.s64     q10, q11, #26             \n\t"
    "vand.u64     q0, q11, q8               \n\t"

    "vshr.s64     q9, q14, #26              \n\t"
    "vand.u64     q3, q14, q8               \n\t"
    "vadd.s64     q10, q12, q10             \n\t"
    "vadd.s64     q9, q15, q9               \n\t"
    "vand.u64     q1, q10, q8               \n\t"
    "vand.u64     q11, q9, q6               \n\t" 

    "ldm          %2!, {r5,r6}              \n\t"    //***** 
    "ldm          %3!, {r7,r8}              \n\t"    //***** 
    "add          r5, r7                    \n\t"    //***** 
    "add          r6, r8                    \n\t"    //***** 
    "stm          %4!, {r5,r6}              \n\t"    //***** 
    "pop          {r5-r8}                 	\n\t"

    "vshr.s64     q10, q10, #26             \n\t"
    "vshr.s64     q9, q9, #23               \n\t"
    "vadd.s64     q10, q13, q10             \n\t"
    "vand.u64     q12, q9, q8               \n\t"
    "vand.u64     q2, q10, q8               \n\t"

    "vshr.s64     q10, q10, #26             \n\t"
    "vshr.s64     q6, q9, #26               \n\t"
    "vadd.s64     q10, q3, q10              \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"
    "vshr.s64     q9, q10, #26              \n\t"
    "vst2.32      {d2[0],d3[0]}, [%1]!      \n\t"
    "vand.u64     q3, q10, q8               \n\t"
    "vst2.32      {d4[0],d5[0]}, [%1]!      \n\t" 
    "vpop         {q4-q7}                   \n\t"
    "vadd.s64     q11, q11, q9              \n\t"   
    "vst2.32      {d6[0],d7[0]}, [%1]!      \n\t"
    "vst2.32      {d22[0],d23[0]}, [%1]!    \n\t"
    :
    :"r"(&a[0]), "r"(&c[0]), "r"(&d[0]), "r"(&e[0]), "r"(&f[0])
    :"memory","r5","r6","r7","r8"
	);
	return;
}