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_intra_pred_luma_horz_neon.s
22@*
23@* @brief
24@*  contains function definition for intra prediction  interpolation filters
25@*
26@*
27@* @author
28@*  parthiban v
29@*
30@* @par list of functions:
31@*  - ihevc_intra_pred_luma_horz()
32@*
33@* @remarks
34@*  none
35@*
36@*******************************************************************************
37@*/
38@
39@/**
40@*******************************************************************************
41@*
42@* @brief
43@*     intra prediction interpolation filter for horizontal luma variable.
44@*
45@* @par description:
46@*      horizontal intraprediction(mode 10) with.extern  samples location
47@*      pointed by 'pu1_ref' to the tu block  location pointed by 'pu1_dst'  refer
48@*      to section 8.4.4.2.6 in the standard (special case)
49@*
50@* @param[in] pu1_src
51@*  uword8 pointer to the source
52@*
53@* @param[out] pu1_dst
54@*  uword8 pointer to the destination
55@*
56@* @param[in] src_strd
57@*  integer source stride
58@*
59@* @param[in] dst_strd
60@*  integer destination stride
61@*
62@* @param[in] nt
63@*  integer transform block size
64@*
65@* @param[in] mode
66@*  integer intraprediction mode
67@*
68@* @returns
69@*
70@* @remarks
71@*  none
72@*
73@*******************************************************************************
74@*/
75@void ihevc_intra_pred_luma_horz(uword8 *pu1_ref,
76@                                word32 src_strd,
77@                                uword8 *pu1_dst,
78@                                word32 dst_strd,
79@                                word32 nt,
80@                                word32 mode)
81@**************variables vs registers*****************************************
82@r0 => *pu1_ref
83@r1 =>  src_strd
84@r2 => *pu1_dst
85@r3 =>  dst_strd
86
87.equ    nt_offset,      104
88
89.text
90.align 4
91
92
93
94
95.globl ihevc_intra_pred_luma_horz_a9q
96
97.type ihevc_intra_pred_luma_horz_a9q, %function
98
99ihevc_intra_pred_luma_horz_a9q:
100
101    stmfd       sp!, {r4-r12, r14}          @stack stores the values of the arguments
102    vpush       {d8 - d15}
103    ldr         r4,[sp,#nt_offset]          @loads nt
104
105    lsl         r6,r4,#1                    @two_nt
106
107    add         r12,r0,r6                   @*pu1_ref[two_nt]
108    cmp         r4,#4                       @if nt == 4
109    beq         core_loop_4
110
111    cmp         r4,#8                       @if nt == 8
112    beq         core_loop_8
113
114    cmp         r4,#16                      @if nt == 16
115    beq         core_loop_16
116    sub         r12,r12,#16                 @move to 16th value pointer
117    add         r9,r2,#16
118
119core_loop_32:
120    vld1.8      {q0},[r12]                  @load 16 values. d1[7] will have the 1st value.
121
122    vdup.8      q1,d1[7]                    @duplicate the i value.
123
124    vdup.8      q2,d1[6]                    @duplicate the ii value.
125    vdup.8      q3,d1[5]                    @duplicate the iii value.
126    vst1.8      {q1},[r2],r3                @store in 1st row 0-16 columns
127    vst1.8      {q1},[r9],r3                @store in 1st row 16-32 columns
128
129    vdup.8      q4,d1[4]
130    vst1.8      {q2},[r2],r3
131    vst1.8      {q2},[r9],r3
132
133    vdup.8      q1,d1[3]
134    vst1.8      {q3},[r2],r3
135    vst1.8      {q3},[r9],r3
136
137    vdup.8      q2,d1[2]
138    vst1.8      {q4},[r2],r3
139    vst1.8      {q4},[r9],r3
140
141    vdup.8      q3,d1[1]
142    vst1.8      {q1},[r2],r3
143    vst1.8      {q1},[r9],r3
144
145    vdup.8      q4,d1[0]
146    vst1.8      {q2},[r2],r3
147    vst1.8      {q2},[r9],r3
148
149    vdup.8      q1,d0[7]
150    vst1.8      {q3},[r2],r3
151    vst1.8      {q3},[r9],r3
152
153    vdup.8      q2,d0[6]
154    vst1.8      {q4},[r2],r3
155    vst1.8      {q4},[r9],r3
156
157    vdup.8      q3,d0[5]
158    vst1.8      {q1},[r2],r3
159    vst1.8      {q1},[r9],r3
160
161    vdup.8      q4,d0[4]
162    vst1.8      {q2},[r2],r3
163    vst1.8      {q2},[r9],r3
164
165    vdup.8      q1,d0[3]
166    vst1.8      {q3},[r2],r3
167    vst1.8      {q3},[r9],r3
168
169    vdup.8      q2,d0[2]
170    vst1.8      {q4},[r2],r3
171    vst1.8      {q4},[r9],r3
172
173    vdup.8      q3,d0[1]
174    vst1.8      {q1},[r2],r3
175    vst1.8      {q1},[r9],r3
176    sub         r12,r12,#16                 @move to 16th value pointer
177
178    vdup.8      q4,d0[0]
179    vst1.8      {q2},[r2],r3
180    vst1.8      {q2},[r9],r3
181
182    subs        r4,r4,#16                   @decrement the loop count by 16
183    vst1.8      {q3},[r2],r3
184    vst1.8      {q3},[r9],r3
185
186    vst1.8      {q4},[r2],r3
187    vst1.8      {q4},[r9],r3
188    bgt         core_loop_32
189    vpop        {d8 - d15}
190    ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
191    b           end_func
192
193core_loop_16:
194    ldrb        lr,[r12],#1                 @pu1_ref[two_nt]
195    vld1.8      {q15},[r12]                 @pu1_ref[two_nt + 1 + col]
196
197    vdup.8      d28,lr
198    sub         r12,r12,#17
199    vld1.8      {q0},[r12]
200    vdup.8      d26,d1[7]
201    vmovl.u8    q13,d26
202
203    vdup.8      q1,d1[6]
204    vsubl.u8    q12,d30,d28
205
206    vdup.8      q2,d1[5]
207    vshr.s16    q12,q12,#1
208
209    vdup.8      q3,d1[4]
210    vqadd.s16   q11,q13,q12
211
212    vdup.8      q4,d1[3]
213    vqmovun.s16 d22,q11
214
215    vst1.8      {d22},[r2]!
216
217    vdup.8      q5,d1[2]
218    vsubl.u8    q12,d31,d28
219
220    vdup.8      q6,d1[1]
221    vshr.s16    q12,q12,#1
222
223    vdup.8      q7,d1[0]
224    vqadd.s16   q11,q13,q12
225
226    vdup.8      q8,d0[7]
227    vqmovun.s16 d22,q11
228
229    vst1.8      {d22},[r2],r3
230    sub         r2,r2,#8
231
232    vst1.8      {q1},[r2],r3
233
234    vst1.8      {q2},[r2],r3
235    vst1.8      {q3},[r2],r3
236    vst1.8      {q4},[r2],r3
237
238    vdup.8      q1,d0[6]
239    vst1.8      {q5},[r2],r3
240
241    vdup.8      q2,d0[5]
242    vst1.8      {q6},[r2],r3
243
244    vdup.8      q3,d0[4]
245    vst1.8      {q7},[r2],r3
246
247    vdup.8      q4,d0[3]
248    vst1.8      {q8},[r2],r3
249
250    vdup.8      q5,d0[2]
251    vst1.8      {q1},[r2],r3
252
253    vdup.8      q6,d0[1]
254    vst1.8      {q2},[r2],r3
255
256    vdup.8      q7,d0[0]
257    vst1.8      {q3},[r2],r3
258
259    vst1.8      {q4},[r2],r3
260    vst1.8      {q5},[r2],r3
261    vst1.8      {q6},[r2],r3
262    vst1.8      {q7},[r2],r3
263    vpop        {d8 - d15}
264    ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
265    b           end_func
266
267
268core_loop_8:
269    ldrb        lr,[r12]                    @pu1_ref[two_nt]
270    add         r12,r12,#1                  @pu1_ref[two_nt + 1]
271    vld1.8      {d30},[r12]                 @pu1_ref[two_nt + 1 + col]
272
273    sub         r12,r12,#9
274    vld1.8      {d0},[r12]
275    vdup.8      d26,d0[7]
276    vdup.8      d28,lr
277
278    vdup.8      d3,d0[6]
279    vmovl.u8    q13,d26
280
281    vdup.8      d4,d0[5]
282    vsubl.u8    q12,d30,d28
283
284    vdup.8      d5,d0[4]
285    vshr.s16    q12,q12,#1
286
287    vdup.8      d6,d0[3]
288    vqadd.s16   q11,q13,q12
289
290    vdup.8      d7,d0[2]
291    vqmovun.s16 d22,q11
292
293    vst1.8      {d22},[r2],r3
294    vst1.8      {d3},[r2],r3
295
296    vdup.8      d8,d0[1]
297    vst1.8      {d4},[r2],r3
298    vst1.8      {d5},[r2],r3
299
300    vdup.8      d9,d0[0]
301    vst1.8      {d6},[r2],r3
302    vst1.8      {d7},[r2],r3
303
304    vst1.8      {d8},[r2],r3
305    vst1.8      {d9},[r2],r3
306    vpop        {d8 - d15}
307    ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
308    b           end_func
309
310
311core_loop_4:
312    ldrb        lr,[r12]                    @pu1_ref[two_nt]
313    add         r12,r12,#1                  @pu1_ref[two_nt + 1]
314    vld1.8      {d30},[r12]                 @pu1_ref[two_nt + 1 + col]
315
316    sub         r12,r12,#5
317    vld1.8      {d0},[r12]
318    vdup.8      d28,lr
319    vdup.8      d26,d0[3]
320    vmovl.u8    q13,d26
321
322    vdup.8      d3,d0[2]
323    vsubl.u8    q12,d30,d28
324
325    vdup.8      d4,d0[1]
326    vshr.s16    q12,q12,#1
327
328    vdup.8      d5,d0[0]
329    vqadd.s16   q11,q13,q12
330
331    vqmovun.s16 d22,q11
332
333    vst1.32     {d22[0]},[r2],r3
334    vst1.32     {d3[0]},[r2],r3
335    vst1.32     {d4[0]},[r2],r3
336    vst1.32     {d5[0]},[r2],r3
337    vpop        {d8 - d15}
338    ldmfd       sp!,{r4-r12,r15}            @reload the registers from sp
339end_func:
340
341
342
343