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