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