Home | History | Annotate | Download | only in arm
      1 @/******************************************************************************
      2 @ *
      3 @ * Copyright (C) 2015 The Android Open Source Project
      4 @ *
      5 @ * Licensed under the Apache License, Version 2.0 (the "License");
      6 @ * you may not use this file except in compliance with the License.
      7 @ * You may obtain a copy of the License at:
      8 @ *
      9 @ * http://www.apache.org/licenses/LICENSE-2.0
     10 @ *
     11 @ * Unless required by applicable law or agreed to in writing, software
     12 @ * distributed under the License is distributed on an "AS IS" BASIS,
     13 @ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 @ * See the License for the specific language governing permissions and
     15 @ * limitations under the License.
     16 @ *
     17 @ *****************************************************************************
     18 @ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
     19 @*/
     20 @**
     21 @******************************************************************************
     22 @* @file
     23 @*  ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q.s
     24 @*
     25 @* @brief
     26 @*  Contains function definitions for inter prediction  interpolation.
     27 @*
     28 @* @author
     29 @*  Mohit
     30 @*
     31 @* @par List of Functions:
     32 @*
     33 @*  - ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q()
     34 @*
     35 @* @remarks
     36 @*  None
     37 @*
     38 @*******************************************************************************
     39 @*
     40 
     41 @* All the functions here are replicated from ih264_inter_pred_filters.c
     42 @
     43 
     44 @**
     45 @**
     46 @**
     47 @*******************************************************************************
     48 @*
     49 @* @brief
     50 @*   This function implements a two stage cascaded six tap filter. It
     51 @*   applies the six tap filter in the vertical direction on the
     52 @*   predictor values, followed by applying the same filter in the
     53 @*   horizontal direction on the output of the first stage. It then averages
     54 @*   the output of the 1st stage and the final stage to obtain the quarter
     55 @*   pel values.The six tap filtering operation is described in sec 8.4.2.2.1
     56 @*   titled "Luma sample interpolation process".
     57 @*
     58 @* @par Description:
     59 @*    This function is called to obtain pixels lying at the following
     60 @*    location (1/4,1/2) or (3/4,1/2). The function interpolates
     61 @*    the predictors first in the verical direction and then in the
     62 @*    horizontal direction to output the (1/2,1/2). It then averages
     63 @*    the output of the 2nd stage and (1/2,1/2) value to obtain (1/4,1/2)
     64 @*    or (3/4,1/2) depending on the offset.
     65 @*
     66 @* @param[in] pu1_src
     67 @*  UWORD8 pointer to the source
     68 @*
     69 @* @param[out] pu1_dst
     70 @*  UWORD8 pointer to the destination
     71 @*
     72 @* @param[in] src_strd
     73 @*  integer source stride
     74 @*
     75 @* @param[in] dst_strd
     76 @*  integer destination stride
     77 @*
     78 @* @param[in] ht
     79 @*  integer height of the array
     80 @*
     81 @* @param[in] wd
     82 @*  integer width of the array
     83 @*
     84 @* @param[in] pu1_tmp: temporary buffer
     85 @*
     86 @* @param[in] dydx: x and y reference offset for qpel calculations
     87 @*
     88 @* @returns
     89 @*
     90 @* @remarks
     91 @*  None
     92 @*
     93 @*******************************************************************************
     94 @*;
     95 
     96 @void ih264_inter_pred_luma_horz_qpel_vert_hpel(UWORD8 *pu1_src,
     97 @                                UWORD8 *pu1_dst,
     98 @                                WORD32 src_strd,,
     99 @                                WORD32 dst_strd,
    100 @                                WORD32 ht,
    101 @                                WORD32 wd,
    102 @                                UWORD8* pu1_tmp,
    103 @                                UWORD32 dydx)
    104 
    105 @**************Variables Vs Registers*****************************************
    106 @   r0 => *pu1_src
    107 @   r1 => *pu1_dst
    108 @   r2 =>  src_strd
    109 @   r3 =>  dst_strd
    110 @   r4 =>  ht
    111 @   r5 =>  wd
    112 @   r6 =>  dydx
    113 @   r9 => *pu1_tmp
    114 
    115 .text
    116 .p2align 2
    117 
    118     .global ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q
    119 
    120 ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q:
    121 
    122     stmfd         sp!, {r4-r12, r14}    @store register values to stack
    123     vstmdb        sp!, {d8-d15}         @push neon registers to stack
    124     ldr           r4, [sp, #104]        @ loads ht
    125     sub           r0, r0, r2, lsl #1    @pu1_src-2*src_strd
    126     sub           r0, r0, #2            @pu1_src-2
    127     ldr           r5, [sp, #108]        @ loads wd
    128     ldr           r6, [sp, #116]        @ loads dydx
    129     and           r6, r6, #2            @ dydx & 0x3 followed by dydx>>1 and dydx<<1
    130     ldr           r9, [sp, #112]        @pu1_tmp
    131     add           r7, r9, #4
    132     add           r6, r7, r6            @ pi16_pred1_temp += (x_offset>>1)
    133 
    134     vmov.u16      q13, #0x14            @ Filter coeff 20 into Q13
    135     vmov.u16      q12, #0x5             @ Filter coeff 5  into Q12
    136     mov           r7, #0x20
    137     mov           r8, #0x30
    138     subs          r12, r5, #4           @if wd=4 branch to loop_4
    139     beq           loop_4
    140 
    141     subs          r12, r5, #8           @if wd=8 branch to loop_8
    142     beq           loop_8
    143 
    144     @when  wd=16
    145     vmov.u16      q14, #0x14            @ Filter coeff 20 into Q13
    146     vmov.u16      q15, #0x5             @ Filter coeff 5  into Q12
    147     add           r14, r2, #0
    148     sub           r2, r2, #16
    149 
    150 
    151 loop_16:
    152 
    153     vld1.u32      {q0}, [r0]!           @ Vector load from src[0_0]
    154     vld1.u32      d12, [r0], r2         @ Vector load from src[0_0]
    155     vld1.u32      {q1}, [r0]!           @ Vector load from src[1_0]
    156     vld1.u32      d13, [r0], r2         @ Vector load from src[1_0]
    157     vld1.u32      {q2}, [r0]!           @ Vector load from src[2_0]
    158     vld1.u32      d14, [r0], r2         @ Vector load from src[2_0]
    159     vld1.u32      {q3}, [r0]!           @ Vector load from src[3_0]
    160     vld1.u32      d15, [r0], r2         @ Vector load from src[3_0]
    161     vld1.u32      {q4}, [r0]!           @ Vector load from src[4_0]
    162     vld1.u32      d16, [r0], r2         @ Vector load from src[4_0]
    163 
    164     vld1.u32      {q5}, [r0]!           @ Vector load from src[5_0]
    165     vld1.u32      d17, [r0], r2         @ Vector load from src[5_0]
    166 
    167     vaddl.u8      q10, d4, d6
    168     vaddl.u8      q9, d0, d10
    169     vaddl.u8      q11, d2, d8
    170     vmla.u16      q9, q10, q14
    171     vaddl.u8      q12, d5, d7
    172     vaddl.u8      q10, d1, d11
    173     vaddl.u8      q13, d3, d9
    174     vmla.u16      q10, q12, q14
    175     vaddl.u8      q12, d14, d15
    176     vmls.u16      q9, q11, q15
    177     vaddl.u8      q11, d12, d17
    178     vmls.u16      q10, q13, q15
    179     vaddl.u8      q13, d13, d16
    180     vmla.u16      q11, q12, q14
    181     vmls.u16      q11, q13, q15
    182     vst1.32       {q9}, [r9]!
    183     vst1.32       {q10}, [r9]!
    184     vext.16       q12, q9, q10, #2
    185     vext.16       q13, q9, q10, #3
    186     vst1.32       {q11}, [r9]
    187     vext.16       q11, q9, q10, #5
    188     vadd.s16      q0, q12, q13
    189     vext.16       q12, q9, q10, #1
    190     vext.16       q13, q9, q10, #4
    191     vadd.s16      q12, q12, q13
    192 
    193     vaddl.s16     q13, d18, d22
    194     vmlal.s16     q13, d0, d28
    195     vmlsl.s16     q13, d24, d30
    196 
    197     vaddl.s16     q11, d19, d23
    198     vmlal.s16     q11, d1, d28
    199     vmlsl.s16     q11, d25, d30
    200 
    201     vqrshrun.s32  d18, q13, #10
    202     vqrshrun.s32  d19, q11, #10
    203     vld1.32       {q11}, [r9]!
    204     vqmovn.u16    d18, q9
    205 
    206     vext.16       q12, q10, q11, #2
    207     vext.16       q13, q10, q11, #3
    208     vext.16       q0, q10, q11, #5
    209     vst1.32       d18, [r1]
    210     vadd.s16      q9, q12, q13
    211     vext.16       q12, q10, q11, #1
    212     vext.16       q13, q10, q11, #4
    213     vadd.s16      q12, q12, q13
    214 
    215     vaddl.s16     q13, d0, d20
    216     vmlal.s16     q13, d18, d28
    217     vmlsl.s16     q13, d24, d30
    218 
    219     vaddl.s16     q11, d1, d21
    220     vmlal.s16     q11, d19, d28
    221     vmlsl.s16     q11, d25, d30
    222 
    223     vqrshrun.s32  d18, q13, #10
    224     vqrshrun.s32  d19, q11, #10
    225 
    226     vaddl.u8      q12, d7, d9
    227     vld1.32       {q10}, [r6]!
    228     vld1.32       {q11}, [r6], r7
    229 
    230     vqmovn.u16    d19, q9
    231 
    232     vld1.32       d18, [r1]
    233     vqrshrun.s16  d20, q10, #5
    234     vqrshrun.s16  d21, q11, #5
    235     vaddl.u8      q11, d4, d10
    236     vld1.u32      {q0}, [r0]!           @ Vector load from src[6_0]
    237     vrhadd.u8     q9, q9, q10
    238     vld1.u32      d12, [r0], r2         @ Vector load from src[6_0]
    239     vaddl.u8      q10, d6, d8
    240     vaddl.u8      q13, d5, d11
    241     vst1.32       {q9}, [r1], r3        @ store row 0
    242 
    243 @ROW_2
    244 
    245     vaddl.u8      q9, d2, d0
    246 
    247     vmla.u16      q9, q10, q14
    248 
    249     vaddl.u8      q10, d3, d1
    250 
    251     vmla.u16      q10, q12, q14
    252     vaddl.u8      q12, d15, d16
    253     vmls.u16      q9, q11, q15
    254     vaddl.u8      q11, d13, d12
    255     vmls.u16      q10, q13, q15
    256     vaddl.u8      q13, d14, d17
    257     vmla.u16      q11, q12, q14
    258     vmls.u16      q11, q13, q15
    259     vst1.32       {q9}, [r9]!
    260     vst1.32       {q10}, [r9]!
    261     vext.16       q12, q9, q10, #2
    262     vext.16       q13, q9, q10, #3
    263     vst1.32       {q11}, [r9]
    264     vext.16       q11, q9, q10, #5
    265     vadd.s16      q1, q12, q13
    266     vext.16       q12, q9, q10, #1
    267     vext.16       q13, q9, q10, #4
    268     vadd.s16      q12, q12, q13
    269 
    270     vaddl.s16     q13, d18, d22
    271     vmlal.s16     q13, d2, d28
    272     vmlsl.s16     q13, d24, d30
    273 
    274     vaddl.s16     q11, d19, d23
    275     vmlal.s16     q11, d3, d28
    276     vmlsl.s16     q11, d25, d30
    277 
    278     vqrshrun.s32  d18, q13, #10
    279     vqrshrun.s32  d19, q11, #10
    280     vld1.32       {q11}, [r9]!
    281     vqmovn.u16    d18, q9
    282 
    283     vext.16       q12, q10, q11, #2
    284     vext.16       q13, q10, q11, #3
    285     vext.16       q1, q10, q11, #5
    286     vst1.32       d18, [r1]
    287     vadd.s16      q9, q12, q13
    288     vext.16       q12, q10, q11, #1
    289     vext.16       q13, q10, q11, #4
    290     vadd.s16      q12, q12, q13
    291 
    292     vaddl.s16     q13, d2, d20
    293     vmlal.s16     q13, d18, d28
    294     vmlsl.s16     q13, d24, d30
    295 
    296     vaddl.s16     q11, d3, d21
    297     vmlal.s16     q11, d19, d28
    298     vmlsl.s16     q11, d25, d30
    299 
    300     vqrshrun.s32  d18, q13, #10
    301     vqrshrun.s32  d19, q11, #10
    302     vaddl.u8      q12, d9, d11
    303     vld1.32       {q10}, [r6]!
    304     vld1.32       {q11}, [r6], r7
    305     vqmovn.u16    d19, q9
    306     vld1.32       d18, [r1]
    307     vqrshrun.s16  d20, q10, #5
    308     vqrshrun.s16  d21, q11, #5
    309 
    310     vrhadd.u8     q9, q9, q10
    311 
    312     vst1.32       {q9}, [r1], r3        @ store row 1
    313 
    314     subs          r4, r4, #2
    315     subne         r0, r0 , r14, lsl #2
    316     subne         r0, r0, r14
    317 
    318     beq           end_func              @ Branch if height==4
    319     b             loop_16               @ Loop if height==8
    320 
    321 loop_8:
    322     vld1.u32      {q0}, [r0], r2        @ Vector load from src[0_0]
    323     vld1.u32      {q1}, [r0], r2        @ Vector load from src[1_0]
    324     vld1.u32      {q2}, [r0], r2        @ Vector load from src[2_0]
    325     vld1.u32      {q3}, [r0], r2        @ Vector load from src[3_0]
    326     vld1.u32      {q4}, [r0], r2        @ Vector load from src[4_0]
    327 
    328     vld1.u32      {q5}, [r0], r2        @ Vector load from src[5_0]
    329     vaddl.u8      q7, d4, d6
    330     vaddl.u8      q6, d0, d10
    331     vaddl.u8      q8, d2, d8
    332     vmla.u16      q6, q7, q13
    333     vaddl.u8      q9, d5, d7
    334     vaddl.u8      q7, d1, d11
    335     vaddl.u8      q11, d3, d9
    336     vmla.u16      q7, q9, q13
    337     vmls.u16      q6, q8, q12
    338     vld1.32       {q0}, [r0], r2        @ Vector load from src[6_0]
    339     vaddl.u8      q8, d6, d8
    340     vmls.u16      q7, q11, q12
    341     vaddl.u8      q14, d2, d0
    342     vst1.32       {q6}, [r9]!           @ store row 0 to temp buffer: col 0
    343     vext.16       q11, q6, q7, #5
    344     vaddl.u8      q9, d4, d10
    345     vmla.u16      q14, q8, q13
    346     vaddl.s16     q15, d12, d22
    347     vst1.32       {q7}, [r9], r7        @ store row 0 to temp buffer: col 1
    348     vaddl.s16     q11, d13, d23
    349     vext.16       q8, q6, q7, #2
    350     vmls.u16      q14, q9, q12
    351     vext.16       q9, q6, q7, #3
    352     vext.16       q10, q6, q7, #4
    353     vext.16       q7, q6, q7, #1
    354     vadd.s16      q8, q8, q9
    355     vadd.s16      q9, q7, q10
    356     vaddl.u8      q10, d7, d9
    357     vmlal.s16     q15, d16, d26
    358     vmlsl.s16     q15, d18, d24
    359     vmlal.s16     q11, d17, d26
    360     vmlsl.s16     q11, d19, d24
    361     vaddl.u8      q7, d3, d1
    362     vst1.32       {q14}, [r9]!          @ store row 1 to temp buffer: col 0
    363     vmla.u16      q7, q10, q13
    364     vqrshrun.s32  d12, q15, #10
    365     vaddl.u8      q8, d5, d11
    366     vqrshrun.s32  d13, q11, #10
    367     vmls.u16      q7, q8, q12
    368 @   vld1.32     {q1},[r0],r2            ; Vector load from src[7_0]
    369     vqmovn.u16    d25, q6
    370     vaddl.u8      q8, d8, d10
    371 
    372 
    373     vext.16       q11, q14, q7, #5
    374     vaddl.u8      q10, d4, d2
    375     vaddl.s16     q15, d28, d22
    376     vmla.u16      q10, q8, q13
    377     vst1.32       {q7}, [r9], r7        @ store row 1 to temp buffer: col 1
    378     vaddl.s16     q11, d29, d23
    379     vext.16       q8, q14, q7, #2
    380     vext.16       q9, q14, q7, #3
    381     vext.16       q6, q14, q7, #4
    382     vext.16       q7, q14, q7, #1
    383     vadd.s16      q8, q8, q9
    384     vadd.s16      q9, q6, q7
    385     vld1.32       {q7}, [r6], r8        @ load row 0 from temp buffer
    386     vmlal.s16     q15, d16, d26
    387     vmlsl.s16     q15, d18, d24
    388     vmlal.s16     q11, d17, d26
    389     vmlsl.s16     q11, d19, d24
    390     vqrshrun.s16  d14, q7, #0x5
    391     vld1.32       {q14}, [r6], r8       @ load row 1 from temp buffer
    392     vaddl.u8      q9, d6, d0
    393     vqrshrun.s32  d16, q15, #10
    394     vqrshrun.s16  d15, q14, #0x5
    395     vqrshrun.s32  d17, q11, #10
    396     vmov          d12, d25
    397     vmov          d25, d24
    398 
    399     vqmovn.u16    d13, q8
    400     vrhadd.u8     q6, q6, q7
    401 
    402     vst1.32       d12, [r1], r3         @ store row 0
    403     vst1.32       d13, [r1], r3         @ store row 1
    404 
    405     subs          r4, r4, #2
    406     subne         r0, r0 , r2, lsl #2
    407     subne         r0, r0, r2
    408 
    409     beq           end_func              @ Branch if height==4
    410     b             loop_8                @ Loop if height==8
    411 
    412 loop_4:
    413     vld1.u32      {q0}, [r0], r2        @ Vector load from src[0_0]
    414     vld1.u32      {q1}, [r0], r2        @ Vector load from src[1_0]
    415     vld1.u32      {q2}, [r0], r2        @ Vector load from src[2_0]
    416     vld1.u32      {q3}, [r0], r2        @ Vector load from src[3_0]
    417     vld1.u32      {q4}, [r0], r2        @ Vector load from src[4_0]
    418     vld1.u32      {q5}, [r0], r2        @ Vector load from src[5_0]
    419 
    420     vaddl.u8      q7, d4, d6            @ temp1 = src[2_0] + src[3_0]
    421     vaddl.u8      q6, d0, d10           @ temp = src[0_0] + src[5_0]
    422     vaddl.u8      q8, d2, d8            @ temp2 = src[1_0] + src[4_0]
    423     vmla.u16      q6, q7, q13           @ temp += temp1 * 20
    424     vaddl.u8      q9, d5, d7            @ temp1 = src[2_0] + src[3_0]
    425     vaddl.u8      q7, d1, d11           @ temp = src[0_0] + src[5_0]
    426     vaddl.u8      q11, d3, d9           @ temp2 = src[1_0] + src[4_0]
    427     vmla.u16      q7, q9, q13           @ temp += temp1 * 20
    428     vmls.u16      q6, q8, q12           @ temp -= temp2 * 5
    429     vld1.32       {q0}, [r0], r2        @ Vector load from src[6_0]
    430     vaddl.u8      q8, d6, d8
    431     vmls.u16      q7, q11, q12          @ temp -= temp2 * 5
    432     @Q6 and Q7 have filtered values
    433     vaddl.u8      q14, d2, d0
    434     vst1.32       {q6}, [r9]!           @ store row 0 to temp buffer: col 0
    435     vext.16       q11, q6, q7, #5
    436     vaddl.u8      q9, d4, d10
    437     vmla.u16      q14, q8, q13
    438     vaddl.s16     q15, d12, d22
    439     vst1.32       {q7}, [r9], r7        @ store row 0 to temp buffer: col 1
    440     vaddl.s16     q11, d13, d23
    441     vext.16       q8, q6, q7, #2
    442     vmls.u16      q14, q9, q12
    443     vext.16       q9, q6, q7, #3
    444     vext.16       q10, q6, q7, #4
    445     vext.16       q7, q6, q7, #1
    446     vadd.s16      q8, q8, q9
    447     vadd.s16      q9, q7, q10
    448     vaddl.u8      q10, d7, d9
    449     vmlal.s16     q15, d16, d26
    450     vmlsl.s16     q15, d18, d24
    451     vmlal.s16     q11, d17, d26
    452     vmlsl.s16     q11, d19, d24
    453     vaddl.u8      q7, d3, d1
    454     vst1.32       {q14}, [r9]!          @ store row 1 to temp buffer: col 0
    455     vmla.u16      q7, q10, q13
    456     vqrshrun.s32  d12, q15, #10
    457     vaddl.u8      q8, d5, d11
    458     vqrshrun.s32  d13, q11, #10
    459     vmls.u16      q7, q8, q12
    460     vqmovn.u16    d25, q6
    461     vaddl.u8      q8, d8, d10
    462 
    463     vext.16       q11, q14, q7, #5
    464     vaddl.u8      q10, d4, d2
    465     vaddl.s16     q15, d28, d22
    466     vmla.u16      q10, q8, q13
    467     vst1.32       {q7}, [r9], r7        @ store row 1 to temp buffer: col 1
    468     vaddl.s16     q11, d29, d23
    469     vext.16       q8, q14, q7, #2
    470     vext.16       q9, q14, q7, #3
    471     vext.16       q6, q14, q7, #4
    472     vext.16       q7, q14, q7, #1
    473     vadd.s16      q8, q8, q9
    474     vadd.s16      q9, q6, q7
    475     vld1.32       d14, [r6], r8         @load row 0 from temp buffer
    476     vmlal.s16     q15, d16, d26
    477     vmlsl.s16     q15, d18, d24
    478     vmlal.s16     q11, d17, d26
    479     vmlsl.s16     q11, d19, d24
    480     vqrshrun.s16  d14, q7, #0x5
    481     vld1.32       d28, [r6], r8         @load row 1 from temp buffer
    482     vaddl.u8      q9, d6, d0
    483     vqrshrun.s32  d16, q15, #10
    484     vqrshrun.s16  d15, q14, #0x5
    485     vqrshrun.s32  d17, q11, #10
    486     vmov          d12, d25
    487     vmov          d25, d24
    488 
    489     vqmovn.u16    d13, q8
    490     vrhadd.u8     q6, q6, q7
    491     vst1.32       d12[0], [r1], r3      @ store row 0
    492     vst1.32       d13[0], [r1], r3      @store row 1
    493 
    494     subs          r4, r4, #2
    495     subne         r0, r0 , r2, lsl #2
    496     subne         r0, r0, r2
    497 
    498     beq           end_func              @ Branch if height==4
    499     b             loop_4                @ Loop if height==8
    500 
    501 end_func:
    502     vldmia        sp!, {d8-d15}         @ Restore neon registers that were saved
    503     ldmfd         sp!, {r4-r12, pc}     @Restoring registers from stack
    504 
    505 
    506