Home | History | Annotate | Download | only in neon
      1 ;
      2 ;  Copyright (c) 2013 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     EXPORT  |vp9_lpf_horizontal_16_neon|
     12     EXPORT  |vp9_lpf_vertical_16_neon|
     13     ARM
     14 
     15     AREA ||.text||, CODE, READONLY, ALIGN=2
     16 
     17 ; void vp9_lpf_horizontal_16_neon(uint8_t *s, int p,
     18 ;                                 const uint8_t *blimit,
     19 ;                                 const uint8_t *limit,
     20 ;                                 const uint8_t *thresh
     21 ;                                 int count)
     22 ; r0    uint8_t *s,
     23 ; r1    int p, /* pitch */
     24 ; r2    const uint8_t *blimit,
     25 ; r3    const uint8_t *limit,
     26 ; sp    const uint8_t *thresh,
     27 |vp9_lpf_horizontal_16_neon| PROC
     28     push        {r4-r8, lr}
     29     vpush       {d8-d15}
     30     ldr         r4, [sp, #88]              ; load thresh
     31     ldr         r12, [sp, #92]             ; load count
     32 
     33 h_count
     34     vld1.8      {d16[]}, [r2]              ; load *blimit
     35     vld1.8      {d17[]}, [r3]              ; load *limit
     36     vld1.8      {d18[]}, [r4]              ; load *thresh
     37 
     38     sub         r8, r0, r1, lsl #3         ; move src pointer down by 8 lines
     39 
     40     vld1.u8     {d0}, [r8@64], r1          ; p7
     41     vld1.u8     {d1}, [r8@64], r1          ; p6
     42     vld1.u8     {d2}, [r8@64], r1          ; p5
     43     vld1.u8     {d3}, [r8@64], r1          ; p4
     44     vld1.u8     {d4}, [r8@64], r1          ; p3
     45     vld1.u8     {d5}, [r8@64], r1          ; p2
     46     vld1.u8     {d6}, [r8@64], r1          ; p1
     47     vld1.u8     {d7}, [r8@64], r1          ; p0
     48     vld1.u8     {d8}, [r8@64], r1          ; q0
     49     vld1.u8     {d9}, [r8@64], r1          ; q1
     50     vld1.u8     {d10}, [r8@64], r1         ; q2
     51     vld1.u8     {d11}, [r8@64], r1         ; q3
     52     vld1.u8     {d12}, [r8@64], r1         ; q4
     53     vld1.u8     {d13}, [r8@64], r1         ; q5
     54     vld1.u8     {d14}, [r8@64], r1         ; q6
     55     vld1.u8     {d15}, [r8@64], r1         ; q7
     56 
     57     bl          vp9_wide_mbfilter_neon
     58 
     59     tst         r7, #1
     60     beq         h_mbfilter
     61 
     62     ; flat && mask were not set for any of the channels. Just store the values
     63     ; from filter.
     64     sub         r8, r0, r1, lsl #1
     65 
     66     vst1.u8     {d25}, [r8@64], r1         ; store op1
     67     vst1.u8     {d24}, [r8@64], r1         ; store op0
     68     vst1.u8     {d23}, [r8@64], r1         ; store oq0
     69     vst1.u8     {d26}, [r8@64], r1         ; store oq1
     70 
     71     b           h_next
     72 
     73 h_mbfilter
     74     tst         r7, #2
     75     beq         h_wide_mbfilter
     76 
     77     ; flat2 was not set for any of the channels. Just store the values from
     78     ; mbfilter.
     79     sub         r8, r0, r1, lsl #1
     80     sub         r8, r8, r1
     81 
     82     vst1.u8     {d18}, [r8@64], r1         ; store op2
     83     vst1.u8     {d19}, [r8@64], r1         ; store op1
     84     vst1.u8     {d20}, [r8@64], r1         ; store op0
     85     vst1.u8     {d21}, [r8@64], r1         ; store oq0
     86     vst1.u8     {d22}, [r8@64], r1         ; store oq1
     87     vst1.u8     {d23}, [r8@64], r1         ; store oq2
     88 
     89     b           h_next
     90 
     91 h_wide_mbfilter
     92     sub         r8, r0, r1, lsl #3
     93     add         r8, r8, r1
     94 
     95     vst1.u8     {d16}, [r8@64], r1         ; store op6
     96     vst1.u8     {d24}, [r8@64], r1         ; store op5
     97     vst1.u8     {d25}, [r8@64], r1         ; store op4
     98     vst1.u8     {d26}, [r8@64], r1         ; store op3
     99     vst1.u8     {d27}, [r8@64], r1         ; store op2
    100     vst1.u8     {d18}, [r8@64], r1         ; store op1
    101     vst1.u8     {d19}, [r8@64], r1         ; store op0
    102     vst1.u8     {d20}, [r8@64], r1         ; store oq0
    103     vst1.u8     {d21}, [r8@64], r1         ; store oq1
    104     vst1.u8     {d22}, [r8@64], r1         ; store oq2
    105     vst1.u8     {d23}, [r8@64], r1         ; store oq3
    106     vst1.u8     {d1}, [r8@64], r1          ; store oq4
    107     vst1.u8     {d2}, [r8@64], r1          ; store oq5
    108     vst1.u8     {d3}, [r8@64], r1          ; store oq6
    109 
    110 h_next
    111     add         r0, r0, #8
    112     subs        r12, r12, #1
    113     bne         h_count
    114 
    115     vpop        {d8-d15}
    116     pop         {r4-r8, pc}
    117 
    118     ENDP        ; |vp9_lpf_horizontal_16_neon|
    119 
    120 ; void vp9_lpf_vertical_16_neon(uint8_t *s, int p,
    121 ;                               const uint8_t *blimit,
    122 ;                               const uint8_t *limit,
    123 ;                               const uint8_t *thresh)
    124 ; r0    uint8_t *s,
    125 ; r1    int p, /* pitch */
    126 ; r2    const uint8_t *blimit,
    127 ; r3    const uint8_t *limit,
    128 ; sp    const uint8_t *thresh,
    129 |vp9_lpf_vertical_16_neon| PROC
    130     push        {r4-r8, lr}
    131     vpush       {d8-d15}
    132     ldr         r4, [sp, #88]              ; load thresh
    133 
    134     vld1.8      {d16[]}, [r2]              ; load *blimit
    135     vld1.8      {d17[]}, [r3]              ; load *limit
    136     vld1.8      {d18[]}, [r4]              ; load *thresh
    137 
    138     sub         r8, r0, #8
    139 
    140     vld1.8      {d0}, [r8@64], r1
    141     vld1.8      {d8}, [r0@64], r1
    142     vld1.8      {d1}, [r8@64], r1
    143     vld1.8      {d9}, [r0@64], r1
    144     vld1.8      {d2}, [r8@64], r1
    145     vld1.8      {d10}, [r0@64], r1
    146     vld1.8      {d3}, [r8@64], r1
    147     vld1.8      {d11}, [r0@64], r1
    148     vld1.8      {d4}, [r8@64], r1
    149     vld1.8      {d12}, [r0@64], r1
    150     vld1.8      {d5}, [r8@64], r1
    151     vld1.8      {d13}, [r0@64], r1
    152     vld1.8      {d6}, [r8@64], r1
    153     vld1.8      {d14}, [r0@64], r1
    154     vld1.8      {d7}, [r8@64], r1
    155     vld1.8      {d15}, [r0@64], r1
    156 
    157     sub         r0, r0, r1, lsl #3
    158 
    159     vtrn.32     q0, q2
    160     vtrn.32     q1, q3
    161     vtrn.32     q4, q6
    162     vtrn.32     q5, q7
    163 
    164     vtrn.16     q0, q1
    165     vtrn.16     q2, q3
    166     vtrn.16     q4, q5
    167     vtrn.16     q6, q7
    168 
    169     vtrn.8      d0, d1
    170     vtrn.8      d2, d3
    171     vtrn.8      d4, d5
    172     vtrn.8      d6, d7
    173 
    174     vtrn.8      d8, d9
    175     vtrn.8      d10, d11
    176     vtrn.8      d12, d13
    177     vtrn.8      d14, d15
    178 
    179     bl          vp9_wide_mbfilter_neon
    180 
    181     tst         r7, #1
    182     beq         v_mbfilter
    183 
    184     ; flat && mask were not set for any of the channels. Just store the values
    185     ; from filter.
    186     sub         r8, r0, #2
    187 
    188     vswp        d23, d25
    189 
    190     vst4.8      {d23[0], d24[0], d25[0], d26[0]}, [r8], r1
    191     vst4.8      {d23[1], d24[1], d25[1], d26[1]}, [r8], r1
    192     vst4.8      {d23[2], d24[2], d25[2], d26[2]}, [r8], r1
    193     vst4.8      {d23[3], d24[3], d25[3], d26[3]}, [r8], r1
    194     vst4.8      {d23[4], d24[4], d25[4], d26[4]}, [r8], r1
    195     vst4.8      {d23[5], d24[5], d25[5], d26[5]}, [r8], r1
    196     vst4.8      {d23[6], d24[6], d25[6], d26[6]}, [r8], r1
    197     vst4.8      {d23[7], d24[7], d25[7], d26[7]}, [r8], r1
    198 
    199     b           v_end
    200 
    201 v_mbfilter
    202     tst         r7, #2
    203     beq         v_wide_mbfilter
    204 
    205     ; flat2 was not set for any of the channels. Just store the values from
    206     ; mbfilter.
    207     sub         r8, r0, #3
    208 
    209     vst3.8      {d18[0], d19[0], d20[0]}, [r8], r1
    210     vst3.8      {d21[0], d22[0], d23[0]}, [r0], r1
    211     vst3.8      {d18[1], d19[1], d20[1]}, [r8], r1
    212     vst3.8      {d21[1], d22[1], d23[1]}, [r0], r1
    213     vst3.8      {d18[2], d19[2], d20[2]}, [r8], r1
    214     vst3.8      {d21[2], d22[2], d23[2]}, [r0], r1
    215     vst3.8      {d18[3], d19[3], d20[3]}, [r8], r1
    216     vst3.8      {d21[3], d22[3], d23[3]}, [r0], r1
    217     vst3.8      {d18[4], d19[4], d20[4]}, [r8], r1
    218     vst3.8      {d21[4], d22[4], d23[4]}, [r0], r1
    219     vst3.8      {d18[5], d19[5], d20[5]}, [r8], r1
    220     vst3.8      {d21[5], d22[5], d23[5]}, [r0], r1
    221     vst3.8      {d18[6], d19[6], d20[6]}, [r8], r1
    222     vst3.8      {d21[6], d22[6], d23[6]}, [r0], r1
    223     vst3.8      {d18[7], d19[7], d20[7]}, [r8], r1
    224     vst3.8      {d21[7], d22[7], d23[7]}, [r0], r1
    225 
    226     b           v_end
    227 
    228 v_wide_mbfilter
    229     sub         r8, r0, #8
    230 
    231     vtrn.32     d0,  d26
    232     vtrn.32     d16, d27
    233     vtrn.32     d24, d18
    234     vtrn.32     d25, d19
    235 
    236     vtrn.16     d0,  d24
    237     vtrn.16     d16, d25
    238     vtrn.16     d26, d18
    239     vtrn.16     d27, d19
    240 
    241     vtrn.8      d0,  d16
    242     vtrn.8      d24, d25
    243     vtrn.8      d26, d27
    244     vtrn.8      d18, d19
    245 
    246     vtrn.32     d20, d1
    247     vtrn.32     d21, d2
    248     vtrn.32     d22, d3
    249     vtrn.32     d23, d15
    250 
    251     vtrn.16     d20, d22
    252     vtrn.16     d21, d23
    253     vtrn.16     d1,  d3
    254     vtrn.16     d2,  d15
    255 
    256     vtrn.8      d20, d21
    257     vtrn.8      d22, d23
    258     vtrn.8      d1,  d2
    259     vtrn.8      d3,  d15
    260 
    261     vst1.8      {d0}, [r8@64], r1
    262     vst1.8      {d20}, [r0@64], r1
    263     vst1.8      {d16}, [r8@64], r1
    264     vst1.8      {d21}, [r0@64], r1
    265     vst1.8      {d24}, [r8@64], r1
    266     vst1.8      {d22}, [r0@64], r1
    267     vst1.8      {d25}, [r8@64], r1
    268     vst1.8      {d23}, [r0@64], r1
    269     vst1.8      {d26}, [r8@64], r1
    270     vst1.8      {d1}, [r0@64], r1
    271     vst1.8      {d27}, [r8@64], r1
    272     vst1.8      {d2}, [r0@64], r1
    273     vst1.8      {d18}, [r8@64], r1
    274     vst1.8      {d3}, [r0@64], r1
    275     vst1.8      {d19}, [r8@64], r1
    276     vst1.8      {d15}, [r0@64], r1
    277 
    278 v_end
    279     vpop        {d8-d15}
    280     pop         {r4-r8, pc}
    281 
    282     ENDP        ; |vp9_lpf_vertical_16_neon|
    283 
    284 ; void vp9_wide_mbfilter_neon();
    285 ; This is a helper function for the loopfilters. The invidual functions do the
    286 ; necessary load, transpose (if necessary) and store.
    287 ;
    288 ; r0-r3 PRESERVE
    289 ; d16    blimit
    290 ; d17    limit
    291 ; d18    thresh
    292 ; d0    p7
    293 ; d1    p6
    294 ; d2    p5
    295 ; d3    p4
    296 ; d4    p3
    297 ; d5    p2
    298 ; d6    p1
    299 ; d7    p0
    300 ; d8    q0
    301 ; d9    q1
    302 ; d10   q2
    303 ; d11   q3
    304 ; d12   q4
    305 ; d13   q5
    306 ; d14   q6
    307 ; d15   q7
    308 |vp9_wide_mbfilter_neon| PROC
    309     mov         r7, #0
    310 
    311     ; filter_mask
    312     vabd.u8     d19, d4, d5                ; abs(p3 - p2)
    313     vabd.u8     d20, d5, d6                ; abs(p2 - p1)
    314     vabd.u8     d21, d6, d7                ; abs(p1 - p0)
    315     vabd.u8     d22, d9, d8                ; abs(q1 - q0)
    316     vabd.u8     d23, d10, d9               ; abs(q2 - q1)
    317     vabd.u8     d24, d11, d10              ; abs(q3 - q2)
    318 
    319     ; only compare the largest value to limit
    320     vmax.u8     d19, d19, d20              ; max(abs(p3 - p2), abs(p2 - p1))
    321     vmax.u8     d20, d21, d22              ; max(abs(p1 - p0), abs(q1 - q0))
    322     vmax.u8     d23, d23, d24              ; max(abs(q2 - q1), abs(q3 - q2))
    323     vmax.u8     d19, d19, d20
    324 
    325     vabd.u8     d24, d7, d8                ; abs(p0 - q0)
    326 
    327     vmax.u8     d19, d19, d23
    328 
    329     vabd.u8     d23, d6, d9                ; a = abs(p1 - q1)
    330     vqadd.u8    d24, d24, d24              ; b = abs(p0 - q0) * 2
    331 
    332     ; abs () > limit
    333     vcge.u8     d19, d17, d19
    334 
    335     ; flatmask4
    336     vabd.u8     d25, d7, d5                ; abs(p0 - p2)
    337     vabd.u8     d26, d8, d10               ; abs(q0 - q2)
    338     vabd.u8     d27, d4, d7                ; abs(p3 - p0)
    339     vabd.u8     d28, d11, d8               ; abs(q3 - q0)
    340 
    341     ; only compare the largest value to thresh
    342     vmax.u8     d25, d25, d26              ; max(abs(p0 - p2), abs(q0 - q2))
    343     vmax.u8     d26, d27, d28              ; max(abs(p3 - p0), abs(q3 - q0))
    344     vmax.u8     d25, d25, d26
    345     vmax.u8     d20, d20, d25
    346 
    347     vshr.u8     d23, d23, #1               ; a = a / 2
    348     vqadd.u8    d24, d24, d23              ; a = b + a
    349 
    350     vmov.u8     d30, #1
    351     vcge.u8     d24, d16, d24              ; (a > blimit * 2 + limit) * -1
    352 
    353     vcge.u8     d20, d30, d20              ; flat
    354 
    355     vand        d19, d19, d24              ; mask
    356 
    357     ; hevmask
    358     vcgt.u8     d21, d21, d18              ; (abs(p1 - p0) > thresh)*-1
    359     vcgt.u8     d22, d22, d18              ; (abs(q1 - q0) > thresh)*-1
    360     vorr        d21, d21, d22              ; hev
    361 
    362     vand        d16, d20, d19              ; flat && mask
    363     vmov        r5, r6, d16
    364 
    365     ; flatmask5(1, p7, p6, p5, p4, p0, q0, q4, q5, q6, q7)
    366     vabd.u8     d22, d3, d7                ; abs(p4 - p0)
    367     vabd.u8     d23, d12, d8               ; abs(q4 - q0)
    368     vabd.u8     d24, d7, d2                ; abs(p0 - p5)
    369     vabd.u8     d25, d8, d13               ; abs(q0 - q5)
    370     vabd.u8     d26, d1, d7                ; abs(p6 - p0)
    371     vabd.u8     d27, d14, d8               ; abs(q6 - q0)
    372     vabd.u8     d28, d0, d7                ; abs(p7 - p0)
    373     vabd.u8     d29, d15, d8               ; abs(q7 - q0)
    374 
    375     ; only compare the largest value to thresh
    376     vmax.u8     d22, d22, d23              ; max(abs(p4 - p0), abs(q4 - q0))
    377     vmax.u8     d23, d24, d25              ; max(abs(p0 - p5), abs(q0 - q5))
    378     vmax.u8     d24, d26, d27              ; max(abs(p6 - p0), abs(q6 - q0))
    379     vmax.u8     d25, d28, d29              ; max(abs(p7 - p0), abs(q7 - q0))
    380 
    381     vmax.u8     d26, d22, d23
    382     vmax.u8     d27, d24, d25
    383     vmax.u8     d23, d26, d27
    384 
    385     vcge.u8     d18, d30, d23              ; flat2
    386 
    387     vmov.u8     d22, #0x80
    388 
    389     orrs        r5, r5, r6                 ; Check for 0
    390     orreq       r7, r7, #1                 ; Only do filter branch
    391 
    392     vand        d17, d18, d16              ; flat2 && flat && mask
    393     vmov        r5, r6, d17
    394 
    395     ; mbfilter() function
    396 
    397     ; filter() function
    398     ; convert to signed
    399     veor        d23, d8, d22               ; qs0
    400     veor        d24, d7, d22               ; ps0
    401     veor        d25, d6, d22               ; ps1
    402     veor        d26, d9, d22               ; qs1
    403 
    404     vmov.u8     d27, #3
    405 
    406     vsub.s8     d28, d23, d24              ; ( qs0 - ps0)
    407     vqsub.s8    d29, d25, d26              ; filter = clamp(ps1-qs1)
    408     vmull.s8    q15, d28, d27              ; 3 * ( qs0 - ps0)
    409     vand        d29, d29, d21              ; filter &= hev
    410     vaddw.s8    q15, q15, d29              ; filter + 3 * (qs0 - ps0)
    411     vmov.u8     d29, #4
    412 
    413     ; filter = clamp(filter + 3 * ( qs0 - ps0))
    414     vqmovn.s16  d28, q15
    415 
    416     vand        d28, d28, d19              ; filter &= mask
    417 
    418     vqadd.s8    d30, d28, d27              ; filter2 = clamp(filter+3)
    419     vqadd.s8    d29, d28, d29              ; filter1 = clamp(filter+4)
    420     vshr.s8     d30, d30, #3               ; filter2 >>= 3
    421     vshr.s8     d29, d29, #3               ; filter1 >>= 3
    422 
    423 
    424     vqadd.s8    d24, d24, d30              ; op0 = clamp(ps0 + filter2)
    425     vqsub.s8    d23, d23, d29              ; oq0 = clamp(qs0 - filter1)
    426 
    427     ; outer tap adjustments: ++filter1 >> 1
    428     vrshr.s8    d29, d29, #1
    429     vbic        d29, d29, d21              ; filter &= ~hev
    430 
    431     vqadd.s8    d25, d25, d29              ; op1 = clamp(ps1 + filter)
    432     vqsub.s8    d26, d26, d29              ; oq1 = clamp(qs1 - filter)
    433 
    434     veor        d24, d24, d22              ; *f_op0 = u^0x80
    435     veor        d23, d23, d22              ; *f_oq0 = u^0x80
    436     veor        d25, d25, d22              ; *f_op1 = u^0x80
    437     veor        d26, d26, d22              ; *f_oq1 = u^0x80
    438 
    439     tst         r7, #1
    440     bxne        lr
    441 
    442     orrs        r5, r5, r6                 ; Check for 0
    443     orreq       r7, r7, #2                 ; Only do mbfilter branch
    444 
    445     ; mbfilter flat && mask branch
    446     ; TODO(fgalligan): Can I decrease the cycles shifting to consective d's
    447     ; and using vibt on the q's?
    448     vmov.u8     d29, #2
    449     vaddl.u8    q15, d7, d8                ; op2 = p0 + q0
    450     vmlal.u8    q15, d4, d27               ; op2 = p0 + q0 + p3 * 3
    451     vmlal.u8    q15, d5, d29               ; op2 = p0 + q0 + p3 * 3 + p2 * 2
    452     vaddl.u8    q10, d4, d5
    453     vaddw.u8    q15, d6                    ; op2=p1 + p0 + q0 + p3 * 3 + p2 *2
    454     vaddl.u8    q14, d6, d9
    455     vqrshrn.u16 d18, q15, #3               ; r_op2
    456 
    457     vsub.i16    q15, q10
    458     vaddl.u8    q10, d4, d6
    459     vadd.i16    q15, q14
    460     vaddl.u8    q14, d7, d10
    461     vqrshrn.u16 d19, q15, #3               ; r_op1
    462 
    463     vsub.i16    q15, q10
    464     vadd.i16    q15, q14
    465     vaddl.u8    q14, d8, d11
    466     vqrshrn.u16 d20, q15, #3               ; r_op0
    467 
    468     vsubw.u8    q15, d4                    ; oq0 = op0 - p3
    469     vsubw.u8    q15, d7                    ; oq0 -= p0
    470     vadd.i16    q15, q14
    471     vaddl.u8    q14, d9, d11
    472     vqrshrn.u16 d21, q15, #3               ; r_oq0
    473 
    474     vsubw.u8    q15, d5                    ; oq1 = oq0 - p2
    475     vsubw.u8    q15, d8                    ; oq1 -= q0
    476     vadd.i16    q15, q14
    477     vaddl.u8    q14, d10, d11
    478     vqrshrn.u16 d22, q15, #3               ; r_oq1
    479 
    480     vsubw.u8    q15, d6                    ; oq2 = oq0 - p1
    481     vsubw.u8    q15, d9                    ; oq2 -= q1
    482     vadd.i16    q15, q14
    483     vqrshrn.u16 d27, q15, #3               ; r_oq2
    484 
    485     ; Filter does not set op2 or oq2, so use p2 and q2.
    486     vbif        d18, d5, d16               ; t_op2 |= p2 & ~(flat & mask)
    487     vbif        d19, d25, d16              ; t_op1 |= f_op1 & ~(flat & mask)
    488     vbif        d20, d24, d16              ; t_op0 |= f_op0 & ~(flat & mask)
    489     vbif        d21, d23, d16              ; t_oq0 |= f_oq0 & ~(flat & mask)
    490     vbif        d22, d26, d16              ; t_oq1 |= f_oq1 & ~(flat & mask)
    491 
    492     vbit        d23, d27, d16              ; t_oq2 |= r_oq2 & (flat & mask)
    493     vbif        d23, d10, d16              ; t_oq2 |= q2 & ~(flat & mask)
    494 
    495     tst         r7, #2
    496     bxne        lr
    497 
    498     ; wide_mbfilter flat2 && flat && mask branch
    499     vmov.u8     d16, #7
    500     vaddl.u8    q15, d7, d8                ; op6 = p0 + q0
    501     vaddl.u8    q12, d2, d3
    502     vaddl.u8    q13, d4, d5
    503     vaddl.u8    q14, d1, d6
    504     vmlal.u8    q15, d0, d16               ; op6 += p7 * 3
    505     vadd.i16    q12, q13
    506     vadd.i16    q15, q14
    507     vaddl.u8    q14, d2, d9
    508     vadd.i16    q15, q12
    509     vaddl.u8    q12, d0, d1
    510     vaddw.u8    q15, d1
    511     vaddl.u8    q13, d0, d2
    512     vadd.i16    q14, q15, q14
    513     vqrshrn.u16 d16, q15, #4               ; w_op6
    514 
    515     vsub.i16    q15, q14, q12
    516     vaddl.u8    q14, d3, d10
    517     vqrshrn.u16 d24, q15, #4               ; w_op5
    518 
    519     vsub.i16    q15, q13
    520     vaddl.u8    q13, d0, d3
    521     vadd.i16    q15, q14
    522     vaddl.u8    q14, d4, d11
    523     vqrshrn.u16 d25, q15, #4               ; w_op4
    524 
    525     vadd.i16    q15, q14
    526     vaddl.u8    q14, d0, d4
    527     vsub.i16    q15, q13
    528     vsub.i16    q14, q15, q14
    529     vqrshrn.u16 d26, q15, #4               ; w_op3
    530 
    531     vaddw.u8    q15, q14, d5               ; op2 += p2
    532     vaddl.u8    q14, d0, d5
    533     vaddw.u8    q15, d12                   ; op2 += q4
    534     vbif        d26, d4, d17               ; op3 |= p3 & ~(f2 & f & m)
    535     vqrshrn.u16 d27, q15, #4               ; w_op2
    536 
    537     vsub.i16    q15, q14
    538     vaddl.u8    q14, d0, d6
    539     vaddw.u8    q15, d6                    ; op1 += p1
    540     vaddw.u8    q15, d13                   ; op1 += q5
    541     vbif        d27, d18, d17              ; op2 |= t_op2 & ~(f2 & f & m)
    542     vqrshrn.u16 d18, q15, #4               ; w_op1
    543 
    544     vsub.i16    q15, q14
    545     vaddl.u8    q14, d0, d7
    546     vaddw.u8    q15, d7                    ; op0 += p0
    547     vaddw.u8    q15, d14                   ; op0 += q6
    548     vbif        d18, d19, d17              ; op1 |= t_op1 & ~(f2 & f & m)
    549     vqrshrn.u16 d19, q15, #4               ; w_op0
    550 
    551     vsub.i16    q15, q14
    552     vaddl.u8    q14, d1, d8
    553     vaddw.u8    q15, d8                    ; oq0 += q0
    554     vaddw.u8    q15, d15                   ; oq0 += q7
    555     vbif        d19, d20, d17              ; op0 |= t_op0 & ~(f2 & f & m)
    556     vqrshrn.u16 d20, q15, #4               ; w_oq0
    557 
    558     vsub.i16    q15, q14
    559     vaddl.u8    q14, d2, d9
    560     vaddw.u8    q15, d9                    ; oq1 += q1
    561     vaddl.u8    q4, d10, d15
    562     vaddw.u8    q15, d15                   ; oq1 += q7
    563     vbif        d20, d21, d17              ; oq0 |= t_oq0 & ~(f2 & f & m)
    564     vqrshrn.u16 d21, q15, #4               ; w_oq1
    565 
    566     vsub.i16    q15, q14
    567     vaddl.u8    q14, d3, d10
    568     vadd.i16    q15, q4
    569     vaddl.u8    q4, d11, d15
    570     vbif        d21, d22, d17              ; oq1 |= t_oq1 & ~(f2 & f & m)
    571     vqrshrn.u16 d22, q15, #4               ; w_oq2
    572 
    573     vsub.i16    q15, q14
    574     vaddl.u8    q14, d4, d11
    575     vadd.i16    q15, q4
    576     vaddl.u8    q4, d12, d15
    577     vbif        d22, d23, d17              ; oq2 |= t_oq2 & ~(f2 & f & m)
    578     vqrshrn.u16 d23, q15, #4               ; w_oq3
    579 
    580     vsub.i16    q15, q14
    581     vaddl.u8    q14, d5, d12
    582     vadd.i16    q15, q4
    583     vaddl.u8    q4, d13, d15
    584     vbif        d16, d1, d17               ; op6 |= p6 & ~(f2 & f & m)
    585     vqrshrn.u16 d1, q15, #4                ; w_oq4
    586 
    587     vsub.i16    q15, q14
    588     vaddl.u8    q14, d6, d13
    589     vadd.i16    q15, q4
    590     vaddl.u8    q4, d14, d15
    591     vbif        d24, d2, d17               ; op5 |= p5 & ~(f2 & f & m)
    592     vqrshrn.u16 d2, q15, #4                ; w_oq5
    593 
    594     vsub.i16    q15, q14
    595     vbif        d25, d3, d17               ; op4 |= p4 & ~(f2 & f & m)
    596     vadd.i16    q15, q4
    597     vbif        d23, d11, d17              ; oq3 |= q3 & ~(f2 & f & m)
    598     vqrshrn.u16 d3, q15, #4                ; w_oq6
    599     vbif        d1, d12, d17               ; oq4 |= q4 & ~(f2 & f & m)
    600     vbif        d2, d13, d17               ; oq5 |= q5 & ~(f2 & f & m)
    601     vbif        d3, d14, d17               ; oq6 |= q6 & ~(f2 & f & m)
    602 
    603     bx          lr
    604     ENDP        ; |vp9_wide_mbfilter_neon|
    605 
    606     END
    607