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