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_w16inp_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 / parthiban
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 16bit 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'  input is 16 bits  the filter output is downshifted by 12 and
51@*    clipped to lie  between 0 and 255   assumptions : the function is
52@*    optimized considering the fact width and  height are multiple of 2.
53@*
54@* @param[in] pi2_src
55@*  word16 pointer to the source
56@*
57@* @param[out] pu1_dst
58@*  uword8 pointer to the destination
59@*
60@* @param[in] src_strd
61@*  integer source stride
62@*
63@* @param[in] dst_strd
64@*  integer destination stride
65@*
66@* @param[in] pi1_coeff
67@*  word8 pointer to the filter coefficients
68@*
69@* @param[in] ht
70@*  integer height of the array
71@*
72@* @param[in] wd
73@*  integer width of the array
74@*
75@* @returns
76@*
77@* @remarks
78@*  none
79@*
80@*******************************************************************************
81@*/
82@void ihevc_inter_pred_chroma_vert_w16inp(word16 *pi2_src,
83@                                          uword8 *pu1_dst,
84@                                          word32 src_strd,
85@                                          word32 dst_strd,
86@                                          word8 *pi1_coeff,
87@                                          word32 ht,
88@                                          word32 wd)
89@**************variables vs registers*****************************************
90@r0 => *pu1_src
91@r1 => *pi2_dst
92@r2 =>  src_strd
93@r3 =>  dst_strd
94
95.text
96.align 4
97
98
99
100
101.globl ihevc_inter_pred_chroma_vert_w16inp_a9q
102
103.type ihevc_inter_pred_chroma_vert_w16inp_a9q, %function
104
105ihevc_inter_pred_chroma_vert_w16inp_a9q:
106
107    stmfd       sp!, {r4-r12, r14}          @stack stores the values of the arguments
108
109    ldr         r4, [sp,#40]                @loads pi1_coeff
110    ldr         r6, [sp,#48]                @wd
111    lsl         r2,r2,#1                    @src_strd = 2* src_strd
112    ldr         r5,[sp,#44]                 @loads ht
113    vld1.8      {d0},[r4]                   @loads pi1_coeff
114    sub         r4,r0,r2                    @pu1_src - src_strd
115    vmovl.s8    q0,d0                       @long the value
116
117    tst         r6,#3                       @checks wd  == 2
118    vdup.16     d12,d0[0]                   @coeff_0
119    vdup.16     d13,d0[1]                   @coeff_1
120    vdup.16     d14,d0[2]                   @coeff_2
121    vdup.16     d15,d0[3]                   @coeff_3
122
123    bgt         core_loop_ht_2              @jumps to loop handles wd 2
124
125    tst         r5,#3                       @checks ht == mul of 4
126    beq         core_loop_ht_4              @jumps to loop handles ht mul of 4
127
128core_loop_ht_2:
129    lsl         r7,r2,#1                    @2*src_strd
130    lsl         r12,r3,#1                   @2*dst_strd
131    lsl         r9,r6,#2                    @4*wd
132    sub         r6,r12,r6,lsl #1            @2*dst_strd - 2*wd
133    sub         r8,r7,r9                    @2*src_strd - 4*wd
134    mov         r12,r9                      @4wd
135
136inner_loop_ht_2:
137    add         r0,r4,r2                    @increments pi2_src
138    vld1.16     {d0},[r4]!                  @loads pu1_src
139    vmull.s16   q0,d0,d12                   @vmull_s16(src_tmp1, coeff_0)
140    subs        r12,r12,#8                  @2wd + 8
141    vld1.16     {d2},[r0],r2                @loads pi2_src
142    vmull.s16   q4,d2,d12                   @vmull_s16(src_tmp2, coeff_0)
143    vld1.16     {d3},[r0],r2                @loads pi2_src
144    vmlal.s16   q0,d2,d13
145    vld1.16     {d6},[r0],r2
146    vmlal.s16   q4,d3,d13
147    vld1.16     {d2},[r0]
148    add         r7,r1,r3                    @pu1_dst + dst_strd
149    vmlal.s16   q0,d3,d14
150    vmlal.s16   q4,d6,d14
151    vmlal.s16   q0,d6,d15
152    vmlal.s16   q4,d2,d15
153    vqshrn.s32  d0,q0,#6                    @right shift
154    vqshrn.s32  d30,q4,#6                   @right shift
155    vqrshrun.s16 d0,q0,#6                   @rounding shift
156    vqrshrun.s16 d30,q15,#6                 @rounding shift
157    vst1.32     {d0[0]},[r1]!               @stores the loaded value
158    vst1.32     {d30[0]},[r7]               @stores the loaded value
159    bgt         inner_loop_ht_2             @inner loop -again
160
161    @inner loop ends
162    subs        r5,r5,#2                    @increments ht
163    add         r1,r1,r6                    @pu1_dst += 2*dst_strd - 2*wd
164    mov         r12,r9                      @4wd
165    add         r4,r4,r8                    @pi1_src_tmp1 += 2*src_strd - 4*wd
166    bgt         inner_loop_ht_2             @loop again
167
168    b           end_loops                   @jumps to end
169
170core_loop_ht_4:
171    lsl         r7,r2,#2                    @2*src_strd
172    lsl         r12,r3,#2                   @2*dst_strd
173    mov         r11,r6,lsr #1               @divide by 2
174    sub         lr,r12,r6,lsl #1            @2*dst_strd - 2*wd
175    sub         r8,r7,r6,lsl #2             @2*src_strd - 4*wd
176
177    mul         r12,r5,r11                  @multiply height by width
178    sub         r12,#4                      @subtract by one for epilog
179    mov         r11,r6,lsl #1               @2*wd
180
181prolog:
182    add         r0,r4,r2                    @increments pi2_src
183    vld1.16     {d0},[r4]!                  @loads pu1_src
184    vld1.16     {d1},[r0],r2                @loads pi2_src
185    subs        r11,r11,#4
186    vld1.16     {d2},[r0],r2                @loads pi2_src
187    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
188    vld1.16     {d3},[r0],r2
189    vmlal.s16   q15,d1,d13
190    vmlal.s16   q15,d2,d14
191    add         r9,r1,r3                    @pu1_dst + dst_strd
192    vmlal.s16   q15,d3,d15
193
194    vld1.16     {d4},[r0],r2
195    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
196    addle       r4,r4,r8
197    vmlal.s16   q14,d2,d13
198    vld1.s16    {d5},[r0],r2
199    vmlal.s16   q14,d3,d14
200    vld1.s16    {d6},[r0],r2
201    vmlal.s16   q14,d4,d15
202    movle       r11,r6,lsl #1
203
204    vqshrn.s32  d30,q15,#6                  @right shift
205
206    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
207    add         r0,r4,r2
208    vmlal.s16   q13,d3,d13
209    vmlal.s16   q13,d4,d14
210    vld1.16     {d0},[r4]!                  @loads pu1_src
211    vmlal.s16   q13,d5,d15
212
213    vqrshrun.s16 d30,q15,#6                 @rounding shift
214    vqshrn.s32  d28,q14,#6                  @right shift
215
216    vld1.16     {d1},[r0],r2                @loads pi2_src
217    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
218    vst1.32     {d30[0]},[r1]!              @stores the loaded value
219    vmlal.s16   q12,d4,d13
220    vld1.16     {d2},[r0],r2                @loads pi2_src
221    vmlal.s16   q12,d5,d14
222    vld1.16     {d3},[r0],r2
223    vmlal.s16   q12,d6,d15
224    addle       r1,r1,lr
225
226    vqshrn.s32  d26,q13,#6                  @right shift
227    subs        r12,r12,#4
228    vqrshrun.s16 d28,q14,#6                 @rounding shift
229
230    beq         epilog                      @jumps to epilog
231
232kernel_4:
233    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
234    subs        r11,r11,#4
235    vmlal.s16   q15,d1,d13
236    vst1.32     {d28[0]},[r9],r3            @stores the loaded value
237    vmlal.s16   q15,d2,d14
238    vmlal.s16   q15,d3,d15
239
240    vqshrn.s32  d24,q12,#6                  @right shift
241    vqrshrun.s16 d26,q13,#6                 @rounding shift
242
243    vld1.16     {d4},[r0],r2
244    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
245    vmlal.s16   q14,d2,d13
246    vmlal.s16   q14,d3,d14
247    vmlal.s16   q14,d4,d15
248    vst1.32     {d26[0]},[r9],r3            @stores the loaded value
249    addle       r4,r4,r8
250    movle       r11,r6,lsl #1
251
252    vqshrn.s32  d30,q15,#6                  @right shift
253    vqrshrun.s16 d24,q12,#6                 @rounding shift
254
255    vld1.s16    {d5},[r0],r2
256    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
257    vld1.s16    {d6},[r0],r2
258    vmlal.s16   q13,d3,d13
259    vst1.32     {d24[0]},[r9]               @stores the loaded value
260    add         r0,r4,r2
261    vmlal.s16   q13,d4,d14
262    vld1.16     {d0},[r4]!                  @loads pu1_src
263    vmlal.s16   q13,d5,d15
264
265    vqshrn.s32  d28,q14,#6                  @right shift
266    vqrshrun.s16 d30,q15,#6                 @rounding shift
267
268    vld1.16     {d1},[r0],r2                @loads pi2_src
269    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
270    add         r9,r1,r3                    @pu1_dst + dst_strd
271    vld1.16     {d2},[r0],r2                @loads pi2_src
272    vmlal.s16   q12,d4,d13
273    vld1.16     {d3},[r0],r2
274    vmlal.s16   q12,d5,d14
275
276    vst1.32     {d30[0]},[r1]!              @stores the loaded value
277    vmlal.s16   q12,d6,d15
278
279    vqshrn.s32  d26,q13,#6                  @right shift
280    vqrshrun.s16 d28,q14,#6                 @rounding shift
281    addle       r1,r1,lr
282
283    subs        r12,r12,#4
284
285    bgt         kernel_4                    @jumps to kernel_4
286
287epilog:
288    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
289    vst1.32     {d28[0]},[r9],r3            @stores the loaded value
290    vmlal.s16   q15,d1,d13
291    vmlal.s16   q15,d2,d14
292    vmlal.s16   q15,d3,d15
293
294    vqshrn.s32  d24,q12,#6                  @right shift
295    vqrshrun.s16 d26,q13,#6                 @rounding shift
296
297    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
298    vld1.16     {d4},[r0],r2
299    vmlal.s16   q14,d2,d13
300    vst1.32     {d26[0]},[r9],r3            @stores the loaded value
301    vmlal.s16   q14,d3,d14
302    vmlal.s16   q14,d4,d15
303
304    vqshrn.s32  d30,q15,#6                  @right shift
305    vqrshrun.s16 d24,q12,#6                 @rounding shift
306
307    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
308    vld1.s16    {d5},[r0],r2
309    vmlal.s16   q13,d3,d13
310    vmlal.s16   q13,d4,d14
311    vmlal.s16   q13,d5,d15
312
313    vqshrn.s32  d28,q14,#6                  @right shift
314    vqrshrun.s16 d30,q15,#6                 @rounding shift
315
316    vst1.32     {d24[0]},[r9]               @stores the loaded value
317    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
318    vmlal.s16   q12,d4,d13
319    add         r9,r1,r3                    @pu1_dst + dst_strd
320    vld1.s16    {d6},[r0],r2
321    vmlal.s16   q12,d5,d14
322    vmlal.s16   q12,d6,d15
323    vst1.32     {d30[0]},[r1]!              @stores the loaded value
324
325    vqrshrun.s16 d28,q14,#6                 @rounding shift
326    vqshrn.s32  d26,q13,#6                  @right shift
327
328    vst1.32     {d28[0]},[r9],r3            @stores the loaded value
329    vqrshrun.s16 d26,q13,#6                 @rounding shift
330
331    vqshrn.s32  d24,q12,#6                  @right shift
332    vst1.32     {d26[0]},[r9],r3            @stores the loaded value
333    vqrshrun.s16 d24,q12,#6                 @rounding shift
334
335    vst1.32     {d24[0]},[r9]               @stores the loaded value
336
337end_loops:
338    ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
339
340
341
342
343