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_sao_edge_offset_class1_chroma.s
     22 @*
     23 @* ,:brief
     24 @*  Contains function definitions for inter prediction  interpolation.
     25 @* Functions are coded using NEON  intrinsics and can be compiled using@ ARM
     26 @* RVCT
     27 @*
     28 @* ,:author
     29 @*  Parthiban V
     30 @*
     31 @* ,:par List of Functions:
     32 @*
     33 @*
     34 @* ,:remarks
     35 @*  None
     36 @*
     37 @*******************************************************************************
     38 @*/
     39 @void ihevc_sao_edge_offset_class1_chroma(UWORD8 *pu1_src,
     40 @                              WORD32 src_strd,
     41 @                              UWORD8 *pu1_src_left,
     42 @                              UWORD8 *pu1_src_top,
     43 @                              UWORD8 *pu1_src_top_left,
     44 @                              UWORD8 *pu1_src_top_right,
     45 @                              UWORD8 *pu1_src_bot_left,
     46 @                              UWORD8 *pu1_avail,
     47 @                              WORD8 *pi1_sao_offset_u,
     48 @                              WORD8 *pi1_sao_offset_v,
     49 @                              WORD32 wd,
     50 @                              WORD32 ht)
     51 @**************Variables Vs Registers*****************************************
     52 @r0 =>  *pu1_src
     53 @r1 =>  src_strd
     54 @r2 =>  *pu1_src_left
     55 @r3 =>  *pu1_src_top
     56 @r4 =>  *pu1_src_top_left
     57 @r5 =>  *pu1_avail
     58 @r6 =>  *pi1_sao_offset_u
     59 @r7 =>  *pi1_sao_offset_v
     60 @r8 =>  wd
     61 @r9 =>  ht
     62 
     63 .equ    pu1_src_top_left_offset,    104
     64 .equ    pu1_src_top_right_offset,   108
     65 .equ    pu1_src_bot_left_offset,    112
     66 .equ    pu1_avail_offset,           116
     67 .equ    pi1_sao_u_offset,           120
     68 .equ    pi1_sao_v_offset,           124
     69 .equ    wd_offset,                  128
     70 .equ    ht_offset,                  132
     71 
     72 .text
     73 .p2align 2
     74 
     75 .extern gi1_table_edge_idx
     76 .globl ihevc_sao_edge_offset_class1_chroma_a9q
     77 
     78 gi1_table_edge_idx_addr:
     79 .long gi1_table_edge_idx - ulbl1 - 8
     80 
     81 ihevc_sao_edge_offset_class1_chroma_a9q:
     82 
     83 
     84     STMFD       sp!, {r4-r12, r14}          @stack stores the values of the arguments
     85     vpush       {d8  -  d15}
     86     LDR         r4,[sp,#pu1_src_top_left_offset]    @Loads pu1_src_top_left
     87     LDR         r5,[sp,#pu1_avail_offset]   @Loads pu1_avail
     88     LDR         r6,[sp,#pi1_sao_u_offset]   @Loads pi1_sao_offset_u
     89     LDR         r7,[sp,#pi1_sao_v_offset]   @Loads pi1_sao_offset_v
     90     LDR         r8,[sp,#wd_offset]          @Loads wd
     91     LDR         r9,[sp,#ht_offset]          @Loads ht
     92 
     93     SUB         r10,r8,#2                   @wd - 2
     94     LDRH        r11,[r3,r10]                @pu1_src_top[wd - 2]
     95     STRH        r11,[r4]                    @*pu1_src_top_left = pu1_src_top[wd - 2]
     96     ADD         r11,r0,r10                  @pu1_src[row * src_strd + wd - 2]
     97     MOV         r12,r2                      @Move pu1_src_left pointer to r11
     98     MOV         r14,r9                      @Move ht to r14 for loop count
     99 SRC_LEFT_LOOP:
    100     LDRH        r10,[r11],r1                @Load pu1_src[row * src_strd + wd - 2]
    101     STRH        r10,[r12],#2                @pu1_src_left[row]
    102     SUBS        r14,#1                      @Decrement the loop count
    103     BNE         SRC_LEFT_LOOP               @If not equal to 0 jump to the src_left_loop
    104 
    105     SUB         r12,r9,#1                   @ht - 1
    106     MUL         r12,r12,r1                  @(ht - 1) * src_strd
    107     ADD         r12,r12,r0                  @pu1_src[(ht - 1) * src_strd]
    108 
    109     LDRB        r4,[r5,#2]                  @pu1_avail[2]
    110     CMP         r4,#0                       @0 == pu1_avail[2]
    111     ADDEQ       r0,r0,r1                    @pu1_src += src_strd
    112     SUBEQ       r9,r9,#1                    @ht--
    113 
    114     LDRB        r4,[r5,#3]                  @pu1_avail[3]
    115     CMP         r4,#0                       @0 == pu1_avail[3]
    116     SUBEQ       r9,r9,#1                    @ht--
    117 
    118     VMOV.I8     Q0,#2                       @const_2 = vdupq_n_s8(2)
    119     VMOV.I16    Q1,#0                       @const_min_clip = vdupq_n_s16(0)
    120     VMOV.I16    Q2,#255                     @const_max_clip = vdupq_n_u16((1 << bit_depth) - 1)
    121     LDR         r14, gi1_table_edge_idx_addr @table pointer
    122 ulbl1:
    123     add         r14,r14,pc
    124     VLD1.8      D6,[r14]                    @edge_idx_tbl = vld1_s8(gi1_table_edge_idx)
    125     VLD1.8      D7,[r6]                     @offset_tbl_u = vld1_s8(pi1_sao_offset_u)
    126     VLD1.8      D8,[r7]                     @offset_tbl_v = vld1_s8(pi1_sao_offset_v)
    127 
    128     CMP         r8,#16                      @Compare wd with 16
    129     BLT         WIDTH_RESIDUE               @If not jump to WIDTH_RESIDUE where loop is unrolled for 8 case
    130 
    131 WIDTH_LOOP_16:
    132     LDRB        r4,[r5,#2]                  @pu1_avail[2]
    133     CMP         r4,#0                       @0 == pu1_avail[2]
    134     SUBEQ       r11,r0,r1                   @pu1_src -= src_strd
    135     MOVNE       r11,r3                      @*pu1_src_top
    136 
    137     MOV         r10,r0                      @*pu1_src
    138 
    139     VLD1.8      D28,[r11]!                  @pu1_top_row = vld1q_u8(pu1_src_top_cpy || pu1_src - src_strd)
    140     VLD1.8      D29,[r11]!                  @pu1_top_row = vld1q_u8(pu1_src_top_cpy || pu1_src - src_strd)
    141     VLD1.8      D10,[r0]!                   @pu1_cur_row = vld1q_u8(pu1_src)
    142     VLD1.8      D11,[r0]!                   @pu1_cur_row = vld1q_u8(pu1_src)
    143 
    144     VLD1.8      D30,[r12]!                  @vld1q_u8(pu1_src[(ht - 1) * src_strd])
    145     VLD1.8      D31,[r12]!                  @vld1q_u8(pu1_src[(ht - 1) * src_strd])
    146     VCGT.U8     Q6,Q5,Q14                   @vcgtq_u8(pu1_cur_row, pu1_top_row)
    147 
    148     VST1.8      {Q15},[r3]!                 @vst1q_u8(pu1_src_top[col])
    149     VCLT.U8     Q7,Q5,Q14                   @vcltq_u8(pu1_cur_row, pu1_top_row)
    150 
    151     VSUB.U8     Q8,Q7,Q6                    @sign_up = vreinterpretq_s8_u8(vsubq_u8(cmp_lt, cmp_gt))
    152     MOV         r11,r9                      @move ht to r11 for loop count
    153 
    154 PU1_SRC_LOOP:
    155     ADD         r10,r10,r1                  @*pu1_src + src_strd
    156     VLD1.8      D18,[r10]!                  @pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    157     VLD1.8      D19,[r10]                   @pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    158     SUB         r10,#8
    159     ADD         r6,r10,r1                   @II Iteration *pu1_src + src_strd
    160 
    161     VCGT.U8     Q6,Q5,Q9                    @vcgtq_u8(pu1_cur_row, pu1_top_row)
    162     VLD1.8      D30,[r6]!                   @II pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    163     VLD1.8      D31,[r6]                    @II pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    164     SUB         r6,#8
    165 
    166     VCLT.U8     Q7,Q5,Q9                    @vcltq_u8(pu1_cur_row, pu1_top_row)
    167     SUB         r10,r10,r1
    168 
    169     VSUB.U8     Q10,Q7,Q6                   @sign_down = vreinterpretq_s8_u8(vsubq_u8(cmp_lt, cmp_gt))
    170     VMOVL.U8    Q13,D18                     @II pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(pu1_cur_row)))
    171 
    172     VADD.I8     Q6,Q0,Q8                    @edge_idx = vaddq_s8(const_2, sign_up)
    173     VMOVL.U8    Q14,D19                     @II pi2_tmp_cur_row.val[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(pu1_cur_row)))
    174 
    175     VADD.I8     Q6,Q6,Q10                   @edge_idx = vaddq_s8(edge_idx, sign_down)
    176     VCGT.U8     Q11,Q9,Q15                  @II vcgtq_u8(pu1_cur_row, pu1_top_row)
    177 
    178     VNEG.S8     Q8,Q10                      @sign_up = vnegq_s8(sign_down)
    179     VTBL.8      D12,{D6},D12                @vtbl1_s8(edge_idx_tbl, vget_low_s8(edge_idx))
    180     VCLT.U8     Q12,Q9,Q15                  @II vcltq_u8(pu1_cur_row, pu1_top_row)
    181 
    182     VSUB.U8     Q14,Q12,Q11                 @II sign_down = vreinterpretq_s8_u8(vsubq_u8(cmp_lt, cmp_gt))
    183     VTBL.8      D13,{D6},D13                @vtbl1_s8(edge_idx_tbl, vget_high_s8(edge_idx))
    184     VADD.I8     Q11,Q0,Q8                   @II edge_idx = vaddq_s8(const_2, sign_up)
    185 
    186 
    187     VUZP.8      D12,D13
    188     VNEG.S8     Q8,Q14                      @II sign_up = vnegq_s8(sign_down)
    189     VTBL.8      D12,{D7},D12                @offset = vtbl1_s8(offset_tbl, vget_low_s8(edge_idx))
    190     VADD.I8     Q11,Q11,Q14                 @II edge_idx = vaddq_s8(edge_idx, sign_down)
    191 
    192     VMOVL.U8    Q10,D10                     @pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(pu1_cur_row)))
    193     VTBL.8      D13,{D8},D13
    194     VZIP.8      D12,D13
    195 
    196     VADDW.S8    Q10,Q10,D12                 @pi2_tmp_cur_row.val[0] = vaddw_s8(pi2_tmp_cur_row.val[0], offset)
    197     VTBL.8      D22,{D6},D22                @II vtbl1_s8(edge_idx_tbl, vget_low_s8(edge_idx))
    198     VMAX.S16    Q10,Q10,Q1                  @pi2_tmp_cur_row.val[0] = vmaxq_s16(pi2_tmp_cur_row.val[0], const_min_clip)
    199 
    200     VMIN.U16    Q10,Q10,Q2                  @pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[0]), const_max_clip))
    201     VTBL.8      D23,{D6},D23                @II vtbl1_s8(edge_idx_tbl, vget_high_s8(edge_idx))
    202     VUZP.8      D22,D23
    203 
    204     VMOVL.U8    Q14,D11                     @pi2_tmp_cur_row.val[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(pu1_cur_row)))
    205     @VTBL.8     D13,D7,D13                  @offset = vtbl1_s8(offset_tbl, vget_high_s8(edge_idx))
    206     VMOV        Q5,Q15                      @II pu1_cur_row = pu1_next_row
    207 
    208     VADDW.S8    Q14,Q14,D13                 @pi2_tmp_cur_row.val[1] = vaddw_s8(pi2_tmp_cur_row.val[1], offset)
    209     VTBL.8      D24,{D7},D22                @offset = vtbl1_s8(offset_tbl, vget_low_s8(edge_idx))
    210     VMAX.S16    Q14,Q14,Q1                  @pi2_tmp_cur_row.val[1] = vmaxq_s16(pi2_tmp_cur_row.val[1], const_min_clip)
    211 
    212     VTBL.8      D25,{D8},D23
    213     VZIP.8      D24,D25
    214     @VTBL.8     D24,D7,D22                  @II offset = vtbl1_s8(offset_tbl, vget_low_s8(edge_idx))
    215     VMIN.U16    Q14,Q14,Q2                  @pi2_tmp_cur_row.val[1] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[1]), const_max_clip))
    216     @VTBL.8     D25,D7,D23                  @II offset = vtbl1_s8(offset_tbl, vget_high_s8(edge_idx))
    217 
    218     VMOVN.I16   D20,Q10                     @vmovn_s16(pi2_tmp_cur_row.val[0])
    219     VADDW.S8    Q13,Q13,D24                 @II pi2_tmp_cur_row.val[0] = vaddw_s8(pi2_tmp_cur_row.val[0], offset)
    220 
    221     VMOVN.I16   D21,Q14                     @vmovn_s16(pi2_tmp_cur_row.val[1])
    222 
    223     VMOVL.U8    Q14,D19                     @II pi2_tmp_cur_row.val[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(pu1_cur_row)))
    224     VADDW.S8    Q14,Q14,D25                 @II pi2_tmp_cur_row.val[1] = vaddw_s8(pi2_tmp_cur_row.val[1], offset)
    225 
    226 
    227     VMAX.S16    Q13,Q13,Q1                  @II pi2_tmp_cur_row.val[0] = vmaxq_s16(pi2_tmp_cur_row.val[0], const_min_clip)
    228     VMIN.U16    Q13,Q13,Q2                  @II pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[0]), const_max_clip))
    229 
    230     VMAX.S16    Q14,Q14,Q1                  @II pi2_tmp_cur_row.val[1] = vmaxq_s16(pi2_tmp_cur_row.val[1], const_min_clip)
    231     VMIN.U16    Q14,Q14,Q2                  @II pi2_tmp_cur_row.val[1] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[1]), const_max_clip))
    232     VST1.8      {Q10},[r10],r1              @vst1q_u8(pu1_src_cpy, pu1_cur_row)
    233 
    234     VMOVN.I16   D30,Q13                     @II vmovn_s16(pi2_tmp_cur_row.val[0])
    235     SUBS        r11,r11,#2                  @II Decrement the ht loop count by 1
    236     VMOVN.I16   D31,Q14                     @II vmovn_s16(pi2_tmp_cur_row.val[1])
    237 
    238     VST1.8      {Q15},[r10],r1              @II vst1q_u8(pu1_src_cpy, pu1_cur_row)
    239 
    240     BEQ         PU1_SRC_LOOP_END            @if 0 == pu1_avail[3] || 0 == pu1_avail[2] ht = ht--
    241     CMP         r11,#1                      @checking any residue remains
    242     BGT         PU1_SRC_LOOP                @If not equal jump to PU1_SRC_LOOP
    243 
    244     ADD         r10,r10,r1                  @*pu1_src + src_strd
    245     VLD1.8      D18,[r10]!                  @pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    246     VLD1.8      D19,[r10]                   @pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    247     SUB         r10,#8
    248     VCGT.U8     Q6,Q5,Q9                    @vcgtq_u8(pu1_cur_row, pu1_top_row)
    249     VCLT.U8     Q7,Q5,Q9                    @vcltq_u8(pu1_cur_row, pu1_top_row)
    250     VSUB.U8     Q10,Q7,Q6                   @sign_down = vreinterpretq_s8_u8(vsubq_u8(cmp_lt, cmp_gt))
    251     SUB         r10,r10,r1
    252 
    253     VADD.I8     Q11,Q0,Q8                   @edge_idx = vaddq_s8(const_2, sign_up)
    254     VADD.I8     Q11,Q11,Q10                 @edge_idx = vaddq_s8(edge_idx, sign_down)
    255     VTBL.8      D22,{D6},D22                @vtbl1_s8(edge_idx_tbl, vget_low_s8(edge_idx))
    256     VTBL.8      D23,{D6},D23                @vtbl1_s8(edge_idx_tbl, vget_high_s8(edge_idx))
    257 
    258     VUZP.8      D22,D23
    259     VTBL.8      D24,{D7},D22
    260     VTBL.8      D25,{D8},D23
    261     VZIP.8      D24,D25
    262 
    263     @VTBL.8     D24,D7,D22                  @offset = vtbl1_s8(offset_tbl, vget_low_s8(edge_idx))
    264     VMOVL.U8    Q13,D10                     @pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(pu1_cur_row)))
    265     VADDW.S8    Q13,Q13,D24                 @pi2_tmp_cur_row.val[0] = vaddw_s8(pi2_tmp_cur_row.val[0], offset)
    266     VMAX.S16    Q13,Q13,Q1                  @pi2_tmp_cur_row.val[0] = vmaxq_s16(pi2_tmp_cur_row.val[0], const_min_clip)
    267     VMIN.U16    Q13,Q13,Q2                  @pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[0]), const_max_clip))
    268 
    269     @VTBL.8     D25,D7,D23                  @offset = vtbl1_s8(offset_tbl, vget_high_s8(edge_idx))
    270     VMOVL.U8    Q14,D11                     @pi2_tmp_cur_row.val[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(pu1_cur_row)))
    271     VADDW.S8    Q14,Q14,D25                 @pi2_tmp_cur_row.val[1] = vaddw_s8(pi2_tmp_cur_row.val[1], offset)
    272     VMAX.S16    Q14,Q14,Q1                  @pi2_tmp_cur_row.val[1] = vmaxq_s16(pi2_tmp_cur_row.val[1], const_min_clip)
    273     VMIN.U16    Q14,Q14,Q2                  @pi2_tmp_cur_row.val[1] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[1]), const_max_clip))
    274 
    275     VMOVN.I16   D30,Q13                     @vmovn_s16(pi2_tmp_cur_row.val[0])
    276     VMOVN.I16   D31,Q14                     @vmovn_s16(pi2_tmp_cur_row.val[1])
    277 
    278     VST1.8      {Q15},[r10],r1              @vst1q_u8(pu1_src_cpy, pu1_cur_row)
    279 
    280 PU1_SRC_LOOP_END:
    281     VMOV        Q5,Q9                       @pu1_cur_row = pu1_next_row
    282     SUBS        r8,r8,#16                   @Decrement the wd loop count by 16
    283     CMP         r8,#8                       @Check whether residue remains
    284     BEQ         WIDTH_RESIDUE               @If residue remains jump to residue loop
    285     BGT         WIDTH_LOOP_16               @If not equal jump to width_loop
    286     BLT         END_LOOPS                   @Jump to end function
    287 
    288 
    289 WIDTH_RESIDUE:
    290     LDRB        r4,[r5,#2]                  @pu1_avail[2]
    291     CMP         r4,#0                       @0 == pu1_avail[2]
    292     SUBEQ       r11,r0,r1                   @pu1_src -= src_strd
    293     MOVNE       r11,r3                      @*pu1_src_top
    294     MOV         r10,r0
    295 
    296     VLD1.8      D28,[r11]!                  @pu1_top_row = vld1q_u8(pu1_src_top_cpy || pu1_src - src_strd)
    297     VLD1.8      D29,[r11]!                  @pu1_top_row = vld1q_u8(pu1_src_top_cpy || pu1_src - src_strd)
    298     VLD1.8      D10,[r0]!                   @pu1_cur_row = vld1q_u8(pu1_src)
    299     VLD1.8      D11,[r0]!                   @pu1_cur_row = vld1q_u8(pu1_src)
    300 
    301     VLD1.8      D30,[r12]                   @vld1_u8(pu1_src[(ht - 1) * src_strd])
    302     VST1.8      {D30},[r3]                  @vst1_u8(pu1_src_top[col])
    303 
    304     VCGT.U8     Q6,Q5,Q14                   @vcgtq_u8(pu1_cur_row, pu1_top_row)
    305     VCLT.U8     Q7,Q5,Q14                   @vcltq_u8(pu1_cur_row, pu1_top_row)
    306     VSUB.U8     Q8,Q7,Q6                    @sign_up = vreinterpretq_s8_u8(vsubq_u8(cmp_lt, cmp_gt))
    307     MOV         r11,r9                      @move ht to r11 for loop count
    308 
    309 PU1_SRC_LOOP_RESIDUE:
    310     ADD         r10,r10,r1                  @*pu1_src + src_strd
    311     VLD1.8      D18,[r10]!                  @pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    312     VLD1.8      D19,[r10]                   @pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    313     SUB         r10,#8
    314     ADD         r6,r10,r1                   @II Iteration *pu1_src + src_strd
    315 
    316     VCGT.U8     Q6,Q5,Q9                    @vcgtq_u8(pu1_cur_row, pu1_next_row)
    317     VLD1.8      D30,[r6]!                   @II pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    318     VLD1.8      D31,[r6]                    @II pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    319     SUB         r6,#8
    320 
    321     VCLT.U8     Q7,Q5,Q9                    @vcltq_u8(pu1_cur_row, pu1_next_row)
    322     SUB         r10,r10,r1
    323 
    324     VSUB.U8     Q10,Q7,Q6                   @sign_down = vreinterpretq_s8_u8(vsubq_u8(cmp_lt, cmp_gt))
    325     VMOVL.U8    Q13,D18                     @II pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(pu1_cur_row)))
    326 
    327     VADD.I8     Q6,Q0,Q8                    @edge_idx = vaddq_s8(const_2, sign_up)
    328     VCGT.U8     Q11,Q9,Q15                  @II vcgtq_u8(pu1_cur_row, pu1_next_row)
    329 
    330     VADD.I8     Q6,Q6,Q10                   @edge_idx = vaddq_s8(edge_idx, sign_down)
    331     VCLT.U8     Q12,Q9,Q15                  @II vcltq_u8(pu1_cur_row, pu1_next_row)
    332 
    333     VNEG.S8     Q8,Q10                      @sign_up = vnegq_s8(sign_down)
    334     VTBL.8      D12,{D6},D12                @vtbl1_s8(edge_idx_tbl, vget_low_s8(edge_idx))
    335     VSUB.U8     Q10,Q12,Q11                 @II sign_down = vreinterpretq_s8_u8(vsubq_u8(cmp_lt, cmp_gt))
    336 
    337     VUZP.8      D12,D13
    338 
    339     VADD.I8     Q11,Q0,Q8                   @II edge_idx = vaddq_s8(const_2, sign_up)
    340     VTBL.8      D12,{D7},D12
    341     VNEG.S8     Q8,Q10                      @II sign_up = vnegq_s8(sign_down)
    342 
    343     VTBL.8      D13,{D8},D13
    344     VZIP.8      D12,D13
    345 
    346     @VTBL.8     D12,D7,D12                  @offset = vtbl1_s8(offset_tbl, vget_low_s8(edge_idx))
    347 
    348     VADD.I8     Q11,Q11,Q10                 @II edge_idx = vaddq_s8(edge_idx, sign_down)
    349     VMOVL.U8    Q10,D10                     @pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(pu1_cur_row)))
    350 
    351     VADDW.S8    Q10,Q10,D12                 @pi2_tmp_cur_row.val[0] = vaddw_s8(pi2_tmp_cur_row.val[0], offset)
    352     VTBL.8      D22,{D6},D22                @II vtbl1_s8(edge_idx_tbl, vget_low_s8(edge_idx))
    353     VMAX.S16    Q10,Q10,Q1                  @pi2_tmp_cur_row.val[0] = vmaxq_s16(pi2_tmp_cur_row.val[0], const_min_clip)
    354 
    355     VUZP.8      D22,D23
    356 
    357     VMIN.U16    Q10,Q10,Q2                  @pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[0]), const_max_clip))
    358     VTBL.8      D24,{D7},D22
    359     VMOVN.I16   D20,Q10                     @vmovn_s16(pi2_tmp_cur_row.val[0])
    360 
    361     VTBL.8      D25,{D8},D23
    362     VZIP.8      D24,D25
    363     @VTBL.8     D24,D7,D22                  @II offset = vtbl1_s8(offset_tbl, vget_low_s8(edge_idx))
    364 
    365     VADDW.S8    Q13,Q13,D24                 @II pi2_tmp_cur_row.val[0] = vaddw_s8(pi2_tmp_cur_row.val[0], offset)
    366     VMAX.S16    Q13,Q13,Q1                  @II pi2_tmp_cur_row.val[0] = vmaxq_s16(pi2_tmp_cur_row.val[0], const_min_clip)
    367     VMIN.U16    Q13,Q13,Q2                  @II pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[0]), const_max_clip))
    368 
    369     VMOV        Q5,Q15                      @II pu1_cur_row = pu1_next_row
    370     VST1.8      {D20},[r10],r1              @vst1q_u8(pu1_src_cpy, pu1_cur_row)
    371     VMOVN.I16   D30,Q13                     @II vmovn_s16(pi2_tmp_cur_row.val[0])
    372 
    373     SUBS        r11,r11,#2                  @Decrement the ht loop count by 1
    374     VST1.8      {D30},[r10],r1              @II vst1q_u8(pu1_src_cpy, pu1_cur_row)
    375 
    376     BEQ         END_LOOPS
    377     CMP         r11,#1
    378     BGT         PU1_SRC_LOOP_RESIDUE        @If not equal jump to PU1_SRC_LOOP
    379 
    380 
    381     ADD         r10,r10,r1                  @*pu1_src + src_strd
    382     VLD1.8      D18,[r10]!                  @pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    383     VLD1.8      D19,[r10]                   @pu1_next_row = vld1q_u8(pu1_src_cpy + src_strd)
    384     SUB         r10,#8
    385     VCGT.U8     Q6,Q5,Q9                    @vcgtq_u8(pu1_cur_row, pu1_next_row)
    386     VCGT.U8     Q7,Q9,Q5                    @vcltq_u8(pu1_cur_row, pu1_next_row)
    387     VSUB.U8     Q10,Q7,Q6                   @sign_down = vreinterpretq_s8_u8(vsubq_u8(cmp_lt, cmp_gt))
    388     SUB         r10,r10,r1
    389 
    390     VADD.I8     Q11,Q0,Q8                   @edge_idx = vaddq_s8(const_2, sign_up)
    391     VADD.I8     Q11,Q11,Q10                 @edge_idx = vaddq_s8(edge_idx, sign_down)
    392     VTBL.8      D22,{D6},D22                @vtbl1_s8(edge_idx_tbl, vget_low_s8(edge_idx))
    393 
    394     VUZP.8      D22,D23
    395     VTBL.8      D24,{D7},D22
    396     VTBL.8      D25,{D8},D23
    397     VZIP.8      D24,D25
    398 
    399     @VTBL.8     D24,D7,D22                  @offset = vtbl1_s8(offset_tbl, vget_low_s8(edge_idx))
    400     VMOVL.U8    Q13,D10                     @pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(pu1_cur_row)))
    401     VADDW.S8    Q13,Q13,D24                 @pi2_tmp_cur_row.val[0] = vaddw_s8(pi2_tmp_cur_row.val[0], offset)
    402     VMAX.S16    Q13,Q13,Q1                  @pi2_tmp_cur_row.val[0] = vmaxq_s16(pi2_tmp_cur_row.val[0], const_min_clip)
    403     VMIN.U16    Q13,Q13,Q2                  @pi2_tmp_cur_row.val[0] = vreinterpretq_s16_u16(vminq_u16(vreinterpretq_u16_s16(pi2_tmp_cur_row.val[0]), const_max_clip))
    404 
    405     VMOVN.I16   D30,Q13                     @vmovn_s16(pi2_tmp_cur_row.val[0])
    406 
    407     VST1.8      {D30},[r10],r1              @vst1q_u8(pu1_src_cpy, pu1_cur_row)
    408 
    409 END_LOOPS:
    410     vpop        {d8  -  d15}
    411     LDMFD       sp!,{r4-r12,r15}            @Reload the registers from SP
    412 
    413 
    414 
    415 
    416 
    417 
    418