2 ; Copyright (c) 2013 The WebM project authors. All Rights Reserved.
4 ; Use of this source code is governed by a BSD-style license
5 ; that can be found in the LICENSE file in the root of the source
6 ; tree. An additional intellectual property rights grant can be found
7 ; in the file PATENTS. All contributing project authors may
8 ; be found in the AUTHORS file in the root of the source tree.
11 ;TODO(cd): adjust these constant to be able to use vqdmulh for faster
12 ; dct_const_round_shift(a * b) within butterfly calculations.
46 EXPORT |vp9_idct32x32_1024_add_neon|
51 AREA ||.text||, CODE, READONLY, ALIGN=2
53 AREA Block, CODE, READONLY
55 ; --------------------------------------------------------------------------
56 ; Load from transposed_buffer
57 ; q13 = transposed_buffer[first_offset]
58 ; q14 = transposed_buffer[second_offset]
59 ; for proper address calculation, the last offset used when manipulating
60 ; transposed_buffer must be passed in. use 0 for first use.
62 LOAD_FROM_TRANSPOSED $prev_offset, $first_offset, $second_offset
63 ; address calculation with proper stride and loading
64 add r0, #($first_offset - $prev_offset )*8*2
66 add r0, #($second_offset - $first_offset)*8*2
68 ; (used) two registers (q14, q13)
70 ; --------------------------------------------------------------------------
71 ; Load from output (used as temporary storage)
72 ; reg1 = output[first_offset]
73 ; reg2 = output[second_offset]
74 ; for proper address calculation, the last offset used when manipulating
75 ; output, wethere reading or storing) must be passed in. use 0 for first
78 LOAD_FROM_OUTPUT $prev_offset, $first_offset, $second_offset, $reg1, $reg2
79 ; address calculation with proper stride and loading
80 add r1, #($first_offset - $prev_offset )*32*2
81 vld1.s16 {$reg1}, [r1]
82 add r1, #($second_offset - $first_offset)*32*2
83 vld1.s16 {$reg2}, [r1]
84 ; (used) two registers ($reg1, $reg2)
86 ; --------------------------------------------------------------------------
87 ; Store into output (sometimes as as temporary storage)
88 ; output[first_offset] = reg1
89 ; output[second_offset] = reg2
90 ; for proper address calculation, the last offset used when manipulating
91 ; output, wethere reading or storing) must be passed in. use 0 for first
94 STORE_IN_OUTPUT $prev_offset, $first_offset, $second_offset, $reg1, $reg2
95 ; address calculation with proper stride and storing
96 add r1, #($first_offset - $prev_offset )*32*2
98 add r1, #($second_offset - $first_offset)*32*2
101 ; --------------------------------------------------------------------------
102 ; Combine-add results with current destination content
103 ; q6-q9 contain the results (out[j * 32 + 0-31])
105 STORE_COMBINE_CENTER_RESULTS
106 ; load dest[j * dest_stride + 0-31]
107 vld1.s16 {d8}, [r10], r2
108 vld1.s16 {d11}, [r9], r11
116 ; add to dest[j * dest_stride + 0-31]
126 ; store back into dest[j * dest_stride + 0-31]
127 vst1.16 {d9}, [r10], r11
128 vst1.16 {d10}, [r9], r2
131 ; update pointers (by dest_stride * 2)
132 sub r9, r9, r2, lsl #1
133 add r10, r10, r2, lsl #1
135 ; --------------------------------------------------------------------------
136 ; Combine-add results with current destination content
137 ; q6-q9 contain the results (out[j * 32 + 0-31])
139 STORE_COMBINE_CENTER_RESULTS_LAST
140 ; load dest[j * dest_stride + 0-31]
141 vld1.s16 {d8}, [r10], r2
142 vld1.s16 {d11}, [r9], r11
150 ; add to dest[j * dest_stride + 0-31]
160 ; store back into dest[j * dest_stride + 0-31]
161 vst1.16 {d9}, [r10], r11
162 vst1.16 {d10}, [r9], r2
165 ; update pointers (by dest_stride * 2)
166 sub r9, r9, r2, lsl #1
167 add r10, r10, r2, lsl #1
169 ; --------------------------------------------------------------------------
170 ; Combine-add results with current destination content
171 ; q4-q7 contain the results (out[j * 32 + 0-31])
173 STORE_COMBINE_EXTREME_RESULTS
174 ; load dest[j * dest_stride + 0-31]
175 vld1.s16 {d4}, [r7], r2
176 vld1.s16 {d7}, [r6], r11
184 ; add to dest[j * dest_stride + 0-31]
194 ; store back into dest[j * dest_stride + 0-31]
195 vst1.16 {d5}, [r7], r11
196 vst1.16 {d6}, [r6], r2
199 ; update pointers (by dest_stride * 2)
200 sub r6, r6, r2, lsl #1
201 add r7, r7, r2, lsl #1
203 ; --------------------------------------------------------------------------
204 ; Combine-add results with current destination content
205 ; q4-q7 contain the results (out[j * 32 + 0-31])
207 STORE_COMBINE_EXTREME_RESULTS_LAST
208 ; load dest[j * dest_stride + 0-31]
209 vld1.s16 {d4}, [r7], r2
210 vld1.s16 {d7}, [r6], r11
218 ; add to dest[j * dest_stride + 0-31]
228 ; store back into dest[j * dest_stride + 0-31]
229 vst1.16 {d5}, [r7], r11
230 vst1.16 {d6}, [r6], r2
233 ; update pointers (by dest_stride * 2)
234 sub r6, r6, r2, lsl #1
235 add r7, r7, r2, lsl #1
237 ; --------------------------------------------------------------------------
238 ; Touches q8-q12, q15 (q13-q14 are preserved)
239 ; valid output registers are anything but q8-q11
241 DO_BUTTERFLY $regC, $regD, $regA, $regB, $first_constant, $second_constant, $reg1, $reg2, $reg3, $reg4
242 ; TODO(cd): have special case to re-use constants when they are similar for
243 ; consecutive butterflies
244 ; TODO(cd): have special case when both constants are the same, do the
245 ; additions/substractions before the multiplies.
246 ; generate the constants
247 ; generate scalar constants
248 mov r8, #$first_constant & 0xFF00
249 mov r12, #$second_constant & 0xFF00
250 add r8, #$first_constant & 0x00FF
251 add r12, #$second_constant & 0x00FF
252 ; generate vector constants
255 ; (used) two for inputs (regA-regD), one for constants (q15)
256 ; do some multiplications (ordered for maximum latency hiding)
257 vmull.s16 q8, $regC, d30
258 vmull.s16 q10, $regA, d31
259 vmull.s16 q9, $regD, d30
260 vmull.s16 q11, $regB, d31
261 vmull.s16 q12, $regC, d31
262 ; (used) five for intermediate (q8-q12), one for constants (q15)
263 ; do some addition/substractions (to get back two register)
266 ; do more multiplications (ordered for maximum latency hiding)
267 vmull.s16 q10, $regD, d31
268 vmull.s16 q11, $regA, d30
269 vmull.s16 q15, $regB, d30
270 ; (used) six for intermediate (q8-q12, q15)
271 ; do more addition/substractions
272 vadd.s32 q11, q12, q11
273 vadd.s32 q10, q10, q15
274 ; (used) four for intermediate (q8-q11)
275 ; dct_const_round_shift
276 vqrshrn.s32 $reg1, q8, #14
277 vqrshrn.s32 $reg2, q9, #14
278 vqrshrn.s32 $reg3, q11, #14
279 vqrshrn.s32 $reg4, q10, #14
280 ; (used) two for results, well four d registers
282 ; --------------------------------------------------------------------------
283 ; Touches q8-q12, q15 (q13-q14 are preserved)
284 ; valid output registers are anything but q8-q11
286 DO_BUTTERFLY_STD $first_constant, $second_constant, $reg1, $reg2, $reg3, $reg4
287 DO_BUTTERFLY d28, d29, d26, d27, $first_constant, $second_constant, $reg1, $reg2, $reg3, $reg4
289 ; --------------------------------------------------------------------------
291 ;void vp9_idct32x32_1024_add_neon(int16_t *input, uint8_t *dest, int dest_stride);
295 ; r2 int dest_stride)
297 ; r4 bands loop counter
298 ; r5 pass loop counter
299 ; r8 transpose loop counter
300 ; combine-add pointers
301 ; r6 dest + 31 * dest_stride, descending (30, 29, 28, ...)
302 ; r7 dest + 0 * dest_stride, ascending (1, 2, 3, ...)
303 ; r9 dest + 15 * dest_stride, descending (14, 13, 12, ...)
304 ; r10 dest + 16 * dest_stride, ascending (17, 18, 19, ...)
306 |vp9_idct32x32_1024_add_neon| PROC
307 ; This function does one pass of idct32x32 transform.
309 ; This is done by transposing the input and then doing a 1d transform on
310 ; columns. In the first pass, the transposed columns are the original
311 ; rows. In the second pass, after the transposition, the colums are the
313 ; The 1d transform is done by looping over bands of eight columns (the
314 ; idct32_bands loop). For each band, the transform input transposition
315 ; is done on demand, one band of four 8x8 matrices at a time. The four
316 ; matrices are transposed by pairs (the idct32_transpose_pair loop).
320 ; internal buffer used to transpose 8 lines into before transforming them
321 ; int16_t transpose_buffer[32 * 8];
322 ; at sp + [4096, 4607]
323 ; results of the first pass (transpose and transform rows)
324 ; int16_t pass1[32 * 32];
326 ; results of the second pass (transpose and transform columns)
327 ; int16_t pass2[32 * 32];
328 ; at sp + [2048, 4095]
329 sub sp, sp, #512+2048+2048
331 ; r6 = dest + 31 * dest_stride
332 ; r7 = dest + 0 * dest_stride
333 ; r9 = dest + 15 * dest_stride
334 ; r10 = dest + 16 * dest_stride
335 rsb r6, r2, r2, lsl #5
336 rsb r9, r2, r2, lsl #4
337 add r10, r1, r2, lsl #4
345 ; parameters for first pass
346 ; r0 = transpose_buffer[32 * 8]
348 ; r1 = pass1[32 * 32]
351 mov r5, #0 ; initialize pass loop counter
353 mov r4, #4 ; initialize bands loop counter
355 mov r8, #2 ; initialize transpose loop counter
356 idct32_transpose_pair_loop
357 ; Load two horizontally consecutive 8x8 16bit data matrices. The first one
358 ; into q0-q7 and the second one into q8-q15. There is a stride of 64,
359 ; adjusted to 32 because of the two post-increments.
366 vld1.s16 {q10}, [r3]!
369 vld1.s16 {q11}, [r3]!
372 vld1.s16 {q12}, [r3]!
375 vld1.s16 {q13}, [r3]!
378 vld1.s16 {q14}, [r3]!
381 vld1.s16 {q15}, [r3]!
384 ; Transpose the two 8x8 16bit data matrices.
410 ; Store both matrices after each other. There is a stride of 32, which
411 ; adjusts to nothing because of the post-increments.
429 ; increment pointers by adjusted stride (not necessary for r0/out)
430 ; go back by 7*32 for the seven lines moved fully by read and add
431 ; go back by 32 for the eigth line only read
432 ; advance by 16*2 to go the next pair
433 sub r3, r3, #7*32*2 + 32 - 16*2
434 ; transpose pair loop processing
436 bne idct32_transpose_pair_loop
438 ; restore r0/input to its original value
441 ; Instead of doing the transforms stage by stage, it is done by loading
442 ; some input values and doing as many stages as possible to minimize the
443 ; storing/loading of intermediate results. To fit within registers, the
444 ; final coefficients are cut into four blocks:
445 ; BLOCK A: 16-19,28-31
446 ; BLOCK B: 20-23,24-27
447 ; BLOCK C: 8-10,11-15
449 ; Blocks A and C are straight calculation through the various stages. In
450 ; block B, further calculations are performed using the results from
451 ; block A. In block D, further calculations are performed using the results
452 ; from block C and then the final calculations are done using results from
453 ; block A and B which have been combined at the end of block B.
455 ; --------------------------------------------------------------------------
456 ; BLOCK A: 16-19,28-31
457 ; --------------------------------------------------------------------------
458 ; generate 16,17,30,31
459 ; --------------------------------------------------------------------------
461 ;temp1 = input[1 * 32] * cospi_31_64 - input[31 * 32] * cospi_1_64;
462 ;temp2 = input[1 * 32] * cospi_1_64 + input[31 * 32] * cospi_31_64;
463 ;step1b[16][i] = dct_const_round_shift(temp1);
464 ;step1b[31][i] = dct_const_round_shift(temp2);
465 LOAD_FROM_TRANSPOSED 0, 1, 31
466 DO_BUTTERFLY_STD cospi_31_64, cospi_1_64, d0, d1, d4, d5
467 ; --------------------------------------------------------------------------
469 ;temp1 = input[17 * 32] * cospi_15_64 - input[15 * 32] * cospi_17_64;
470 ;temp2 = input[17 * 32] * cospi_17_64 + input[15 * 32] * cospi_15_64;
471 ;step1b[17][i] = dct_const_round_shift(temp1);
472 ;step1b[30][i] = dct_const_round_shift(temp2);
473 LOAD_FROM_TRANSPOSED 31, 17, 15
474 DO_BUTTERFLY_STD cospi_15_64, cospi_17_64, d2, d3, d6, d7
475 ; --------------------------------------------------------------------------
477 ;step2[16] = step1b[16][i] + step1b[17][i];
478 ;step2[17] = step1b[16][i] - step1b[17][i];
479 ;step2[30] = -step1b[30][i] + step1b[31][i];
480 ;step2[31] = step1b[30][i] + step1b[31][i];
485 ; --------------------------------------------------------------------------
487 ;temp1 = step1b[30][i] * cospi_28_64 - step1b[17][i] * cospi_4_64;
488 ;temp2 = step1b[30][i] * cospi_4_64 - step1b[17][i] * cospi_28_64;
489 ;step3[17] = dct_const_round_shift(temp1);
490 ;step3[30] = dct_const_round_shift(temp2);
491 DO_BUTTERFLY_STD cospi_28_64, cospi_4_64, d10, d11, d14, d15
492 ; --------------------------------------------------------------------------
493 ; generate 18,19,28,29
494 ; --------------------------------------------------------------------------
496 ;temp1 = input[9 * 32] * cospi_23_64 - input[23 * 32] * cospi_9_64;
497 ;temp2 = input[9 * 32] * cospi_9_64 + input[23 * 32] * cospi_23_64;
498 ;step1b[18][i] = dct_const_round_shift(temp1);
499 ;step1b[29][i] = dct_const_round_shift(temp2);
500 LOAD_FROM_TRANSPOSED 15, 9, 23
501 DO_BUTTERFLY_STD cospi_23_64, cospi_9_64, d0, d1, d4, d5
502 ; --------------------------------------------------------------------------
504 ;temp1 = input[25 * 32] * cospi_7_64 - input[7 * 32] * cospi_25_64;
505 ;temp2 = input[25 * 32] * cospi_25_64 + input[7 * 32] * cospi_7_64;
506 ;step1b[19][i] = dct_const_round_shift(temp1);
507 ;step1b[28][i] = dct_const_round_shift(temp2);
508 LOAD_FROM_TRANSPOSED 23, 25, 7
509 DO_BUTTERFLY_STD cospi_7_64, cospi_25_64, d2, d3, d6, d7
510 ; --------------------------------------------------------------------------
512 ;step2[18] = -step1b[18][i] + step1b[19][i];
513 ;step2[19] = step1b[18][i] + step1b[19][i];
514 ;step2[28] = step1b[28][i] + step1b[29][i];
515 ;step2[29] = step1b[28][i] - step1b[29][i];
520 ; --------------------------------------------------------------------------
522 ;temp1 = step1b[18][i] * (-cospi_4_64) - step1b[29][i] * (-cospi_28_64);
523 ;temp2 = step1b[18][i] * (-cospi_28_64) + step1b[29][i] * (-cospi_4_64);
524 ;step3[29] = dct_const_round_shift(temp1);
525 ;step3[18] = dct_const_round_shift(temp2);
526 DO_BUTTERFLY_STD (-cospi_4_64), (-cospi_28_64), d2, d3, d0, d1
527 ; --------------------------------------------------------------------------
528 ; combine 16-19,28-31
529 ; --------------------------------------------------------------------------
531 ;step1[16] = step1b[16][i] + step1b[19][i];
532 ;step1[17] = step1b[17][i] + step1b[18][i];
533 ;step1[18] = step1b[17][i] - step1b[18][i];
534 ;step1[29] = step1b[30][i] - step1b[29][i];
535 ;step1[30] = step1b[30][i] + step1b[29][i];
536 ;step1[31] = step1b[31][i] + step1b[28][i];
543 STORE_IN_OUTPUT 0, 16, 31, q8, q15
544 STORE_IN_OUTPUT 31, 17, 30, q9, q10
545 ; --------------------------------------------------------------------------
547 ;temp1 = step1b[29][i] * cospi_24_64 - step1b[18][i] * cospi_8_64;
548 ;temp2 = step1b[29][i] * cospi_8_64 + step1b[18][i] * cospi_24_64;
549 ;step2[18] = dct_const_round_shift(temp1);
550 ;step2[29] = dct_const_round_shift(temp2);
551 DO_BUTTERFLY_STD cospi_24_64, cospi_8_64, d0, d1, d2, d3
552 STORE_IN_OUTPUT 30, 29, 18, q1, q0
553 ; --------------------------------------------------------------------------
555 ;step1[19] = step1b[16][i] - step1b[19][i];
556 ;step1[28] = step1b[31][i] - step1b[28][i];
559 ; --------------------------------------------------------------------------
561 ;temp1 = step1b[28][i] * cospi_24_64 - step1b[19][i] * cospi_8_64;
562 ;temp2 = step1b[28][i] * cospi_8_64 + step1b[19][i] * cospi_24_64;
563 ;step2[19] = dct_const_round_shift(temp1);
564 ;step2[28] = dct_const_round_shift(temp2);
565 DO_BUTTERFLY_STD cospi_24_64, cospi_8_64, d8, d9, d12, d13
566 STORE_IN_OUTPUT 18, 19, 28, q4, q6
567 ; --------------------------------------------------------------------------
570 ; --------------------------------------------------------------------------
571 ; BLOCK B: 20-23,24-27
572 ; --------------------------------------------------------------------------
573 ; generate 20,21,26,27
574 ; --------------------------------------------------------------------------
576 ;temp1 = input[5 * 32] * cospi_27_64 - input[27 * 32] * cospi_5_64;
577 ;temp2 = input[5 * 32] * cospi_5_64 + input[27 * 32] * cospi_27_64;
578 ;step1b[20][i] = dct_const_round_shift(temp1);
579 ;step1b[27][i] = dct_const_round_shift(temp2);
580 LOAD_FROM_TRANSPOSED 7, 5, 27
581 DO_BUTTERFLY_STD cospi_27_64, cospi_5_64, d0, d1, d4, d5
582 ; --------------------------------------------------------------------------
584 ;temp1 = input[21 * 32] * cospi_11_64 - input[11 * 32] * cospi_21_64;
585 ;temp2 = input[21 * 32] * cospi_21_64 + input[11 * 32] * cospi_11_64;
586 ;step1b[21][i] = dct_const_round_shift(temp1);
587 ;step1b[26][i] = dct_const_round_shift(temp2);
588 LOAD_FROM_TRANSPOSED 27, 21, 11
589 DO_BUTTERFLY_STD cospi_11_64, cospi_21_64, d2, d3, d6, d7
590 ; --------------------------------------------------------------------------
592 ;step2[20] = step1b[20][i] + step1b[21][i];
593 ;step2[21] = step1b[20][i] - step1b[21][i];
594 ;step2[26] = -step1b[26][i] + step1b[27][i];
595 ;step2[27] = step1b[26][i] + step1b[27][i];
600 ; --------------------------------------------------------------------------
602 ;temp1 = step1b[26][i] * cospi_12_64 - step1b[21][i] * cospi_20_64;
603 ;temp2 = step1b[26][i] * cospi_20_64 + step1b[21][i] * cospi_12_64;
604 ;step3[21] = dct_const_round_shift(temp1);
605 ;step3[26] = dct_const_round_shift(temp2);
606 DO_BUTTERFLY_STD cospi_12_64, cospi_20_64, d2, d3, d6, d7
607 ; --------------------------------------------------------------------------
608 ; generate 22,23,24,25
609 ; --------------------------------------------------------------------------
611 ;temp1 = input[13 * 32] * cospi_19_64 - input[19 * 32] * cospi_13_64;
612 ;temp2 = input[13 * 32] * cospi_13_64 + input[19 * 32] * cospi_19_64;
613 ;step1b[22][i] = dct_const_round_shift(temp1);
614 ;step1b[25][i] = dct_const_round_shift(temp2);
615 LOAD_FROM_TRANSPOSED 11, 13, 19
616 DO_BUTTERFLY_STD cospi_19_64, cospi_13_64, d10, d11, d14, d15
617 ; --------------------------------------------------------------------------
619 ;temp1 = input[29 * 32] * cospi_3_64 - input[3 * 32] * cospi_29_64;
620 ;temp2 = input[29 * 32] * cospi_29_64 + input[3 * 32] * cospi_3_64;
621 ;step1b[23][i] = dct_const_round_shift(temp1);
622 ;step1b[24][i] = dct_const_round_shift(temp2);
623 LOAD_FROM_TRANSPOSED 19, 29, 3
624 DO_BUTTERFLY_STD cospi_3_64, cospi_29_64, d8, d9, d12, d13
625 ; --------------------------------------------------------------------------
627 ;step2[22] = -step1b[22][i] + step1b[23][i];
628 ;step2[23] = step1b[22][i] + step1b[23][i];
629 ;step2[24] = step1b[24][i] + step1b[25][i];
630 ;step2[25] = step1b[24][i] - step1b[25][i];
635 ; --------------------------------------------------------------------------
637 ;temp1 = step1b[22][i] * (-cospi_20_64) - step1b[25][i] * (-cospi_12_64);
638 ;temp2 = step1b[22][i] * (-cospi_12_64) + step1b[25][i] * (-cospi_20_64);
639 ;step3[25] = dct_const_round_shift(temp1);
640 ;step3[22] = dct_const_round_shift(temp2);
641 DO_BUTTERFLY_STD (-cospi_20_64), (-cospi_12_64), d8, d9, d14, d15
642 ; --------------------------------------------------------------------------
643 ; combine 20-23,24-27
644 ; --------------------------------------------------------------------------
646 ;step1[22] = step1b[22][i] + step1b[21][i];
647 ;step1[23] = step1b[23][i] + step1b[20][i];
650 ;step1[24] = step1b[24][i] + step1b[27][i];
651 ;step1[25] = step1b[25][i] + step1b[26][i];
654 ; --------------------------------------------------------------------------
656 ;step3[16] = step1b[16][i] + step1b[23][i];
657 ;step3[17] = step1b[17][i] + step1b[22][i];
658 ;step3[22] = step1b[17][i] - step1b[22][i];
659 ;step3[23] = step1b[16][i] - step1b[23][i];
660 LOAD_FROM_OUTPUT 28, 16, 17, q14, q13
661 vadd.s16 q8, q14, q11
662 vadd.s16 q9, q13, q10
663 vsub.s16 q13, q13, q10
664 vsub.s16 q11, q14, q11
665 STORE_IN_OUTPUT 17, 17, 16, q9, q8
666 ; --------------------------------------------------------------------------
668 ;step3[24] = step1b[31][i] - step1b[24][i];
669 ;step3[25] = step1b[30][i] - step1b[25][i];
670 ;step3[30] = step1b[30][i] + step1b[25][i];
671 ;step3[31] = step1b[31][i] + step1b[24][i];
672 LOAD_FROM_OUTPUT 16, 30, 31, q14, q9
674 vadd.s16 q10, q14, q15
675 vsub.s16 q14, q14, q15
676 vadd.s16 q12, q9, q12
677 STORE_IN_OUTPUT 31, 30, 31, q10, q12
678 ; --------------------------------------------------------------------------
679 ; TODO(cd) do some register allocation change to remove these push/pop
682 ; --------------------------------------------------------------------------
684 ;temp1 = (step1b[25][i] - step1b[22][i]) * cospi_16_64;
685 ;temp2 = (step1b[25][i] + step1b[22][i]) * cospi_16_64;
686 ;step1[22] = dct_const_round_shift(temp1);
687 ;step1[25] = dct_const_round_shift(temp2);
688 DO_BUTTERFLY_STD cospi_16_64, cospi_16_64, d26, d27, d28, d29
689 STORE_IN_OUTPUT 31, 25, 22, q14, q13
690 ; --------------------------------------------------------------------------
692 ;temp1 = (step1b[24][i] - step1b[23][i]) * cospi_16_64;
693 ;temp2 = (step1b[24][i] + step1b[23][i]) * cospi_16_64;
694 ;step1[23] = dct_const_round_shift(temp1);
695 ;step1[24] = dct_const_round_shift(temp2);
696 ; TODO(cd) do some register allocation change to remove these push/pop
699 DO_BUTTERFLY_STD cospi_16_64, cospi_16_64, d26, d27, d28, d29
700 STORE_IN_OUTPUT 22, 24, 23, q14, q13
701 ; --------------------------------------------------------------------------
703 ;step1[20] = step1b[23][i] - step1b[20][i];
704 ;step1[27] = step1b[24][i] - step1b[27][i];
707 ; --------------------------------------------------------------------------
709 ;temp1 = step1b[20][i] * (-cospi_8_64) - step1b[27][i] * (-cospi_24_64);
710 ;temp2 = step1b[20][i] * (-cospi_24_64) + step1b[27][i] * (-cospi_8_64);
711 ;step2[27] = dct_const_round_shift(temp1);
712 ;step2[20] = dct_const_round_shift(temp2);
713 DO_BUTTERFLY_STD (-cospi_8_64), (-cospi_24_64), d10, d11, d12, d13
714 ; --------------------------------------------------------------------------
716 ;step1[21] = step1b[22][i] - step1b[21][i];
717 ;step1[26] = step1b[25][i] - step1b[26][i];
720 ; --------------------------------------------------------------------------
722 ;temp1 = step1b[21][i] * (-cospi_8_64) - step1b[26][i] * (-cospi_24_64);
723 ;temp2 = step1b[21][i] * (-cospi_24_64) + step1b[26][i] * (-cospi_8_64);
724 ;step2[26] = dct_const_round_shift(temp1);
725 ;step2[21] = dct_const_round_shift(temp2);
726 DO_BUTTERFLY_STD (-cospi_8_64), (-cospi_24_64), d0, d1, d2, d3
727 ; --------------------------------------------------------------------------
729 ;step3[18] = step1b[18][i] + step1b[21][i];
730 ;step3[19] = step1b[19][i] + step1b[20][i];
731 ;step3[20] = step1b[19][i] - step1b[20][i];
732 ;step3[21] = step1b[18][i] - step1b[21][i];
733 LOAD_FROM_OUTPUT 23, 18, 19, q14, q13
736 vsub.s16 q13, q13, q6
738 STORE_IN_OUTPUT 19, 18, 19, q8, q9
739 ; --------------------------------------------------------------------------
741 ;step3[27] = step1b[28][i] - step1b[27][i];
742 ;step3[28] = step1b[28][i] + step1b[27][i];
743 ;step3[29] = step1b[29][i] + step1b[26][i];
744 ;step3[26] = step1b[29][i] - step1b[26][i];
745 LOAD_FROM_OUTPUT 19, 28, 29, q8, q9
750 STORE_IN_OUTPUT 29, 28, 29, q10, q11
751 ; --------------------------------------------------------------------------
753 ;temp1 = (step1b[27][i] - step1b[20][i]) * cospi_16_64;
754 ;temp2 = (step1b[27][i] + step1b[20][i]) * cospi_16_64;
755 ;step1[20] = dct_const_round_shift(temp1);
756 ;step1[27] = dct_const_round_shift(temp2);
757 DO_BUTTERFLY_STD cospi_16_64, cospi_16_64, d26, d27, d28, d29
758 STORE_IN_OUTPUT 29, 20, 27, q13, q14
759 ; --------------------------------------------------------------------------
761 ;temp1 = (step1b[26][i] - step1b[21][i]) * cospi_16_64;
762 ;temp2 = (step1b[26][i] + step1b[21][i]) * cospi_16_64;
763 ;step1[21] = dct_const_round_shift(temp1);
764 ;step1[26] = dct_const_round_shift(temp2);
765 DO_BUTTERFLY d0, d1, d2, d3, cospi_16_64, cospi_16_64, d2, d3, d0, d1
766 STORE_IN_OUTPUT 27, 21, 26, q1, q0
767 ; --------------------------------------------------------------------------
770 ; --------------------------------------------------------------------------
771 ; BLOCK C: 8-10,11-15
772 ; --------------------------------------------------------------------------
774 ; --------------------------------------------------------------------------
776 ;temp1 = input[2 * 32] * cospi_30_64 - input[30 * 32] * cospi_2_64;
777 ;temp2 = input[2 * 32] * cospi_2_64 + input[30 * 32] * cospi_30_64;
778 ;step2[8] = dct_const_round_shift(temp1);
779 ;step2[15] = dct_const_round_shift(temp2);
780 LOAD_FROM_TRANSPOSED 3, 2, 30
781 DO_BUTTERFLY_STD cospi_30_64, cospi_2_64, d0, d1, d4, d5
782 ; --------------------------------------------------------------------------
784 ;temp1 = input[18 * 32] * cospi_14_64 - input[14 * 32] * cospi_18_64;
785 ;temp2 = input[18 * 32] * cospi_18_64 + input[14 * 32] * cospi_14_64;
786 ;step2[9] = dct_const_round_shift(temp1);
787 ;step2[14] = dct_const_round_shift(temp2);
788 LOAD_FROM_TRANSPOSED 30, 18, 14
789 DO_BUTTERFLY_STD cospi_14_64, cospi_18_64, d2, d3, d6, d7
790 ; --------------------------------------------------------------------------
792 ;step3[8] = step1b[8][i] + step1b[9][i];
793 ;step3[9] = step1b[8][i] - step1b[9][i];
794 ;step3[14] = step1b[15][i] - step1b[14][i];
795 ;step3[15] = step1b[15][i] + step1b[14][i];
800 ; --------------------------------------------------------------------------
802 ;temp1 = step1b[14][i] * cospi_24_64 - step1b[9][i] * cospi_8_64;
803 ;temp2 = step1b[14][i] * cospi_8_64 + step1b[9][i] * cospi_24_64;
804 ;step1[9] = dct_const_round_shift(temp1);
805 ;step1[14] = dct_const_round_shift(temp2);
806 DO_BUTTERFLY_STD cospi_24_64, cospi_8_64, d2, d3, d6, d7
807 ; --------------------------------------------------------------------------
808 ; generate 10,11,12,13
809 ; --------------------------------------------------------------------------
811 ;temp1 = input[10 * 32] * cospi_22_64 - input[22 * 32] * cospi_10_64;
812 ;temp2 = input[10 * 32] * cospi_10_64 + input[22 * 32] * cospi_22_64;
813 ;step2[10] = dct_const_round_shift(temp1);
814 ;step2[13] = dct_const_round_shift(temp2);
815 LOAD_FROM_TRANSPOSED 14, 10, 22
816 DO_BUTTERFLY_STD cospi_22_64, cospi_10_64, d10, d11, d14, d15
817 ; --------------------------------------------------------------------------
819 ;temp1 = input[26 * 32] * cospi_6_64 - input[6 * 32] * cospi_26_64;
820 ;temp2 = input[26 * 32] * cospi_26_64 + input[6 * 32] * cospi_6_64;
821 ;step2[11] = dct_const_round_shift(temp1);
822 ;step2[12] = dct_const_round_shift(temp2);
823 LOAD_FROM_TRANSPOSED 22, 26, 6
824 DO_BUTTERFLY_STD cospi_6_64, cospi_26_64, d8, d9, d12, d13
825 ; --------------------------------------------------------------------------
827 ;step3[10] = step1b[11][i] - step1b[10][i];
828 ;step3[11] = step1b[11][i] + step1b[10][i];
829 ;step3[12] = step1b[12][i] + step1b[13][i];
830 ;step3[13] = step1b[12][i] - step1b[13][i];
835 ; --------------------------------------------------------------------------
837 ;temp1 = step1b[10][i] * (-cospi_8_64) - step1b[13][i] * (-cospi_24_64);
838 ;temp2 = step1b[10][i] * (-cospi_24_64) + step1b[13][i] * (-cospi_8_64);
839 ;step1[13] = dct_const_round_shift(temp1);
840 ;step1[10] = dct_const_round_shift(temp2);
841 DO_BUTTERFLY_STD (-cospi_8_64), (-cospi_24_64), d8, d9, d14, d15
842 ; --------------------------------------------------------------------------
844 ; --------------------------------------------------------------------------
846 ;step2[8] = step1b[8][i] + step1b[11][i];
847 ;step2[9] = step1b[9][i] + step1b[10][i];
848 ;step2[10] = step1b[9][i] - step1b[10][i];
852 ;step2[13] = step1b[14][i] - step1b[13][i];
853 ;step2[14] = step1b[14][i] + step1b[13][i];
854 ;step2[15] = step1b[15][i] + step1b[12][i];
858 STORE_IN_OUTPUT 26, 8, 15, q8, q15
859 STORE_IN_OUTPUT 15, 9, 14, q9, q10
860 ; --------------------------------------------------------------------------
862 ;temp1 = (step1b[13][i] - step1b[10][i]) * cospi_16_64;
863 ;temp2 = (step1b[13][i] + step1b[10][i]) * cospi_16_64;
864 ;step3[10] = dct_const_round_shift(temp1);
865 ;step3[13] = dct_const_round_shift(temp2);
866 DO_BUTTERFLY_STD cospi_16_64, cospi_16_64, d2, d3, d6, d7
867 STORE_IN_OUTPUT 14, 13, 10, q3, q1
868 ; --------------------------------------------------------------------------
870 ;step2[11] = step1b[8][i] - step1b[11][i];
871 ;step2[12] = step1b[15][i] - step1b[12][i];
874 ; --------------------------------------------------------------------------
876 ;temp1 = (step1b[12][i] - step1b[11][i]) * cospi_16_64;
877 ;temp2 = (step1b[12][i] + step1b[11][i]) * cospi_16_64;
878 ;step3[11] = dct_const_round_shift(temp1);
879 ;step3[12] = dct_const_round_shift(temp2);
880 DO_BUTTERFLY_STD cospi_16_64, cospi_16_64, d2, d3, d6, d7
881 STORE_IN_OUTPUT 10, 11, 12, q1, q3
882 ; --------------------------------------------------------------------------
885 ; --------------------------------------------------------------------------
887 ; --------------------------------------------------------------------------
889 ; --------------------------------------------------------------------------
891 ;temp1 = input[4 * 32] * cospi_28_64 - input[28 * 32] * cospi_4_64;
892 ;temp2 = input[4 * 32] * cospi_4_64 + input[28 * 32] * cospi_28_64;
893 ;step3[4] = dct_const_round_shift(temp1);
894 ;step3[7] = dct_const_round_shift(temp2);
895 LOAD_FROM_TRANSPOSED 6, 4, 28
896 DO_BUTTERFLY_STD cospi_28_64, cospi_4_64, d0, d1, d4, d5
897 ; --------------------------------------------------------------------------
899 ;temp1 = input[20 * 32] * cospi_12_64 - input[12 * 32] * cospi_20_64;
900 ;temp2 = input[20 * 32] * cospi_20_64 + input[12 * 32] * cospi_12_64;
901 ;step3[5] = dct_const_round_shift(temp1);
902 ;step3[6] = dct_const_round_shift(temp2);
903 LOAD_FROM_TRANSPOSED 28, 20, 12
904 DO_BUTTERFLY_STD cospi_12_64, cospi_20_64, d2, d3, d6, d7
905 ; --------------------------------------------------------------------------
907 ;step1[4] = step1b[4][i] + step1b[5][i];
908 ;step1[5] = step1b[4][i] - step1b[5][i];
909 ;step1[6] = step1b[7][i] - step1b[6][i];
910 ;step1[7] = step1b[7][i] + step1b[6][i];
915 ; --------------------------------------------------------------------------
917 ;temp1 = (step1b[6][i] - step1b[5][i]) * cospi_16_64;
918 ;temp2 = (step1b[5][i] + step1b[6][i]) * cospi_16_64;
919 ;step2[5] = dct_const_round_shift(temp1);
920 ;step2[6] = dct_const_round_shift(temp2);
921 DO_BUTTERFLY_STD cospi_16_64, cospi_16_64, d2, d3, d6, d7
922 ; --------------------------------------------------------------------------
924 ; --------------------------------------------------------------------------
926 ;temp1 = (input[0 * 32] - input[16 * 32]) * cospi_16_64;
927 ;temp2 = (input[0 * 32] + input[16 * 32]) * cospi_16_64;
928 ;step1[1] = dct_const_round_shift(temp1);
929 ;step1[0] = dct_const_round_shift(temp2);
930 LOAD_FROM_TRANSPOSED 12, 0, 16
931 DO_BUTTERFLY_STD cospi_16_64, cospi_16_64, d10, d11, d14, d15
932 ; --------------------------------------------------------------------------
934 ;temp1 = input[8 * 32] * cospi_24_64 - input[24 * 32] * cospi_8_64;
935 ;temp2 = input[8 * 32] * cospi_8_64 + input[24 * 32] * cospi_24_64;
936 ;step1[2] = dct_const_round_shift(temp1);
937 ;step1[3] = dct_const_round_shift(temp2);
938 LOAD_FROM_TRANSPOSED 16, 8, 24
939 DO_BUTTERFLY_STD cospi_24_64, cospi_8_64, d28, d29, d12, d13
940 ; --------------------------------------------------------------------------
942 ;step2[0] = step1b[0][i] + step1b[3][i];
943 ;step2[1] = step1b[1][i] + step1b[2][i];
944 ;step2[2] = step1b[1][i] - step1b[2][i];
945 ;step2[3] = step1b[0][i] - step1b[3][i];
950 ; --------------------------------------------------------------------------
952 ; --------------------------------------------------------------------------
954 ;step3[0] = step1b[0][i] + step1b[7][i];
955 ;step3[1] = step1b[1][i] + step1b[6][i];
956 ;step3[2] = step1b[2][i] + step1b[5][i];
957 ;step3[3] = step1b[3][i] + step1b[4][i];
962 ;step3[4] = step1b[3][i] - step1b[4][i];
963 ;step3[5] = step1b[2][i] - step1b[5][i];
964 ;step3[6] = step1b[1][i] - step1b[6][i];
965 ;step3[7] = step1b[0][i] - step1b[7][i];
970 ; --------------------------------------------------------------------------
972 ;step1[0] = step1b[0][i] + step1b[15][i];
973 ;step1[1] = step1b[1][i] + step1b[14][i];
974 ;step1[14] = step1b[1][i] - step1b[14][i];
975 ;step1[15] = step1b[0][i] - step1b[15][i];
976 LOAD_FROM_OUTPUT 12, 14, 15, q0, q1
981 ; --------------------------------------------------------------------------
982 ; part of final stage
983 ;output[14 * 32] = step1b[14][i] + step1b[17][i];
984 ;output[15 * 32] = step1b[15][i] + step1b[16][i];
985 ;output[16 * 32] = step1b[15][i] - step1b[16][i];
986 ;output[17 * 32] = step1b[14][i] - step1b[17][i];
987 LOAD_FROM_OUTPUT 15, 16, 17, q0, q1
994 bgt idct32_bands_end_2nd_pass
996 idct32_bands_end_1st_pass
997 STORE_IN_OUTPUT 17, 16, 17, q6, q7
998 STORE_IN_OUTPUT 17, 14, 15, q8, q9
999 ; --------------------------------------------------------------------------
1000 ; part of final stage
1001 ;output[ 0 * 32] = step1b[0][i] + step1b[31][i];
1002 ;output[ 1 * 32] = step1b[1][i] + step1b[30][i];
1003 ;output[30 * 32] = step1b[1][i] - step1b[30][i];
1004 ;output[31 * 32] = step1b[0][i] - step1b[31][i];
1005 LOAD_FROM_OUTPUT 15, 30, 31, q0, q1
1010 STORE_IN_OUTPUT 31, 30, 31, q6, q7
1011 STORE_IN_OUTPUT 31, 0, 1, q4, q5
1012 ; --------------------------------------------------------------------------
1014 ;step1[2] = step1b[2][i] + step1b[13][i];
1015 ;step1[3] = step1b[3][i] + step1b[12][i];
1016 ;step1[12] = step1b[3][i] - step1b[12][i];
1017 ;step1[13] = step1b[2][i] - step1b[13][i];
1018 LOAD_FROM_OUTPUT 1, 12, 13, q0, q1
1019 vadd.s16 q2, q10, q1
1020 vadd.s16 q3, q11, q0
1021 vsub.s16 q4, q11, q0
1022 vsub.s16 q5, q10, q1
1023 ; --------------------------------------------------------------------------
1024 ; part of final stage
1025 ;output[12 * 32] = step1b[12][i] + step1b[19][i];
1026 ;output[13 * 32] = step1b[13][i] + step1b[18][i];
1027 ;output[18 * 32] = step1b[13][i] - step1b[18][i];
1028 ;output[19 * 32] = step1b[12][i] - step1b[19][i];
1029 LOAD_FROM_OUTPUT 13, 18, 19, q0, q1
1034 STORE_IN_OUTPUT 19, 18, 19, q6, q7
1035 STORE_IN_OUTPUT 19, 12, 13, q8, q9
1036 ; --------------------------------------------------------------------------
1037 ; part of final stage
1038 ;output[ 2 * 32] = step1b[2][i] + step1b[29][i];
1039 ;output[ 3 * 32] = step1b[3][i] + step1b[28][i];
1040 ;output[28 * 32] = step1b[3][i] - step1b[28][i];
1041 ;output[29 * 32] = step1b[2][i] - step1b[29][i];
1042 LOAD_FROM_OUTPUT 13, 28, 29, q0, q1
1047 STORE_IN_OUTPUT 29, 28, 29, q6, q7
1048 STORE_IN_OUTPUT 29, 2, 3, q4, q5
1049 ; --------------------------------------------------------------------------
1051 ;step1[4] = step1b[4][i] + step1b[11][i];
1052 ;step1[5] = step1b[5][i] + step1b[10][i];
1053 ;step1[10] = step1b[5][i] - step1b[10][i];
1054 ;step1[11] = step1b[4][i] - step1b[11][i];
1055 LOAD_FROM_OUTPUT 3, 10, 11, q0, q1
1056 vadd.s16 q2, q12, q1
1057 vadd.s16 q3, q13, q0
1058 vsub.s16 q4, q13, q0
1059 vsub.s16 q5, q12, q1
1060 ; --------------------------------------------------------------------------
1061 ; part of final stage
1062 ;output[10 * 32] = step1b[10][i] + step1b[21][i];
1063 ;output[11 * 32] = step1b[11][i] + step1b[20][i];
1064 ;output[20 * 32] = step1b[11][i] - step1b[20][i];
1065 ;output[21 * 32] = step1b[10][i] - step1b[21][i];
1066 LOAD_FROM_OUTPUT 11, 20, 21, q0, q1
1071 STORE_IN_OUTPUT 21, 20, 21, q6, q7
1072 STORE_IN_OUTPUT 21, 10, 11, q8, q9
1073 ; --------------------------------------------------------------------------
1074 ; part of final stage
1075 ;output[ 4 * 32] = step1b[4][i] + step1b[27][i];
1076 ;output[ 5 * 32] = step1b[5][i] + step1b[26][i];
1077 ;output[26 * 32] = step1b[5][i] - step1b[26][i];
1078 ;output[27 * 32] = step1b[4][i] - step1b[27][i];
1079 LOAD_FROM_OUTPUT 11, 26, 27, q0, q1
1084 STORE_IN_OUTPUT 27, 26, 27, q6, q7
1085 STORE_IN_OUTPUT 27, 4, 5, q4, q5
1086 ; --------------------------------------------------------------------------
1088 ;step1[6] = step1b[6][i] + step1b[9][i];
1089 ;step1[7] = step1b[7][i] + step1b[8][i];
1090 ;step1[8] = step1b[7][i] - step1b[8][i];
1091 ;step1[9] = step1b[6][i] - step1b[9][i];
1092 LOAD_FROM_OUTPUT 5, 8, 9, q0, q1
1093 vadd.s16 q2, q14, q1
1094 vadd.s16 q3, q15, q0
1095 vsub.s16 q4, q15, q0
1096 vsub.s16 q5, q14, q1
1097 ; --------------------------------------------------------------------------
1098 ; part of final stage
1099 ;output[ 8 * 32] = step1b[8][i] + step1b[23][i];
1100 ;output[ 9 * 32] = step1b[9][i] + step1b[22][i];
1101 ;output[22 * 32] = step1b[9][i] - step1b[22][i];
1102 ;output[23 * 32] = step1b[8][i] - step1b[23][i];
1103 LOAD_FROM_OUTPUT 9, 22, 23, q0, q1
1108 STORE_IN_OUTPUT 23, 22, 23, q6, q7
1109 STORE_IN_OUTPUT 23, 8, 9, q8, q9
1110 ; --------------------------------------------------------------------------
1111 ; part of final stage
1112 ;output[ 6 * 32] = step1b[6][i] + step1b[25][i];
1113 ;output[ 7 * 32] = step1b[7][i] + step1b[24][i];
1114 ;output[24 * 32] = step1b[7][i] - step1b[24][i];
1115 ;output[25 * 32] = step1b[6][i] - step1b[25][i];
1116 LOAD_FROM_OUTPUT 9, 24, 25, q0, q1
1121 STORE_IN_OUTPUT 25, 24, 25, q6, q7
1122 STORE_IN_OUTPUT 25, 6, 7, q4, q5
1124 ; restore r0 by removing the last offset from the last
1125 ; operation (LOAD_FROM_TRANSPOSED 16, 8, 24) => 24*8*2
1127 ; restore r1 by removing the last offset from the last
1128 ; operation (STORE_IN_OUTPUT 24, 6, 7) => 7*32*2
1129 ; advance by 8 columns => 8*2
1130 sub r1, r1, #7*32*2 - 8*2
1131 ; advance by 8 lines (8*32*2)
1132 ; go back by the two pairs from the loop (32*2)
1133 add r3, r3, #8*32*2 - 32*2
1135 ; bands loop processing
1137 bne idct32_bands_loop
1139 ; parameters for second pass
1140 ; the input of pass2 is the result of pass1. we have to remove the offset
1141 ; of 32 columns induced by the above idct32_bands_loop
1143 ; r1 = pass2[32 * 32]
1146 ; pass loop processing
1150 idct32_bands_end_2nd_pass
1151 STORE_COMBINE_CENTER_RESULTS
1152 ; --------------------------------------------------------------------------
1153 ; part of final stage
1154 ;output[ 0 * 32] = step1b[0][i] + step1b[31][i];
1155 ;output[ 1 * 32] = step1b[1][i] + step1b[30][i];
1156 ;output[30 * 32] = step1b[1][i] - step1b[30][i];
1157 ;output[31 * 32] = step1b[0][i] - step1b[31][i];
1158 LOAD_FROM_OUTPUT 17, 30, 31, q0, q1
1163 STORE_COMBINE_EXTREME_RESULTS
1164 ; --------------------------------------------------------------------------
1166 ;step1[2] = step1b[2][i] + step1b[13][i];
1167 ;step1[3] = step1b[3][i] + step1b[12][i];
1168 ;step1[12] = step1b[3][i] - step1b[12][i];
1169 ;step1[13] = step1b[2][i] - step1b[13][i];
1170 LOAD_FROM_OUTPUT 31, 12, 13, q0, q1
1171 vadd.s16 q2, q10, q1
1172 vadd.s16 q3, q11, q0
1173 vsub.s16 q4, q11, q0
1174 vsub.s16 q5, q10, q1
1175 ; --------------------------------------------------------------------------
1176 ; part of final stage
1177 ;output[12 * 32] = step1b[12][i] + step1b[19][i];
1178 ;output[13 * 32] = step1b[13][i] + step1b[18][i];
1179 ;output[18 * 32] = step1b[13][i] - step1b[18][i];
1180 ;output[19 * 32] = step1b[12][i] - step1b[19][i];
1181 LOAD_FROM_OUTPUT 13, 18, 19, q0, q1
1186 STORE_COMBINE_CENTER_RESULTS
1187 ; --------------------------------------------------------------------------
1188 ; part of final stage
1189 ;output[ 2 * 32] = step1b[2][i] + step1b[29][i];
1190 ;output[ 3 * 32] = step1b[3][i] + step1b[28][i];
1191 ;output[28 * 32] = step1b[3][i] - step1b[28][i];
1192 ;output[29 * 32] = step1b[2][i] - step1b[29][i];
1193 LOAD_FROM_OUTPUT 19, 28, 29, q0, q1
1198 STORE_COMBINE_EXTREME_RESULTS
1199 ; --------------------------------------------------------------------------
1201 ;step1[4] = step1b[4][i] + step1b[11][i];
1202 ;step1[5] = step1b[5][i] + step1b[10][i];
1203 ;step1[10] = step1b[5][i] - step1b[10][i];
1204 ;step1[11] = step1b[4][i] - step1b[11][i];
1205 LOAD_FROM_OUTPUT 29, 10, 11, q0, q1
1206 vadd.s16 q2, q12, q1
1207 vadd.s16 q3, q13, q0
1208 vsub.s16 q4, q13, q0
1209 vsub.s16 q5, q12, q1
1210 ; --------------------------------------------------------------------------
1211 ; part of final stage
1212 ;output[10 * 32] = step1b[10][i] + step1b[21][i];
1213 ;output[11 * 32] = step1b[11][i] + step1b[20][i];
1214 ;output[20 * 32] = step1b[11][i] - step1b[20][i];
1215 ;output[21 * 32] = step1b[10][i] - step1b[21][i];
1216 LOAD_FROM_OUTPUT 11, 20, 21, q0, q1
1221 STORE_COMBINE_CENTER_RESULTS
1222 ; --------------------------------------------------------------------------
1223 ; part of final stage
1224 ;output[ 4 * 32] = step1b[4][i] + step1b[27][i];
1225 ;output[ 5 * 32] = step1b[5][i] + step1b[26][i];
1226 ;output[26 * 32] = step1b[5][i] - step1b[26][i];
1227 ;output[27 * 32] = step1b[4][i] - step1b[27][i];
1228 LOAD_FROM_OUTPUT 21, 26, 27, q0, q1
1233 STORE_COMBINE_EXTREME_RESULTS
1234 ; --------------------------------------------------------------------------
1236 ;step1[6] = step1b[6][i] + step1b[9][i];
1237 ;step1[7] = step1b[7][i] + step1b[8][i];
1238 ;step1[8] = step1b[7][i] - step1b[8][i];
1239 ;step1[9] = step1b[6][i] - step1b[9][i];
1240 LOAD_FROM_OUTPUT 27, 8, 9, q0, q1
1241 vadd.s16 q2, q14, q1
1242 vadd.s16 q3, q15, q0
1243 vsub.s16 q4, q15, q0
1244 vsub.s16 q5, q14, q1
1245 ; --------------------------------------------------------------------------
1246 ; part of final stage
1247 ;output[ 8 * 32] = step1b[8][i] + step1b[23][i];
1248 ;output[ 9 * 32] = step1b[9][i] + step1b[22][i];
1249 ;output[22 * 32] = step1b[9][i] - step1b[22][i];
1250 ;output[23 * 32] = step1b[8][i] - step1b[23][i];
1251 LOAD_FROM_OUTPUT 9, 22, 23, q0, q1
1256 STORE_COMBINE_CENTER_RESULTS_LAST
1257 ; --------------------------------------------------------------------------
1258 ; part of final stage
1259 ;output[ 6 * 32] = step1b[6][i] + step1b[25][i];
1260 ;output[ 7 * 32] = step1b[7][i] + step1b[24][i];
1261 ;output[24 * 32] = step1b[7][i] - step1b[24][i];
1262 ;output[25 * 32] = step1b[6][i] - step1b[25][i];
1263 LOAD_FROM_OUTPUT 23, 24, 25, q0, q1
1268 STORE_COMBINE_EXTREME_RESULTS_LAST
1269 ; --------------------------------------------------------------------------
1270 ; restore pointers to their initial indices for next band pass by
1271 ; removing/adding dest_stride * 8. The actual increment by eight
1272 ; is taken care of within the _LAST macros.
1273 add r6, r6, r2, lsl #3
1274 add r9, r9, r2, lsl #3
1275 sub r7, r7, r2, lsl #3
1276 sub r10, r10, r2, lsl #3
1278 ; restore r0 by removing the last offset from the last
1279 ; operation (LOAD_FROM_TRANSPOSED 16, 8, 24) => 24*8*2
1281 ; restore r1 by removing the last offset from the last
1282 ; operation (LOAD_FROM_OUTPUT 23, 24, 25) => 25*32*2
1283 ; advance by 8 columns => 8*2
1284 sub r1, r1, #25*32*2 - 8*2
1285 ; advance by 8 lines (8*32*2)
1286 ; go back by the two pairs from the loop (32*2)
1287 add r3, r3, #8*32*2 - 32*2
1289 ; bands loop processing
1291 bne idct32_bands_loop
1294 add sp, sp, #512+2048+2048
1298 ENDP ; |vp9_idct32x32_1024_add_neon|