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