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