Home | History | Annotate | Download | only in arm
      1 @/*****************************************************************************
      2 @*
      3 @* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
      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 @/**
     19 @*******************************************************************************
     20 @* @file
     21 @*  ihevc_inter_pred_chroma_vert_neon_w16inp_neon.s
     22 @*
     23 @* @brief
     24 @*  contains function definitions for inter prediction  interpolation.
     25 @* functions are coded using neon  intrinsics and can be compiled using
     26 
     27 @* rvct
     28 @*
     29 @* @author
     30 @*  yogeswaran rs / parthiban
     31 @*
     32 @* @par list of functions:
     33 @*
     34 @*
     35 @* @remarks
     36 @*  none
     37 @*
     38 @*******************************************************************************
     39 @*/
     40 @/**
     41 @/**
     42 @*******************************************************************************
     43 @*
     44 @* @brief
     45 @*       chroma interprediction filter for 16bit vertical input.
     46 @*
     47 @* @par description:
     48 @*    applies a vertical filter with coefficients pointed to  by 'pi1_coeff' to
     49 @*    the elements pointed by 'pu1_src' and  writes to the location pointed by
     50 @*    'pu1_dst'  input is 16 bits  the filter output is downshifted by 12 and
     51 @*    clipped to lie  between 0 and 255   assumptions : the function is
     52 @*    optimized considering the fact width and  height are multiple of 2.
     53 @*
     54 @* @param[in] pi2_src
     55 @*  word16 pointer to the source
     56 @*
     57 @* @param[out] pu1_dst
     58 @*  uword8 pointer to the destination
     59 @*
     60 @* @param[in] src_strd
     61 @*  integer source stride
     62 @*
     63 @* @param[in] dst_strd
     64 @*  integer destination stride
     65 @*
     66 @* @param[in] pi1_coeff
     67 @*  word8 pointer to the filter coefficients
     68 @*
     69 @* @param[in] ht
     70 @*  integer height of the array
     71 @*
     72 @* @param[in] wd
     73 @*  integer width of the array
     74 @*
     75 @* @returns
     76 @*
     77 @* @remarks
     78 @*  none
     79 @*
     80 @*******************************************************************************
     81 @*/
     82 @void ihevc_inter_pred_chroma_vert_w16inp(word16 *pi2_src,
     83 @                                          uword8 *pu1_dst,
     84 @                                          word32 src_strd,
     85 @                                          word32 dst_strd,
     86 @                                          word8 *pi1_coeff,
     87 @                                          word32 ht,
     88 @                                          word32 wd)
     89 @**************variables vs registers*****************************************
     90 @r0 => *pu1_src
     91 @r1 => *pi2_dst
     92 @r2 =>  src_strd
     93 @r3 =>  dst_strd
     94 
     95 .equ    coeff_offset,   104
     96 .equ    ht_offset,      108
     97 .equ    wd_offset,      112
     98 
     99 
    100 .text
    101 .align 4
    102 
    103 
    104 
    105 
    106 .globl ihevc_inter_pred_chroma_vert_w16inp_a9q
    107 
    108 .type ihevc_inter_pred_chroma_vert_w16inp_a9q, %function
    109 
    110 ihevc_inter_pred_chroma_vert_w16inp_a9q:
    111 
    112     stmfd       sp!, {r4-r12, r14}          @stack stores the values of the arguments
    113     vpush        {d8 - d15}
    114 
    115     ldr         r4, [sp,#coeff_offset]                @loads pi1_coeff
    116     ldr         r6, [sp,#wd_offset]                @wd
    117     lsl         r2,r2,#1                    @src_strd = 2* src_strd
    118     ldr         r5,[sp,#ht_offset]                 @loads ht
    119     vld1.8      {d0},[r4]                   @loads pi1_coeff
    120     sub         r4,r0,r2                    @pu1_src - src_strd
    121     vmovl.s8    q0,d0                       @long the value
    122 
    123     tst         r6,#3                       @checks wd  == 2
    124     vdup.16     d12,d0[0]                   @coeff_0
    125     vdup.16     d13,d0[1]                   @coeff_1
    126     vdup.16     d14,d0[2]                   @coeff_2
    127     vdup.16     d15,d0[3]                   @coeff_3
    128 
    129     bgt         core_loop_ht_2              @jumps to loop handles wd 2
    130 
    131     tst         r5,#3                       @checks ht == mul of 4
    132     beq         core_loop_ht_4              @jumps to loop handles ht mul of 4
    133 
    134 core_loop_ht_2:
    135     lsl         r7,r2,#1                    @2*src_strd
    136     lsl         r12,r3,#1                   @2*dst_strd
    137     lsl         r9,r6,#2                    @4*wd
    138     sub         r6,r12,r6,lsl #1            @2*dst_strd - 2*wd
    139     sub         r8,r7,r9                    @2*src_strd - 4*wd
    140     mov         r12,r9                      @4wd
    141 
    142 inner_loop_ht_2:
    143     add         r0,r4,r2                    @increments pi2_src
    144     vld1.16     {d0},[r4]!                  @loads pu1_src
    145     vmull.s16   q0,d0,d12                   @vmull_s16(src_tmp1, coeff_0)
    146     subs        r12,r12,#8                  @2wd + 8
    147     vld1.16     {d2},[r0],r2                @loads pi2_src
    148     vmull.s16   q4,d2,d12                   @vmull_s16(src_tmp2, coeff_0)
    149     vld1.16     {d3},[r0],r2                @loads pi2_src
    150     vmlal.s16   q0,d2,d13
    151     vld1.16     {d6},[r0],r2
    152     vmlal.s16   q4,d3,d13
    153     vld1.16     {d2},[r0]
    154     add         r7,r1,r3                    @pu1_dst + dst_strd
    155     vmlal.s16   q0,d3,d14
    156     vmlal.s16   q4,d6,d14
    157     vmlal.s16   q0,d6,d15
    158     vmlal.s16   q4,d2,d15
    159     vqshrn.s32  d0,q0,#6                    @right shift
    160     vqshrn.s32  d30,q4,#6                   @right shift
    161     vqrshrun.s16 d0,q0,#6                   @rounding shift
    162     vqrshrun.s16 d30,q15,#6                 @rounding shift
    163     vst1.32     {d0[0]},[r1]!               @stores the loaded value
    164     vst1.32     {d30[0]},[r7]               @stores the loaded value
    165     bgt         inner_loop_ht_2             @inner loop -again
    166 
    167     @inner loop ends
    168     subs        r5,r5,#2                    @increments ht
    169     add         r1,r1,r6                    @pu1_dst += 2*dst_strd - 2*wd
    170     mov         r12,r9                      @4wd
    171     add         r4,r4,r8                    @pi1_src_tmp1 += 2*src_strd - 4*wd
    172     bgt         inner_loop_ht_2             @loop again
    173 
    174     b           end_loops                   @jumps to end
    175 
    176 core_loop_ht_4:
    177     lsl         r7,r2,#2                    @2*src_strd
    178     lsl         r12,r3,#2                   @2*dst_strd
    179     mov         r11,r6,lsr #1               @divide by 2
    180     sub         lr,r12,r6,lsl #1            @2*dst_strd - 2*wd
    181     sub         r8,r7,r6,lsl #2             @2*src_strd - 4*wd
    182 
    183     mul         r12,r5,r11                  @multiply height by width
    184     sub         r12,#4                      @subtract by one for epilog
    185     mov         r11,r6,lsl #1               @2*wd
    186 
    187 prolog:
    188     add         r0,r4,r2                    @increments pi2_src
    189     vld1.16     {d0},[r4]!                  @loads pu1_src
    190     vld1.16     {d1},[r0],r2                @loads pi2_src
    191     subs        r11,r11,#4
    192     vld1.16     {d2},[r0],r2                @loads pi2_src
    193     vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
    194     vld1.16     {d3},[r0],r2
    195     vmlal.s16   q15,d1,d13
    196     vmlal.s16   q15,d2,d14
    197     add         r9,r1,r3                    @pu1_dst + dst_strd
    198     vmlal.s16   q15,d3,d15
    199 
    200     vld1.16     {d4},[r0],r2
    201     vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
    202     addle       r4,r4,r8
    203     vmlal.s16   q14,d2,d13
    204     vld1.s16    {d5},[r0],r2
    205     vmlal.s16   q14,d3,d14
    206     vld1.s16    {d6},[r0],r2
    207     vmlal.s16   q14,d4,d15
    208     movle       r11,r6,lsl #1
    209 
    210     vqshrn.s32  d30,q15,#6                  @right shift
    211 
    212     vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
    213     add         r0,r4,r2
    214     vmlal.s16   q13,d3,d13
    215     vmlal.s16   q13,d4,d14
    216     vld1.16     {d0},[r4]!                  @loads pu1_src
    217     vmlal.s16   q13,d5,d15
    218 
    219     vqrshrun.s16 d30,q15,#6                 @rounding shift
    220     vqshrn.s32  d28,q14,#6                  @right shift
    221 
    222     vld1.16     {d1},[r0],r2                @loads pi2_src
    223     vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
    224     vst1.32     {d30[0]},[r1]!              @stores the loaded value
    225     vmlal.s16   q12,d4,d13
    226     vld1.16     {d2},[r0],r2                @loads pi2_src
    227     vmlal.s16   q12,d5,d14
    228     vld1.16     {d3},[r0],r2
    229     vmlal.s16   q12,d6,d15
    230     addle       r1,r1,lr
    231 
    232     vqshrn.s32  d26,q13,#6                  @right shift
    233     subs        r12,r12,#4
    234     vqrshrun.s16 d28,q14,#6                 @rounding shift
    235 
    236     beq         epilog                      @jumps to epilog
    237 
    238 kernel_4:
    239     vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
    240     subs        r11,r11,#4
    241     vmlal.s16   q15,d1,d13
    242     vst1.32     {d28[0]},[r9],r3            @stores the loaded value
    243     vmlal.s16   q15,d2,d14
    244     vmlal.s16   q15,d3,d15
    245 
    246     vqshrn.s32  d24,q12,#6                  @right shift
    247     vqrshrun.s16 d26,q13,#6                 @rounding shift
    248 
    249     vld1.16     {d4},[r0],r2
    250     vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
    251     vmlal.s16   q14,d2,d13
    252     vmlal.s16   q14,d3,d14
    253     vmlal.s16   q14,d4,d15
    254     vst1.32     {d26[0]},[r9],r3            @stores the loaded value
    255     addle       r4,r4,r8
    256     movle       r11,r6,lsl #1
    257 
    258     vqshrn.s32  d30,q15,#6                  @right shift
    259     vqrshrun.s16 d24,q12,#6                 @rounding shift
    260 
    261     vld1.s16    {d5},[r0],r2
    262     vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
    263     vld1.s16    {d6},[r0],r2
    264     vmlal.s16   q13,d3,d13
    265     vst1.32     {d24[0]},[r9]               @stores the loaded value
    266     add         r0,r4,r2
    267     vmlal.s16   q13,d4,d14
    268     vld1.16     {d0},[r4]!                  @loads pu1_src
    269     vmlal.s16   q13,d5,d15
    270 
    271     vqshrn.s32  d28,q14,#6                  @right shift
    272     vqrshrun.s16 d30,q15,#6                 @rounding shift
    273 
    274     vld1.16     {d1},[r0],r2                @loads pi2_src
    275     vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
    276     add         r9,r1,r3                    @pu1_dst + dst_strd
    277     vld1.16     {d2},[r0],r2                @loads pi2_src
    278     vmlal.s16   q12,d4,d13
    279     vld1.16     {d3},[r0],r2
    280     vmlal.s16   q12,d5,d14
    281 
    282     vst1.32     {d30[0]},[r1]!              @stores the loaded value
    283     vmlal.s16   q12,d6,d15
    284 
    285     vqshrn.s32  d26,q13,#6                  @right shift
    286     vqrshrun.s16 d28,q14,#6                 @rounding shift
    287     addle       r1,r1,lr
    288 
    289     subs        r12,r12,#4
    290 
    291     bgt         kernel_4                    @jumps to kernel_4
    292 
    293 epilog:
    294     vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
    295     vst1.32     {d28[0]},[r9],r3            @stores the loaded value
    296     vmlal.s16   q15,d1,d13
    297     vmlal.s16   q15,d2,d14
    298     vmlal.s16   q15,d3,d15
    299 
    300     vqshrn.s32  d24,q12,#6                  @right shift
    301     vqrshrun.s16 d26,q13,#6                 @rounding shift
    302 
    303     vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
    304     vld1.16     {d4},[r0],r2
    305     vmlal.s16   q14,d2,d13
    306     vst1.32     {d26[0]},[r9],r3            @stores the loaded value
    307     vmlal.s16   q14,d3,d14
    308     vmlal.s16   q14,d4,d15
    309 
    310     vqshrn.s32  d30,q15,#6                  @right shift
    311     vqrshrun.s16 d24,q12,#6                 @rounding shift
    312 
    313     vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
    314     vld1.s16    {d5},[r0],r2
    315     vmlal.s16   q13,d3,d13
    316     vmlal.s16   q13,d4,d14
    317     vmlal.s16   q13,d5,d15
    318 
    319     vqshrn.s32  d28,q14,#6                  @right shift
    320     vqrshrun.s16 d30,q15,#6                 @rounding shift
    321 
    322     vst1.32     {d24[0]},[r9]               @stores the loaded value
    323     vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
    324     vmlal.s16   q12,d4,d13
    325     add         r9,r1,r3                    @pu1_dst + dst_strd
    326     vld1.s16    {d6},[r0],r2
    327     vmlal.s16   q12,d5,d14
    328     vmlal.s16   q12,d6,d15
    329     vst1.32     {d30[0]},[r1]!              @stores the loaded value
    330 
    331     vqrshrun.s16 d28,q14,#6                 @rounding shift
    332     vqshrn.s32  d26,q13,#6                  @right shift
    333 
    334     vst1.32     {d28[0]},[r9],r3            @stores the loaded value
    335     vqrshrun.s16 d26,q13,#6                 @rounding shift
    336 
    337     vqshrn.s32  d24,q12,#6                  @right shift
    338     vst1.32     {d26[0]},[r9],r3            @stores the loaded value
    339     vqrshrun.s16 d24,q12,#6                 @rounding shift
    340 
    341     vst1.32     {d24[0]},[r9]               @stores the loaded value
    342 
    343 end_loops:
    344     vpop         {d8 - d15}
    345     ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
    346 
    347 
    348 
    349 
    350