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