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_sixtap_predict8x8_neon|
     13     ARM
     14     REQUIRE8
     15     PRESERVE8
     16 
     17     AREA ||.text||, CODE, READONLY, ALIGN=2
     18 ; r0    unsigned char  *src_ptr,
     19 ; r1    int  src_pixels_per_line,
     20 ; r2    int  xoffset,
     21 ; r3    int  yoffset,
     22 ; stack(r4) unsigned char *dst_ptr,
     23 ; stack(r5) int  dst_pitch
     24 
     25 |vp8_sixtap_predict8x8_neon| PROC
     26     push            {r4-r5, lr}
     27 
     28     ldr             r12, _filter8_coeff_
     29 
     30     ldr             r4, [sp, #12]           ;load parameters from stack
     31     ldr             r5, [sp, #16]           ;load parameters from stack
     32 
     33     cmp             r2, #0                  ;skip first_pass filter if xoffset=0
     34     beq             secondpass_filter8x8_only
     35 
     36     add             r2, r12, r2, lsl #5     ;calculate filter location
     37 
     38     cmp             r3, #0                  ;skip second_pass filter if yoffset=0
     39 
     40     vld1.s32        {q14, q15}, [r2]        ;load first_pass filter
     41 
     42     beq             firstpass_filter8x8_only
     43 
     44     sub             sp, sp, #64             ;reserve space on stack for temporary storage
     45     mov             lr, sp
     46 
     47     vabs.s32        q12, q14
     48     vabs.s32        q13, q15
     49 
     50     mov             r2, #2                  ;loop counter
     51     sub             r0, r0, #2              ;move srcptr back to (line-2) and (column-2)
     52     sub             r0, r0, r1, lsl #1
     53 
     54     vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
     55     vdup.8          d1, d24[4]
     56     vdup.8          d2, d25[0]
     57 
     58 ;First pass: output_height lines x output_width columns (13x8)
     59     vld1.u8         {q3}, [r0], r1          ;load src data
     60     vdup.8          d3, d25[4]
     61     vld1.u8         {q4}, [r0], r1
     62     vdup.8          d4, d26[0]
     63     vld1.u8         {q5}, [r0], r1
     64     vdup.8          d5, d26[4]
     65     vld1.u8         {q6}, [r0], r1
     66 
     67 filt_blk2d_fp8x8_loop_neon
     68     pld             [r0]
     69     pld             [r0, r1]
     70     pld             [r0, r1, lsl #1]
     71 
     72     vmull.u8        q7, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
     73     vmull.u8        q8, d8, d0
     74     vmull.u8        q9, d10, d0
     75     vmull.u8        q10, d12, d0
     76 
     77     vext.8          d28, d6, d7, #1         ;construct src_ptr[-1]
     78     vext.8          d29, d8, d9, #1
     79     vext.8          d30, d10, d11, #1
     80     vext.8          d31, d12, d13, #1
     81 
     82     vmlsl.u8        q7, d28, d1             ;-(src_ptr[-1] * vp8_filter[1])
     83     vmlsl.u8        q8, d29, d1
     84     vmlsl.u8        q9, d30, d1
     85     vmlsl.u8        q10, d31, d1
     86 
     87     vext.8          d28, d6, d7, #4         ;construct src_ptr[2]
     88     vext.8          d29, d8, d9, #4
     89     vext.8          d30, d10, d11, #4
     90     vext.8          d31, d12, d13, #4
     91 
     92     vmlsl.u8        q7, d28, d4             ;-(src_ptr[2] * vp8_filter[4])
     93     vmlsl.u8        q8, d29, d4
     94     vmlsl.u8        q9, d30, d4
     95     vmlsl.u8        q10, d31, d4
     96 
     97     vext.8          d28, d6, d7, #2         ;construct src_ptr[0]
     98     vext.8          d29, d8, d9, #2
     99     vext.8          d30, d10, d11, #2
    100     vext.8          d31, d12, d13, #2
    101 
    102     vmlal.u8        q7, d28, d2             ;(src_ptr[0] * vp8_filter[2])
    103     vmlal.u8        q8, d29, d2
    104     vmlal.u8        q9, d30, d2
    105     vmlal.u8        q10, d31, d2
    106 
    107     vext.8          d28, d6, d7, #5         ;construct src_ptr[3]
    108     vext.8          d29, d8, d9, #5
    109     vext.8          d30, d10, d11, #5
    110     vext.8          d31, d12, d13, #5
    111 
    112     vmlal.u8        q7, d28, d5             ;(src_ptr[3] * vp8_filter[5])
    113     vmlal.u8        q8, d29, d5
    114     vmlal.u8        q9, d30, d5
    115     vmlal.u8        q10, d31, d5
    116 
    117     vext.8          d28, d6, d7, #3         ;construct src_ptr[1]
    118     vext.8          d29, d8, d9, #3
    119     vext.8          d30, d10, d11, #3
    120     vext.8          d31, d12, d13, #3
    121 
    122     vmull.u8        q3, d28, d3             ;(src_ptr[1] * vp8_filter[3])
    123     vmull.u8        q4, d29, d3
    124     vmull.u8        q5, d30, d3
    125     vmull.u8        q6, d31, d3
    126 
    127     subs            r2, r2, #1
    128 
    129     vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
    130     vqadd.s16       q8, q4
    131     vqadd.s16       q9, q5
    132     vqadd.s16       q10, q6
    133 
    134     vld1.u8         {q3}, [r0], r1          ;load src data
    135 
    136     vqrshrun.s16    d22, q7, #7             ;shift/round/saturate to u8
    137     vqrshrun.s16    d23, q8, #7
    138     vqrshrun.s16    d24, q9, #7
    139     vqrshrun.s16    d25, q10, #7
    140 
    141     vst1.u8         {d22}, [lr]!            ;store result
    142     vld1.u8         {q4}, [r0], r1
    143     vst1.u8         {d23}, [lr]!
    144     vld1.u8         {q5}, [r0], r1
    145     vst1.u8         {d24}, [lr]!
    146     vld1.u8         {q6}, [r0], r1
    147     vst1.u8         {d25}, [lr]!
    148 
    149     bne             filt_blk2d_fp8x8_loop_neon
    150 
    151     ;first_pass filtering on the rest 5-line data
    152     ;vld1.u8            {q3}, [r0], r1          ;load src data
    153     ;vld1.u8            {q4}, [r0], r1
    154     ;vld1.u8            {q5}, [r0], r1
    155     ;vld1.u8            {q6}, [r0], r1
    156     vld1.u8         {q7}, [r0], r1
    157 
    158     vmull.u8        q8, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
    159     vmull.u8        q9, d8, d0
    160     vmull.u8        q10, d10, d0
    161     vmull.u8        q11, d12, d0
    162     vmull.u8        q12, d14, d0
    163 
    164     vext.8          d27, d6, d7, #1         ;construct src_ptr[-1]
    165     vext.8          d28, d8, d9, #1
    166     vext.8          d29, d10, d11, #1
    167     vext.8          d30, d12, d13, #1
    168     vext.8          d31, d14, d15, #1
    169 
    170     vmlsl.u8        q8, d27, d1             ;-(src_ptr[-1] * vp8_filter[1])
    171     vmlsl.u8        q9, d28, d1
    172     vmlsl.u8        q10, d29, d1
    173     vmlsl.u8        q11, d30, d1
    174     vmlsl.u8        q12, d31, d1
    175 
    176     vext.8          d27, d6, d7, #4         ;construct src_ptr[2]
    177     vext.8          d28, d8, d9, #4
    178     vext.8          d29, d10, d11, #4
    179     vext.8          d30, d12, d13, #4
    180     vext.8          d31, d14, d15, #4
    181 
    182     vmlsl.u8        q8, d27, d4             ;-(src_ptr[2] * vp8_filter[4])
    183     vmlsl.u8        q9, d28, d4
    184     vmlsl.u8        q10, d29, d4
    185     vmlsl.u8        q11, d30, d4
    186     vmlsl.u8        q12, d31, d4
    187 
    188     vext.8          d27, d6, d7, #2         ;construct src_ptr[0]
    189     vext.8          d28, d8, d9, #2
    190     vext.8          d29, d10, d11, #2
    191     vext.8          d30, d12, d13, #2
    192     vext.8          d31, d14, d15, #2
    193 
    194     vmlal.u8        q8, d27, d2             ;(src_ptr[0] * vp8_filter[2])
    195     vmlal.u8        q9, d28, d2
    196     vmlal.u8        q10, d29, d2
    197     vmlal.u8        q11, d30, d2
    198     vmlal.u8        q12, d31, d2
    199 
    200     vext.8          d27, d6, d7, #5         ;construct src_ptr[3]
    201     vext.8          d28, d8, d9, #5
    202     vext.8          d29, d10, d11, #5
    203     vext.8          d30, d12, d13, #5
    204     vext.8          d31, d14, d15, #5
    205 
    206     vmlal.u8        q8, d27, d5             ;(src_ptr[3] * vp8_filter[5])
    207     vmlal.u8        q9, d28, d5
    208     vmlal.u8        q10, d29, d5
    209     vmlal.u8        q11, d30, d5
    210     vmlal.u8        q12, d31, d5
    211 
    212     vext.8          d27, d6, d7, #3         ;construct src_ptr[1]
    213     vext.8          d28, d8, d9, #3
    214     vext.8          d29, d10, d11, #3
    215     vext.8          d30, d12, d13, #3
    216     vext.8          d31, d14, d15, #3
    217 
    218     vmull.u8        q3, d27, d3             ;(src_ptr[1] * vp8_filter[3])
    219     vmull.u8        q4, d28, d3
    220     vmull.u8        q5, d29, d3
    221     vmull.u8        q6, d30, d3
    222     vmull.u8        q7, d31, d3
    223 
    224     vqadd.s16       q8, q3                  ;sum of all (src_data*filter_parameters)
    225     vqadd.s16       q9, q4
    226     vqadd.s16       q10, q5
    227     vqadd.s16       q11, q6
    228     vqadd.s16       q12, q7
    229 
    230     add             r3, r12, r3, lsl #5
    231 
    232     vqrshrun.s16    d26, q8, #7             ;shift/round/saturate to u8
    233     sub             lr, lr, #64
    234     vqrshrun.s16    d27, q9, #7
    235     vld1.u8         {q9}, [lr]!             ;load intermediate data from stack
    236     vqrshrun.s16    d28, q10, #7
    237     vld1.u8         {q10}, [lr]!
    238 
    239     vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
    240 
    241     vqrshrun.s16    d29, q11, #7
    242     vld1.u8         {q11}, [lr]!
    243 
    244     vabs.s32        q7, q5
    245     vabs.s32        q8, q6
    246 
    247     vqrshrun.s16    d30, q12, #7
    248     vld1.u8         {q12}, [lr]!
    249 
    250 ;Second pass: 8x8
    251     mov             r3, #2                  ;loop counter
    252 
    253     vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
    254     vdup.8          d1, d14[4]
    255     vdup.8          d2, d15[0]
    256     vdup.8          d3, d15[4]
    257     vdup.8          d4, d16[0]
    258     vdup.8          d5, d16[4]
    259 
    260 filt_blk2d_sp8x8_loop_neon
    261     vmull.u8        q3, d18, d0             ;(src_ptr[-2] * vp8_filter[0])
    262     vmull.u8        q4, d19, d0
    263     vmull.u8        q5, d20, d0
    264     vmull.u8        q6, d21, d0
    265 
    266     vmlsl.u8        q3, d19, d1             ;-(src_ptr[-1] * vp8_filter[1])
    267     vmlsl.u8        q4, d20, d1
    268     vmlsl.u8        q5, d21, d1
    269     vmlsl.u8        q6, d22, d1
    270 
    271     vmlsl.u8        q3, d22, d4             ;-(src_ptr[2] * vp8_filter[4])
    272     vmlsl.u8        q4, d23, d4
    273     vmlsl.u8        q5, d24, d4
    274     vmlsl.u8        q6, d25, d4
    275 
    276     vmlal.u8        q3, d20, d2             ;(src_ptr[0] * vp8_filter[2])
    277     vmlal.u8        q4, d21, d2
    278     vmlal.u8        q5, d22, d2
    279     vmlal.u8        q6, d23, d2
    280 
    281     vmlal.u8        q3, d23, d5             ;(src_ptr[3] * vp8_filter[5])
    282     vmlal.u8        q4, d24, d5
    283     vmlal.u8        q5, d25, d5
    284     vmlal.u8        q6, d26, d5
    285 
    286     vmull.u8        q7, d21, d3             ;(src_ptr[1] * vp8_filter[3])
    287     vmull.u8        q8, d22, d3
    288     vmull.u8        q9, d23, d3
    289     vmull.u8        q10, d24, d3
    290 
    291     subs            r3, r3, #1
    292 
    293     vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
    294     vqadd.s16       q8, q4
    295     vqadd.s16       q9, q5
    296     vqadd.s16       q10, q6
    297 
    298     vqrshrun.s16    d6, q7, #7              ;shift/round/saturate to u8
    299     vqrshrun.s16    d7, q8, #7
    300     vqrshrun.s16    d8, q9, #7
    301     vqrshrun.s16    d9, q10, #7
    302 
    303     vmov            q9, q11
    304     vst1.u8         {d6}, [r4], r5          ;store result
    305     vmov            q10, q12
    306     vst1.u8         {d7}, [r4], r5
    307     vmov            q11, q13
    308     vst1.u8         {d8}, [r4], r5
    309     vmov            q12, q14
    310     vst1.u8         {d9}, [r4], r5
    311     vmov            d26, d30
    312 
    313     bne filt_blk2d_sp8x8_loop_neon
    314 
    315     add             sp, sp, #64
    316     pop             {r4-r5,pc}
    317 
    318 ;---------------------
    319 firstpass_filter8x8_only
    320     ;add                r2, r12, r2, lsl #5     ;calculate filter location
    321     ;vld1.s32       {q14, q15}, [r2]        ;load first_pass filter
    322     vabs.s32        q12, q14
    323     vabs.s32        q13, q15
    324 
    325     mov             r2, #2                  ;loop counter
    326     sub             r0, r0, #2              ;move srcptr back to (line-2) and (column-2)
    327 
    328     vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
    329     vdup.8          d1, d24[4]
    330     vdup.8          d2, d25[0]
    331     vdup.8          d3, d25[4]
    332     vdup.8          d4, d26[0]
    333     vdup.8          d5, d26[4]
    334 
    335 ;First pass: output_height lines x output_width columns (8x8)
    336 filt_blk2d_fpo8x8_loop_neon
    337     vld1.u8         {q3}, [r0], r1          ;load src data
    338     vld1.u8         {q4}, [r0], r1
    339     vld1.u8         {q5}, [r0], r1
    340     vld1.u8         {q6}, [r0], r1
    341 
    342     pld             [r0]
    343     pld             [r0, r1]
    344     pld             [r0, r1, lsl #1]
    345 
    346     vmull.u8        q7, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
    347     vmull.u8        q8, d8, d0
    348     vmull.u8        q9, d10, d0
    349     vmull.u8        q10, d12, d0
    350 
    351     vext.8          d28, d6, d7, #1         ;construct src_ptr[-1]
    352     vext.8          d29, d8, d9, #1
    353     vext.8          d30, d10, d11, #1
    354     vext.8          d31, d12, d13, #1
    355 
    356     vmlsl.u8        q7, d28, d1             ;-(src_ptr[-1] * vp8_filter[1])
    357     vmlsl.u8        q8, d29, d1
    358     vmlsl.u8        q9, d30, d1
    359     vmlsl.u8        q10, d31, d1
    360 
    361     vext.8          d28, d6, d7, #4         ;construct src_ptr[2]
    362     vext.8          d29, d8, d9, #4
    363     vext.8          d30, d10, d11, #4
    364     vext.8          d31, d12, d13, #4
    365 
    366     vmlsl.u8        q7, d28, d4             ;-(src_ptr[2] * vp8_filter[4])
    367     vmlsl.u8        q8, d29, d4
    368     vmlsl.u8        q9, d30, d4
    369     vmlsl.u8        q10, d31, d4
    370 
    371     vext.8          d28, d6, d7, #2         ;construct src_ptr[0]
    372     vext.8          d29, d8, d9, #2
    373     vext.8          d30, d10, d11, #2
    374     vext.8          d31, d12, d13, #2
    375 
    376     vmlal.u8        q7, d28, d2             ;(src_ptr[0] * vp8_filter[2])
    377     vmlal.u8        q8, d29, d2
    378     vmlal.u8        q9, d30, d2
    379     vmlal.u8        q10, d31, d2
    380 
    381     vext.8          d28, d6, d7, #5         ;construct src_ptr[3]
    382     vext.8          d29, d8, d9, #5
    383     vext.8          d30, d10, d11, #5
    384     vext.8          d31, d12, d13, #5
    385 
    386     vmlal.u8        q7, d28, d5             ;(src_ptr[3] * vp8_filter[5])
    387     vmlal.u8        q8, d29, d5
    388     vmlal.u8        q9, d30, d5
    389     vmlal.u8        q10, d31, d5
    390 
    391     vext.8          d28, d6, d7, #3         ;construct src_ptr[1]
    392     vext.8          d29, d8, d9, #3
    393     vext.8          d30, d10, d11, #3
    394     vext.8          d31, d12, d13, #3
    395 
    396     vmull.u8        q3, d28, d3             ;(src_ptr[1] * vp8_filter[3])
    397     vmull.u8        q4, d29, d3
    398     vmull.u8        q5, d30, d3
    399     vmull.u8        q6, d31, d3
    400  ;
    401     vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
    402     vqadd.s16       q8, q4
    403     vqadd.s16       q9, q5
    404     vqadd.s16       q10, q6
    405 
    406     subs            r2, r2, #1
    407 
    408     vqrshrun.s16    d22, q7, #7             ;shift/round/saturate to u8
    409     vqrshrun.s16    d23, q8, #7
    410     vqrshrun.s16    d24, q9, #7
    411     vqrshrun.s16    d25, q10, #7
    412 
    413     vst1.u8         {d22}, [r4], r5         ;store result
    414     vst1.u8         {d23}, [r4], r5
    415     vst1.u8         {d24}, [r4], r5
    416     vst1.u8         {d25}, [r4], r5
    417 
    418     bne             filt_blk2d_fpo8x8_loop_neon
    419 
    420     pop             {r4-r5,pc}
    421 
    422 ;---------------------
    423 secondpass_filter8x8_only
    424     sub             r0, r0, r1, lsl #1
    425     add             r3, r12, r3, lsl #5
    426 
    427     vld1.u8         {d18}, [r0], r1         ;load src data
    428     vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
    429     vld1.u8         {d19}, [r0], r1
    430     vabs.s32        q7, q5
    431     vld1.u8         {d20}, [r0], r1
    432     vabs.s32        q8, q6
    433     vld1.u8         {d21}, [r0], r1
    434     mov             r3, #2                  ;loop counter
    435     vld1.u8         {d22}, [r0], r1
    436     vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
    437     vld1.u8         {d23}, [r0], r1
    438     vdup.8          d1, d14[4]
    439     vld1.u8         {d24}, [r0], r1
    440     vdup.8          d2, d15[0]
    441     vld1.u8         {d25}, [r0], r1
    442     vdup.8          d3, d15[4]
    443     vld1.u8         {d26}, [r0], r1
    444     vdup.8          d4, d16[0]
    445     vld1.u8         {d27}, [r0], r1
    446     vdup.8          d5, d16[4]
    447     vld1.u8         {d28}, [r0], r1
    448     vld1.u8         {d29}, [r0], r1
    449     vld1.u8         {d30}, [r0], r1
    450 
    451 ;Second pass: 8x8
    452 filt_blk2d_spo8x8_loop_neon
    453     vmull.u8        q3, d18, d0             ;(src_ptr[-2] * vp8_filter[0])
    454     vmull.u8        q4, d19, d0
    455     vmull.u8        q5, d20, d0
    456     vmull.u8        q6, d21, d0
    457 
    458     vmlsl.u8        q3, d19, d1             ;-(src_ptr[-1] * vp8_filter[1])
    459     vmlsl.u8        q4, d20, d1
    460     vmlsl.u8        q5, d21, d1
    461     vmlsl.u8        q6, d22, d1
    462 
    463     vmlsl.u8        q3, d22, d4             ;-(src_ptr[2] * vp8_filter[4])
    464     vmlsl.u8        q4, d23, d4
    465     vmlsl.u8        q5, d24, d4
    466     vmlsl.u8        q6, d25, d4
    467 
    468     vmlal.u8        q3, d20, d2             ;(src_ptr[0] * vp8_filter[2])
    469     vmlal.u8        q4, d21, d2
    470     vmlal.u8        q5, d22, d2
    471     vmlal.u8        q6, d23, d2
    472 
    473     vmlal.u8        q3, d23, d5             ;(src_ptr[3] * vp8_filter[5])
    474     vmlal.u8        q4, d24, d5
    475     vmlal.u8        q5, d25, d5
    476     vmlal.u8        q6, d26, d5
    477 
    478     vmull.u8        q7, d21, d3             ;(src_ptr[1] * vp8_filter[3])
    479     vmull.u8        q8, d22, d3
    480     vmull.u8        q9, d23, d3
    481     vmull.u8        q10, d24, d3
    482 
    483     subs            r3, r3, #1
    484 
    485     vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
    486     vqadd.s16       q8, q4
    487     vqadd.s16       q9, q5
    488     vqadd.s16       q10, q6
    489 
    490     vqrshrun.s16    d6, q7, #7              ;shift/round/saturate to u8
    491     vqrshrun.s16    d7, q8, #7
    492     vqrshrun.s16    d8, q9, #7
    493     vqrshrun.s16    d9, q10, #7
    494 
    495     vmov            q9, q11
    496     vst1.u8         {d6}, [r4], r5          ;store result
    497     vmov            q10, q12
    498     vst1.u8         {d7}, [r4], r5
    499     vmov            q11, q13
    500     vst1.u8         {d8}, [r4], r5
    501     vmov            q12, q14
    502     vst1.u8         {d9}, [r4], r5
    503     vmov            d26, d30
    504 
    505     bne filt_blk2d_spo8x8_loop_neon
    506 
    507     pop             {r4-r5,pc}
    508 
    509     ENDP
    510 
    511 ;-----------------
    512     AREA    subpelfilters8_dat, DATA, READWRITE         ;read/write by default
    513 ;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
    514 ;One word each is reserved. Label filter_coeff can be used to access the data.
    515 ;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
    516 _filter8_coeff_
    517     DCD     filter8_coeff
    518 filter8_coeff
    519     DCD     0,  0,  128,    0,   0,  0,   0,  0
    520     DCD     0, -6,  123,   12,  -1,  0,   0,  0
    521     DCD     2, -11, 108,   36,  -8,  1,   0,  0
    522     DCD     0, -9,   93,   50,  -6,  0,   0,  0
    523     DCD     3, -16,  77,   77, -16,  3,   0,  0
    524     DCD     0, -6,   50,   93,  -9,  0,   0,  0
    525     DCD     1, -8,   36,  108, -11,  2,   0,  0
    526     DCD     0, -1,   12,  123,  -6,   0,  0,  0
    527 
    528     END
    529