• 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_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.equ    coeff_offset,   104
96.equ    ht_offset,      108
97.equ    wd_offset,      112
98
99
100.text
101.align 4
102
103
104
105
106.globl ihevc_inter_pred_chroma_vert_w16inp_a9q
107
108.type ihevc_inter_pred_chroma_vert_w16inp_a9q, %function
109
110ihevc_inter_pred_chroma_vert_w16inp_a9q:
111
112    stmfd       sp!, {r4-r12, r14}          @stack stores the values of the arguments
113    vpush        {d8 - d15}
114
115    ldr         r4, [sp,#coeff_offset]                @loads pi1_coeff
116    ldr         r6, [sp,#wd_offset]                @wd
117    lsl         r2,r2,#1                    @src_strd = 2* src_strd
118    ldr         r5,[sp,#ht_offset]                 @loads ht
119    vld1.8      {d0},[r4]                   @loads pi1_coeff
120    sub         r4,r0,r2                    @pu1_src - src_strd
121    vmovl.s8    q0,d0                       @long the value
122
123    tst         r6,#3                       @checks wd  == 2
124    vdup.16     d12,d0[0]                   @coeff_0
125    vdup.16     d13,d0[1]                   @coeff_1
126    vdup.16     d14,d0[2]                   @coeff_2
127    vdup.16     d15,d0[3]                   @coeff_3
128
129    bgt         core_loop_ht_2              @jumps to loop handles wd 2
130
131    tst         r5,#3                       @checks ht == mul of 4
132    beq         core_loop_ht_4              @jumps to loop handles ht mul of 4
133
134core_loop_ht_2:
135    lsl         r7,r2,#1                    @2*src_strd
136    lsl         r12,r3,#1                   @2*dst_strd
137    lsl         r9,r6,#2                    @4*wd
138    sub         r6,r12,r6,lsl #1            @2*dst_strd - 2*wd
139    sub         r8,r7,r9                    @2*src_strd - 4*wd
140    mov         r12,r9                      @4wd
141
142inner_loop_ht_2:
143    add         r0,r4,r2                    @increments pi2_src
144    vld1.16     {d0},[r4]!                  @loads pu1_src
145    vmull.s16   q0,d0,d12                   @vmull_s16(src_tmp1, coeff_0)
146    subs        r12,r12,#8                  @2wd + 8
147    vld1.16     {d2},[r0],r2                @loads pi2_src
148    vmull.s16   q4,d2,d12                   @vmull_s16(src_tmp2, coeff_0)
149    vld1.16     {d3},[r0],r2                @loads pi2_src
150    vmlal.s16   q0,d2,d13
151    vld1.16     {d6},[r0],r2
152    vmlal.s16   q4,d3,d13
153    vld1.16     {d2},[r0]
154    add         r7,r1,r3                    @pu1_dst + dst_strd
155    vmlal.s16   q0,d3,d14
156    vmlal.s16   q4,d6,d14
157    vmlal.s16   q0,d6,d15
158    vmlal.s16   q4,d2,d15
159    vqshrn.s32  d0,q0,#6                    @right shift
160    vqshrn.s32  d30,q4,#6                   @right shift
161    vqrshrun.s16 d0,q0,#6                   @rounding shift
162    vqrshrun.s16 d30,q15,#6                 @rounding shift
163    vst1.32     {d0[0]},[r1]!               @stores the loaded value
164    vst1.32     {d30[0]},[r7]               @stores the loaded value
165    bgt         inner_loop_ht_2             @inner loop -again
166
167    @inner loop ends
168    subs        r5,r5,#2                    @increments ht
169    add         r1,r1,r6                    @pu1_dst += 2*dst_strd - 2*wd
170    mov         r12,r9                      @4wd
171    add         r4,r4,r8                    @pi1_src_tmp1 += 2*src_strd - 4*wd
172    bgt         inner_loop_ht_2             @loop again
173
174    b           end_loops                   @jumps to end
175
176core_loop_ht_4:
177    lsl         r7,r2,#2                    @2*src_strd
178    lsl         r12,r3,#2                   @2*dst_strd
179    mov         r11,r6,lsr #1               @divide by 2
180    sub         lr,r12,r6,lsl #1            @2*dst_strd - 2*wd
181    sub         r8,r7,r6,lsl #2             @2*src_strd - 4*wd
182
183    mul         r12,r5,r11                  @multiply height by width
184    sub         r12,#4                      @subtract by one for epilog
185    mov         r11,r6,lsl #1               @2*wd
186
187prolog:
188    add         r0,r4,r2                    @increments pi2_src
189    vld1.16     {d0},[r4]!                  @loads pu1_src
190    vld1.16     {d1},[r0],r2                @loads pi2_src
191    subs        r11,r11,#4
192    vld1.16     {d2},[r0],r2                @loads pi2_src
193    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
194    vld1.16     {d3},[r0],r2
195    vmlal.s16   q15,d1,d13
196    vmlal.s16   q15,d2,d14
197    add         r9,r1,r3                    @pu1_dst + dst_strd
198    vmlal.s16   q15,d3,d15
199
200    vld1.16     {d4},[r0],r2
201    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
202    addle       r4,r4,r8
203    vmlal.s16   q14,d2,d13
204    vld1.s16    {d5},[r0],r2
205    vmlal.s16   q14,d3,d14
206    vld1.s16    {d6},[r0],r2
207    vmlal.s16   q14,d4,d15
208    movle       r11,r6,lsl #1
209
210    vqshrn.s32  d30,q15,#6                  @right shift
211
212    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
213    add         r0,r4,r2
214    vmlal.s16   q13,d3,d13
215    vmlal.s16   q13,d4,d14
216    vld1.16     {d0},[r4]!                  @loads pu1_src
217    vmlal.s16   q13,d5,d15
218
219    vqrshrun.s16 d30,q15,#6                 @rounding shift
220    vqshrn.s32  d28,q14,#6                  @right shift
221
222    vld1.16     {d1},[r0],r2                @loads pi2_src
223    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
224    vst1.32     {d30[0]},[r1]!              @stores the loaded value
225    vmlal.s16   q12,d4,d13
226    vld1.16     {d2},[r0],r2                @loads pi2_src
227    vmlal.s16   q12,d5,d14
228    vld1.16     {d3},[r0],r2
229    vmlal.s16   q12,d6,d15
230    addle       r1,r1,lr
231
232    vqshrn.s32  d26,q13,#6                  @right shift
233    subs        r12,r12,#4
234    vqrshrun.s16 d28,q14,#6                 @rounding shift
235
236    beq         epilog                      @jumps to epilog
237
238kernel_4:
239    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
240    subs        r11,r11,#4
241    vmlal.s16   q15,d1,d13
242    vst1.32     {d28[0]},[r9],r3            @stores the loaded value
243    vmlal.s16   q15,d2,d14
244    vmlal.s16   q15,d3,d15
245
246    vqshrn.s32  d24,q12,#6                  @right shift
247    vqrshrun.s16 d26,q13,#6                 @rounding shift
248
249    vld1.16     {d4},[r0],r2
250    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
251    vmlal.s16   q14,d2,d13
252    vmlal.s16   q14,d3,d14
253    vmlal.s16   q14,d4,d15
254    vst1.32     {d26[0]},[r9],r3            @stores the loaded value
255    addle       r4,r4,r8
256    movle       r11,r6,lsl #1
257
258    vqshrn.s32  d30,q15,#6                  @right shift
259    vqrshrun.s16 d24,q12,#6                 @rounding shift
260
261    vld1.s16    {d5},[r0],r2
262    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
263    vld1.s16    {d6},[r0],r2
264    vmlal.s16   q13,d3,d13
265    vst1.32     {d24[0]},[r9]               @stores the loaded value
266    add         r0,r4,r2
267    vmlal.s16   q13,d4,d14
268    vld1.16     {d0},[r4]!                  @loads pu1_src
269    vmlal.s16   q13,d5,d15
270
271    vqshrn.s32  d28,q14,#6                  @right shift
272    vqrshrun.s16 d30,q15,#6                 @rounding shift
273
274    vld1.16     {d1},[r0],r2                @loads pi2_src
275    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
276    add         r9,r1,r3                    @pu1_dst + dst_strd
277    vld1.16     {d2},[r0],r2                @loads pi2_src
278    vmlal.s16   q12,d4,d13
279    vld1.16     {d3},[r0],r2
280    vmlal.s16   q12,d5,d14
281
282    vst1.32     {d30[0]},[r1]!              @stores the loaded value
283    vmlal.s16   q12,d6,d15
284
285    vqshrn.s32  d26,q13,#6                  @right shift
286    vqrshrun.s16 d28,q14,#6                 @rounding shift
287    addle       r1,r1,lr
288
289    subs        r12,r12,#4
290
291    bgt         kernel_4                    @jumps to kernel_4
292
293epilog:
294    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
295    vst1.32     {d28[0]},[r9],r3            @stores the loaded value
296    vmlal.s16   q15,d1,d13
297    vmlal.s16   q15,d2,d14
298    vmlal.s16   q15,d3,d15
299
300    vqshrn.s32  d24,q12,#6                  @right shift
301    vqrshrun.s16 d26,q13,#6                 @rounding shift
302
303    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
304    vld1.16     {d4},[r0],r2
305    vmlal.s16   q14,d2,d13
306    vst1.32     {d26[0]},[r9],r3            @stores the loaded value
307    vmlal.s16   q14,d3,d14
308    vmlal.s16   q14,d4,d15
309
310    vqshrn.s32  d30,q15,#6                  @right shift
311    vqrshrun.s16 d24,q12,#6                 @rounding shift
312
313    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
314    vld1.s16    {d5},[r0],r2
315    vmlal.s16   q13,d3,d13
316    vmlal.s16   q13,d4,d14
317    vmlal.s16   q13,d5,d15
318
319    vqshrn.s32  d28,q14,#6                  @right shift
320    vqrshrun.s16 d30,q15,#6                 @rounding shift
321
322    vst1.32     {d24[0]},[r9]               @stores the loaded value
323    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
324    vmlal.s16   q12,d4,d13
325    add         r9,r1,r3                    @pu1_dst + dst_strd
326    vld1.s16    {d6},[r0],r2
327    vmlal.s16   q12,d5,d14
328    vmlal.s16   q12,d6,d15
329    vst1.32     {d30[0]},[r1]!              @stores the loaded value
330
331    vqrshrun.s16 d28,q14,#6                 @rounding shift
332    vqshrn.s32  d26,q13,#6                  @right shift
333
334    vst1.32     {d28[0]},[r9],r3            @stores the loaded value
335    vqrshrun.s16 d26,q13,#6                 @rounding shift
336
337    vqshrn.s32  d24,q12,#6                  @right shift
338    vst1.32     {d26[0]},[r9],r3            @stores the loaded value
339    vqrshrun.s16 d24,q12,#6                 @rounding shift
340
341    vst1.32     {d24[0]},[r9]               @stores the loaded value
342
343end_loops:
344    vpop         {d8 - d15}
345    ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
346
347
348
349
350