Home | History | Annotate | Download | only in neon
      1 ;
      2 ;  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3 ;
      4 ;  Use of this source code is governed by a BSD-style license
      5 ;  that can be found in the LICENSE file in the root of the source
      6 ;  tree. An additional intellectual property rights grant can be found
      7 ;  in the file PATENTS.  All contributing project authors may
      8 ;  be found in the AUTHORS file in the root of the source tree.
      9 ;
     10 
     11 
     12     EXPORT  |vp8_variance_halfpixvar16x16_h_neon|
     13     EXPORT  |vp8_variance_halfpixvar16x16_v_neon|
     14     EXPORT  |vp8_variance_halfpixvar16x16_hv_neon|
     15     EXPORT  |vp8_sub_pixel_variance16x16s_neon|
     16     ARM
     17     REQUIRE8
     18     PRESERVE8
     19 
     20     AREA ||.text||, CODE, READONLY, ALIGN=2
     21 
     22 ;================================================
     23 ;unsigned int vp8_variance_halfpixvar16x16_h_neon
     24 ;(
     25 ;    unsigned char  *src_ptr, r0
     26 ;    int  src_pixels_per_line,  r1
     27 ;    unsigned char *dst_ptr,  r2
     28 ;    int dst_pixels_per_line,   r3
     29 ;    unsigned int *sse
     30 ;);
     31 ;================================================
     32 |vp8_variance_halfpixvar16x16_h_neon| PROC
     33     push            {lr}
     34 
     35     mov             r12, #4                  ;loop counter
     36     ldr             lr, [sp, #4]           ;load *sse from stack
     37     vmov.i8         q8, #0                      ;q8 - sum
     38     vmov.i8         q9, #0                      ;q9, q10 - sse
     39     vmov.i8         q10, #0
     40 
     41 ;First Pass: output_height lines x output_width columns (16x16)
     42 vp8_filt_fpo16x16s_4_0_loop_neon
     43     vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
     44     vld1.8          {q11}, [r2], r3
     45     vld1.u8         {d4, d5, d6, d7}, [r0], r1
     46     vld1.8          {q12}, [r2], r3
     47     vld1.u8         {d8, d9, d10, d11}, [r0], r1
     48     vld1.8          {q13}, [r2], r3
     49     vld1.u8         {d12, d13, d14, d15}, [r0], r1
     50 
     51     ;pld                [r0]
     52     ;pld                [r0, r1]
     53     ;pld                [r0, r1, lsl #1]
     54 
     55     vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
     56     vext.8          q3, q2, q3, #1
     57     vext.8          q5, q4, q5, #1
     58     vext.8          q7, q6, q7, #1
     59 
     60     vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
     61     vld1.8          {q14}, [r2], r3
     62     vrhadd.u8       q1, q2, q3
     63     vrhadd.u8       q2, q4, q5
     64     vrhadd.u8       q3, q6, q7
     65 
     66     vsubl.u8        q4, d0, d22                 ;diff
     67     vsubl.u8        q5, d1, d23
     68     vsubl.u8        q6, d2, d24
     69     vsubl.u8        q7, d3, d25
     70     vsubl.u8        q0, d4, d26
     71     vsubl.u8        q1, d5, d27
     72     vsubl.u8        q2, d6, d28
     73     vsubl.u8        q3, d7, d29
     74 
     75     vpadal.s16      q8, q4                     ;sum
     76     vmlal.s16       q9, d8, d8                ;sse
     77     vmlal.s16       q10, d9, d9
     78 
     79     subs            r12, r12, #1
     80 
     81     vpadal.s16      q8, q5
     82     vmlal.s16       q9, d10, d10
     83     vmlal.s16       q10, d11, d11
     84     vpadal.s16      q8, q6
     85     vmlal.s16       q9, d12, d12
     86     vmlal.s16       q10, d13, d13
     87     vpadal.s16      q8, q7
     88     vmlal.s16       q9, d14, d14
     89     vmlal.s16       q10, d15, d15
     90 
     91     vpadal.s16      q8, q0                     ;sum
     92     vmlal.s16       q9, d0, d0                ;sse
     93     vmlal.s16       q10, d1, d1
     94     vpadal.s16      q8, q1
     95     vmlal.s16       q9, d2, d2
     96     vmlal.s16       q10, d3, d3
     97     vpadal.s16      q8, q2
     98     vmlal.s16       q9, d4, d4
     99     vmlal.s16       q10, d5, d5
    100     vpadal.s16      q8, q3
    101     vmlal.s16       q9, d6, d6
    102     vmlal.s16       q10, d7, d7
    103 
    104     bne             vp8_filt_fpo16x16s_4_0_loop_neon
    105 
    106     vadd.u32        q10, q9, q10                ;accumulate sse
    107     vpaddl.s32      q0, q8                      ;accumulate sum
    108 
    109     vpaddl.u32      q1, q10
    110     vadd.s64        d0, d0, d1
    111     vadd.u64        d1, d2, d3
    112 
    113     vmull.s32       q5, d0, d0
    114     vst1.32         {d1[0]}, [lr]               ;store sse
    115     vshr.s32        d10, d10, #8
    116     vsub.s32        d0, d1, d10
    117 
    118     vmov.32         r0, d0[0]                   ;return
    119     pop             {pc}
    120     ENDP
    121 
    122 ;================================================
    123 ;unsigned int vp8_variance_halfpixvar16x16_v_neon
    124 ;(
    125 ;    unsigned char  *src_ptr, r0
    126 ;    int  src_pixels_per_line,  r1
    127 ;    unsigned char *dst_ptr,  r2
    128 ;    int dst_pixels_per_line,   r3
    129 ;    unsigned int *sse
    130 ;);
    131 ;================================================
    132 |vp8_variance_halfpixvar16x16_v_neon| PROC
    133     push            {lr}
    134 
    135     mov             r12, #4                     ;loop counter
    136 
    137     vld1.u8         {q0}, [r0], r1              ;load src data
    138     ldr             lr, [sp, #4]                ;load *sse from stack
    139 
    140     vmov.i8         q8, #0                      ;q8 - sum
    141     vmov.i8         q9, #0                      ;q9, q10 - sse
    142     vmov.i8         q10, #0
    143 
    144 vp8_filt_spo16x16s_0_4_loop_neon
    145     vld1.u8         {q2}, [r0], r1
    146     vld1.8          {q1}, [r2], r3
    147     vld1.u8         {q4}, [r0], r1
    148     vld1.8          {q3}, [r2], r3
    149     vld1.u8         {q6}, [r0], r1
    150     vld1.8          {q5}, [r2], r3
    151     vld1.u8         {q15}, [r0], r1
    152 
    153     vrhadd.u8       q0, q0, q2
    154     vld1.8          {q7}, [r2], r3
    155     vrhadd.u8       q2, q2, q4
    156     vrhadd.u8       q4, q4, q6
    157     vrhadd.u8       q6, q6, q15
    158 
    159     vsubl.u8        q11, d0, d2                 ;diff
    160     vsubl.u8        q12, d1, d3
    161     vsubl.u8        q13, d4, d6
    162     vsubl.u8        q14, d5, d7
    163     vsubl.u8        q0, d8, d10
    164     vsubl.u8        q1, d9, d11
    165     vsubl.u8        q2, d12, d14
    166     vsubl.u8        q3, d13, d15
    167 
    168     vpadal.s16      q8, q11                     ;sum
    169     vmlal.s16       q9, d22, d22                ;sse
    170     vmlal.s16       q10, d23, d23
    171 
    172     subs            r12, r12, #1
    173 
    174     vpadal.s16      q8, q12
    175     vmlal.s16       q9, d24, d24
    176     vmlal.s16       q10, d25, d25
    177     vpadal.s16      q8, q13
    178     vmlal.s16       q9, d26, d26
    179     vmlal.s16       q10, d27, d27
    180     vpadal.s16      q8, q14
    181     vmlal.s16       q9, d28, d28
    182     vmlal.s16       q10, d29, d29
    183 
    184     vpadal.s16      q8, q0                     ;sum
    185     vmlal.s16       q9, d0, d0                 ;sse
    186     vmlal.s16       q10, d1, d1
    187     vpadal.s16      q8, q1
    188     vmlal.s16       q9, d2, d2
    189     vmlal.s16       q10, d3, d3
    190     vpadal.s16      q8, q2
    191     vmlal.s16       q9, d4, d4
    192     vmlal.s16       q10, d5, d5
    193 
    194     vmov            q0, q15
    195 
    196     vpadal.s16      q8, q3
    197     vmlal.s16       q9, d6, d6
    198     vmlal.s16       q10, d7, d7
    199 
    200     bne             vp8_filt_spo16x16s_0_4_loop_neon
    201 
    202     vadd.u32        q10, q9, q10                ;accumulate sse
    203     vpaddl.s32      q0, q8                      ;accumulate sum
    204 
    205     vpaddl.u32      q1, q10
    206     vadd.s64        d0, d0, d1
    207     vadd.u64        d1, d2, d3
    208 
    209     vmull.s32       q5, d0, d0
    210     vst1.32         {d1[0]}, [lr]               ;store sse
    211     vshr.s32        d10, d10, #8
    212     vsub.s32        d0, d1, d10
    213 
    214     vmov.32         r0, d0[0]                   ;return
    215     pop             {pc}
    216     ENDP
    217 
    218 ;================================================
    219 ;unsigned int vp8_variance_halfpixvar16x16_hv_neon
    220 ;(
    221 ;    unsigned char  *src_ptr, r0
    222 ;    int  src_pixels_per_line,  r1
    223 ;    unsigned char *dst_ptr,  r2
    224 ;    int dst_pixels_per_line,   r3
    225 ;    unsigned int *sse
    226 ;);
    227 ;================================================
    228 |vp8_variance_halfpixvar16x16_hv_neon| PROC
    229     push            {lr}
    230 
    231     vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
    232 
    233     ldr             lr, [sp, #4]           ;load *sse from stack
    234     vmov.i8         q13, #0                      ;q8 - sum
    235     vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
    236 
    237     vmov.i8         q14, #0                      ;q9, q10 - sse
    238     vmov.i8         q15, #0
    239 
    240     mov             r12, #4                  ;loop counter
    241     vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
    242 
    243 ;First Pass: output_height lines x output_width columns (17x16)
    244 vp8_filt16x16s_4_4_loop_neon
    245     vld1.u8         {d4, d5, d6, d7}, [r0], r1
    246     vld1.u8         {d8, d9, d10, d11}, [r0], r1
    247     vld1.u8         {d12, d13, d14, d15}, [r0], r1
    248     vld1.u8         {d16, d17, d18, d19}, [r0], r1
    249 
    250     ;pld                [r0]
    251     ;pld                [r0, r1]
    252     ;pld                [r0, r1, lsl #1]
    253 
    254     vext.8          q3, q2, q3, #1          ;construct src_ptr[1]
    255     vext.8          q5, q4, q5, #1
    256     vext.8          q7, q6, q7, #1
    257     vext.8          q9, q8, q9, #1
    258 
    259     vrhadd.u8       q1, q2, q3              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
    260     vrhadd.u8       q2, q4, q5
    261     vrhadd.u8       q3, q6, q7
    262     vrhadd.u8       q4, q8, q9
    263 
    264     vld1.8          {q5}, [r2], r3
    265     vrhadd.u8       q0, q0, q1
    266     vld1.8          {q6}, [r2], r3
    267     vrhadd.u8       q1, q1, q2
    268     vld1.8          {q7}, [r2], r3
    269     vrhadd.u8       q2, q2, q3
    270     vld1.8          {q8}, [r2], r3
    271     vrhadd.u8       q3, q3, q4
    272 
    273     vsubl.u8        q9, d0, d10                 ;diff
    274     vsubl.u8        q10, d1, d11
    275     vsubl.u8        q11, d2, d12
    276     vsubl.u8        q12, d3, d13
    277 
    278     vsubl.u8        q0, d4, d14                 ;diff
    279     vsubl.u8        q1, d5, d15
    280     vsubl.u8        q5, d6, d16
    281     vsubl.u8        q6, d7, d17
    282 
    283     vpadal.s16      q13, q9                     ;sum
    284     vmlal.s16       q14, d18, d18                ;sse
    285     vmlal.s16       q15, d19, d19
    286 
    287     vpadal.s16      q13, q10                     ;sum
    288     vmlal.s16       q14, d20, d20                ;sse
    289     vmlal.s16       q15, d21, d21
    290 
    291     vpadal.s16      q13, q11                     ;sum
    292     vmlal.s16       q14, d22, d22                ;sse
    293     vmlal.s16       q15, d23, d23
    294 
    295     vpadal.s16      q13, q12                     ;sum
    296     vmlal.s16       q14, d24, d24                ;sse
    297     vmlal.s16       q15, d25, d25
    298 
    299     subs            r12, r12, #1
    300 
    301     vpadal.s16      q13, q0                     ;sum
    302     vmlal.s16       q14, d0, d0                ;sse
    303     vmlal.s16       q15, d1, d1
    304 
    305     vpadal.s16      q13, q1                     ;sum
    306     vmlal.s16       q14, d2, d2                ;sse
    307     vmlal.s16       q15, d3, d3
    308 
    309     vpadal.s16      q13, q5                     ;sum
    310     vmlal.s16       q14, d10, d10                ;sse
    311     vmlal.s16       q15, d11, d11
    312 
    313     vmov            q0, q4
    314 
    315     vpadal.s16      q13, q6                     ;sum
    316     vmlal.s16       q14, d12, d12                ;sse
    317     vmlal.s16       q15, d13, d13
    318 
    319     bne             vp8_filt16x16s_4_4_loop_neon
    320 
    321     vadd.u32        q15, q14, q15                ;accumulate sse
    322     vpaddl.s32      q0, q13                      ;accumulate sum
    323 
    324     vpaddl.u32      q1, q15
    325     vadd.s64        d0, d0, d1
    326     vadd.u64        d1, d2, d3
    327 
    328     vmull.s32       q5, d0, d0
    329     vst1.32         {d1[0]}, [lr]               ;store sse
    330     vshr.s32        d10, d10, #8
    331     vsub.s32        d0, d1, d10
    332 
    333     vmov.32         r0, d0[0]                   ;return
    334     pop             {pc}
    335     ENDP
    336 
    337 ;==============================
    338 ; r0    unsigned char  *src_ptr,
    339 ; r1    int  src_pixels_per_line,
    340 ; r2    int  xoffset,
    341 ; r3    int  yoffset,
    342 ; stack unsigned char *dst_ptr,
    343 ; stack int dst_pixels_per_line,
    344 ; stack unsigned int *sse
    345 ;note: in vp8_find_best_half_pixel_step()(called when 8<Speed<15), and first call of vp8_find_best_sub_pixel_step()
    346 ;(called when speed<=8). xoffset/yoffset can only be 4 or 0, which means either by pass the filter,
    347 ;or filter coeff is {64, 64}. This simplified program only works in this situation.
    348 ;note: It happens that both xoffset and yoffset are zero. This can be handled in c code later.
    349 
    350 |vp8_sub_pixel_variance16x16s_neon| PROC
    351     push            {r4, lr}
    352 
    353     ldr             r4, [sp, #8]            ;load *dst_ptr from stack
    354     ldr             r12, [sp, #12]          ;load dst_pixels_per_line from stack
    355     ldr             lr, [sp, #16]           ;load *sse from stack
    356 
    357     cmp             r2, #0                  ;skip first_pass filter if xoffset=0
    358     beq             secondpass_bfilter16x16s_only
    359 
    360     cmp             r3, #0                  ;skip second_pass filter if yoffset=0
    361     beq             firstpass_bfilter16x16s_only
    362 
    363     vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
    364     sub             sp, sp, #256            ;reserve space on stack for temporary storage
    365     vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
    366     mov             r3, sp
    367     mov             r2, #4                  ;loop counter
    368     vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
    369 
    370 ;First Pass: output_height lines x output_width columns (17x16)
    371 vp8e_filt_blk2d_fp16x16s_loop_neon
    372     vld1.u8         {d4, d5, d6, d7}, [r0], r1
    373     vld1.u8         {d8, d9, d10, d11}, [r0], r1
    374     vld1.u8         {d12, d13, d14, d15}, [r0], r1
    375     vld1.u8         {d16, d17, d18, d19}, [r0], r1
    376 
    377     ;pld                [r0]
    378     ;pld                [r0, r1]
    379     ;pld                [r0, r1, lsl #1]
    380 
    381     vext.8          q3, q2, q3, #1          ;construct src_ptr[1]
    382     vext.8          q5, q4, q5, #1
    383     vext.8          q7, q6, q7, #1
    384     vext.8          q9, q8, q9, #1
    385 
    386     vrhadd.u8       q1, q2, q3              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
    387     vrhadd.u8       q2, q4, q5
    388     vrhadd.u8       q3, q6, q7
    389     vrhadd.u8       q4, q8, q9
    390 
    391     vrhadd.u8       q0, q0, q1
    392     vrhadd.u8       q1, q1, q2
    393     vrhadd.u8       q2, q2, q3
    394     vrhadd.u8       q3, q3, q4
    395 
    396     subs            r2, r2, #1
    397     vst1.u8         {d0, d1 ,d2, d3}, [r3]!         ;store result
    398     vmov            q0, q4
    399     vst1.u8         {d4, d5, d6, d7}, [r3]!
    400 
    401     bne             vp8e_filt_blk2d_fp16x16s_loop_neon
    402 
    403     b               sub_pixel_variance16x16s_neon
    404 
    405 ;--------------------
    406 firstpass_bfilter16x16s_only
    407     mov             r2, #2                  ;loop counter
    408     sub             sp, sp, #256            ;reserve space on stack for temporary storage
    409     mov             r3, sp
    410 
    411 ;First Pass: output_height lines x output_width columns (16x16)
    412 vp8e_filt_blk2d_fpo16x16s_loop_neon
    413     vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
    414     vld1.u8         {d4, d5, d6, d7}, [r0], r1
    415     vld1.u8         {d8, d9, d10, d11}, [r0], r1
    416     vld1.u8         {d12, d13, d14, d15}, [r0], r1
    417 
    418     ;pld                [r0]
    419     ;pld                [r0, r1]
    420     ;pld                [r0, r1, lsl #1]
    421 
    422     vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
    423     vld1.u8         {d16, d17, d18, d19}, [r0], r1
    424     vext.8          q3, q2, q3, #1
    425     vld1.u8         {d20, d21, d22, d23}, [r0], r1
    426     vext.8          q5, q4, q5, #1
    427     vld1.u8         {d24, d25, d26, d27}, [r0], r1
    428     vext.8          q7, q6, q7, #1
    429     vld1.u8         {d28, d29, d30, d31}, [r0], r1
    430     vext.8          q9, q8, q9, #1
    431     vext.8          q11, q10, q11, #1
    432     vext.8          q13, q12, q13, #1
    433     vext.8          q15, q14, q15, #1
    434 
    435     vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
    436     vrhadd.u8       q1, q2, q3
    437     vrhadd.u8       q2, q4, q5
    438     vrhadd.u8       q3, q6, q7
    439     vrhadd.u8       q4, q8, q9
    440     vrhadd.u8       q5, q10, q11
    441     vrhadd.u8       q6, q12, q13
    442     vrhadd.u8       q7, q14, q15
    443 
    444     subs            r2, r2, #1
    445 
    446     vst1.u8         {d0, d1, d2, d3}, [r3]!         ;store result
    447     vst1.u8         {d4, d5, d6, d7}, [r3]!
    448     vst1.u8         {d8, d9, d10, d11}, [r3]!
    449     vst1.u8         {d12, d13, d14, d15}, [r3]!
    450 
    451     bne             vp8e_filt_blk2d_fpo16x16s_loop_neon
    452 
    453     b               sub_pixel_variance16x16s_neon
    454 
    455 ;---------------------
    456 secondpass_bfilter16x16s_only
    457     sub             sp, sp, #256            ;reserve space on stack for temporary storage
    458 
    459     mov             r2, #2                  ;loop counter
    460     vld1.u8         {d0, d1}, [r0], r1      ;load src data
    461     mov             r3, sp
    462 
    463 vp8e_filt_blk2d_spo16x16s_loop_neon
    464     vld1.u8         {d2, d3}, [r0], r1
    465     vld1.u8         {d4, d5}, [r0], r1
    466     vld1.u8         {d6, d7}, [r0], r1
    467     vld1.u8         {d8, d9}, [r0], r1
    468 
    469     vrhadd.u8       q0, q0, q1
    470     vld1.u8         {d10, d11}, [r0], r1
    471     vrhadd.u8       q1, q1, q2
    472     vld1.u8         {d12, d13}, [r0], r1
    473     vrhadd.u8       q2, q2, q3
    474     vld1.u8         {d14, d15}, [r0], r1
    475     vrhadd.u8       q3, q3, q4
    476     vld1.u8         {d16, d17}, [r0], r1
    477     vrhadd.u8       q4, q4, q5
    478     vrhadd.u8       q5, q5, q6
    479     vrhadd.u8       q6, q6, q7
    480     vrhadd.u8       q7, q7, q8
    481 
    482     subs            r2, r2, #1
    483 
    484     vst1.u8         {d0, d1, d2, d3}, [r3]!         ;store result
    485     vmov            q0, q8
    486     vst1.u8         {d4, d5, d6, d7}, [r3]!
    487     vst1.u8         {d8, d9, d10, d11}, [r3]!           ;store result
    488     vst1.u8         {d12, d13, d14, d15}, [r3]!
    489 
    490     bne             vp8e_filt_blk2d_spo16x16s_loop_neon
    491 
    492     b               sub_pixel_variance16x16s_neon
    493 
    494 ;----------------------------
    495 ;variance16x16
    496 sub_pixel_variance16x16s_neon
    497     vmov.i8         q8, #0                      ;q8 - sum
    498     vmov.i8         q9, #0                      ;q9, q10 - sse
    499     vmov.i8         q10, #0
    500 
    501     sub             r3, r3, #256
    502     mov             r2, #4
    503 
    504 sub_pixel_variance16x16s_neon_loop
    505     vld1.8          {q0}, [r3]!                 ;Load up source and reference
    506     vld1.8          {q1}, [r4], r12
    507     vld1.8          {q2}, [r3]!
    508     vld1.8          {q3}, [r4], r12
    509     vld1.8          {q4}, [r3]!
    510     vld1.8          {q5}, [r4], r12
    511     vld1.8          {q6}, [r3]!
    512     vld1.8          {q7}, [r4], r12
    513 
    514     vsubl.u8        q11, d0, d2                 ;diff
    515     vsubl.u8        q12, d1, d3
    516     vsubl.u8        q13, d4, d6
    517     vsubl.u8        q14, d5, d7
    518     vsubl.u8        q0, d8, d10
    519     vsubl.u8        q1, d9, d11
    520     vsubl.u8        q2, d12, d14
    521     vsubl.u8        q3, d13, d15
    522 
    523     vpadal.s16      q8, q11                     ;sum
    524     vmlal.s16       q9, d22, d22                ;sse
    525     vmlal.s16       q10, d23, d23
    526 
    527     subs            r2, r2, #1
    528 
    529     vpadal.s16      q8, q12
    530     vmlal.s16       q9, d24, d24
    531     vmlal.s16       q10, d25, d25
    532     vpadal.s16      q8, q13
    533     vmlal.s16       q9, d26, d26
    534     vmlal.s16       q10, d27, d27
    535     vpadal.s16      q8, q14
    536     vmlal.s16       q9, d28, d28
    537     vmlal.s16       q10, d29, d29
    538 
    539     vpadal.s16      q8, q0                     ;sum
    540     vmlal.s16       q9, d0, d0                ;sse
    541     vmlal.s16       q10, d1, d1
    542     vpadal.s16      q8, q1
    543     vmlal.s16       q9, d2, d2
    544     vmlal.s16       q10, d3, d3
    545     vpadal.s16      q8, q2
    546     vmlal.s16       q9, d4, d4
    547     vmlal.s16       q10, d5, d5
    548     vpadal.s16      q8, q3
    549     vmlal.s16       q9, d6, d6
    550     vmlal.s16       q10, d7, d7
    551 
    552     bne             sub_pixel_variance16x16s_neon_loop
    553 
    554     vadd.u32        q10, q9, q10                ;accumulate sse
    555     vpaddl.s32      q0, q8                      ;accumulate sum
    556 
    557     vpaddl.u32      q1, q10
    558     vadd.s64        d0, d0, d1
    559     vadd.u64        d1, d2, d3
    560 
    561     vmull.s32       q5, d0, d0
    562     vst1.32         {d1[0]}, [lr]               ;store sse
    563     vshr.s32        d10, d10, #8
    564     vsub.s32        d0, d1, d10
    565 
    566     add             sp, sp, #256
    567     vmov.32         r0, d0[0]                   ;return
    568 
    569     pop             {r4, pc}
    570     ENDP
    571 
    572     END
    573