• 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_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 / 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 and output.
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 6 and
51@*    8192 is  subtracted to store it as a 16 bit number  the output is used as
52@*    a input to weighted prediction   assumptions : the function is optimized
53@*    considering the fact width and  height are multiple of 2.
54@*
55@* @param[in] pi2_src
56@*  word16 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_w16inp_w16out(word16 *pi2_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_w16inp_w16out_a9q
107
108.type ihevc_inter_pred_chroma_vert_w16inp_w16out_a9q, %function
109
110ihevc_inter_pred_chroma_vert_w16inp_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,#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         r3,r3,#1                    @2*dst_strd
137    lsl         r9,r6,#2                    @4*wd
138    sub         r6,r3,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    vst1.32     {d0},[r1]!                  @stores the loaded value
162    vst1.32     {d30},[r7]                  @stores the loaded value
163    bgt         inner_loop_ht_2             @inner loop -again
164
165    @inner loop ends
166    subs        r5,r5,#2                    @increments ht
167    add         r1,r1,r6,lsl #1             @pu1_dst += 2*dst_strd - 2*wd
168    mov         r12,r9                      @4wd
169    add         r4,r4,r8                    @pi1_src_tmp1 += 2*src_strd - 4*wd
170    bgt         inner_loop_ht_2             @loop again
171
172    b           end_loops                   @jumps to end
173
174core_loop_ht_4:
175    lsl         r7,r2,#2                    @2*src_strd
176    lsl         r10,r3,#2                   @2*dst_strd
177    mov         r11,r6,lsr #1               @divide by 2
178    sub         lr,r10,r6,lsl #1            @2*dst_strd - 2*wd
179    sub         r8,r7,r6,lsl #2             @2*src_strd - 4*wd
180
181    mul         r12,r5,r11                  @multiply height by width
182    sub         r12,#4                      @subtract by one for epilog
183    mov         r11,r6,lsl #1               @2*wd
184    lsl         r3,r3,#1                    @2*dst_strd
185
186prolog:
187    add         r0,r4,r2                    @increments pi2_src
188    vld1.16     {d0},[r4]!                  @loads pu1_src
189    vld1.16     {d1},[r0],r2                @loads pi2_src
190    subs        r11,r11,#4
191    vld1.16     {d2},[r0],r2                @loads pi2_src
192    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
193    vld1.16     {d3},[r0],r2
194    vmlal.s16   q15,d1,d13
195    vmlal.s16   q15,d2,d14
196    add         r9,r1,r3                    @pu1_dst + dst_strd
197    vmlal.s16   q15,d3,d15
198
199    vld1.16     {d4},[r0],r2
200    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
201    addle       r4,r4,r8
202    movle       r11,r6,lsl #1
203    vmlal.s16   q14,d2,d13
204    vmlal.s16   q14,d3,d14
205    vld1.s16    {d5},[r0],r2
206    vmlal.s16   q14,d4,d15
207
208    vqshrn.s32  d30,q15,#6                  @right shift
209
210    vld1.s16    {d6},[r0],r2
211    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
212    vmlal.s16   q13,d3,d13
213    vmlal.s16   q13,d4,d14
214    add         r0,r4,r2
215    vld1.16     {d0},[r4]!                  @loads pu1_src
216    vmlal.s16   q13,d5,d15
217
218    vqshrn.s32  d28,q14,#6                  @right shift
219
220    vld1.16     {d1},[r0],r2                @loads pi2_src
221    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
222    vst1.32     {d30},[r1]!                 @stores the loaded value
223    vmlal.s16   q12,d4,d13
224    vld1.16     {d2},[r0],r2                @loads pi2_src
225    vmlal.s16   q12,d5,d14
226    vld1.16     {d3},[r0],r2
227    vmlal.s16   q12,d6,d15
228    addle       r1,r1,lr,lsl #1
229
230    vqshrn.s32  d26,q13,#6                  @right shift
231    subs        r12,r12,#4
232
233    beq         epilog                      @jumps to epilog
234
235kernel_4:
236    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
237    subs        r11,r11,#4
238    vmlal.s16   q15,d1,d13
239    vst1.32     {d28},[r9],r3               @stores the loaded value
240    vmlal.s16   q15,d2,d14
241    vmlal.s16   q15,d3,d15
242
243    vqshrn.s32  d24,q12,#6                  @right shift
244
245    vld1.16     {d4},[r0],r2
246    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
247    vmlal.s16   q14,d2,d13
248    vmlal.s16   q14,d3,d14
249    vmlal.s16   q14,d4,d15
250    vst1.32     {d26},[r9],r3               @stores the loaded value
251    addle       r4,r4,r8
252    movle       r11,r6,lsl #1
253
254    vqshrn.s32  d30,q15,#6                  @right shift
255
256    vld1.s16    {d5},[r0],r2
257    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
258    vld1.s16    {d6},[r0],r2
259    vmlal.s16   q13,d3,d13
260    vst1.32     {d24},[r9]                  @stores the loaded value
261    add         r0,r4,r2
262    vmlal.s16   q13,d4,d14
263    vld1.16     {d0},[r4]!                  @loads pu1_src
264    vmlal.s16   q13,d5,d15
265
266    vqshrn.s32  d28,q14,#6                  @right shift
267
268    vld1.16     {d1},[r0],r2                @loads pi2_src
269    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
270    vld1.16     {d2},[r0],r2                @loads pi2_src
271    vmlal.s16   q12,d4,d13
272    add         r9,r1,r3                    @pu1_dst + dst_strd
273    vld1.16     {d3},[r0],r2
274    vmlal.s16   q12,d5,d14
275
276    vst1.32     {d30},[r1]!                 @stores the loaded value
277    vmlal.s16   q12,d6,d15
278
279    vqshrn.s32  d26,q13,#6                  @right shift
280    addle       r1,r1,lr,lsl #1
281
282    subs        r12,r12,#4
283
284    bgt         kernel_4                    @jumps to kernel_4
285
286epilog:
287    vmull.s16   q15,d0,d12                  @vmull_s16(src_tmp1, coeff_0)
288    vst1.32     {d28},[r9],r3               @stores the loaded value
289    vmlal.s16   q15,d1,d13
290    vmlal.s16   q15,d2,d14
291    vmlal.s16   q15,d3,d15
292
293    vqshrn.s32  d24,q12,#6                  @right shift
294
295    vmull.s16   q14,d1,d12                  @vmull_s16(src_tmp2, coeff_0)
296    vld1.16     {d4},[r0],r2
297    vmlal.s16   q14,d2,d13
298    vst1.32     {d26},[r9],r3               @stores the loaded value
299    vmlal.s16   q14,d3,d14
300    vmlal.s16   q14,d4,d15
301
302    vqshrn.s32  d30,q15,#6                  @right shift
303
304    vmull.s16   q13,d2,d12                  @vmull_s16(src_tmp2, coeff_0)
305    vld1.s16    {d5},[r0],r2
306    vmlal.s16   q13,d3,d13
307    vmlal.s16   q13,d4,d14
308    vmlal.s16   q13,d5,d15
309
310    vqshrn.s32  d28,q14,#6                  @right shift
311
312    vst1.32     {d24},[r9]                  @stores the loaded value
313    vmull.s16   q12,d3,d12                  @vmull_s16(src_tmp2, coeff_0)
314    vmlal.s16   q12,d4,d13
315    add         r9,r1,r3                    @pu1_dst + dst_strd
316    vld1.s16    {d6},[r0],r2
317    vmlal.s16   q12,d5,d14
318    vmlal.s16   q12,d6,d15
319    vst1.32     {d30},[r1]!                 @stores the loaded value
320
321    vqshrn.s32  d26,q13,#6                  @right shift
322
323    vst1.32     {d28},[r9],r3               @stores the loaded value
324
325    vqshrn.s32  d24,q12,#6                  @right shift
326    vst1.32     {d26},[r9],r3               @stores the loaded value
327
328    vst1.32     {d24},[r9]                  @stores the loaded value
329
330end_loops:
331    vpop         {d8 - d15}
332    ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
333
334
335
336
337