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_itrans_recon_8x8_neon.s
22@ *
23@ * @brief
24@ *  contains function definitions for single stage  inverse transform
25@ *
26@ * @author
27@ *  anand s
28@ *
29@ * @par list of functions:
30@ *  - ihevc_itrans_recon_8x8()
31@ *
32@ * @remarks
33@ *  none
34@ *
35@ *******************************************************************************
36@*/
37
38@/**
39@ *******************************************************************************
40@ *
41@ * @brief
42@ *  this function performs inverse transform  and reconstruction for 8x8
43@ * input block
44@ *
45@ * @par description:
46@ *  performs inverse transform and adds the prediction  data and clips output
47@ * to 8 bit
48@ *
49@ * @param[in] pi2_src
50@ *  input 8x8 coefficients
51@ *
52@ * @param[in] pi2_tmp
53@ *  temporary 8x8 buffer for storing inverse
54@ *
55@ *  transform
56@ *  1st stage output
57@ *
58@ * @param[in] pu1_pred
59@ *  prediction 8x8 block
60@ *
61@ * @param[out] pu1_dst
62@ *  output 8x8 block
63@ *
64@ * @param[in] src_strd
65@ *  input stride
66@ *
67@ * @param[in] pred_strd
68@ *  prediction stride
69@ *
70@ * @param[in] dst_strd
71@ *  output stride
72@ *
73@ * @param[in] shift
74@ *  output shift
75@ *
76@ * @param[in] zero_cols
77@ *  zero columns in pi2_src
78@ *
79@ * @returns  void
80@ *
81@ * @remarks
82@ *  none
83@ *
84@ *******************************************************************************
85@ */
86
87@void ihevc_itrans_recon_8x8(word16 *pi2_src,
88@                            word16 *pi2_tmp,
89@                            uword8 *pu1_pred,
90@                            uword8 *pu1_dst,
91@                            word32 src_strd,
92@                            word32 pred_strd,
93@                            word32 dst_strd,
94@                            word32 zero_cols
95@                            word32 zero_rows               )
96
97@**************variables vs registers*************************
98@   r0 => *pi2_src
99@   r1 => *pi2_tmp
100@   r2 => *pu1_pred
101@   r3 => *pu1_dst
102@   src_strd
103@   pred_strd
104@   dst_strd
105@   zero_cols
106
107
108
109.text
110.align 4
111
112
113
114
115.set width_x_size_x5 ,   40
116.set width_x_size_x2 ,   32
117.set shift_stage1_idct ,   7
118.set shift_stage2_idct ,   12
119
120.globl ihevc_itrans_recon_8x8_a9q
121
122.extern g_ai2_ihevc_trans_8_transpose
123
124g_ai2_ihevc_trans_8_transpose_addr:
125.long g_ai2_ihevc_trans_8_transpose - ulbl1 - 8
126
127.type ihevc_itrans_recon_8x8_a9q, %function
128
129ihevc_itrans_recon_8x8_a9q:
130@//register usage.extern        - loading and until idct of columns
131@// cosine constants    -   d0
132@// sine constants      -   d1
133@// row 0 first half    -   d2      -   y0
134@// row 1 first half    -   d6      -   y1
135@// row 2 first half    -   d3      -   y2
136@// row 3 first half    -   d7      -   y3
137@// row 4 first half    -   d10     -   y4
138@// row 5 first half    -   d14     -   y5
139@// row 6 first half    -   d11     -   y6
140@// row 7 first half    -   d15     -   y7
141
142@// row 0 second half   -   d4      -   y0
143@// row 1 second half   -   d8      -   y1
144@// row 2 second half   -   d5      -   y2
145@// row 3 second half   -   d9      -   y3
146@// row 4 second half   -   d12     -   y4
147@// row 5 second half   -   d16     -   y5
148@// row 6 second half   -   d13     -   y6
149@// row 7 second half   -   d17     -   y7
150
151    @// copy the input pointer to another register
152    @// step 1 : load all constants
153    stmfd       sp!,{r4-r12,lr}
154
155    ldr         r8,[sp,#44]                  @ prediction stride
156    ldr         r7,[sp,#48]                  @ destination stride
157    ldr         r6,[sp, #40]                     @ src stride
158    ldr         r12,[sp,#52]
159    ldr         r11,[sp,#56]
160    mov         r6,r6,lsl #1                @ x sizeof(word16)
161    add         r9,r0,r6, lsl #1            @ 2 rows
162
163    add         r10,r6,r6, lsl #1           @ 3 rows
164
165    sub         r10,r10, #8                 @ - 4 cols * sizeof(word16)
166    sub         r5,r6, #8                   @ src_strd - 4 cols * sizeof(word16)
167
168@   ldr         r14,=g_imp4d_cxa8_idct_q15
169    ldr         r14,g_ai2_ihevc_trans_8_transpose_addr
170ulbl1:
171    add         r14,r14,pc
172    vld1.16     {d0,d1},[r14]               @//d0,d1 are used for storing the constant data
173
174    @//step 2 load all the input data
175    @//step 3 operate first 4 colums at a time
176
177    and         r11,r11,#0xff
178    and         r12,r12,#0xff
179
180    cmp         r11,#0xf0
181    bge         skip_last4_rows
182
183
184    vld1.16     d2,[r0]!
185    vld1.16     d3,[r9]!
186    vld1.16     d4,[r0],r5
187    vmull.s16   q10,d2,d0[0]                @// y0 * cos4(part of c0 and c1)
188    vld1.16     d5,[r9],r5
189    vmull.s16   q9,d3,d1[2]                 @// y2 * sin2 (q3 is freed by this time)(part of d1)
190    vld1.16     d6,[r0]!
191    vld1.16     d7,[r9]!
192    vmull.s16   q12,d6,d0[1]                @// y1 * cos1(part of b0)
193    vld1.16     d8,[r0],r10
194    vmull.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
195    vld1.16     d9,[r9],r10
196    vmull.s16   q14,d6,d1[1]                @// y1 * sin3(part of b2)
197    vld1.16     d10,[r0]!
198    vmull.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
199    vld1.16     d11,[r9]!
200    vmlal.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
201    vld1.16     d12,[r0],r5
202    vmlsl.s16   q13,d7,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
203    vld1.16     d13,[r9],r5
204    vmlsl.s16   q14,d7,d0[1]                @// y1 * sin3 - y3 * cos1(part of b2)
205    vld1.16     d14,[r0]!
206    vmlsl.s16   q15,d7,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
207    vld1.16     d15,[r9]!
208    vmull.s16   q11,d10,d0[0]               @// y4 * cos4(part of c0 and c1)
209    vld1.16     d16,[r0],r10
210    vmull.s16   q3,d3,d0[2]                 @// y2 * cos2(part of d0)
211    vld1.16     d17,[r9],r10
212
213    @/* this following was activated when alignment is not there */
214@// vld1.16     d2,[r0]!
215@// vld1.16     d3,[r2]!
216@// vld1.16     d4,[r0]!
217@// vld1.16     d5,[r2]!
218@// vld1.16     d6,[r0]!
219@// vld1.16     d7,[r2]!
220@// vld1.16     d8,[r0],r3
221@// vld1.16     d9,[r2],r3
222@// vld1.16     d10,[r0]!
223@// vld1.16     d11,[r2]!
224@// vld1.16     d12,[r0]!
225@// vld1.16     d13,[r2]!
226@// vld1.16     d14,[r0]!
227@// vld1.16     d15,[r2]!
228@// vld1.16     d16,[r0],r3
229@// vld1.16     d17,[r2],r3
230
231
232
233
234    vmlal.s16   q12,d14,d1[1]               @// y1 * cos1 + y3 * cos3 + y5 * sin3(part of b0)
235    vmlsl.s16   q13,d14,d0[1]               @// y1 * cos3 - y3 * sin1 - y5 * cos1(part of b1)
236    vmlal.s16   q14,d14,d1[3]               @// y1 * sin3 - y3 * cos1 + y5 * sin1(part of b2)
237    vmlal.s16   q15,d14,d0[3]               @// y1 * sin1 - y3 * sin3 + y5 * cos3(part of b3)
238
239    vmlsl.s16   q9,d11,d0[2]                @// d1 = y2 * sin2 - y6 * cos2(part of a0 and a1)
240    vmlal.s16   q3,d11,d1[2]                @// d0 = y2 * cos2 + y6 * sin2(part of a0 and a1)
241
242    vadd.s32    q5,q10,q11                  @// c0 = y0 * cos4 + y4 * cos4(part of a0 and a1)
243    vsub.s32    q10,q10,q11                 @// c1 = y0 * cos4 - y4 * cos4(part of a0 and a1)
244
245    vmlal.s16   q12,d15,d1[3]               @// b0 = y1 * cos1 + y3 * cos3 + y5 * sin3 + y7 * sin1(part of r0,r7)
246    vmlsl.s16   q13,d15,d1[1]               @// b1 = y1 * cos3 - y3 * sin1 - y5 * cos1 - y7 * sin3(part of r1,r6)
247    vmlal.s16   q14,d15,d0[3]               @// b2 = y1 * sin3 - y3 * cos1 + y5 * sin1 + y7 * cos3(part of r2,r5)
248    vmlsl.s16   q15,d15,d0[1]               @// b3 = y1 * sin1 - y3 * sin3 + y5 * cos3 - y7 * cos1(part of r3,r4)
249
250    vadd.s32    q7,q5,q3                    @// a0 = c0 + d0(part of r0,r7)
251    vsub.s32    q5,q5,q3                    @// a3 = c0 - d0(part of r3,r4)
252    vsub.s32    q11,q10,q9                  @// a2 = c1 - d1(part of r2,r5)
253    vadd.s32    q9,q10,q9                   @// a1 = c1 + d1(part of r1,r6)
254
255    vadd.s32    q10,q7,q12                  @// a0 + b0(part of r0)
256    vsub.s32    q3,q7,q12                   @// a0 - b0(part of r7)
257
258    vadd.s32    q12,q11,q14                 @// a2 + b2(part of r2)
259    vsub.s32    q11,q11,q14                 @// a2 - b2(part of r5)
260
261    vadd.s32    q14,q9,q13                  @// a1 + b1(part of r1)
262    vsub.s32    q9,q9,q13                   @// a1 - b1(part of r6)
263
264    vadd.s32    q13,q5,q15                  @// a3 + b3(part of r3)
265    vsub.s32    q15,q5,q15                  @// a3 - b3(part of r4)
266
267    vqrshrn.s32 d2,q10,#shift_stage1_idct   @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
268    vqrshrn.s32 d15,q3,#shift_stage1_idct   @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
269    vqrshrn.s32 d3,q12,#shift_stage1_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
270    vqrshrn.s32 d14,q11,#shift_stage1_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
271    vqrshrn.s32 d6,q14,#shift_stage1_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
272    vqrshrn.s32 d11,q9,#shift_stage1_idct   @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
273    vqrshrn.s32 d7,q13,#shift_stage1_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
274    vqrshrn.s32 d10,q15,#shift_stage1_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
275
276
277    b           last4_cols
278
279
280
281skip_last4_rows:
282
283
284
285    vld1.16     d2,[r0]!
286    vld1.16     d3,[r9]!
287    vld1.16     d4,[r0],r5
288    vld1.16     d5,[r9],r5
289    vld1.16     d6,[r0]!
290    vld1.16     d7,[r9]!
291    vld1.16     d8,[r0],r10
292    vld1.16     d9,[r9],r10
293
294
295
296    vmov.s16    q6,#0
297    vmov.s16    q8,#0
298
299
300
301
302    vmull.s16   q12,d6,d0[1]                @// y1 * cos1(part of b0)
303    vmull.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
304    vmull.s16   q14,d6,d1[1]                @// y1 * sin3(part of b2)
305    vmull.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
306
307    vmlal.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
308    vmlsl.s16   q13,d7,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
309    vmlsl.s16   q14,d7,d0[1]                @// y1 * sin3 - y3 * cos1(part of b2)
310    vmlsl.s16   q15,d7,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
311
312    vmull.s16   q9,d3,d1[2]                 @// y2 * sin2 (q3 is freed by this time)(part of d1)
313    vmull.s16   q3,d3,d0[2]                 @// y2 * cos2(part of d0)
314
315    vmull.s16   q10,d2,d0[0]                @// y0 * cos4(part of c0 and c1)
316
317
318    vadd.s32    q7,q10,q3                   @// a0 = c0 + d0(part of r0,r7)
319    vsub.s32    q5,q10,q3                   @// a3 = c0 - d0(part of r3,r4)
320    vsub.s32    q11,q10,q9                  @// a2 = c1 - d1(part of r2,r5)
321    vadd.s32    q9,q10,q9                   @// a1 = c1 + d1(part of r1,r6)
322
323    vadd.s32    q10,q7,q12                  @// a0 + b0(part of r0)
324    vsub.s32    q3,q7,q12                   @// a0 - b0(part of r7)
325
326    vadd.s32    q12,q11,q14                 @// a2 + b2(part of r2)
327    vsub.s32    q11,q11,q14                 @// a2 - b2(part of r5)
328
329    vadd.s32    q14,q9,q13                  @// a1 + b1(part of r1)
330    vsub.s32    q9,q9,q13                   @// a1 - b1(part of r6)
331
332    vadd.s32    q13,q5,q15                  @// a3 + b3(part of r3)
333    vsub.s32    q15,q5,q15                  @// a3 - b3(part of r4)
334
335    vqrshrn.s32 d2,q10,#shift_stage1_idct   @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
336    vqrshrn.s32 d15,q3,#shift_stage1_idct   @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
337    vqrshrn.s32 d3,q12,#shift_stage1_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
338    vqrshrn.s32 d14,q11,#shift_stage1_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
339    vqrshrn.s32 d6,q14,#shift_stage1_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
340    vqrshrn.s32 d11,q9,#shift_stage1_idct   @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
341    vqrshrn.s32 d7,q13,#shift_stage1_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
342    vqrshrn.s32 d10,q15,#shift_stage1_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
343
344
345last4_cols:
346
347
348    cmp         r12,#0xf0
349    bge         skip_last4cols
350
351    vmull.s16   q12,d8,d0[1]                @// y1 * cos1(part of b0)
352    vmull.s16   q13,d8,d0[3]                @// y1 * cos3(part of b1)
353    vmull.s16   q14,d8,d1[1]                @// y1 * sin3(part of b2)
354    vmull.s16   q15,d8,d1[3]                @// y1 * sin1(part of b3)
355
356    vmlal.s16   q12,d9,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
357    vmlsl.s16   q13,d9,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
358    vmlsl.s16   q14,d9,d0[1]                @// y1 * sin3 - y3 * cos1(part of b2)
359    vmlsl.s16   q15,d9,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
360
361    vmull.s16   q9,d5,d1[2]                 @// y2 * sin2 (q4 is freed by this time)(part of d1)
362    vmull.s16   q4,d5,d0[2]                 @// y2 * cos2(part of d0)
363
364    vmull.s16   q10,d4,d0[0]                @// y0 * cos4(part of c0 and c1)
365    vmull.s16   q11,d12,d0[0]               @// y4 * cos4(part of c0 and c1)
366
367    vmlal.s16   q12,d16,d1[1]               @// y1 * cos1 + y3 * cos3 + y5 * sin3(part of b0)
368    vmlsl.s16   q13,d16,d0[1]               @// y1 * cos3 - y3 * sin1 - y5 * cos1(part of b1)
369    vmlal.s16   q14,d16,d1[3]               @// y1 * sin3 - y3 * cos1 + y5 * sin1(part of b2)
370    vmlal.s16   q15,d16,d0[3]               @// y1 * sin1 - y3 * sin3 + y5 * cos3(part of b3)
371
372    vmlsl.s16   q9,d13,d0[2]                @// d1 = y2 * sin2 - y6 * cos2(part of a0 and a1)
373    vmlal.s16   q4,d13,d1[2]                @// d0 = y2 * cos2 + y6 * sin2(part of a0 and a1)
374
375    vadd.s32    q6,q10,q11                  @// c0 = y0 * cos4 + y4 * cos4(part of a0 and a1)
376    vsub.s32    q10,q10,q11                 @// c1 = y0 * cos4 - y4 * cos4(part of a0 and a1)
377
378    vmlal.s16   q12,d17,d1[3]               @// b0 = y1 * cos1 + y3 * cos3 + y5 * sin3 + y7 * sin1(part of e0,e7)
379    vmlsl.s16   q13,d17,d1[1]               @// b1 = y1 * cos3 - y3 * sin1 - y5 * cos1 - y7 * sin3(part of e1,e6)
380    vmlal.s16   q14,d17,d0[3]               @// b2 = y1 * sin3 - y3 * cos1 + y5 * sin1 + y7 * cos3(part of e2,e5)
381    vmlsl.s16   q15,d17,d0[1]               @// b3 = y1 * sin1 - y3 * sin3 + y5 * cos3 - y7 * cos1(part of e3,e4)
382
383    vadd.s32    q8,q6,q4                    @// a0 = c0 + d0(part of e0,e7)
384    vsub.s32    q6,q6,q4                    @// a3 = c0 - d0(part of e3,e4)
385    vsub.s32    q11,q10,q9                  @// a2 = c1 - d1(part of e2,e5)
386    vadd.s32    q9,q10,q9                   @// a1 = c1 + d1(part of e1,e6)
387
388    vadd.s32    q10,q8,q12                  @// a0 + b0(part of e0)
389    vsub.s32    q4,q8,q12                   @// a0 - b0(part of e7)
390
391    vadd.s32    q12,q11,q14                 @// a2 + b2(part of e2)
392    vsub.s32    q11,q11,q14                 @// a2 - b2(part of e5)
393
394    vadd.s32    q14,q9,q13                  @// a1 + b1(part of e1)
395    vsub.s32    q9,q9,q13                   @// a1 - b1(part of e6)
396
397    vadd.s32    q13,q6,q15                  @// a3 + b3(part of e3)
398    vsub.s32    q15,q6,q15                  @// a3 - b3(part of r4)
399
400    vqrshrn.s32 d4,q10,#shift_stage1_idct   @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
401    vqrshrn.s32 d17,q4,#shift_stage1_idct   @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
402    vqrshrn.s32 d5,q12,#shift_stage1_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
403    vqrshrn.s32 d16,q11,#shift_stage1_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
404    vqrshrn.s32 d8,q14,#shift_stage1_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
405    vqrshrn.s32 d13,q9,#shift_stage1_idct   @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
406    vqrshrn.s32 d9,q13,#shift_stage1_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
407    vqrshrn.s32 d12,q15,#shift_stage1_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
408    b           end_skip_last4cols
409
410
411
412skip_last4cols:
413
414
415
416
417
418
419    vtrn.16     q1,q3                       @//[r3,r1],[r2,r0] first qudrant transposing
420
421    vtrn.16     q5,q7                       @//[r7,r5],[r6,r4] third qudrant transposing
422
423
424    vtrn.32     d6,d7                       @//r0,r1,r2,r3 first qudrant transposing continued.....
425    vtrn.32     d2,d3                       @//r0,r1,r2,r3 first qudrant transposing continued.....
426
427    vtrn.32     d10,d11                     @//r4,r5,r6,r7 third qudrant transposing continued.....
428    vtrn.32     d14,d15                     @//r4,r5,r6,r7 third qudrant transposing continued.....
429
430
431    vmull.s16   q12,d6,d0[1]                @// y1 * cos1(part of b0)
432    vmull.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
433    vmull.s16   q14,d6,d1[1]                @// y1 * sin3(part of b2)
434    vmull.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
435
436    vmlal.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
437    vmlsl.s16   q13,d7,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
438    vmlsl.s16   q14,d7,d0[1]                @// y1 * sin3 - y3 * cos1(part of b2)
439    vmlsl.s16   q15,d7,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
440
441    vmull.s16   q10,d2,d0[0]                @// y0 * cos4(part of c0 and c1)
442@   vmull.s16   q11,d4,d0[0]                    @// y4 * cos4(part of c0 and c1)
443
444    vmull.s16   q9,d3,d1[2]                 @// y2 * sin2 (q3 is freed by this time)(part of d1)
445    vmull.s16   q3,d3,d0[2]                 @// y2 * cos2(part of d0)
446
447
448
449
450    vsub.s32    q11,q10,q3                  @// a3 = c0 - d0(part of r3,r4)
451    vadd.s32    q2,q10,q3                   @// a0 = c0 + d0(part of r0,r7)
452
453
454    vadd.s32    q1,q2,q12
455
456    vsub.s32    q3,q2,q12
457
458    vadd.s32    q4,q11,q15
459
460    vsub.s32    q12,q11,q15
461
462    vqrshrn.s32 d5,q4,#shift_stage2_idct
463    vqrshrn.s32 d2,q1,#shift_stage2_idct
464    vqrshrn.s32 d9,q3,#shift_stage2_idct
465    vqrshrn.s32 d6,q12,#shift_stage2_idct
466
467    vsub.s32    q11,q10,q9                  @// a2 = c1 - d1(part of r2,r5)
468    vadd.s32    q9,q10,q9                   @// a1 = c1 + d1(part of r1,r6)
469
470
471    vadd.s32    q15,q11,q14
472
473    vsub.s32    q12,q11,q14
474
475    vadd.s32    q14,q9,q13
476
477    vsub.s32    q11,q9,q13
478    vqrshrn.s32 d4,q15,#shift_stage2_idct
479    vqrshrn.s32 d7,q12,#shift_stage2_idct
480    vqrshrn.s32 d3,q14,#shift_stage2_idct
481    vqrshrn.s32 d8,q11,#shift_stage2_idct
482
483
484
485
486
487
488
489
490
491
492    vmull.s16   q12,d14,d0[1]               @// y1 * cos1(part of b0)
493
494    vmull.s16   q13,d14,d0[3]               @// y1 * cos3(part of b1)
495    vmull.s16   q14,d14,d1[1]               @// y1 * sin3(part of b2)
496    vmull.s16   q15,d14,d1[3]               @// y1 * sin1(part of b3)
497
498    vmlal.s16   q12,d15,d0[3]               @// y1 * cos1 + y3 * cos3(part of b0)
499    vtrn.16     d2,d3
500    vmlsl.s16   q13,d15,d1[3]               @// y1 * cos3 - y3 * sin1(part of b1)
501    vtrn.16     d4,d5
502    vmlsl.s16   q14,d15,d0[1]               @// y1 * sin3 - y3 * cos1(part of b2)
503    vtrn.16     d6,d7
504    vmlsl.s16   q15,d15,d1[1]               @// y1 * sin1 - y3 * sin3(part of b3)
505    vtrn.16     d8,d9
506    vmull.s16   q10,d10,d0[0]               @// y0 * cos4(part of c0 and c1)
507    vtrn.32     d2,d4
508
509    vtrn.32     d3,d5
510    vmull.s16   q9,d11,d1[2]                @// y2 * sin2 (q7 is freed by this time)(part of d1)
511    vtrn.32     d6,d8
512    vmull.s16   q7,d11,d0[2]                @// y2 * cos2(part of d0)
513    vtrn.32     d7,d9
514
515
516    add         r4,r2,r8, lsl #1            @ r4 = r2 + pred_strd * 2    => r4 points to 3rd row of pred data
517
518
519    add         r5,r8,r8, lsl #1            @
520
521
522    add         r0,r3,r7, lsl #1            @ r0 points to 3rd row of dest data
523
524
525    add         r10,r7,r7, lsl #1           @
526
527
528    vswp        d3,d6
529
530
531    vswp        d5,d8
532
533
534    vsub.s32    q11,q10,q7                  @// a3 = c0 - d0(part of r3,r4)
535    vadd.s32    q6,q10,q7                   @// a0 = c0 + d0(part of r0,r7)
536
537
538    vadd.s32    q0,q6,q12
539
540
541    vsub.s32    q12,q6,q12
542
543
544    vadd.s32    q6,q11,q15
545
546
547    vsub.s32    q7,q11,q15
548
549    vqrshrn.s32 d10,q0,#shift_stage2_idct
550    vqrshrn.s32 d17,q12,#shift_stage2_idct
551    vqrshrn.s32 d13,q6,#shift_stage2_idct
552    vqrshrn.s32 d14,q7,#shift_stage2_idct
553
554    vsub.s32    q11,q10,q9                  @// a2 = c1 - d1(part of r2,r5)
555    vadd.s32    q9,q10,q9                   @// a1 = c1 + d1(part of r1,r6)
556
557
558    vadd.s32    q0,q11,q14
559
560
561    vsub.s32    q12,q11,q14
562
563
564    vadd.s32    q14,q9,q13
565
566
567    vsub.s32    q13,q9,q13
568    vld1.8      d18,[r2],r8
569
570    vqrshrn.s32 d12,q0,#shift_stage2_idct
571    vld1.8      d20,[r2],r5
572
573
574    vqrshrn.s32 d15,q12,#shift_stage2_idct
575    vld1.8      d19,[r2],r8
576
577
578
579
580    vqrshrn.s32 d11,q14,#shift_stage2_idct
581    vld1.8      d22,[r4],r8
582
583
584
585
586    vqrshrn.s32 d16,q13,#shift_stage2_idct
587    vld1.8      d21,[r2],r5
588
589
590    b           pred_buff_addition
591end_skip_last4cols:
592
593
594
595@/* now the idct of columns is done, transpose so that row idct done efficiently(step5) */
596    vtrn.16     q1,q3                       @//[r3,r1],[r2,r0] first qudrant transposing
597    vtrn.16     q2,q4                       @//[r3,r1],[r2,r0] second qudrant transposing
598    vtrn.16     q5,q7                       @//[r7,r5],[r6,r4] third qudrant transposing
599    vtrn.16     q6,q8                       @//[r7,r5],[r6,r4] fourth qudrant transposing
600
601    vtrn.32     d6,d7                       @//r0,r1,r2,r3 first qudrant transposing continued.....
602    vtrn.32     d2,d3                       @//r0,r1,r2,r3 first qudrant transposing continued.....
603    vtrn.32     d4,d5                       @//r0,r1,r2,r3 second qudrant transposing continued.....
604    vtrn.32     d8,d9                       @//r0,r1,r2,r3 second qudrant transposing continued.....
605    vtrn.32     d10,d11                     @//r4,r5,r6,r7 third qudrant transposing continued.....
606    vtrn.32     d14,d15                     @//r4,r5,r6,r7 third qudrant transposing continued.....
607    vtrn.32     d12,d13                     @//r4,r5,r6,r7 fourth qudrant transposing continued.....
608    vtrn.32     d16,d17                     @//r4,r5,r6,r7 fourth qudrant transposing continued.....
609
610    @//step6 operate on first four rows and find their idct
611    @//register usage.extern        - storing and idct of rows
612@// cosine constants    -   d0
613@// sine constants      -   d1
614@// element 0 first four    -   d2      -   y0
615@// element 1 first four    -   d6      -   y1
616@// element 2 first four    -   d3      -   y2
617@// element 3 first four    -   d7      -   y3
618@// element 4 first four    -   d4      -   y4
619@// element 5 first four    -   d8      -   y5
620@// element 6 first four    -   d5      -   y6
621@// element 7 first four    -   d9      -   y7
622@// element 0 second four   -   d10     -   y0
623@// element 1 second four   -   d14     -   y1
624@// element 2 second four   -   d11     -   y2
625@// element 3 second four   -   d15     -   y3
626@// element 4 second four   -   d12     -   y4
627@// element 5 second four   -   d16     -   y5
628@// element 6 second four   -   d13     -   y6
629@// element 7 second four   -   d17     -   y7
630
631    @// map between first kernel code seq and current
632@//     d2  ->  d2
633@//     d6  ->  d6
634@//     d3  ->  d3
635@//     d7  ->  d7
636@//     d10 ->  d4
637@//     d14 ->  d8
638@//     d11 ->  d5
639@//     d15 ->  d9
640@//     q3  ->  q3
641@//     q5  ->  q2
642@//     q7  ->  q4
643
644    vmull.s16   q12,d6,d0[1]                @// y1 * cos1(part of b0)
645    vmull.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
646    vmull.s16   q14,d6,d1[1]                @// y1 * sin3(part of b2)
647    vmull.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
648
649    vmlal.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
650    vmlsl.s16   q13,d7,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
651    vmlsl.s16   q14,d7,d0[1]                @// y1 * sin3 - y3 * cos1(part of b2)
652    vmlsl.s16   q15,d7,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
653
654    vmull.s16   q10,d2,d0[0]                @// y0 * cos4(part of c0 and c1)
655    vmull.s16   q11,d4,d0[0]                @// y4 * cos4(part of c0 and c1)
656
657    vmull.s16   q9,d3,d1[2]                 @// y2 * sin2 (q3 is freed by this time)(part of d1)
658    vmull.s16   q3,d3,d0[2]                 @// y2 * cos2(part of d0)
659
660
661    vmlal.s16   q12,d8,d1[1]                @// y1 * cos1 + y3 * cos3 + y5 * sin3(part of b0)
662    vmlsl.s16   q13,d8,d0[1]                @// y1 * cos3 - y3 * sin1 - y5 * cos1(part of b1)
663    vmlal.s16   q14,d8,d1[3]                @// y1 * sin3 - y3 * cos1 + y5 * sin1(part of b2)
664    vmlal.s16   q15,d8,d0[3]                @// y1 * sin1 - y3 * sin3 + y5 * cos3(part of b3)
665
666    vmlsl.s16   q9,d5,d0[2]                 @// d1 = y2 * sin2 - y6 * cos2(part of a0 and a1)
667    vmlal.s16   q3,d5,d1[2]                 @// d0 = y2 * cos2 + y6 * sin2(part of a0 and a1)
668
669    vadd.s32    q1,q10,q11                  @// c0 = y0 * cos4 + y4 * cos4(part of a0 and a1)
670    vsub.s32    q10,q10,q11                 @// c1 = y0 * cos4 - y4 * cos4(part of a0 and a1)
671
672    vmlal.s16   q12,d9,d1[3]                @// b0 = y1 * cos1 + y3 * cos3 + y5 * sin3 + y7 * sin1(part of r0,r7)
673    vmlsl.s16   q13,d9,d1[1]                @// b1 = y1 * cos3 - y3 * sin1 - y5 * cos1 - y7 * sin3(part of r1,r6)
674    vmlal.s16   q14,d9,d0[3]                @// b2 = y1 * sin3 - y3 * cos1 + y5 * sin1 + y7 * cos3(part of r2,r5)
675    vmlsl.s16   q15,d9,d0[1]                @// b3 = y1 * sin1 - y3 * sin3 + y5 * cos3 - y7 * cos1(part of r3,r4)
676
677    vsub.s32    q11,q1,q3                   @// a3 = c0 - d0(part of r3,r4)
678    vadd.s32    q2,q1,q3                    @// a0 = c0 + d0(part of r0,r7)
679
680
681    vadd.s32    q1,q2,q12
682
683    vsub.s32    q3,q2,q12
684
685    vadd.s32    q4,q11,q15
686
687    vsub.s32    q12,q11,q15
688
689    vqrshrn.s32 d5,q4,#shift_stage2_idct
690    vqrshrn.s32 d2,q1,#shift_stage2_idct
691    vqrshrn.s32 d9,q3,#shift_stage2_idct
692    vqrshrn.s32 d6,q12,#shift_stage2_idct
693
694    vsub.s32    q11,q10,q9                  @// a2 = c1 - d1(part of r2,r5)
695    vadd.s32    q9,q10,q9                   @// a1 = c1 + d1(part of r1,r6)
696
697
698    vadd.s32    q15,q11,q14
699
700    vsub.s32    q12,q11,q14
701
702    vadd.s32    q14,q9,q13
703
704    vsub.s32    q11,q9,q13
705    vqrshrn.s32 d4,q15,#shift_stage2_idct
706    vqrshrn.s32 d7,q12,#shift_stage2_idct
707    vqrshrn.s32 d3,q14,#shift_stage2_idct
708    vqrshrn.s32 d8,q11,#shift_stage2_idct
709
710
711
712
713
714
715
716
717
718
719    vmull.s16   q12,d14,d0[1]               @// y1 * cos1(part of b0)
720
721    vmull.s16   q13,d14,d0[3]               @// y1 * cos3(part of b1)
722    vmull.s16   q14,d14,d1[1]               @// y1 * sin3(part of b2)
723    vmull.s16   q15,d14,d1[3]               @// y1 * sin1(part of b3)
724
725    vmlal.s16   q12,d15,d0[3]               @// y1 * cos1 + y3 * cos3(part of b0)
726    vtrn.16     d2,d3
727    vmlsl.s16   q13,d15,d1[3]               @// y1 * cos3 - y3 * sin1(part of b1)
728    vtrn.16     d4,d5
729    vmlsl.s16   q14,d15,d0[1]               @// y1 * sin3 - y3 * cos1(part of b2)
730    vtrn.16     d6,d7
731    vmlsl.s16   q15,d15,d1[1]               @// y1 * sin1 - y3 * sin3(part of b3)
732    vtrn.16     d8,d9
733    vmull.s16   q10,d10,d0[0]               @// y0 * cos4(part of c0 and c1)
734    vtrn.32     d2,d4
735    vmull.s16   q11,d12,d0[0]               @// y4 * cos4(part of c0 and c1)
736    vtrn.32     d3,d5
737    vmull.s16   q9,d11,d1[2]                @// y2 * sin2 (q7 is freed by this time)(part of d1)
738    vtrn.32     d6,d8
739    vmull.s16   q7,d11,d0[2]                @// y2 * cos2(part of d0)
740    vtrn.32     d7,d9
741    vmlal.s16   q12,d16,d1[1]               @// y1 * cos1 + y3 * cos3 + y5 * sin3(part of b0)
742
743    add         r4,r2,r8, lsl #1            @ r4 = r2 + pred_strd * 2    => r4 points to 3rd row of pred data
744    vmlsl.s16   q13,d16,d0[1]               @// y1 * cos3 - y3 * sin1 - y5 * cos1(part of b1)
745
746    add         r5,r8,r8, lsl #1            @
747    vmlal.s16   q14,d16,d1[3]               @// y1 * sin3 - y3 * cos1 + y5 * sin1(part of b2)
748
749    add         r0,r3,r7, lsl #1            @ r0 points to 3rd row of dest data
750    vmlal.s16   q15,d16,d0[3]               @// y1 * sin1 - y3 * sin3 + y5 * cos3(part of b3)
751
752    add         r10,r7,r7, lsl #1           @
753    vmlsl.s16   q9,d13,d0[2]                @// d1 = y2 * sin2 - y6 * cos2(part of a0 and a1)
754
755
756    vmlal.s16   q7,d13,d1[2]                @// d0 = y2 * cos2 + y6 * sin2(part of a0 and a1)
757
758    vadd.s32    q6,q10,q11                  @// c0 = y0 * cos4 + y4 * cos4(part of a0 and a1)
759    vsub.s32    q10,q10,q11                 @// c1 = y0 * cos4 - y4 * cos4(part of a0 and a1)
760
761    vmlal.s16   q12,d17,d1[3]               @// b0 = y1 * cos1 + y3 * cos3 + y5 * sin3 + y7 * sin1(part of r0,r7)
762    vswp        d3,d6
763    vmlsl.s16   q13,d17,d1[1]               @// b1 = y1 * cos3 - y3 * sin1 - y5 * cos1 - y7 * sin3(part of r1,r6)
764
765    vswp        d5,d8
766    vmlal.s16   q14,d17,d0[3]               @// b2 = y1 * sin3 - y3 * cos1 + y5 * sin1 + y7 * cos3(part of r2,r5)
767    vmlsl.s16   q15,d17,d0[1]               @// b3 = y1 * sin1 - y3 * sin3 + y5 * cos3 - y7 * cos1(part of r3,r4)
768
769    vsub.s32    q11,q6,q7                   @// a3 = c0 - d0(part of r3,r4)
770    vadd.s32    q6,q6,q7                    @// a0 = c0 + d0(part of r0,r7)
771
772
773    vadd.s32    q0,q6,q12
774
775
776    vsub.s32    q12,q6,q12
777
778
779    vadd.s32    q6,q11,q15
780
781
782    vsub.s32    q7,q11,q15
783
784    vqrshrn.s32 d10,q0,#shift_stage2_idct
785    vqrshrn.s32 d17,q12,#shift_stage2_idct
786    vqrshrn.s32 d13,q6,#shift_stage2_idct
787    vqrshrn.s32 d14,q7,#shift_stage2_idct
788
789    vsub.s32    q11,q10,q9                  @// a2 = c1 - d1(part of r2,r5)
790    vadd.s32    q9,q10,q9                   @// a1 = c1 + d1(part of r1,r6)
791
792
793    vadd.s32    q0,q11,q14
794
795
796    vsub.s32    q12,q11,q14
797
798
799    vadd.s32    q14,q9,q13
800
801
802    vsub.s32    q13,q9,q13
803    vld1.8      d18,[r2],r8
804
805    vqrshrn.s32 d12,q0,#shift_stage2_idct
806    vld1.8      d20,[r2],r5
807
808
809    vqrshrn.s32 d15,q12,#shift_stage2_idct
810    vld1.8      d19,[r2],r8
811
812
813
814
815    vqrshrn.s32 d11,q14,#shift_stage2_idct
816    vld1.8      d22,[r4],r8
817
818
819
820
821    vqrshrn.s32 d16,q13,#shift_stage2_idct
822    vld1.8      d21,[r2],r5
823
824
825
826
827pred_buff_addition:
828
829
830    vtrn.16     d10,d11
831    vld1.8      d24,[r4],r5
832
833    vtrn.16     d12,d13
834    vld1.8      d23,[r4],r8
835
836    vaddw.u8    q1,q1,d18
837    vld1.8      d25,[r4],r5
838
839    vtrn.16     d14,d15
840    vaddw.u8    q2,q2,d22
841
842    vtrn.16     d16,d17
843    vaddw.u8    q3,q3,d20
844
845    vtrn.32     d10,d12
846    vaddw.u8    q4,q4,d24
847
848    vtrn.32     d11,d13
849    vtrn.32     d14,d16
850    vtrn.32     d15,d17
851
852    vswp        d11,d14
853    vswp        d13,d16
854
855@ row values stored in the q register.
856
857@q1 :r0
858@q3: r1
859@q2: r2
860@q4: r3
861@q5: r4
862@q7: r5
863@q6: r6
864@q8: r7
865
866
867
868@/// adding the prediction buffer
869
870
871
872
873
874
875
876
877
878    @ load prediction data
879
880
881
882
883
884    @adding recon with prediction
885
886
887
888
889
890    vaddw.u8    q5,q5,d19
891    vqmovun.s16 d2,q1
892    vaddw.u8    q7,q7,d21
893    vqmovun.s16 d4,q2
894    vaddw.u8    q6,q6,d23
895    vqmovun.s16 d6,q3
896    vaddw.u8    q8,q8,d25
897    vqmovun.s16 d8,q4
898
899
900
901
902
903
904
905    vst1.8      {d2},[r3],r7
906    vqmovun.s16 d10,q5
907    vst1.8      {d6},[r3],r10
908    vqmovun.s16 d14,q7
909    vst1.8      {d4},[r0],r7
910    vqmovun.s16 d12,q6
911    vst1.8      {d8},[r0],r10
912    vqmovun.s16 d16,q8
913
914
915
916
917
918
919
920    vst1.8      {d10},[r3],r7
921    vst1.8      {d14},[r3],r10
922    vst1.8      {d12},[r0],r7
923    vst1.8      {d16},[r0],r10
924
925
926
927
928
929    ldmfd       sp!,{r4-r12,pc}
930
931
932
933
934
935