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_16x16()
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 16x16 coefficients
51@ *
52@ * @param[in] pi2_tmp
53@ *  temporary 16x16 buffer for storing inverse
54@ *
55@ *  transform
56@ *  1st stage output
57@ *
58@ * @param[in] pu1_pred
59@ *  prediction 16x16 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] r12
77@ *  zero columns in pi2_src
78@ *
79@ * @returns  void
80@ *
81@ * @remarks
82@ *  none
83@ *
84@ *******************************************************************************
85@ */
86
87@void ihevc_itrans_recon_16x16(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 r12
95@                            word32 r11             )
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@   r12
106@   r11
107
108.text
109.align 4
110
111
112
113
114
115
116.set shift_stage1_idct ,   7
117.set shift_stage2_idct ,   12
118@#define zero_cols       r12
119@#define zero_rows       r11
120.globl ihevc_itrans_recon_16x16_a9q
121
122.extern g_ai2_ihevc_trans_16_transpose
123
124g_ai2_ihevc_trans_16_transpose_addr:
125.long g_ai2_ihevc_trans_16_transpose - ulbl1 - 8
126
127.type ihevc_itrans_recon_16x16_a9q, %function
128
129ihevc_itrans_recon_16x16_a9q:
130
131    stmfd       sp!,{r4-r12,lr}
132@   add             sp,sp,#40
133
134
135
136@   ldr         r8,[sp,#4]  @ prediction stride
137@   ldr         r7,[sp,#8]  @ destination stride
138    ldr         r6,[sp,#40]                 @ src stride
139    ldr         r12,[sp,#52]
140    ldr         r11,[sp,#56]
141
142
143
144    ldr         r14,g_ai2_ihevc_trans_16_transpose_addr
145ulbl1:
146    add         r14,r14,pc
147    vld1.16     {d0,d1,d2,d3},[r14]         @//d0,d1 are used for storing the constant data
148    movw        r7,#0xffff
149    and         r12,r12,r7
150    and         r11,r11,r7
151    mov         r6,r6,lsl #1                @ x sizeof(word16)
152    add         r9,r0,r6, lsl #1            @ 2 rows
153
154    add         r10,r6,r6, lsl #1           @ 3 rows
155    add         r5,r6,r6,lsl #2
156    movw        r7,#0xfff0
157
158    cmp         r12,r7
159    bge         zero_12cols_decision
160
161    cmp         r12,#0xff00
162    bge         zero_8cols_decision
163
164
165
166
167    mov         r14,#4
168    cmp         r11,r7
169    rsbge       r10,r6,#0
170
171    cmp         r11,#0xff00
172    movge       r8,r5
173    rsbge       r8,r8,#0
174    movlt       r8,r10
175    add         r5,r5,r6,lsl #3
176    rsb         r5,r5,#0
177
178    b           first_stage_top_four_bottom_four
179
180zero_12cols_decision:
181    mov         r14,#1
182    cmp         r11,#0xff00
183    movge       r8,r5
184    movlt       r8,r10
185    add         r5,r5,r6,lsl #3
186    rsb         r5,r5,#0
187
188    b           first_stage_top_four_bottom_four
189
190zero_8cols_decision:
191    mov         r14,#2
192    mov         r8,r5
193    rsb         r8,r8,#0
194    cmp         r11,#0xff00
195    movlt       r8,r10
196    add         r5,r5,r6,lsl #3
197    rsb         r5,r5,#0
198    cmp         r11,r7
199    rsbge       r10,r6,#0
200
201
202    b           first_stage_top_four_bottom_four
203
204
205@d0[0]= 64      d2[0]=64
206@d0[1]= 90      d2[1]=57
207@d0[2]= 89      d2[2]=50
208@d0[3]= 87      d2[3]=43
209@d1[0]= 83      d3[0]=36
210@d1[1]= 80      d3[1]=25
211@d1[2]= 75      d3[2]=18
212@d1[3]= 70      d3[3]=9
213
214
215
216first_stage:
217    add         r0,r0,#8
218    add         r9,r9,#8
219
220first_stage_top_four_bottom_four:
221
222    vld1.16     d10,[r0],r6
223    vld1.16     d11,[r9],r6
224    vld1.16     d6,[r0],r10
225    vld1.16     d7,[r9],r10
226    cmp         r11,r7
227    bge         skip_load4rows
228
229    vld1.16     d4,[r0],r6
230    vld1.16     d5,[r9],r6
231    vld1.16     d8,[r0],r8
232    vld1.16     d9,[r9],r8
233
234@ registers used: q0,q1,q3,q5,q2,q4
235
236@ d10 =r0
237@d6= r1
238@d11=r2
239@d7=r3
240
241skip_load4rows:
242    vmull.s16   q12,d6,d0[1]                @// y1 * cos1(part of b0)
243    vmull.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
244    vmull.s16   q14,d6,d1[1]                @// y1 * sin3(part of b2)
245    vmull.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
246
247    vmlal.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
248    vmlal.s16   q13,d7,d2[1]                @// y1 * cos3 - y3 * sin1(part of b1)
249    vmlal.s16   q14,d7,d3[3]                @// y1 * sin3 - y3 * cos1(part of b2)
250    vmlsl.s16   q15,d7,d2[3]                @// y1 * sin1 - y3 * sin3(part of b3)
251
252
253
254
255
256
257    vmull.s16   q6,d10,d0[0]
258    vmlal.s16   q6,d11,d0[2]
259    vmull.s16   q7,d10,d0[0]
260    vmlal.s16   q7,d11,d1[2]
261    vmull.s16   q8,d10,d0[0]
262    vmlal.s16   q8,d11,d2[2]
263    vmull.s16   q9,d10,d0[0]
264    vmlal.s16   q9,d11,d3[2]
265
266    bge         skip_last12rows_kernel1
267
268
269    vmlal.s16   q12,d8,d1[1]
270    vmlal.s16   q13,d8,d3[3]
271    vmlsl.s16   q14,d8,d1[3]
272    vmlsl.s16   q15,d8,d0[3]
273
274
275    vmlal.s16   q12,d9,d1[3]
276    vmlsl.s16   q13,d9,d2[3]
277    vmlsl.s16   q14,d9,d0[3]
278    vmlal.s16   q15,d9,d3[3]
279
280
281
282
283
284    vmlal.s16   q6,d4,d1[0]
285    vmlal.s16   q6,d5,d1[2]
286    vmlal.s16   q7,d4,d3[0]
287    vmlsl.s16   q7,d5,d3[2]
288    vmlsl.s16   q8,d4,d3[0]
289    vmlsl.s16   q8,d5,d0[2]
290    vmlsl.s16   q9,d4,d1[0]
291    vmlsl.s16   q9,d5,d2[2]
292
293@d0[0]= 64      d2[0]=64
294@d0[1]= 90      d2[1]=57
295@d0[2]= 89      d2[2]=50
296@d0[3]= 87      d2[3]=43
297@d1[0]= 83      d3[0]=36
298@d1[1]= 80      d3[1]=25
299@d1[2]= 75      d3[2]=18
300@d1[3]= 70      d3[3]=9
301    cmp         r11,#0xff00
302    bge         skip_last12rows_kernel1
303
304
305    vld1.16     d10,[r0],r6
306    vld1.16     d11,[r9],r6
307    vld1.16     d6,[r0],r10
308    vld1.16     d7,[r9],r10
309    vld1.16     d4,[r0],r6
310    vld1.16     d5,[r9],r6
311    vld1.16     d8,[r0],r5
312    vld1.16     d9,[r9],r5
313
314
315
316
317    vmlal.s16   q12,d6,d2[1]                @// y1 * cos1(part of b0)
318    vmlsl.s16   q13,d6,d1[1]                @// y1 * cos3(part of b1)
319    vmlsl.s16   q14,d6,d3[1]                @// y1 * sin3(part of b2)
320    vmlal.s16   q15,d6,d0[1]                @// y1 * sin1(part of b3)
321
322    vmlal.s16   q12,d7,d2[3]                @// y1 * cos1 + y3 * cos3(part of b0)
323    vmlsl.s16   q13,d7,d0[1]                @// y1 * cos3 - y3 * sin1(part of b1)
324    vmlal.s16   q14,d7,d2[1]                @// y1 * sin3 - y3 * cos1(part of b2)
325    vmlal.s16   q15,d7,d3[1]                @// y1 * sin1 - y3 * sin3(part of b3)
326
327
328
329    vmlal.s16   q12,d8,d3[1]
330    vmlsl.s16   q13,d8,d1[3]
331    vmlal.s16   q14,d8,d0[1]
332    vmlsl.s16   q15,d8,d1[1]
333
334
335    vmlal.s16   q12,d9,d3[3]
336    vmlsl.s16   q13,d9,d3[1]
337    vmlal.s16   q14,d9,d2[3]
338    vmlsl.s16   q15,d9,d2[1]
339
340
341
342
343
344    vmlal.s16   q6,d10,d0[0]
345    vmlal.s16   q6,d11,d2[2]
346    vmlal.s16   q6,d4,d3[0]
347    vmlal.s16   q6,d5,d3[2]
348
349
350
351
352    vmlsl.s16   q7,d10,d0[0]
353    vmlsl.s16   q7,d11,d0[2]
354    vmlsl.s16   q7,d4,d1[0]
355    vmlsl.s16   q7,d5,d2[2]
356
357
358    vmlsl.s16   q8,d10,d0[0]
359    vmlal.s16   q8,d11,d3[2]
360    vmlal.s16   q8,d4,d1[0]
361    vmlal.s16   q8,d5,d1[2]
362
363
364    vmlal.s16   q9,d10,d0[0]
365    vmlal.s16   q9,d11,d1[2]
366    vmlsl.s16   q9,d4,d3[0]
367    vmlsl.s16   q9,d5,d0[2]
368
369skip_last12rows_kernel1:
370    vadd.s32    q10,q6,q12
371    vsub.s32    q11,q6,q12
372
373    vadd.s32    q6,q7,q13
374    vsub.s32    q12,q7,q13
375
376    vadd.s32    q7,q8,q14
377    vsub.s32    q13,q8,q14
378
379
380    vadd.s32    q8,q9,q15
381    vsub.s32    q14,q9,q15
382
383
384
385
386
387
388
389    vqrshrn.s32 d30,q10,#shift_stage1_idct  @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
390    vqrshrn.s32 d19,q11,#shift_stage1_idct  @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
391    vqrshrn.s32 d31,q7,#shift_stage1_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
392    vqrshrn.s32 d18,q13,#shift_stage1_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
393    vqrshrn.s32 d12,q6,#shift_stage1_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
394    vqrshrn.s32 d15,q12,#shift_stage1_idct  @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
395    vqrshrn.s32 d13,q8,#shift_stage1_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
396    vqrshrn.s32 d14,q14,#shift_stage1_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
397
398    vst1.16     {d30,d31},[r1]!
399    vst1.16     {d18,d19},[r1]!
400    sub         r1,r1,#32
401
402    bge         skip_stage1_kernel_load
403
404first_stage_middle_eight:
405
406
407
408    vld1.16     d10,[r0],r6
409    vld1.16     d11,[r9],r6
410    vld1.16     d6,[r0],r10
411    vld1.16     d7,[r9],r10
412    vld1.16     d4,[r0],r6
413    vld1.16     d5,[r9],r6
414    vld1.16     d8,[r0],r8
415    vld1.16     d9,[r9],r8
416
417
418skip_stage1_kernel_load:
419    vmull.s16   q12,d6,d2[1]                @// y1 * cos1(part of b0)
420    vmull.s16   q13,d6,d2[3]                @// y1 * cos3(part of b1)
421    vmull.s16   q14,d6,d3[1]                @// y1 * sin3(part of b2)
422    vmull.s16   q15,d6,d3[3]                @// y1 * sin1(part of b3)
423
424    vmlsl.s16   q12,d7,d1[1]                @// y1 * cos1 + y3 * cos3(part of b0)
425    vmlsl.s16   q13,d7,d0[1]                @// y1 * cos3 - y3 * sin1(part of b1)
426    vmlsl.s16   q14,d7,d1[3]                @// y1 * sin3 - y3 * cos1(part of b2)
427    vmlsl.s16   q15,d7,d3[1]                @// y1 * sin1 - y3 * sin3(part of b3)
428
429
430
431
432
433
434    vmull.s16   q11,d10,d0[0]
435    vmlsl.s16   q11,d11,d3[2]
436    vmull.s16   q10,d10,d0[0]
437    vmlsl.s16   q10,d11,d2[2]
438    vmull.s16   q8,d10,d0[0]
439    vmlsl.s16   q8,d11,d1[2]
440    vmull.s16   q9,d10,d0[0]
441    vmlsl.s16   q9,d11,d0[2]
442
443
444    cmp         r11,r7
445    bge         skip_last12rows_kernel2
446
447    vmlsl.s16   q12,d8,d3[1]
448    vmlal.s16   q13,d8,d2[1]
449    vmlal.s16   q14,d8,d0[1]
450    vmlal.s16   q15,d8,d2[3]
451
452
453    vmlal.s16   q12,d9,d0[1]
454    vmlal.s16   q13,d9,d3[1]
455    vmlsl.s16   q14,d9,d1[1]
456    vmlsl.s16   q15,d9,d2[1]
457
458
459
460    vmlsl.s16   q11,d4,d1[0]
461    vmlal.s16   q11,d5,d2[2]
462    vmlsl.s16   q10,d4,d3[0]
463    vmlal.s16   q10,d5,d0[2]
464    vmlal.s16   q8,d4,d3[0]
465    vmlal.s16   q8,d5,d3[2]
466    vmlal.s16   q9,d4,d1[0]
467    vmlsl.s16   q9,d5,d1[2]
468
469@d0[0]= 64      d2[0]=64
470@d0[1]= 90      d2[1]=57
471@d0[2]= 89      d2[2]=50
472@d0[3]= 87      d2[3]=43
473@d1[0]= 83      d3[0]=36
474@d1[1]= 80      d3[1]=25
475@d1[2]= 75      d3[2]=18
476@d1[3]= 70      d3[3]=9
477    cmp         r11,#0xff00
478    bge         skip_last12rows_kernel2
479
480    vld1.16     d10,[r0],r6
481    vld1.16     d11,[r9],r6
482    vld1.16     d6,[r0],r10
483    vld1.16     d7,[r9],r10
484    vld1.16     d4,[r0],r6
485    vld1.16     d5,[r9],r6
486    vld1.16     d8,[r0],r5
487    vld1.16     d9,[r9],r5
488
489
490    vmlsl.s16   q12,d6,d3[3]                @// y1 * cos1(part of b0)
491    vmlsl.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
492    vmlal.s16   q14,d6,d2[3]                @// y1 * sin3(part of b2)
493    vmlal.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
494
495    vmlsl.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
496    vmlal.s16   q13,d7,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
497    vmlal.s16   q14,d7,d3[3]                @// y1 * sin3 - y3 * cos1(part of b2)
498    vmlsl.s16   q15,d7,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
499
500
501    vmlal.s16   q12,d8,d2[3]
502    vmlal.s16   q13,d8,d3[3]
503    vmlsl.s16   q14,d8,d2[1]
504    vmlal.s16   q15,d8,d0[3]
505
506
507    vmlal.s16   q12,d9,d1[3]
508    vmlsl.s16   q13,d9,d1[1]
509    vmlal.s16   q14,d9,d0[3]
510    vmlsl.s16   q15,d9,d0[1]
511
512
513
514
515    vmlal.s16   q11,d10,d0[0]
516    vmlsl.s16   q11,d11,d1[2]
517    vmlsl.s16   q11,d4,d3[0]
518    vmlal.s16   q11,d5,d0[2]
519
520
521
522    vmlsl.s16   q10,d10,d0[0]
523    vmlsl.s16   q10,d11,d3[2]
524    vmlal.s16   q10,d4,d1[0]
525    vmlsl.s16   q10,d5,d1[2]
526
527
528    vmlsl.s16   q8,d10,d0[0]
529    vmlal.s16   q8,d11,d0[2]
530    vmlsl.s16   q8,d4,d1[0]
531    vmlal.s16   q8,d5,d2[2]
532
533
534
535    vmlal.s16   q9,d10,d0[0]
536    vmlsl.s16   q9,d11,d2[2]
537    vmlal.s16   q9,d4,d3[0]
538    vmlsl.s16   q9,d5,d3[2]
539
540skip_last12rows_kernel2:
541
542    vadd.s32    q2,q11,q12
543    vsub.s32    q11,q11,q12
544
545    vadd.s32    q3,q10,q13
546    vsub.s32    q12,q10,q13
547
548    vadd.s32    q5,q8,q14
549    vsub.s32    q13,q8,q14
550
551
552    vadd.s32    q8,q9,q15
553    vsub.s32    q14,q9,q15
554
555
556    vqrshrn.s32 d18,q2,#shift_stage1_idct   @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
557    vqrshrn.s32 d31,q11,#shift_stage1_idct  @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
558    vqrshrn.s32 d19,q5,#shift_stage1_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
559    vqrshrn.s32 d30,q13,#shift_stage1_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
560    vqrshrn.s32 d20,q3,#shift_stage1_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
561    vqrshrn.s32 d23,q12,#shift_stage1_idct  @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
562    vqrshrn.s32 d21,q8,#shift_stage1_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
563    vqrshrn.s32 d22,q14,#shift_stage1_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
564
565
566    @ registers used:   {q2,q4,q6,q7}, {q9,q15,q10,q11}
567
568
569
570
571
572
573    vld1.16     {d4,d5},[r1]!
574    vld1.16     {d8,d9},[r1]!
575    sub         r1,r1,#32
576
577@d4=r0
578@d12=r1
579@d5=r2
580@d13=r3
581
582@d18=r4
583@d20=r5
584@d19=r6
585@d21=r7
586
587@d22=r8
588@d30=r9
589@d23=r10
590@d31=r11
591
592@d14=r12
593@d8=r13
594@d15=r14
595@d9=r15
596
597
598    vtrn.16     q2,q6
599    vtrn.16     q9,q10
600    vtrn.16     q11,q15
601    vtrn.16     q7,q4
602
603
604
605    vtrn.32     d4,d5
606    vtrn.32     d12,d13
607
608    vtrn.32     d18,d19
609    vtrn.32     d20,d21
610
611    vtrn.32     d22,d23
612    vtrn.32     d30,d31
613
614    vtrn.32     d14,d15
615    vtrn.32     d8,d9
616
617
618@ d4 =r0 1- 4 values
619@ d5 =r2 1- 4 values
620@ d12=r1 1- 4 values
621@ d13=r3 1- 4 values
622
623@ d18 =r0 5- 8 values
624@ d19 =r2 5- 8 values
625@ d20=r1 5- 8 values
626@ d21=r3 5- 8 values
627
628@ d22 =r0 9- 12 values
629@ d23 =r2 9- 12 values
630@ d30=r1 9- 12 values
631@ d31=r3 9- 12 values
632
633@ d14 =r0 13-16 values
634@ d15 =r2 13- 16 values
635@ d8=r1 13- 16 values
636@ d9=r3 13- 16 values
637
638
639    vst1.16     {q2},[r1]!
640    vst1.16     {q6},[r1]!
641
642    vst1.16     {q9},[r1]!
643    vst1.16     {q10},[r1]!
644    vst1.16     {q11},[r1]!
645    vst1.16     {q15},[r1]!
646    vst1.16     {q7},[r1]!
647    vst1.16     {q4},[r1]!
648
649
650    subs        r14,r14,#1
651    bne         first_stage
652
653
654
655
656
657
658
659
660
661
662    mov         r6,r7
663
664    ldr         r8,[sp,#44]                 @ prediction stride
665    ldr         r7,[sp,#48]                 @ destination stride
666
667    mov         r10,#16
668
669    cmp         r12,r6
670    subge       r1,r1,#128
671    bge         label1
672
673    cmp         r12,#0xff00
674    subge       r1,r1,#256
675    bge         label_2
676
677    sub         r1,r1,#512
678    rsb         r10,r10,#0
679
680label_2:
681    add         r9,r1,#128
682    add         r11,r9,#128
683    add         r0,r11,#128
684
685
686
687label1:
688@   mov   r6,r1
689
690
691    mov         r14,#4
692    add         r4,r2,r8, lsl #1            @ r4 = r2 + pred_strd * 2    => r4 points to 3rd row of pred data
693    add         r5,r8,r8, lsl #1            @
694@   add r0,r3,r7, lsl #1    @ r0 points to 3rd row of dest data
695@   add r10,r7,r7, lsl #1   @
696
697
698
699
700second_stage:
701    vld1.16     {d10,d11},[r1]!
702    vld1.16     {d6,d7},[r1],r10
703    cmp         r12,r6
704    bge         second_stage_process
705    vld1.16     {d4,d5},[r9]!
706    vld1.16     {d8,d9},[r9],r10
707
708second_stage_process:
709
710
711    vmull.s16   q12,d6,d0[1]                @// y1 * cos1(part of b0)
712    vmull.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
713    vmull.s16   q14,d6,d1[1]                @// y1 * sin3(part of b2)
714    vmull.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
715
716    vmlal.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
717    vmlal.s16   q13,d7,d2[1]                @// y1 * cos3 - y3 * sin1(part of b1)
718    vmlal.s16   q14,d7,d3[3]                @// y1 * sin3 - y3 * cos1(part of b2)
719    vmlsl.s16   q15,d7,d2[3]                @// y1 * sin1 - y3 * sin3(part of b3)
720
721
722    vmull.s16   q6,d10,d0[0]
723    vmlal.s16   q6,d11,d0[2]
724    vmull.s16   q7,d10,d0[0]
725    vmlal.s16   q7,d11,d1[2]
726    vmull.s16   q8,d10,d0[0]
727    vmlal.s16   q8,d11,d2[2]
728    vmull.s16   q9,d10,d0[0]
729    vmlal.s16   q9,d11,d3[2]
730
731    bge         skip_last8rows_stage2_kernel1
732
733    vmlal.s16   q12,d8,d1[1]
734    vmlal.s16   q13,d8,d3[3]
735    vmlsl.s16   q14,d8,d1[3]
736    vmlsl.s16   q15,d8,d0[3]
737
738
739    vmlal.s16   q12,d9,d1[3]
740    vmlsl.s16   q13,d9,d2[3]
741    vmlsl.s16   q14,d9,d0[3]
742    vmlal.s16   q15,d9,d3[3]
743
744
745    vmlal.s16   q6,d4,d1[0]
746    vmlal.s16   q6,d5,d1[2]
747    vmlal.s16   q7,d4,d3[0]
748    vmlsl.s16   q7,d5,d3[2]
749    vmlsl.s16   q8,d4,d3[0]
750    vmlsl.s16   q8,d5,d0[2]
751    vmlsl.s16   q9,d4,d1[0]
752    vmlsl.s16   q9,d5,d2[2]
753
754    cmp         r12,#0xff00
755    bge         skip_last8rows_stage2_kernel1
756
757
758    vld1.16     {d10,d11},[r11]!
759    vld1.16     {d6,d7},[r11],r10
760    vld1.16     {d4,d5},[r0]!
761    vld1.16     {d8,d9},[r0],r10
762
763
764
765
766
767    vmlal.s16   q12,d6,d2[1]                @// y1 * cos1(part of b0)
768    vmlsl.s16   q13,d6,d1[1]                @// y1 * cos3(part of b1)
769    vmlsl.s16   q14,d6,d3[1]                @// y1 * sin3(part of b2)
770    vmlal.s16   q15,d6,d0[1]                @// y1 * sin1(part of b3)
771
772    vmlal.s16   q12,d7,d2[3]                @// y1 * cos1 + y3 * cos3(part of b0)
773    vmlsl.s16   q13,d7,d0[1]                @// y1 * cos3 - y3 * sin1(part of b1)
774    vmlal.s16   q14,d7,d2[1]                @// y1 * sin3 - y3 * cos1(part of b2)
775    vmlal.s16   q15,d7,d3[1]                @// y1 * sin1 - y3 * sin3(part of b3)
776
777
778
779    vmlal.s16   q12,d8,d3[1]
780    vmlsl.s16   q13,d8,d1[3]
781    vmlal.s16   q14,d8,d0[1]
782    vmlsl.s16   q15,d8,d1[1]
783
784
785    vmlal.s16   q12,d9,d3[3]
786    vmlsl.s16   q13,d9,d3[1]
787    vmlal.s16   q14,d9,d2[3]
788    vmlsl.s16   q15,d9,d2[1]
789
790
791
792
793
794    vmlal.s16   q6,d10,d0[0]
795    vmlal.s16   q6,d11,d2[2]
796    vmlal.s16   q6,d4,d3[0]
797    vmlal.s16   q6,d5,d3[2]
798
799
800
801
802    vmlsl.s16   q7,d10,d0[0]
803    vmlsl.s16   q7,d11,d0[2]
804    vmlsl.s16   q7,d4,d1[0]
805    vmlsl.s16   q7,d5,d2[2]
806
807
808    vmlsl.s16   q8,d10,d0[0]
809    vmlal.s16   q8,d11,d3[2]
810    vmlal.s16   q8,d4,d1[0]
811    vmlal.s16   q8,d5,d1[2]
812
813
814    vmlal.s16   q9,d10,d0[0]
815    vmlal.s16   q9,d11,d1[2]
816    vmlsl.s16   q9,d4,d3[0]
817    vmlsl.s16   q9,d5,d0[2]
818
819
820
821
822
823
824skip_last8rows_stage2_kernel1:
825
826
827
828    vadd.s32    q10,q6,q12
829    vsub.s32    q11,q6,q12
830
831    vadd.s32    q6,q7,q13
832    vsub.s32    q12,q7,q13
833
834    vadd.s32    q7,q8,q14
835    vsub.s32    q13,q8,q14
836
837
838    vadd.s32    q8,q9,q15
839    vsub.s32    q14,q9,q15
840
841
842
843
844
845
846
847    vqrshrn.s32 d30,q10,#shift_stage2_idct  @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
848    vqrshrn.s32 d19,q11,#shift_stage2_idct  @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
849    vqrshrn.s32 d31,q7,#shift_stage2_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
850    vqrshrn.s32 d18,q13,#shift_stage2_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
851    vqrshrn.s32 d12,q6,#shift_stage2_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
852    vqrshrn.s32 d15,q12,#shift_stage2_idct  @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
853    vqrshrn.s32 d13,q8,#shift_stage2_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
854    vqrshrn.s32 d14,q14,#shift_stage2_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
855
856    bge         skip_stage2_kernel_load
857
858    @q2,q4,q6,q7 is used
859    vld1.16     {d10,d11},[r1]!
860    vld1.16     {d6,d7},[r1]!
861    vld1.16     {d4,d5},[r9]!
862    vld1.16     {d8,d9},[r9]!
863skip_stage2_kernel_load:
864    sub         r1,r1,#32
865    vst1.16     {d30,d31},[r1]!
866    vst1.16     {d18,d19},[r1]!
867    sub         r1,r1,#32
868
869    vmull.s16   q12,d6,d2[1]                @// y1 * cos1(part of b0)
870    vmull.s16   q13,d6,d2[3]                @// y1 * cos3(part of b1)
871    vmull.s16   q14,d6,d3[1]                @// y1 * sin3(part of b2)
872    vmull.s16   q15,d6,d3[3]                @// y1 * sin1(part of b3)
873
874    vmlsl.s16   q12,d7,d1[1]                @// y1 * cos1 + y3 * cos3(part of b0)
875    vmlsl.s16   q13,d7,d0[1]                @// y1 * cos3 - y3 * sin1(part of b1)
876    vmlsl.s16   q14,d7,d1[3]                @// y1 * sin3 - y3 * cos1(part of b2)
877    vmlsl.s16   q15,d7,d3[1]                @// y1 * sin1 - y3 * sin3(part of b3)
878
879
880    vmull.s16   q11,d10,d0[0]
881    vmlsl.s16   q11,d11,d3[2]
882    vmull.s16   q10,d10,d0[0]
883    vmlsl.s16   q10,d11,d2[2]
884    vmull.s16   q8,d10,d0[0]
885    vmlsl.s16   q8,d11,d1[2]
886    vmull.s16   q9,d10,d0[0]
887    vmlsl.s16   q9,d11,d0[2]
888
889
890
891    cmp         r12,r6
892    bge         skip_last8rows_stage2_kernel2
893
894
895    vmlsl.s16   q12,d8,d3[1]
896    vmlal.s16   q13,d8,d2[1]
897    vmlal.s16   q14,d8,d0[1]
898    vmlal.s16   q15,d8,d2[3]
899
900
901    vmlal.s16   q12,d9,d0[1]
902    vmlal.s16   q13,d9,d3[1]
903    vmlsl.s16   q14,d9,d1[1]
904    vmlsl.s16   q15,d9,d2[1]
905
906
907
908    vmlsl.s16   q11,d4,d1[0]
909    vmlal.s16   q11,d5,d2[2]
910    vmlsl.s16   q10,d4,d3[0]
911    vmlal.s16   q10,d5,d0[2]
912    vmlal.s16   q8,d4,d3[0]
913    vmlal.s16   q8,d5,d3[2]
914    vmlal.s16   q9,d4,d1[0]
915    vmlsl.s16   q9,d5,d1[2]
916    cmp         r12,#0xff00
917    bge         skip_last8rows_stage2_kernel2
918
919    vld1.16     {d10,d11},[r11]!
920    vld1.16     {d6,d7},[r11]!
921    vld1.16     {d4,d5},[r0]!
922    vld1.16     {d8,d9},[r0]!
923
924    vmlsl.s16   q12,d6,d3[3]                @// y1 * cos1(part of b0)
925    vmlsl.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
926    vmlal.s16   q14,d6,d2[3]                @// y1 * sin3(part of b2)
927    vmlal.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
928
929    vmlsl.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
930    vmlal.s16   q13,d7,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
931    vmlal.s16   q14,d7,d3[3]                @// y1 * sin3 - y3 * cos1(part of b2)
932    vmlsl.s16   q15,d7,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
933
934
935    vmlal.s16   q12,d8,d2[3]
936    vmlal.s16   q13,d8,d3[3]
937    vmlsl.s16   q14,d8,d2[1]
938    vmlal.s16   q15,d8,d0[3]
939
940
941    vmlal.s16   q12,d9,d1[3]
942    vmlsl.s16   q13,d9,d1[1]
943    vmlal.s16   q14,d9,d0[3]
944    vmlsl.s16   q15,d9,d0[1]
945
946
947
948
949    vmlal.s16   q11,d10,d0[0]
950    vmlsl.s16   q11,d11,d1[2]
951    vmlsl.s16   q11,d4,d3[0]
952    vmlal.s16   q11,d5,d0[2]
953
954
955
956    vmlsl.s16   q10,d10,d0[0]
957    vmlsl.s16   q10,d11,d3[2]
958    vmlal.s16   q10,d4,d1[0]
959    vmlsl.s16   q10,d5,d1[2]
960
961
962    vmlsl.s16   q8,d10,d0[0]
963    vmlal.s16   q8,d11,d0[2]
964    vmlsl.s16   q8,d4,d1[0]
965    vmlal.s16   q8,d5,d2[2]
966
967
968
969    vmlal.s16   q9,d10,d0[0]
970    vmlsl.s16   q9,d11,d2[2]
971    vmlal.s16   q9,d4,d3[0]
972    vmlsl.s16   q9,d5,d3[2]
973
974
975skip_last8rows_stage2_kernel2:
976
977
978
979    vadd.s32    q2,q11,q12
980    vsub.s32    q11,q11,q12
981
982    vadd.s32    q3,q10,q13
983    vsub.s32    q12,q10,q13
984
985    vadd.s32    q5,q8,q14
986    vsub.s32    q13,q8,q14
987
988
989    vadd.s32    q8,q9,q15
990    vsub.s32    q14,q9,q15
991
992
993    vqrshrn.s32 d18,q2,#shift_stage2_idct   @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
994    vqrshrn.s32 d31,q11,#shift_stage2_idct  @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
995    vqrshrn.s32 d19,q5,#shift_stage2_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
996    vqrshrn.s32 d30,q13,#shift_stage2_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
997    vqrshrn.s32 d20,q3,#shift_stage2_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
998    vqrshrn.s32 d23,q12,#shift_stage2_idct  @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
999    vqrshrn.s32 d21,q8,#shift_stage2_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
1000    vqrshrn.s32 d22,q14,#shift_stage2_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
1001
1002    vld1.16     {d4,d5},[r1]!
1003    vld1.16     {d8,d9},[r1]!
1004
1005
1006
1007    @ registers used:   {q2,q4,q6,q7}, {q9,q15,q10,q11}
1008
1009@d4=r0
1010@d12=r1
1011@d5=r2
1012@d13=r3
1013
1014@d18=r4
1015@d20=r5
1016@d19=r6
1017@d21=r7
1018
1019@d22=r8
1020@d30=r9
1021@d23=r10
1022@d31=r11
1023
1024@d14=r12
1025@d8=r13
1026@d15=r14
1027@d9=r15
1028
1029
1030    vtrn.16     q2,q6
1031    vtrn.16     q9,q10
1032    vtrn.16     q11,q15
1033    vtrn.16     q7,q4
1034
1035
1036
1037    vtrn.32     d4,d5
1038    vtrn.32     d12,d13
1039
1040    vtrn.32     d18,d19
1041    vtrn.32     d20,d21
1042
1043    vtrn.32     d22,d23
1044    vtrn.32     d30,d31
1045
1046    vtrn.32     d14,d15
1047    vtrn.32     d8,d9
1048
1049@ d4 =r0 1- 4 values
1050@ d5 =r2 1- 4 values
1051@ d12=r1 1- 4 values
1052@ d13=r3 1- 4 values
1053
1054@ d18 =r0 5- 8 values
1055@ d19 =r2 5- 8 values
1056@ d20=r1 5- 8 values
1057@ d21=r3 5- 8 values
1058
1059@ d22 =r0 9- 12 values
1060@ d23 =r2 9- 12 values
1061@ d30=r1 9- 12 values
1062@ d31=r3 9- 12 values
1063
1064@ d14 =r0 13-16 values
1065@ d15 =r2 13- 16 values
1066@ d8=r1 13- 16 values
1067@ d9=r3 13- 16 values
1068
1069
1070    vswp        d5,d18
1071    vswp        d23,d14
1072    vswp        d13,d20
1073    vswp        d31,d8
1074
1075@ q2: r0 1-8 values
1076@ q11: r0 9-16 values
1077@ q9 : r2 1-8 values
1078@ q7 : r2 9-16 values
1079@ q6 : r1 1- 8 values
1080@ q10: r3 1-8 values
1081@ q15: r1 9-16 values
1082@ q4:  r3 9-16 values
1083
1084
1085@   registers free: q8,q14,q12,q13
1086
1087
1088    vld1.8      {d16,d17},[r2],r8
1089    vld1.8      {d28,d29},[r2],r5
1090    vld1.8      {d24,d25},[r4],r8
1091    vld1.8      {d26,d27},[r4],r5
1092
1093
1094
1095
1096    vaddw.u8    q2,q2,d16
1097    vaddw.u8    q11,q11,d17
1098    vaddw.u8    q6,q6,d28
1099    vaddw.u8    q15,q15,d29
1100    vaddw.u8    q9,q9,d24
1101    vaddw.u8    q7,q7,d25
1102    vaddw.u8    q10,q10,d26
1103    vaddw.u8    q4,q4,d27
1104
1105
1106    vqmovun.s16 d16,q2
1107    vqmovun.s16 d17,q11
1108    vqmovun.s16 d28,q6
1109    vqmovun.s16 d29,q15
1110    vqmovun.s16 d24,q9
1111    vqmovun.s16 d25,q7
1112    vqmovun.s16 d26,q10
1113    vqmovun.s16 d27,q4
1114
1115
1116
1117    vst1.8      {d16,d17},[r3],r7
1118    vst1.8      {d28,d29},[r3],r7
1119    vst1.8      {d24,d25},[r3],r7
1120    vst1.8      {d26,d27},[r3],r7
1121
1122    subs        r14,r14,#1
1123
1124
1125
1126    bne         second_stage
1127
1128
1129@   sub         sp,sp,#40
1130    ldmfd       sp!,{r4-r12,pc}
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142