tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

simple_idct_neon.S (12862B)


      1 /*
      2 * ARM NEON IDCT
      3 *
      4 * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
      5 *
      6 * Based on Simple IDCT
      7 * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
      8 *
      9 * This file is part of FFmpeg.
     10 *
     11 * FFmpeg is free software; you can redistribute it and/or
     12 * modify it under the terms of the GNU Lesser General Public
     13 * License as published by the Free Software Foundation; either
     14 * version 2.1 of the License, or (at your option) any later version.
     15 *
     16 * FFmpeg is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19 * Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public
     22 * License along with FFmpeg; if not, write to the Free Software
     23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     24 */
     25 
     26 #include "libavutil/arm/asm.S"
     27 
     28 #define W1  22725  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
     29 #define W2  21407  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
     30 #define W3  19266  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
     31 #define W4  16383  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
     32 #define W5  12873  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
     33 #define W6  8867   //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
     34 #define W7  4520   //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
     35 #define W4c ((1<<(COL_SHIFT-1))/W4)
     36 #define ROW_SHIFT 11
     37 #define COL_SHIFT 20
     38 
     39 #define w1 d0[0]
     40 #define w2 d0[1]
     41 #define w3 d0[2]
     42 #define w4 d0[3]
     43 #define w5 d1[0]
     44 #define w6 d1[1]
     45 #define w7 d1[2]
     46 #define w4c d1[3]
     47 
     48        .macro idct_col4_top
     49        vmull.s16       q7,  d6,  w2    /* q9   = W2 * col[2] */
     50        vmull.s16       q8,  d6,  w6    /* q10  = W6 * col[2] */
     51        vmull.s16       q9,  d4,  w1    /* q9   = W1 * col[1] */
     52        vadd.i32        q11, q15, q7
     53        vmull.s16       q10, d4,  w3    /* q10  = W3 * col[1] */
     54        vadd.i32        q12, q15, q8
     55        vmull.s16       q5,  d4,  w5    /* q5   = W5 * col[1] */
     56        vsub.i32        q13, q15, q8
     57        vmull.s16       q6,  d4,  w7    /* q6   = W7 * col[1] */
     58        vsub.i32        q14, q15, q7
     59 
     60        vmlal.s16       q9,  d8,  w3    /* q9  += W3 * col[3] */
     61        vmlsl.s16       q10, d8,  w7    /* q10 -= W7 * col[3] */
     62        vmlsl.s16       q5,  d8,  w1    /* q5  -= W1 * col[3] */
     63        vmlsl.s16       q6,  d8,  w5    /* q6  -= W5 * col[3] */
     64        .endm
     65 
     66        .text
     67        .align 6
     68 
     69 function idct_row4_pld_neon
     70        pld             [r0]
     71        add             r3,  r0,  r1,  lsl #2
     72        pld             [r0, r1]
     73        pld             [r0, r1, lsl #1]
     74 A       pld             [r3, -r1]
     75        pld             [r3]
     76        pld             [r3, r1]
     77        add             r3,  r3,  r1,  lsl #1
     78        pld             [r3]
     79        pld             [r3, r1]
     80 endfunc
     81 
     82 function idct_row4_neon
     83        vmov.i32        q15, #(1<<(ROW_SHIFT-1))
     84        vld1.64         {d2-d5},  [r2,:128]!
     85        vmlal.s16       q15, d2,  w4    /* q15  += W4 * col[0] */
     86        vld1.64         {d6,d7},  [r2,:128]!
     87        vorr            d10, d3,  d5
     88        vld1.64         {d8,d9},  [r2,:128]!
     89        add             r2,  r2,  #-64
     90 
     91        vorr            d11, d7,  d9
     92        vorr            d10, d10, d11
     93        vmov            r3,  r4,  d10
     94 
     95        idct_col4_top
     96 
     97        orrs            r3,  r3,  r4
     98        beq             1f
     99 
    100        vmull.s16       q7,  d3,  w4    /* q7   = W4 * col[4] */
    101        vmlal.s16       q9,  d5,  w5    /* q9  += W5 * col[5] */
    102        vmlsl.s16       q10, d5,  w1    /* q10 -= W1 * col[5] */
    103        vmull.s16       q8,  d7,  w2    /* q8   = W2 * col[6] */
    104        vmlal.s16       q5,  d5,  w7    /* q5  += W7 * col[5] */
    105        vadd.i32        q11, q11, q7
    106        vsub.i32        q12, q12, q7
    107        vsub.i32        q13, q13, q7
    108        vadd.i32        q14, q14, q7
    109        vmlal.s16       q6,  d5,  w3    /* q6  += W3 * col[5] */
    110        vmull.s16       q7,  d7,  w6    /* q7   = W6 * col[6] */
    111        vmlal.s16       q9,  d9,  w7
    112        vmlsl.s16       q10, d9,  w5
    113        vmlal.s16       q5,  d9,  w3
    114        vmlsl.s16       q6,  d9,  w1
    115        vadd.i32        q11, q11, q7
    116        vsub.i32        q12, q12, q8
    117        vadd.i32        q13, q13, q8
    118        vsub.i32        q14, q14, q7
    119 
    120 1:      vadd.i32        q3,  q11, q9
    121        vadd.i32        q4,  q12, q10
    122        vshrn.i32       d2,  q3,  #ROW_SHIFT
    123        vshrn.i32       d4,  q4,  #ROW_SHIFT
    124        vadd.i32        q7,  q13, q5
    125        vadd.i32        q8,  q14, q6
    126        vtrn.16         d2,  d4
    127        vshrn.i32       d6,  q7,  #ROW_SHIFT
    128        vshrn.i32       d8,  q8,  #ROW_SHIFT
    129        vsub.i32        q14, q14, q6
    130        vsub.i32        q11, q11, q9
    131        vtrn.16         d6,  d8
    132        vsub.i32        q13, q13, q5
    133        vshrn.i32       d3,  q14, #ROW_SHIFT
    134        vtrn.32         d2,  d6
    135        vsub.i32        q12, q12, q10
    136        vtrn.32         d4,  d8
    137        vshrn.i32       d5,  q13, #ROW_SHIFT
    138        vshrn.i32       d7,  q12, #ROW_SHIFT
    139        vshrn.i32       d9,  q11, #ROW_SHIFT
    140 
    141        vtrn.16         d3,  d5
    142        vtrn.16         d7,  d9
    143        vtrn.32         d3,  d7
    144        vtrn.32         d5,  d9
    145 
    146        vst1.64         {d2-d5},  [r2,:128]!
    147        vst1.64         {d6-d9},  [r2,:128]!
    148 
    149        bx              lr
    150 endfunc
    151 
    152 function idct_col4_neon
    153        mov             ip,  #16
    154        vld1.64         {d2}, [r2,:64], ip /* d2 = col[0] */
    155        vdup.16         d30, w4c
    156        vld1.64         {d4}, [r2,:64], ip /* d3 = col[1] */
    157        vadd.i16        d30, d30, d2
    158        vld1.64         {d6}, [r2,:64], ip /* d4 = col[2] */
    159        vmull.s16       q15, d30, w4 /* q15 = W4*(col[0]+(1<<COL_SHIFT-1)/W4)*/
    160        vld1.64         {d8}, [r2,:64], ip /* d5 = col[3] */
    161 
    162        ldrd            r4,  r5,  [r2]
    163        ldrd            r6,  r7,  [r2, #16]
    164        orrs            r4,  r4,  r5
    165 
    166        idct_col4_top
    167        it              eq
    168        addeq           r2,  r2,  #16
    169        beq             1f
    170 
    171        vld1.64         {d3}, [r2,:64], ip /* d6 = col[4] */
    172        vmull.s16       q7,  d3,  w4    /* q7   = W4 * col[4] */
    173        vadd.i32        q11, q11, q7
    174        vsub.i32        q12, q12, q7
    175        vsub.i32        q13, q13, q7
    176        vadd.i32        q14, q14, q7
    177 
    178 1:      orrs            r6,  r6,  r7
    179        ldrd            r4,  r5,  [r2, #16]
    180        it              eq
    181        addeq           r2,  r2,  #16
    182        beq             2f
    183 
    184        vld1.64         {d5}, [r2,:64], ip /* d7 = col[5] */
    185        vmlal.s16       q9,  d5,  w5    /* q9  += W5 * col[5] */
    186        vmlsl.s16       q10, d5,  w1    /* q10 -= W1 * col[5] */
    187        vmlal.s16       q5,  d5,  w7    /* q5  += W7 * col[5] */
    188        vmlal.s16       q6,  d5,  w3    /* q6  += W3 * col[5] */
    189 
    190 2:      orrs            r4,  r4,  r5
    191        ldrd            r4,  r5,  [r2, #16]
    192        it              eq
    193        addeq           r2,  r2,  #16
    194        beq             3f
    195 
    196        vld1.64         {d7}, [r2,:64], ip /* d8 = col[6] */
    197        vmull.s16       q7,  d7,  w6    /* q7   = W6 * col[6] */
    198        vmull.s16       q8,  d7,  w2    /* q8   = W2 * col[6] */
    199        vadd.i32        q11, q11, q7
    200        vsub.i32        q14, q14, q7
    201        vsub.i32        q12, q12, q8
    202        vadd.i32        q13, q13, q8
    203 
    204 3:      orrs            r4,  r4,  r5
    205        it              eq
    206        addeq           r2,  r2,  #16
    207        beq             4f
    208 
    209        vld1.64         {d9}, [r2,:64], ip /* d9 = col[7] */
    210        vmlal.s16       q9,  d9,  w7
    211        vmlsl.s16       q10, d9,  w5
    212        vmlal.s16       q5,  d9,  w3
    213        vmlsl.s16       q6,  d9,  w1
    214 
    215 4:      vaddhn.i32      d2,  q11, q9
    216        vaddhn.i32      d3,  q12, q10
    217        vaddhn.i32      d4,  q13, q5
    218        vaddhn.i32      d5,  q14, q6
    219        vsubhn.i32      d9,  q11, q9
    220        vsubhn.i32      d8,  q12, q10
    221        vsubhn.i32      d7,  q13, q5
    222        vsubhn.i32      d6,  q14, q6
    223 
    224        bx              lr
    225 endfunc
    226 
    227        .align 6
    228 
    229 function idct_col4_st8_neon
    230        vqshrun.s16     d2,  q1,  #COL_SHIFT-16
    231        vqshrun.s16     d3,  q2,  #COL_SHIFT-16
    232        vqshrun.s16     d4,  q3,  #COL_SHIFT-16
    233        vqshrun.s16     d5,  q4,  #COL_SHIFT-16
    234        vst1.32         {d2[0]}, [r0,:32], r1
    235        vst1.32         {d2[1]}, [r0,:32], r1
    236        vst1.32         {d3[0]}, [r0,:32], r1
    237        vst1.32         {d3[1]}, [r0,:32], r1
    238        vst1.32         {d4[0]}, [r0,:32], r1
    239        vst1.32         {d4[1]}, [r0,:32], r1
    240        vst1.32         {d5[0]}, [r0,:32], r1
    241        vst1.32         {d5[1]}, [r0,:32], r1
    242 
    243        bx              lr
    244 endfunc
    245 
    246 const   idct_coeff_neon, align=4
    247        .short W1, W2, W3, W4, W5, W6, W7, W4c
    248 endconst
    249 
    250        .macro idct_start data
    251        push            {r4-r7, lr}
    252        pld             [\data]
    253        pld             [\data, #64]
    254        vpush           {d8-d15}
    255        movrel          r3,  idct_coeff_neon
    256        vld1.64         {d0,d1}, [r3,:128]
    257        .endm
    258 
    259        .macro idct_end
    260        vpop            {d8-d15}
    261        pop             {r4-r7, pc}
    262        .endm
    263 
    264 /* void ff_simple_idct_put_neon(uint8_t *dst, ptrdiff_t line_size, int16_t *data); */
    265 function ff_simple_idct_put_neon, export=1
    266        idct_start      r2
    267 
    268        bl              idct_row4_pld_neon
    269        bl              idct_row4_neon
    270        add             r2,  r2,  #-128
    271        bl              idct_col4_neon
    272        bl              idct_col4_st8_neon
    273        sub             r0,  r0,  r1, lsl #3
    274        add             r0,  r0,  #4
    275        add             r2,  r2,  #-120
    276        bl              idct_col4_neon
    277        bl              idct_col4_st8_neon
    278 
    279        idct_end
    280 endfunc
    281 
    282        .align 6
    283 
    284 function idct_col4_add8_neon
    285        mov             ip,  r0
    286 
    287        vld1.32         {d10[0]}, [r0,:32], r1
    288        vshr.s16        q1,  q1,  #COL_SHIFT-16
    289        vld1.32         {d10[1]}, [r0,:32], r1
    290        vshr.s16        q2,  q2,  #COL_SHIFT-16
    291        vld1.32         {d11[0]}, [r0,:32], r1
    292        vshr.s16        q3,  q3,  #COL_SHIFT-16
    293        vld1.32         {d11[1]}, [r0,:32], r1
    294        vshr.s16        q4,  q4,  #COL_SHIFT-16
    295        vld1.32         {d12[0]}, [r0,:32], r1
    296        vaddw.u8        q1,  q1,  d10
    297        vld1.32         {d12[1]}, [r0,:32], r1
    298        vaddw.u8        q2,  q2,  d11
    299        vld1.32         {d13[0]}, [r0,:32], r1
    300        vqmovun.s16     d2,  q1
    301        vld1.32         {d13[1]}, [r0,:32], r1
    302        vaddw.u8        q3,  q3,  d12
    303        vst1.32         {d2[0]},  [ip,:32], r1
    304        vqmovun.s16     d3,  q2
    305        vst1.32         {d2[1]},  [ip,:32], r1
    306        vaddw.u8        q4,  q4,  d13
    307        vst1.32         {d3[0]},  [ip,:32], r1
    308        vqmovun.s16     d4,  q3
    309        vst1.32         {d3[1]},  [ip,:32], r1
    310        vqmovun.s16     d5,  q4
    311        vst1.32         {d4[0]},  [ip,:32], r1
    312        vst1.32         {d4[1]},  [ip,:32], r1
    313        vst1.32         {d5[0]},  [ip,:32], r1
    314        vst1.32         {d5[1]},  [ip,:32], r1
    315 
    316        bx              lr
    317 endfunc
    318 
    319 /* void ff_simple_idct_add_neon(uint8_t *dst, ptrdiff_t line_size, int16_t *data); */
    320 function ff_simple_idct_add_neon, export=1
    321        idct_start      r2
    322 
    323        bl              idct_row4_pld_neon
    324        bl              idct_row4_neon
    325        add             r2,  r2,  #-128
    326        bl              idct_col4_neon
    327        bl              idct_col4_add8_neon
    328        sub             r0,  r0,  r1, lsl #3
    329        add             r0,  r0,  #4
    330        add             r2,  r2,  #-120
    331        bl              idct_col4_neon
    332        bl              idct_col4_add8_neon
    333 
    334        idct_end
    335 endfunc
    336 
    337        .align 6
    338 
    339 function idct_col4_st16_neon
    340        mov             ip,  #16
    341 
    342        vshr.s16        q1,  q1,  #COL_SHIFT-16
    343        vshr.s16        q2,  q2,  #COL_SHIFT-16
    344        vst1.64         {d2}, [r2,:64], ip
    345        vshr.s16        q3,  q3,  #COL_SHIFT-16
    346        vst1.64         {d3}, [r2,:64], ip
    347        vshr.s16        q4,  q4,  #COL_SHIFT-16
    348        vst1.64         {d4}, [r2,:64], ip
    349        vst1.64         {d5}, [r2,:64], ip
    350        vst1.64         {d6}, [r2,:64], ip
    351        vst1.64         {d7}, [r2,:64], ip
    352        vst1.64         {d8}, [r2,:64], ip
    353        vst1.64         {d9}, [r2,:64], ip
    354 
    355        bx              lr
    356 endfunc
    357 
    358 /* void ff_simple_idct_neon(int16_t *data); */
    359 function ff_simple_idct_neon, export=1
    360        idct_start      r0
    361 
    362        mov             r2,  r0
    363        bl              idct_row4_neon
    364        bl              idct_row4_neon
    365        add             r2,  r2,  #-128
    366        bl              idct_col4_neon
    367        add             r2,  r2,  #-128
    368        bl              idct_col4_st16_neon
    369        add             r2,  r2,  #-120
    370        bl              idct_col4_neon
    371        add             r2,  r2,  #-128
    372        bl              idct_col4_st16_neon
    373 
    374        idct_end
    375 endfunc