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 .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_w16out_a9q
    107 
    108 .type ihevc_inter_pred_chroma_vert_w16out_a9q, %function
    109 
    110 ihevc_inter_pred_chroma_vert_w16out_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,#2                    @2*dst_strd
    138     sub         r9,r7,r10,lsl #1            @4*dst_strd - 4wd
    139     lsl         r12,r2,#1                   @2*src_strd
    140     sub         r8,r12,r10                  @2*src_strd - 2wd
    141     mov         r3,r3,lsl #1
    142     mov         r5,r10                      @2wd
    143 
    144 inner_loop_ht_2:                            @called when wd is multiple of 4 and ht is 4,2
    145 
    146     add         r6,r0,r2                    @pu1_src +src_strd
    147     vld1.8      {d9},[r6],r2                @loads pu1_src
    148     subs        r5,r5,#8                    @2wd - 8
    149     vld1.8      {d5},[r0]!                  @loads src
    150     vmull.u8    q3,d9,d1                    @vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1)
    151     vld1.8      {d4},[r6],r2                @loads incremented src
    152     vmlsl.u8    q3,d5,d0                    @vmlsl_u8(mul_res1, vreinterpret_u8_u32(src_tmp1), coeffabs_0)
    153     vld1.8      {d8},[r6],r2                @loads incremented src
    154     vmlal.u8    q3,d4,d2                    @vmlal_u8(mul_res1, vreinterpret_u8_u32(src_tmp3), coeffabs_2)
    155     vmull.u8    q2,d4,d1
    156     vld1.8      {d10},[r6]                  @loads the incremented src
    157     vmlsl.u8    q3,d8,d3
    158     vmlsl.u8    q2,d9,d0
    159     vmlal.u8    q2,d8,d2
    160     vmlsl.u8    q2,d10,d3
    161     add         r6,r1,r3                    @pu1_dst + dst_strd
    162     vst1.8      {q3},[r1]!                  @stores the loaded value
    163 
    164     vst1.8      {q2},[r6]                   @stores the loaded value
    165 
    166     bgt         inner_loop_ht_2             @inner loop again
    167 
    168     subs        r4,r4,#2                    @ht - 2
    169     add         r1,r1,r9                    @pu1_dst += (2*dst_strd - 2wd)
    170     mov         r5,r10                      @2wd
    171     add         r0,r0,r8                    @pu1_src += (2*src_strd - 2wd)
    172 
    173     bgt         inner_loop_ht_2             @loop again
    174 
    175     b           end_loops                   @jumps to end
    176 
    177 outer_loop_wd_2:                            @called when width is multiple of 2
    178     lsl         r5,r3,#2                    @2*dst_strd
    179     mov         r12,r10                     @2wd
    180     sub         r9,r5,r10,lsl #1            @4*dst_strd - 4wd
    181     lsl         r7,r2,#1                    @2*src_strd
    182     sub         r8,r7,r10                   @2*src_strd - 2wd
    183 
    184 inner_loop_wd_2:
    185 
    186     add         r6,r0,r2                    @pu1_src + src_strd
    187     vld1.32     {d6[0]},[r0]                @vld1_lane_u32((uint32_t *)pu1_src_tmp, src_tmp1, 0
    188     subs        r12,r12,#4                  @2wd - 4
    189     add         r0,r0,#4                    @pu1_src + 4
    190     vld1.32     {d6[1]},[r6],r2             @loads pu1_src_tmp
    191     vdup.32     d7,d6[1]
    192     vld1.32     {d7[1]},[r6],r2             @loads pu1_src_tmp
    193     vmull.u8    q2,d7,d1                    @vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1)
    194     vdup.32     d7,d7[1]
    195     vld1.32     {d7[1]},[r6],r2
    196     vmlsl.u8    q2,d6,d0
    197     vmlal.u8    q2,d7,d2
    198     vdup.32     d7,d7[1]
    199     vld1.32     {d7[1]},[r6]
    200     add         r6,r1,r3,lsl #1             @pu1_dst + dst_strd
    201     vmlsl.u8    q2,d7,d3
    202     vst1.32     {d4},[r1]                   @stores the loaded value
    203     add         r1,r1,#8                    @pu1_dst += 4
    204     vst1.32     {d5},[r6]                   @stores the loaded value
    205 
    206     bgt         inner_loop_wd_2             @inner loop again
    207 
    208     @inner loop ends
    209     subs        r4,r4,#2                    @ht - 2
    210     add         r1,r1,r9                    @pu1_dst += 2*dst_strd - 2*wd
    211     mov         r12,r10                     @2wd
    212     add         r0,r0,r8                    @pu1_src += 2*src_strd - 2*wd
    213 
    214     bgt         inner_loop_wd_2             @loop again
    215 
    216     b           end_loops                   @jumps to end
    217 
    218 core_loop_ht_8:                             @when wd & ht is multiple of 8
    219 
    220     lsl         r12,r3,#3                   @4*dst_strd
    221     sub         r8,r12,r10,lsl #1           @4*dst_strd - 2wd
    222     lsl         r12,r2,#2                   @4*src_strd
    223     sub         r9,r12,r10                  @4*src_strd - 2wd
    224 
    225     bic         r5,r10,#7                   @r5 ->wd
    226     mov         r14,r10,lsr #3              @divide by 8
    227     mul         r12,r4,r14                  @multiply height by width
    228     sub         r12,#4                      @subtract by one for epilog
    229     mov         r3,r3,lsl #1
    230 
    231 prolog:
    232     add         r6,r0,r2                    @pu1_src + src_strd
    233     vld1.8      {d5},[r6],r2                @loads pu1_src
    234     subs        r5,r5,#8                    @2wd - 8
    235     vld1.8      {d4},[r0]!                  @loads the source
    236     vld1.8      {d6},[r6],r2                @load and increment
    237     vmull.u8    q15,d5,d1                   @mul with coeff 1
    238     vld1.8      {d7},[r6],r2                @load and increment
    239     vmlsl.u8    q15,d4,d0
    240     add         r7,r1,r3                    @pu1_dst
    241     vmlal.u8    q15,d6,d2
    242     vmlsl.u8    q15,d7,d3
    243     vld1.8      {d8},[r6],r2                @load and increment
    244 
    245     vmull.u8    q14,d6,d1                   @mul_res 2
    246     addle       r0,r0,r9                    @pu1_dst += 4*dst_strd - 2*wd
    247     vmlsl.u8    q14,d5,d0
    248     bicle       r5,r10,#7                   @r5 ->wd
    249     vmlal.u8    q14,d7,d2
    250     vld1.8      {d9},[r6],r2
    251     vmlsl.u8    q14,d8,d3
    252 
    253     vld1.8      {d10},[r6],r2
    254     vmull.u8    q13,d7,d1
    255     add         r6,r0,r2                    @pu1_src + src_strd
    256     vmlsl.u8    q13,d6,d0
    257     vst1.8      {q15},[r1]!                 @stores the loaded value
    258     vmlal.u8    q13,d8,d2
    259     vld1.8      {d4},[r0]!                  @loads the source
    260     vmlsl.u8    q13,d9,d3
    261 
    262     addle       r1,r1,r8                    @pu1_src += 4*src_strd - 2*wd
    263     vmull.u8    q12,d8,d1
    264     vld1.8      {d5},[r6],r2                @loads pu1_src
    265     vmlsl.u8    q12,d7,d0
    266     subs        r12,r12,#4
    267     vld1.8      {d6},[r6],r2                @load and increment
    268     vmlal.u8    q12,d9,d2
    269     vld1.8      {d7},[r6],r2                @load and increment
    270     vmlsl.u8    q12,d10,d3
    271     rsb         r11,r2,r2,lsl #3
    272     add         r14,r2,r2,lsl #1
    273     add         r14,r14,r11
    274     vst1.8      {q14},[r7],r3               @stores the loaded value
    275 
    276     ble         epilog                      @jumps to epilog
    277 
    278 kernel_8:
    279 
    280     vmull.u8    q15,d5,d1                   @mul with coeff 1
    281     subs        r5,r5,#8                    @2wd - 8
    282     vmlsl.u8    q15,d4,d0
    283     addle       r0,r0,r9                    @pu1_dst += 4*dst_strd - 2*wd
    284     vmlal.u8    q15,d6,d2
    285     rsble       r11,r2,r2,lsl #3
    286     vmlsl.u8    q15,d7,d3
    287     vst1.8      {q13},[r7],r3               @stores the loaded value
    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      {q12},[r7],r3               @stores the loaded value
    295 
    296     vmlal.u8    q14,d7,d2
    297     vld1.8      {d9},[r6],r2
    298 
    299     vmlsl.u8    q14,d8,d3
    300     vld1.8      {d10},[r6],r2
    301     add         r7,r1,r3                    @pu1_dst
    302     vmull.u8    q13,d7,d1
    303     add         r6,r0,r2                    @pu1_src + src_strd
    304     pld         [r0,r11]
    305 
    306     vmlsl.u8    q13,d6,d0
    307     vld1.8      {d4},[r0]!                  @loads the source
    308 
    309     add         r11,r11,r2
    310     vmlal.u8    q13,d8,d2
    311     vst1.8      {q15},[r1]!                 @stores the loaded value
    312 
    313     vmlsl.u8    q13,d9,d3
    314     vld1.8      {d5},[r6],r2                @loads pu1_src
    315 
    316     vmull.u8    q12,d8,d1
    317     vld1.8      {d6},[r6],r2                @load and increment
    318     addle       r1,r1,r8                    @pu1_src += 4*src_strd - 2*wd
    319 
    320     cmp         r11,r14
    321     rsbgt       r11,r2,r2,lsl #3
    322 
    323     vmlsl.u8    q12,d7,d0
    324     subs        r12,r12,#4
    325 
    326 
    327     vmlal.u8    q12,d9,d2
    328     vld1.8      {d7},[r6],r2                @load and increment
    329 
    330     vmlsl.u8    q12,d10,d3
    331     vst1.8      {q14},[r7],r3               @stores the loaded value
    332 
    333     bgt         kernel_8                    @jumps to kernel_8
    334 
    335 epilog:
    336 
    337     vmull.u8    q15,d5,d1                   @mul with coeff 1
    338     vmlsl.u8    q15,d4,d0
    339     vmlal.u8    q15,d6,d2
    340     vmlsl.u8    q15,d7,d3
    341     vst1.8      {q13},[r7],r3               @stores the loaded value
    342 
    343     vld1.8      {d8},[r6],r2                @load and increment
    344     vmull.u8    q14,d6,d1                   @mul_res 2
    345     vmlsl.u8    q14,d5,d0
    346     vmlal.u8    q14,d7,d2
    347     vmlsl.u8    q14,d8,d3
    348     vst1.8      {q12},[r7],r3               @stores the loaded value
    349 
    350     vld1.8      {d9},[r6],r2
    351     vmull.u8    q13,d7,d1
    352     add         r7,r1,r3                    @pu1_dst
    353     vmlsl.u8    q13,d6,d0
    354     vst1.8      {q15},[r1]!                 @stores the loaded value
    355     vmlal.u8    q13,d8,d2
    356     vld1.8      {d10},[r6],r2
    357     vmlsl.u8    q13,d9,d3
    358 
    359     vmull.u8    q12,d8,d1
    360     vst1.8      {q14},[r7],r3               @stores the loaded value
    361     vmlsl.u8    q12,d7,d0
    362     vmlal.u8    q12,d9,d2
    363     vst1.8      {q13},[r7],r3               @stores the loaded value
    364     vmlsl.u8    q12,d10,d3
    365 
    366     vst1.8      {q12},[r7],r3               @stores the loaded value
    367 
    368 end_loops:
    369     vpop         {d8 - d15}
    370     ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
    371 
    372 
    373 
    374