• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
110ihevc_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
143inner_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
178outer_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
185inner_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
220core_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
232prolog:
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
283kernel_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
347epilog:
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
385end_loops:
386    vpop         {d8 - d15}
387    ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
388
389
390
391