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_w16out_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/ pathiban
     31 @*
     32 @* @par list of functions:
     33 @*
     34 @*
     35 @* @remarks
     36 @*  none
     37 @*
     38 @*******************************************************************************
     39 @*/
     40 @/**
     41 @/**
     42 @*******************************************************************************
     43 @*
     44 @* @brief
     45 @*   interprediction chroma filter to store vertical 16bit ouput
     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'  no downshifting or clipping is done and the output is  used as
     51 @*    an input for weighted prediction   assumptions : the function is optimized
     52 @*    considering the fact width is  multiple of 2,4 or 8. and also considering
     53 @*    height  should be multiple of 2. width 4,8 is optimized further
     54 @*
     55 @* @param[in] pu1_src
     56 @*  uword8 pointer to the source
     57 @*
     58 @* @param[out] pi2_dst
     59 @*  word16 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_w16out(uword8 *pu1_src,
     84 @                                           word16 *pi2_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 .text
     97 .align 4
     98 
     99 
    100 
    101 
    102 .globl ihevc_inter_pred_chroma_vert_w16out_a9q
    103 
    104 .type ihevc_inter_pred_chroma_vert_w16out_a9q, %function
    105 
    106 ihevc_inter_pred_chroma_vert_w16out_a9q:
    107 
    108     stmfd       sp!,{r4-r12,r14}            @stack stores the values of the arguments
    109 
    110     ldr         r4,[sp,#44]                 @loads ht
    111     ldr         r12,[sp,#40]                @loads pi1_coeff
    112     cmp         r4,#0                       @checks ht == 0
    113     ldr         r6,[sp,#48]                 @loads wd
    114     sub         r0,r0,r2                    @pu1_src - src_strd
    115     vld1.8      {d0},[r12]                  @loads pi1_coeff
    116 
    117     ble         end_loops                   @jumps to end
    118 
    119     tst         r6,#3                       @checks (wd & 3)
    120     vabs.s8     d3,d0                       @vabs_s8(coeff)
    121     lsl         r10,r6,#1                   @2*wd
    122     vdup.8      d0,d3[0]                    @coeffabs_0
    123     vdup.8      d1,d3[1]                    @coeffabs_1
    124     vdup.8      d2,d3[2]                    @coeffabs_2
    125     vdup.8      d3,d3[3]                    @coeffabs_3
    126 
    127     bgt         outer_loop_wd_2             @jumps to loop handling wd ==2
    128 
    129     tst         r4,#7                       @checks ht for mul of 8
    130     beq         core_loop_ht_8              @when height is multiple of 8
    131 
    132     lsl         r7,r3,#2                    @2*dst_strd
    133     sub         r9,r7,r10,lsl #1            @4*dst_strd - 4wd
    134     lsl         r12,r2,#1                   @2*src_strd
    135     sub         r8,r12,r10                  @2*src_strd - 2wd
    136     mov         r3,r3,lsl #1
    137     mov         r5,r10                      @2wd
    138 
    139 inner_loop_ht_2:                            @called when wd is multiple of 4 and ht is 4,2
    140 
    141     add         r6,r0,r2                    @pu1_src +src_strd
    142     vld1.8      {d9},[r6],r2                @loads pu1_src
    143     subs        r5,r5,#8                    @2wd - 8
    144     vld1.8      {d5},[r0]!                  @loads src
    145     vmull.u8    q3,d9,d1                    @vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1)
    146     vld1.8      {d4},[r6],r2                @loads incremented src
    147     vmlsl.u8    q3,d5,d0                    @vmlsl_u8(mul_res1, vreinterpret_u8_u32(src_tmp1), coeffabs_0)
    148     vld1.8      {d8},[r6],r2                @loads incremented src
    149     vmlal.u8    q3,d4,d2                    @vmlal_u8(mul_res1, vreinterpret_u8_u32(src_tmp3), coeffabs_2)
    150     vmull.u8    q2,d4,d1
    151     vld1.8      {d10},[r6]                  @loads the incremented src
    152     vmlsl.u8    q3,d8,d3
    153     vmlsl.u8    q2,d9,d0
    154     vmlal.u8    q2,d8,d2
    155     vmlsl.u8    q2,d10,d3
    156     add         r6,r1,r3                    @pu1_dst + dst_strd
    157     vst1.8      {q3},[r1]!                  @stores the loaded value
    158 
    159     vst1.8      {q2},[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,#2                    @2*dst_strd
    174     mov         r12,r10                     @2wd
    175     sub         r9,r5,r10,lsl #1            @4*dst_strd - 4wd
    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,lsl #1             @pu1_dst + dst_strd
    196     vmlsl.u8    q2,d7,d3
    197     vst1.32     {d4},[r1]                   @stores the loaded value
    198     add         r1,r1,#8                    @pu1_dst += 4
    199     vst1.32     {d5},[r6]                   @stores the loaded value
    200 
    201     bgt         inner_loop_wd_2             @inner loop again
    202 
    203     @inner loop ends
    204     subs        r4,r4,#2                    @ht - 2
    205     add         r1,r1,r9                    @pu1_dst += 2*dst_strd - 2*wd
    206     mov         r12,r10                     @2wd
    207     add         r0,r0,r8                    @pu1_src += 2*src_strd - 2*wd
    208 
    209     bgt         inner_loop_wd_2             @loop again
    210 
    211     b           end_loops                   @jumps to end
    212 
    213 core_loop_ht_8:                             @when wd & ht is multiple of 8
    214 
    215     lsl         r12,r3,#3                   @4*dst_strd
    216     sub         r8,r12,r10,lsl #1           @4*dst_strd - 2wd
    217     lsl         r12,r2,#2                   @4*src_strd
    218     sub         r9,r12,r10                  @4*src_strd - 2wd
    219 
    220     bic         r5,r10,#7                   @r5 ->wd
    221     mov         r14,r10,lsr #3              @divide by 8
    222     mul         r12,r4,r14                  @multiply height by width
    223     sub         r12,#4                      @subtract by one for epilog
    224     mov         r3,r3,lsl #1
    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 
    248     vld1.8      {d10},[r6],r2
    249     vmull.u8    q13,d7,d1
    250     add         r6,r0,r2                    @pu1_src + src_strd
    251     vmlsl.u8    q13,d6,d0
    252     vst1.8      {q15},[r1]!                 @stores the loaded value
    253     vmlal.u8    q13,d8,d2
    254     vld1.8      {d4},[r0]!                  @loads the source
    255     vmlsl.u8    q13,d9,d3
    256 
    257     addle       r1,r1,r8                    @pu1_src += 4*src_strd - 2*wd
    258     vmull.u8    q12,d8,d1
    259     vld1.8      {d5},[r6],r2                @loads pu1_src
    260     vmlsl.u8    q12,d7,d0
    261     subs        r12,r12,#4
    262     vld1.8      {d6},[r6],r2                @load and increment
    263     vmlal.u8    q12,d9,d2
    264     vld1.8      {d7},[r6],r2                @load and increment
    265     vmlsl.u8    q12,d10,d3
    266     rsb         r11,r2,r2,lsl #3
    267     add         r14,r2,r2,lsl #1
    268     add         r14,r14,r11
    269     vst1.8      {q14},[r7],r3               @stores the loaded value
    270 
    271     ble         epilog                      @jumps to epilog
    272 
    273 kernel_8:
    274 
    275     vmull.u8    q15,d5,d1                   @mul with coeff 1
    276     subs        r5,r5,#8                    @2wd - 8
    277     vmlsl.u8    q15,d4,d0
    278     addle       r0,r0,r9                    @pu1_dst += 4*dst_strd - 2*wd
    279     vmlal.u8    q15,d6,d2
    280     rsble       r11,r2,r2,lsl #3
    281     vmlsl.u8    q15,d7,d3
    282     vst1.8      {q13},[r7],r3               @stores the loaded value
    283 
    284     vld1.8      {d8},[r6],r2                @load and increment
    285 
    286     vmull.u8    q14,d6,d1                   @mul_res 2
    287     bicle       r5,r10,#7                   @r5 ->wd
    288     vmlsl.u8    q14,d5,d0
    289     vst1.8      {q12},[r7],r3               @stores the loaded value
    290 
    291     vmlal.u8    q14,d7,d2
    292     vld1.8      {d9},[r6],r2
    293 
    294     vmlsl.u8    q14,d8,d3
    295     vld1.8      {d10},[r6],r2
    296     add         r7,r1,r3                    @pu1_dst
    297     vmull.u8    q13,d7,d1
    298     add         r6,r0,r2                    @pu1_src + src_strd
    299     pld         [r0,r11]
    300 
    301     vmlsl.u8    q13,d6,d0
    302     vld1.8      {d4},[r0]!                  @loads the source
    303 
    304     add         r11,r11,r2
    305     vmlal.u8    q13,d8,d2
    306     vst1.8      {q15},[r1]!                 @stores the loaded value
    307 
    308     vmlsl.u8    q13,d9,d3
    309     vld1.8      {d5},[r6],r2                @loads pu1_src
    310 
    311     vmull.u8    q12,d8,d1
    312     vld1.8      {d6},[r6],r2                @load and increment
    313     addle       r1,r1,r8                    @pu1_src += 4*src_strd - 2*wd
    314 
    315     cmp         r11,r14
    316     rsbgt       r11,r2,r2,lsl #3
    317 
    318     vmlsl.u8    q12,d7,d0
    319     subs        r12,r12,#4
    320 
    321 
    322     vmlal.u8    q12,d9,d2
    323     vld1.8      {d7},[r6],r2                @load and increment
    324 
    325     vmlsl.u8    q12,d10,d3
    326     vst1.8      {q14},[r7],r3               @stores the loaded value
    327 
    328     bgt         kernel_8                    @jumps to kernel_8
    329 
    330 epilog:
    331 
    332     vmull.u8    q15,d5,d1                   @mul with coeff 1
    333     vmlsl.u8    q15,d4,d0
    334     vmlal.u8    q15,d6,d2
    335     vmlsl.u8    q15,d7,d3
    336     vst1.8      {q13},[r7],r3               @stores the loaded value
    337 
    338     vld1.8      {d8},[r6],r2                @load and increment
    339     vmull.u8    q14,d6,d1                   @mul_res 2
    340     vmlsl.u8    q14,d5,d0
    341     vmlal.u8    q14,d7,d2
    342     vmlsl.u8    q14,d8,d3
    343     vst1.8      {q12},[r7],r3               @stores the loaded value
    344 
    345     vld1.8      {d9},[r6],r2
    346     vmull.u8    q13,d7,d1
    347     add         r7,r1,r3                    @pu1_dst
    348     vmlsl.u8    q13,d6,d0
    349     vst1.8      {q15},[r1]!                 @stores the loaded value
    350     vmlal.u8    q13,d8,d2
    351     vld1.8      {d10},[r6],r2
    352     vmlsl.u8    q13,d9,d3
    353 
    354     vmull.u8    q12,d8,d1
    355     vst1.8      {q14},[r7],r3               @stores the loaded value
    356     vmlsl.u8    q12,d7,d0
    357     vmlal.u8    q12,d9,d2
    358     vst1.8      {q13},[r7],r3               @stores the loaded value
    359     vmlsl.u8    q12,d10,d3
    360 
    361     vst1.8      {q12},[r7],r3               @stores the loaded value
    362 
    363 end_loops:
    364     ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
    365 
    366 
    367 
    368