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.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
     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 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'  the output is down shifted by 6 and clipped to 8 bits
     51 @*    assumptions : the function is optimized considering the fact width is
     52 @*    multiple of 2,4 or 8. and also considering height  should be multiple of 2
     53 @*    width 4,8 is optimized further
     54 @*
     55 @* @param[in] pu1_src
     56 @*  uword8 pointer to the source
     57 @*
     58 @* @param[out] pu1_dst
     59 @*  uword8 pointer to the destination
     60 @*
     61 @* @param[in] src_strd
     62 @*  integer source stride
     63 @*
     64 @* @param[in] dst_strd
     65 @*  integer destination stride
     66 @*
     67 @* @param[in] pi1_coeff
     68 @*  word8 pointer to the filter coefficients
     69 @*
     70 @* @param[in] ht
     71 @*  integer height of the array
     72 @*
     73 @* @param[in] wd
     74 @*  integer width of the array
     75 @*
     76 @* @returns
     77 @*
     78 @* @remarks
     79 @*  none
     80 @*
     81 @*******************************************************************************
     82 @*/
     83 @void ihevc_inter_pred_chroma_vert(uword8 *pu1_src,
     84 @                                   uword8 *pu1_dst,
     85 @                                   word32 src_strd,
     86 @                                   word32 dst_strd,
     87 @                                   word8 *pi1_coeff,
     88 @                                   word32 ht,
     89 @                                   word32 wd)
     90 @**************variables vs registers*****************************************
     91 @r0 => *pu1_src
     92 @r1 => *pi2_dst
     93 @r2 =>  src_strd
     94 @r3 =>  dst_strd
     95 .text
     96 .align 4
     97 
     98 
     99 
    100 
    101 .globl ihevc_inter_pred_chroma_vert_a9q
    102 
    103 .type ihevc_inter_pred_chroma_vert_a9q, %function
    104 
    105 ihevc_inter_pred_chroma_vert_a9q:
    106 
    107     stmfd       sp!,{r4-r12,r14}            @stack stores the values of the arguments
    108 
    109     ldr         r4,[sp,#44]                 @loads ht
    110     ldr         r12,[sp,#40]                @loads pi1_coeff
    111     cmp         r4,#0                       @checks ht == 0
    112     ldr         r6,[sp,#48]                 @loads wd
    113     sub         r0,r0,r2                    @pu1_src - src_strd
    114     vld1.8      {d0},[r12]                  @loads pi1_coeff
    115 
    116     ble         end_loops                   @jumps to end
    117 
    118     tst         r6,#3                       @checks (wd & 3)
    119     vabs.s8     d3,d0                       @vabs_s8(coeff)
    120     lsl         r10,r6,#1                   @2*wd
    121     vdup.8      d0,d3[0]                    @coeffabs_0
    122     vdup.8      d1,d3[1]                    @coeffabs_1
    123     vdup.8      d2,d3[2]                    @coeffabs_2
    124     vdup.8      d3,d3[3]                    @coeffabs_3
    125 
    126     bgt         outer_loop_wd_2             @jumps to loop handling wd ==2
    127 
    128     tst         r4,#7                       @checks ht for mul of 8
    129     beq         core_loop_ht_8              @when height is multiple of 8
    130 
    131     lsl         r7,r3,#1                    @2*dst_strd
    132     sub         r9,r7,r10                   @2*dst_strd - 2wd
    133     lsl         r12,r2,#1                   @2*src_strd
    134     sub         r8,r12,r10                  @2*src_strd - 2wd
    135     mov         r5,r10                      @2wd
    136 
    137 inner_loop_ht_2:                            @called when wd is multiple of 4 and ht is 4,2
    138 
    139     add         r6,r0,r2                    @pu1_src +src_strd
    140     vld1.8      {d9},[r6],r2                @loads pu1_src
    141     subs        r5,r5,#8                    @2wd - 8
    142     vld1.8      {d5},[r0]!                  @loads src
    143     vmull.u8    q3,d9,d1                    @vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1)
    144     vld1.8      {d4},[r6],r2                @loads incremented src
    145     vmlsl.u8    q3,d5,d0                    @vmlsl_u8(mul_res1, vreinterpret_u8_u32(src_tmp1), coeffabs_0)
    146     vld1.8      {d8},[r6],r2                @loads incremented src
    147     vmlal.u8    q3,d4,d2                    @vmlal_u8(mul_res1, vreinterpret_u8_u32(src_tmp3), coeffabs_2)
    148     vmull.u8    q2,d4,d1
    149     vmlsl.u8    q3,d8,d3
    150     vmlsl.u8    q2,d9,d0
    151     vld1.8      {d10},[r6]                  @loads the incremented src
    152     vmlal.u8    q2,d8,d2
    153     vqrshrun.s16 d6,q3,#6                   @shifts right
    154     vmlsl.u8    q2,d10,d3
    155     add         r6,r1,r3                    @pu1_dst + dst_strd
    156     vqrshrun.s16 d4,q2,#6                   @shifts right
    157     vst1.8      {d6},[r1]!                  @stores the loaded value
    158 
    159     vst1.8      {d4},[r6]                   @stores the loaded value
    160 
    161     bgt         inner_loop_ht_2             @inner loop again
    162 
    163     subs        r4,r4,#2                    @ht - 2
    164     add         r1,r1,r9                    @pu1_dst += (2*dst_strd - 2wd)
    165     mov         r5,r10                      @2wd
    166     add         r0,r0,r8                    @pu1_src += (2*src_strd - 2wd)
    167 
    168     bgt         inner_loop_ht_2             @loop again
    169 
    170     b           end_loops                   @jumps to end
    171 
    172 outer_loop_wd_2:                            @called when width is multiple of 2
    173     lsl         r5,r3,#1                    @2*dst_strd
    174     mov         r12,r10                     @2wd
    175     sub         r9,r5,r10                   @2*dst_strd - 2wd
    176     lsl         r7,r2,#1                    @2*src_strd
    177     sub         r8,r7,r10                   @2*src_strd - 2wd
    178 
    179 inner_loop_wd_2:
    180 
    181     add         r6,r0,r2                    @pu1_src + src_strd
    182     vld1.32     {d6[0]},[r0]                @vld1_lane_u32((uint32_t *)pu1_src_tmp, src_tmp1, 0
    183     subs        r12,r12,#4                  @2wd - 4
    184     add         r0,r0,#4                    @pu1_src + 4
    185     vld1.32     {d6[1]},[r6],r2             @loads pu1_src_tmp
    186     vdup.32     d7,d6[1]
    187     vld1.32     {d7[1]},[r6],r2             @loads pu1_src_tmp
    188     vmull.u8    q2,d7,d1                    @vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1)
    189     vdup.32     d7,d7[1]
    190     vld1.32     {d7[1]},[r6],r2
    191     vmlsl.u8    q2,d6,d0
    192     vmlal.u8    q2,d7,d2
    193     vdup.32     d7,d7[1]
    194     vld1.32     {d7[1]},[r6]
    195     add         r6,r1,r3                    @pu1_dst + dst_strd
    196     vmlsl.u8    q2,d7,d3
    197     vqrshrun.s16 d4,q2,#6                   @vrshrq_n_s16(vreinterpretq_s16_u16(mul_res1),6)
    198     vst1.32     {d4[0]},[r1]                @stores the loaded value
    199     add         r1,r1,#4                    @pu1_dst += 4
    200     vst1.32     {d4[1]},[r6]                @stores the loaded value
    201 
    202     bgt         inner_loop_wd_2             @inner loop again
    203 
    204     @inner loop ends
    205     subs        r4,r4,#2                    @ht - 2
    206     add         r1,r1,r9                    @pu1_dst += 2*dst_strd - 2*wd
    207     mov         r12,r10                     @2wd
    208     add         r0,r0,r8                    @pu1_src += 2*src_strd - 2*wd
    209 
    210     bgt         inner_loop_wd_2             @loop again
    211 
    212     b           end_loops                   @jumps to end
    213 
    214 core_loop_ht_8:                             @when wd & ht is multiple of 8
    215 
    216     lsl         r12,r3,#2                   @4*dst_strd
    217     sub         r8,r12,r10                  @4*dst_strd - 2wd
    218     lsl         r12,r2,#2                   @4*src_strd
    219     sub         r9,r12,r10                  @4*src_strd - 2wd
    220 
    221     bic         r5,r10,#7                   @r5 ->wd
    222     mov         r14,r10,lsr #3              @divide by 8
    223     mul         r12,r4,r14                  @multiply height by width
    224     sub         r12,#4                      @subtract by one for epilog
    225 
    226 prolog:
    227     add         r6,r0,r2                    @pu1_src + src_strd
    228     vld1.8      {d5},[r6],r2                @loads pu1_src
    229     subs        r5,r5,#8                    @2wd - 8
    230     vld1.8      {d4},[r0]!                  @loads the source
    231     vld1.8      {d6},[r6],r2                @load and increment
    232     vmull.u8    q15,d5,d1                   @mul with coeff 1
    233     vld1.8      {d7},[r6],r2                @load and increment
    234     vmlsl.u8    q15,d4,d0
    235     add         r7,r1,r3                    @pu1_dst
    236     vmlal.u8    q15,d6,d2
    237     vmlsl.u8    q15,d7,d3
    238     vld1.8      {d8},[r6],r2                @load and increment
    239 
    240     vmull.u8    q14,d6,d1                   @mul_res 2
    241     addle       r0,r0,r9                    @pu1_dst += 4*dst_strd - 2*wd
    242     vmlsl.u8    q14,d5,d0
    243     bicle       r5,r10,#7                   @r5 ->wd
    244     vmlal.u8    q14,d7,d2
    245     vld1.8      {d9},[r6],r2
    246     vmlsl.u8    q14,d8,d3
    247     vqrshrun.s16 d30,q15,#6
    248 
    249     vld1.8      {d10},[r6],r2
    250     vmull.u8    q13,d7,d1
    251     add         r6,r0,r2                    @pu1_src + src_strd
    252     vmlsl.u8    q13,d6,d0
    253     vst1.8      {d30},[r1]!                 @stores the loaded value
    254     vmlal.u8    q13,d8,d2
    255     vld1.8      {d4},[r0]!                  @loads the source
    256     vmlsl.u8    q13,d9,d3
    257     vqrshrun.s16 d28,q14,#6
    258 
    259     addle       r1,r1,r8                    @pu1_src += 4*src_strd - 2*wd
    260     vmull.u8    q12,d8,d1
    261     vld1.8      {d5},[r6],r2                @loads pu1_src
    262     vmlsl.u8    q12,d7,d0
    263     subs        r12,r12,#4
    264     vld1.8      {d6},[r6],r2                @load and increment
    265     vmlal.u8    q12,d9,d2
    266     vld1.8      {d7},[r6],r2                @load and increment
    267     vmlsl.u8    q12,d10,d3
    268 
    269     lsl         r11,r2,#2
    270     vst1.8      {d28},[r7],r3               @stores the loaded value
    271     vqrshrun.s16 d26,q13,#6
    272     rsb         r11,r2,r2,lsl #3
    273     add         r14,r2,r2,lsl #1
    274     add         r14,r14,r11
    275     ble         epilog                      @jumps to epilog
    276 
    277 kernel_8:
    278 
    279     vmull.u8    q15,d5,d1                   @mul with coeff 1
    280     subs        r5,r5,#8                    @2wd - 8
    281     vmlsl.u8    q15,d4,d0
    282     addle       r0,r0,r9                    @pu1_dst += 4*dst_strd - 2*wd
    283     vmlal.u8    q15,d6,d2
    284     rsble       r11,r2,r2,lsl #3
    285     vmlsl.u8    q15,d7,d3
    286     vst1.8      {d26},[r7],r3               @stores the loaded value
    287     vqrshrun.s16 d24,q12,#6
    288 
    289     vld1.8      {d8},[r6],r2                @load and increment
    290 
    291     vmull.u8    q14,d6,d1                   @mul_res 2
    292     bicle       r5,r10,#7                   @r5 ->wd
    293     vmlsl.u8    q14,d5,d0
    294     vst1.8      {d24},[r7],r3               @stores the loaded value
    295 
    296     vmlal.u8    q14,d7,d2
    297 
    298     vld1.8      {d9},[r6],r2
    299     vqrshrun.s16 d30,q15,#6
    300 
    301     vmlsl.u8    q14,d8,d3
    302     vld1.8      {d10},[r6],r2
    303     add         r7,r1,r3                    @pu1_dst
    304     vmull.u8    q13,d7,d1
    305     add         r6,r0,r2                    @pu1_src + src_strd
    306 
    307     pld         [r0,r11]
    308 
    309 
    310     vmlsl.u8    q13,d6,d0
    311     vld1.8      {d4},[r0]!                  @loads the source
    312 
    313     vmlal.u8    q13,d8,d2
    314     vst1.8      {d30},[r1]!                 @stores the loaded value
    315 
    316     vmlsl.u8    q13,d9,d3
    317     vld1.8      {d5},[r6],r2                @loads pu1_src
    318 
    319     add         r11,r11,r2
    320     vqrshrun.s16 d28,q14,#6
    321 
    322     vmull.u8    q12,d8,d1
    323     vld1.8      {d6},[r6],r2                @load and increment
    324     addle       r1,r1,r8                    @pu1_src += 4*src_strd - 2*wd
    325 
    326     cmp         r11,r14
    327     rsbgt       r11,r2,r2,lsl #3
    328 
    329     vmlsl.u8    q12,d7,d0
    330     subs        r12,r12,#4
    331 
    332     vmlal.u8    q12,d9,d2
    333     vld1.8      {d7},[r6],r2                @load and increment
    334 
    335     vmlsl.u8    q12,d10,d3
    336     vst1.8      {d28},[r7],r3               @stores the loaded value
    337     vqrshrun.s16 d26,q13,#6
    338 
    339     bgt         kernel_8                    @jumps to kernel_8
    340 
    341 epilog:
    342 
    343     vmull.u8    q15,d5,d1                   @mul with coeff 1
    344     vmlsl.u8    q15,d4,d0
    345     vmlal.u8    q15,d6,d2
    346     vmlsl.u8    q15,d7,d3
    347     vst1.8      {d26},[r7],r3               @stores the loaded value
    348     vqrshrun.s16 d24,q12,#6
    349 
    350     vld1.8      {d8},[r6],r2                @load and increment
    351     vmull.u8    q14,d6,d1                   @mul_res 2
    352     vmlsl.u8    q14,d5,d0
    353     vmlal.u8    q14,d7,d2
    354     vmlsl.u8    q14,d8,d3
    355     vst1.8      {d24},[r7],r3               @stores the loaded value
    356     vqrshrun.s16 d30,q15,#6
    357 
    358     vld1.8      {d9},[r6],r2
    359     vmull.u8    q13,d7,d1
    360     add         r7,r1,r3                    @pu1_dst
    361     vmlsl.u8    q13,d6,d0
    362     vst1.8      {d30},[r1]!                 @stores the loaded value
    363 
    364     vqrshrun.s16 d28,q14,#6
    365     vmlal.u8    q13,d8,d2
    366     vld1.8      {d10},[r6],r2
    367     vmlsl.u8    q13,d9,d3
    368 
    369     vmull.u8    q12,d8,d1
    370     vqrshrun.s16 d26,q13,#6
    371     vst1.8      {d28},[r7],r3               @stores the loaded value
    372     vmlsl.u8    q12,d7,d0
    373     vmlal.u8    q12,d9,d2
    374     vst1.8      {d26},[r7],r3               @stores the loaded value
    375     vmlsl.u8    q12,d10,d3
    376 
    377     vqrshrun.s16 d24,q12,#6
    378     vst1.8      {d24},[r7],r3               @stores the loaded value
    379 end_loops:
    380     ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
    381 
    382 
    383 
    384