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_loop_filter_simple_vertical_edge_neon|
     13     ARM
     14     REQUIRE8
     15     PRESERVE8
     16 
     17     AREA ||.text||, CODE, READONLY, ALIGN=2
     18 ;Note: flimit, limit, and thresh should be positive numbers. All 16 elements in flimit
     19 ;are equal. So, in the code, only one load is needed
     20 ;for flimit. Same way applies to limit and thresh.
     21 ; r0    unsigned char *s,
     22 ; r1    int p, //pitch
     23 ; r2    const signed char *flimit,
     24 ; r3    const signed char *limit,
     25 ; stack(r4) const signed char *thresh,
     26 ; //stack(r5)   int count --unused
     27 
     28 |vp8_loop_filter_simple_vertical_edge_neon| PROC
     29     sub         r0, r0, #2                  ; move src pointer down by 2 columns
     30 
     31     vld4.8      {d6[0], d7[0], d8[0], d9[0]}, [r0], r1
     32     vld1.s8     {d2[], d3[]}, [r2]          ; flimit
     33     vld1.s8     {d26[], d27[]}, [r3]        ; limit -> q13
     34     vld4.8      {d6[1], d7[1], d8[1], d9[1]}, [r0], r1
     35     ldr         r12, _vlfy_coeff_
     36     vld4.8      {d6[2], d7[2], d8[2], d9[2]}, [r0], r1
     37     vld4.8      {d6[3], d7[3], d8[3], d9[3]}, [r0], r1
     38     vld4.8      {d6[4], d7[4], d8[4], d9[4]}, [r0], r1
     39     vld4.8      {d6[5], d7[5], d8[5], d9[5]}, [r0], r1
     40     vld4.8      {d6[6], d7[6], d8[6], d9[6]}, [r0], r1
     41     vld4.8      {d6[7], d7[7], d8[7], d9[7]}, [r0], r1
     42 
     43     vld4.8      {d10[0], d11[0], d12[0], d13[0]}, [r0], r1
     44     vld1.u8     {q0}, [r12]!                ; 0x80
     45     vld4.8      {d10[1], d11[1], d12[1], d13[1]}, [r0], r1
     46     vld1.u8     {q11}, [r12]!               ; 0x03
     47     vld4.8      {d10[2], d11[2], d12[2], d13[2]}, [r0], r1
     48     vld1.u8     {q12}, [r12]!               ; 0x04
     49     vld4.8      {d10[3], d11[3], d12[3], d13[3]}, [r0], r1
     50     vld4.8      {d10[4], d11[4], d12[4], d13[4]}, [r0], r1
     51     vld4.8      {d10[5], d11[5], d12[5], d13[5]}, [r0], r1
     52     vld4.8      {d10[6], d11[6], d12[6], d13[6]}, [r0], r1
     53     vld4.8      {d10[7], d11[7], d12[7], d13[7]}, [r0], r1
     54 
     55     vswp        d7, d10
     56     vswp        d12, d9
     57     ;vswp       q4, q5                      ; p1:q3, p0:q5, q0:q4, q1:q6
     58 
     59     ;vp8_filter_mask() function
     60     ;vp8_hevmask() function
     61     sub         r0, r0, r1, lsl #4
     62     vabd.u8     q15, q5, q4                 ; abs(p0 - q0)
     63     vabd.u8     q14, q3, q6                 ; abs(p1 - q1)
     64     vqadd.u8    q15, q15, q15               ; abs(p0 - q0) * 2
     65     vshr.u8     q14, q14, #1                ; abs(p1 - q1) / 2
     66     vqadd.u8    q15, q15, q14               ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
     67 
     68     veor        q4, q4, q0                  ; qs0: q0 offset to convert to a signed value
     69     veor        q5, q5, q0                  ; ps0: p0 offset to convert to a signed value
     70     veor        q3, q3, q0                  ; ps1: p1 offset to convert to a signed value
     71     veor        q6, q6, q0                  ; qs1: q1 offset to convert to a signed value
     72 
     73     vadd.u8     q1, q1, q1                  ; flimit * 2
     74     vadd.u8     q1, q1, q13                 ; flimit * 2 + limit
     75     vcge.u8     q15, q1, q15                ; abs(p0 - q0)*2 + abs(p1-q1)/2 > flimit*2 + limit)*-1
     76 
     77     ;vp8_filter() function
     78 ;;;;;;;;;;
     79     ;vqsub.s8   q2, q5, q4                  ; ( qs0 - ps0)
     80     vsubl.s8    q2, d8, d10                 ; ( qs0 - ps0)
     81     vsubl.s8    q13, d9, d11
     82 
     83     vqsub.s8    q1, q3, q6                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
     84 
     85     ;vmul.i8    q2, q2, q11                 ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
     86     vadd.s16    q10, q2, q2                 ;  3 * ( qs0 - ps0)
     87     vadd.s16    q14, q13, q13
     88     vadd.s16    q2, q2, q10
     89     vadd.s16    q13, q13, q14
     90 
     91     ;vqadd.s8   q1, q1, q2
     92     vaddw.s8    q2, q2, d2                  ; vp8_filter + 3 * ( qs0 - ps0)
     93     vaddw.s8    q13, q13, d3
     94 
     95     vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
     96     vqmovn.s16  d3, q13
     97 
     98     add         r0, r0, #1
     99     add         r2, r0, r1
    100 ;;;;;;;;;;;
    101 
    102     vand        q1, q1, q15                 ; vp8_filter &= mask
    103 
    104     vqadd.s8    q2, q1, q11                 ; Filter2 = vp8_signed_char_clamp(vp8_filter+3)
    105     vqadd.s8    q1, q1, q12                 ; Filter1 = vp8_signed_char_clamp(vp8_filter+4)
    106     vshr.s8     q2, q2, #3                  ; Filter2 >>= 3
    107     vshr.s8     q1, q1, #3                  ; Filter1 >>= 3
    108 
    109     ;calculate output
    110     vqsub.s8    q10, q4, q1                 ; u = vp8_signed_char_clamp(qs0 - Filter1)
    111     vqadd.s8    q11, q5, q2                 ; u = vp8_signed_char_clamp(ps0 + Filter2)
    112 
    113     veor        q7, q10, q0                 ; *oq0 = u^0x80
    114     veor        q6, q11, q0                 ; *op0 = u^0x80
    115 
    116     add         r3, r2, r1
    117     vswp        d13, d14
    118     add         r12, r3, r1
    119 
    120     ;store op1, op0, oq0, oq1
    121     vst2.8      {d12[0], d13[0]}, [r0]
    122     vst2.8      {d12[1], d13[1]}, [r2]
    123     vst2.8      {d12[2], d13[2]}, [r3]
    124     vst2.8      {d12[3], d13[3]}, [r12], r1
    125     add         r0, r12, r1
    126     vst2.8      {d12[4], d13[4]}, [r12]
    127     vst2.8      {d12[5], d13[5]}, [r0], r1
    128     add         r2, r0, r1
    129     vst2.8      {d12[6], d13[6]}, [r0]
    130     vst2.8      {d12[7], d13[7]}, [r2], r1
    131     add         r3, r2, r1
    132     vst2.8      {d14[0], d15[0]}, [r2]
    133     vst2.8      {d14[1], d15[1]}, [r3], r1
    134     add         r12, r3, r1
    135     vst2.8      {d14[2], d15[2]}, [r3]
    136     vst2.8      {d14[3], d15[3]}, [r12], r1
    137     add         r0, r12, r1
    138     vst2.8      {d14[4], d15[4]}, [r12]
    139     vst2.8      {d14[5], d15[5]}, [r0], r1
    140     add         r2, r0, r1
    141     vst2.8      {d14[6], d15[6]}, [r0]
    142     vst2.8      {d14[7], d15[7]}, [r2]
    143 
    144     bx          lr
    145     ENDP        ; |vp8_loop_filter_simple_vertical_edge_neon|
    146 
    147 ;-----------------
    148 
    149 _vlfy_coeff_
    150     DCD     vlfy_coeff
    151 vlfy_coeff
    152     DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
    153     DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
    154     DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
    155 
    156     END
    157