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