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_bilinear_predict16x16_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_bilinear_predict16x16_neon| PROC
     26     push            {r4-r5, lr}
     27 
     28     ldr             r12, _bifilter16_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_bfilter16x16_only
     34 
     35     add             r2, r12, r2, lsl #3     ;calculate filter location
     36 
     37     cmp             r3, #0                  ;skip second_pass filter if yoffset=0
     38 
     39     vld1.s32        {d31}, [r2]             ;load first_pass filter
     40 
     41     beq             firstpass_bfilter16x16_only
     42 
     43     sub             sp, sp, #272            ;reserve space on stack for temporary storage
     44     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
     45     mov             lr, sp
     46     vld1.u8         {d5, d6, d7}, [r0], r1
     47 
     48     mov             r2, #3                  ;loop counter
     49     vld1.u8         {d8, d9, d10}, [r0], r1
     50 
     51     vdup.8          d0, d31[0]              ;first_pass filter (d0 d1)
     52     vld1.u8         {d11, d12, d13}, [r0], r1
     53 
     54     vdup.8          d1, d31[4]
     55 
     56 ;First Pass: output_height lines x output_width columns (17x16)
     57 filt_blk2d_fp16x16_loop_neon
     58     pld             [r0]
     59     pld             [r0, r1]
     60     pld             [r0, r1, lsl #1]
     61 
     62     vmull.u8        q7, d2, d0              ;(src_ptr[0] * vp8_filter[0])
     63     vmull.u8        q8, d3, d0
     64     vmull.u8        q9, d5, d0
     65     vmull.u8        q10, d6, d0
     66     vmull.u8        q11, d8, d0
     67     vmull.u8        q12, d9, d0
     68     vmull.u8        q13, d11, d0
     69     vmull.u8        q14, d12, d0
     70 
     71     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
     72     vext.8          d5, d5, d6, #1
     73     vext.8          d8, d8, d9, #1
     74     vext.8          d11, d11, d12, #1
     75 
     76     vmlal.u8        q7, d2, d1              ;(src_ptr[0] * vp8_filter[1])
     77     vmlal.u8        q9, d5, d1
     78     vmlal.u8        q11, d8, d1
     79     vmlal.u8        q13, d11, d1
     80 
     81     vext.8          d3, d3, d4, #1
     82     vext.8          d6, d6, d7, #1
     83     vext.8          d9, d9, d10, #1
     84     vext.8          d12, d12, d13, #1
     85 
     86     vmlal.u8        q8, d3, d1              ;(src_ptr[0] * vp8_filter[1])
     87     vmlal.u8        q10, d6, d1
     88     vmlal.u8        q12, d9, d1
     89     vmlal.u8        q14, d12, d1
     90 
     91     subs            r2, r2, #1
     92 
     93     vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
     94     vqrshrn.u16    d15, q8, #7
     95     vqrshrn.u16    d16, q9, #7
     96     vqrshrn.u16    d17, q10, #7
     97     vqrshrn.u16    d18, q11, #7
     98     vqrshrn.u16    d19, q12, #7
     99     vqrshrn.u16    d20, q13, #7
    100 
    101     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
    102     vqrshrn.u16    d21, q14, #7
    103     vld1.u8         {d5, d6, d7}, [r0], r1
    104 
    105     vst1.u8         {d14, d15, d16, d17}, [lr]!     ;store result
    106     vld1.u8         {d8, d9, d10}, [r0], r1
    107     vst1.u8         {d18, d19, d20, d21}, [lr]!
    108     vld1.u8         {d11, d12, d13}, [r0], r1
    109 
    110     bne             filt_blk2d_fp16x16_loop_neon
    111 
    112 ;First-pass filtering for rest 5 lines
    113     vld1.u8         {d14, d15, d16}, [r0], r1
    114 
    115     vmull.u8        q9, d2, d0              ;(src_ptr[0] * vp8_filter[0])
    116     vmull.u8        q10, d3, d0
    117     vmull.u8        q11, d5, d0
    118     vmull.u8        q12, d6, d0
    119     vmull.u8        q13, d8, d0
    120     vmull.u8        q14, d9, d0
    121 
    122     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
    123     vext.8          d5, d5, d6, #1
    124     vext.8          d8, d8, d9, #1
    125 
    126     vmlal.u8        q9, d2, d1              ;(src_ptr[0] * vp8_filter[1])
    127     vmlal.u8        q11, d5, d1
    128     vmlal.u8        q13, d8, d1
    129 
    130     vext.8          d3, d3, d4, #1
    131     vext.8          d6, d6, d7, #1
    132     vext.8          d9, d9, d10, #1
    133 
    134     vmlal.u8        q10, d3, d1             ;(src_ptr[0] * vp8_filter[1])
    135     vmlal.u8        q12, d6, d1
    136     vmlal.u8        q14, d9, d1
    137 
    138     vmull.u8        q1, d11, d0
    139     vmull.u8        q2, d12, d0
    140     vmull.u8        q3, d14, d0
    141     vmull.u8        q4, d15, d0
    142 
    143     vext.8          d11, d11, d12, #1       ;construct src_ptr[1]
    144     vext.8          d14, d14, d15, #1
    145 
    146     vmlal.u8        q1, d11, d1             ;(src_ptr[0] * vp8_filter[1])
    147     vmlal.u8        q3, d14, d1
    148 
    149     vext.8          d12, d12, d13, #1
    150     vext.8          d15, d15, d16, #1
    151 
    152     vmlal.u8        q2, d12, d1             ;(src_ptr[0] * vp8_filter[1])
    153     vmlal.u8        q4, d15, d1
    154 
    155     vqrshrn.u16    d10, q9, #7              ;shift/round/saturate to u8
    156     vqrshrn.u16    d11, q10, #7
    157     vqrshrn.u16    d12, q11, #7
    158     vqrshrn.u16    d13, q12, #7
    159     vqrshrn.u16    d14, q13, #7
    160     vqrshrn.u16    d15, q14, #7
    161     vqrshrn.u16    d16, q1, #7
    162     vqrshrn.u16    d17, q2, #7
    163     vqrshrn.u16    d18, q3, #7
    164     vqrshrn.u16    d19, q4, #7
    165 
    166     vst1.u8         {d10, d11, d12, d13}, [lr]!         ;store result
    167     vst1.u8         {d14, d15, d16, d17}, [lr]!
    168     vst1.u8         {d18, d19}, [lr]!
    169 
    170 ;Second pass: 16x16
    171 ;secondpass_filter
    172     add             r3, r12, r3, lsl #3
    173     sub             lr, lr, #272
    174 
    175     vld1.u32        {d31}, [r3]             ;load second_pass filter
    176 
    177     vld1.u8         {d22, d23}, [lr]!       ;load src data
    178 
    179     vdup.8          d0, d31[0]              ;second_pass filter parameters (d0 d1)
    180     vdup.8          d1, d31[4]
    181     mov             r12, #4                 ;loop counter
    182 
    183 filt_blk2d_sp16x16_loop_neon
    184     vld1.u8         {d24, d25}, [lr]!
    185     vmull.u8        q1, d22, d0             ;(src_ptr[0] * vp8_filter[0])
    186     vld1.u8         {d26, d27}, [lr]!
    187     vmull.u8        q2, d23, d0
    188     vld1.u8         {d28, d29}, [lr]!
    189     vmull.u8        q3, d24, d0
    190     vld1.u8         {d30, d31}, [lr]!
    191 
    192     vmull.u8        q4, d25, d0
    193     vmull.u8        q5, d26, d0
    194     vmull.u8        q6, d27, d0
    195     vmull.u8        q7, d28, d0
    196     vmull.u8        q8, d29, d0
    197 
    198     vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * vp8_filter[1])
    199     vmlal.u8        q2, d25, d1
    200     vmlal.u8        q3, d26, d1
    201     vmlal.u8        q4, d27, d1
    202     vmlal.u8        q5, d28, d1
    203     vmlal.u8        q6, d29, d1
    204     vmlal.u8        q7, d30, d1
    205     vmlal.u8        q8, d31, d1
    206 
    207     subs            r12, r12, #1
    208 
    209     vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
    210     vqrshrn.u16    d3, q2, #7
    211     vqrshrn.u16    d4, q3, #7
    212     vqrshrn.u16    d5, q4, #7
    213     vqrshrn.u16    d6, q5, #7
    214     vqrshrn.u16    d7, q6, #7
    215     vqrshrn.u16    d8, q7, #7
    216     vqrshrn.u16    d9, q8, #7
    217 
    218     vst1.u8         {d2, d3}, [r4], r5      ;store result
    219     vst1.u8         {d4, d5}, [r4], r5
    220     vst1.u8         {d6, d7}, [r4], r5
    221     vmov            q11, q15
    222     vst1.u8         {d8, d9}, [r4], r5
    223 
    224     bne             filt_blk2d_sp16x16_loop_neon
    225 
    226     add             sp, sp, #272
    227 
    228     pop             {r4-r5,pc}
    229 
    230 ;--------------------
    231 firstpass_bfilter16x16_only
    232     mov             r2, #4                      ;loop counter
    233     vdup.8          d0, d31[0]                  ;first_pass filter (d0 d1)
    234     vdup.8          d1, d31[4]
    235 
    236 ;First Pass: output_height lines x output_width columns (16x16)
    237 filt_blk2d_fpo16x16_loop_neon
    238     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
    239     vld1.u8         {d5, d6, d7}, [r0], r1
    240     vld1.u8         {d8, d9, d10}, [r0], r1
    241     vld1.u8         {d11, d12, d13}, [r0], r1
    242 
    243     pld             [r0]
    244     pld             [r0, r1]
    245     pld             [r0, r1, lsl #1]
    246 
    247     vmull.u8        q7, d2, d0              ;(src_ptr[0] * vp8_filter[0])
    248     vmull.u8        q8, d3, d0
    249     vmull.u8        q9, d5, d0
    250     vmull.u8        q10, d6, d0
    251     vmull.u8        q11, d8, d0
    252     vmull.u8        q12, d9, d0
    253     vmull.u8        q13, d11, d0
    254     vmull.u8        q14, d12, d0
    255 
    256     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
    257     vext.8          d5, d5, d6, #1
    258     vext.8          d8, d8, d9, #1
    259     vext.8          d11, d11, d12, #1
    260 
    261     vmlal.u8        q7, d2, d1              ;(src_ptr[0] * vp8_filter[1])
    262     vmlal.u8        q9, d5, d1
    263     vmlal.u8        q11, d8, d1
    264     vmlal.u8        q13, d11, d1
    265 
    266     vext.8          d3, d3, d4, #1
    267     vext.8          d6, d6, d7, #1
    268     vext.8          d9, d9, d10, #1
    269     vext.8          d12, d12, d13, #1
    270 
    271     vmlal.u8        q8, d3, d1              ;(src_ptr[0] * vp8_filter[1])
    272     vmlal.u8        q10, d6, d1
    273     vmlal.u8        q12, d9, d1
    274     vmlal.u8        q14, d12, d1
    275 
    276     subs            r2, r2, #1
    277 
    278     vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
    279     vqrshrn.u16    d15, q8, #7
    280     vqrshrn.u16    d16, q9, #7
    281     vqrshrn.u16    d17, q10, #7
    282     vqrshrn.u16    d18, q11, #7
    283     vqrshrn.u16    d19, q12, #7
    284     vqrshrn.u16    d20, q13, #7
    285     vst1.u8         {d14, d15}, [r4], r5        ;store result
    286     vqrshrn.u16    d21, q14, #7
    287 
    288     vst1.u8         {d16, d17}, [r4], r5
    289     vst1.u8         {d18, d19}, [r4], r5
    290     vst1.u8         {d20, d21}, [r4], r5
    291 
    292     bne             filt_blk2d_fpo16x16_loop_neon
    293     pop             {r4-r5,pc}
    294 
    295 ;---------------------
    296 secondpass_bfilter16x16_only
    297 ;Second pass: 16x16
    298 ;secondpass_filter
    299     add             r3, r12, r3, lsl #3
    300     mov             r12, #4                     ;loop counter
    301     vld1.u32        {d31}, [r3]                 ;load second_pass filter
    302     vld1.u8         {d22, d23}, [r0], r1        ;load src data
    303 
    304     vdup.8          d0, d31[0]                  ;second_pass filter parameters (d0 d1)
    305     vdup.8          d1, d31[4]
    306 
    307 filt_blk2d_spo16x16_loop_neon
    308     vld1.u8         {d24, d25}, [r0], r1
    309     vmull.u8        q1, d22, d0             ;(src_ptr[0] * vp8_filter[0])
    310     vld1.u8         {d26, d27}, [r0], r1
    311     vmull.u8        q2, d23, d0
    312     vld1.u8         {d28, d29}, [r0], r1
    313     vmull.u8        q3, d24, d0
    314     vld1.u8         {d30, d31}, [r0], r1
    315 
    316     vmull.u8        q4, d25, d0
    317     vmull.u8        q5, d26, d0
    318     vmull.u8        q6, d27, d0
    319     vmull.u8        q7, d28, d0
    320     vmull.u8        q8, d29, d0
    321 
    322     vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * vp8_filter[1])
    323     vmlal.u8        q2, d25, d1
    324     vmlal.u8        q3, d26, d1
    325     vmlal.u8        q4, d27, d1
    326     vmlal.u8        q5, d28, d1
    327     vmlal.u8        q6, d29, d1
    328     vmlal.u8        q7, d30, d1
    329     vmlal.u8        q8, d31, d1
    330 
    331     vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
    332     vqrshrn.u16    d3, q2, #7
    333     vqrshrn.u16    d4, q3, #7
    334     vqrshrn.u16    d5, q4, #7
    335     vqrshrn.u16    d6, q5, #7
    336     vqrshrn.u16    d7, q6, #7
    337     vqrshrn.u16    d8, q7, #7
    338     vqrshrn.u16    d9, q8, #7
    339 
    340     vst1.u8         {d2, d3}, [r4], r5      ;store result
    341     subs            r12, r12, #1
    342     vst1.u8         {d4, d5}, [r4], r5
    343     vmov            q11, q15
    344     vst1.u8         {d6, d7}, [r4], r5
    345     vst1.u8         {d8, d9}, [r4], r5
    346 
    347     bne             filt_blk2d_spo16x16_loop_neon
    348     pop             {r4-r5,pc}
    349 
    350     ENDP
    351 
    352 ;-----------------
    353 
    354 _bifilter16_coeff_
    355     DCD     bifilter16_coeff
    356 bifilter16_coeff
    357     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
    358 
    359     END
    360