History

arm: vp9itxfm: Do a simpler half/quarter idct16/idct32 when possible

This work is sponsored by, and copyright, Google. This avoids loading and calculating coefficients that we know will be zero, and avoids filling the temp buffer with zeros in places where we know the second pass won't read. This gives a pretty substantial speedup for the smaller subpartitions. The code size increases from 12388 bytes to 19784 bytes. The idct16/32_end macros are moved above the individual functions; the instructions themselves are unchanged, but since new functions are added at the same place where the code is moved from, the diff looks rather messy. Before: Cortex A7 A8 A9 A53 vp9_inv_dct_dct_16x16_sub1_add_neon: 273.0 189.5 212.0 235.8 vp9_inv_dct_dct_16x16_sub2_add_neon: 2102.1 1521.7 1736.2 1265.8 vp9_inv_dct_dct_16x16_sub4_add_neon: 2104.5 1533.0 1736.6 1265.5 vp9_inv_dct_dct_16x16_sub8_add_neon: 2484.8 1828.7 2014.4 1506.5 vp9_inv_dct_dct_16x16_sub12_add_neon: 2851.2 2117.8 2294.8 1753.2 vp9_inv_dct_dct_16x16_sub16_add_neon: 3239.4 2408.3 2543.5 1994.9 vp9_inv_dct_dct_32x32_sub1_add_neon: 758.3 456.7 864.5 553.9 vp9_inv_dct_dct_32x32_sub2_add_neon: 10776.7 7949.8 8567.7 6819.7 vp9_inv_dct_dct_32x32_sub4_add_neon: 10865.6 8131.5 8589.6 6816.3 vp9_inv_dct_dct_32x32_sub8_add_neon: 12053.9 9271.3 9387.7 7564.0 vp9_inv_dct_dct_32x32_sub12_add_neon: 13328.3 10463.2 10217.0 8321.3 vp9_inv_dct_dct_32x32_sub16_add_neon: 14176.4 11509.5 11018.7 9062.3 vp9_inv_dct_dct_32x32_sub20_add_neon: 15301.5 12999.9 11855.1 9828.2 vp9_inv_dct_dct_32x32_sub24_add_neon: 16482.7 14931.5 12650.1 10575.0 vp9_inv_dct_dct_32x32_sub28_add_neon: 17589.5 15811.9 13482.8 11333.4 vp9_inv_dct_dct_32x32_sub32_add_neon: 18696.2 17049.2 14355.6 12089.7 After: vp9_inv_dct_dct_16x16_sub1_add_neon: 273.0 189.5 211.7 235.8 vp9_inv_dct_dct_16x16_sub2_add_neon: 1203.5 998.2 1035.3 763.0 vp9_inv_dct_dct_16x16_sub4_add_neon: 1203.5 998.1 1035.5 760.8 vp9_inv_dct_dct_16x16_sub8_add_neon: 1926.1 1610.6 1722.1 1271.7 vp9_inv_dct_dct_16x16_sub12_add_neon: 2873.2 2129.7 2285.1 1757.3 vp9_inv_dct_dct_16x16_sub16_add_neon: 3221.4 2520.3 2557.6 2002.1 vp9_inv_dct_dct_32x32_sub1_add_neon: 753.0 457.5 866.6 554.6 vp9_inv_dct_dct_32x32_sub2_add_neon: 7554.6 5652.4 6048.4 4920.2 vp9_inv_dct_dct_32x32_sub4_add_neon: 7549.9 5685.0 6046.9 4925.7 vp9_inv_dct_dct_32x32_sub8_add_neon: 8336.9 6704.5 6604.0 5478.0 vp9_inv_dct_dct_32x32_sub12_add_neon: 10914.0 9777.2 9240.4 7416.9 vp9_inv_dct_dct_32x32_sub16_add_neon: 11859.2 11223.3 9966.3 8095.1 vp9_inv_dct_dct_32x32_sub20_add_neon: 15237.1 13029.4 11838.3 9829.4 vp9_inv_dct_dct_32x32_sub24_add_neon: 16293.2 14379.8 12644.9 10572.0 vp9_inv_dct_dct_32x32_sub28_add_neon: 17424.3 15734.7 13473.0 11326.9 vp9_inv_dct_dct_32x32_sub32_add_neon: 18531.3 17457.0 14298.6 12080.0

Martin Storsjö committed 9 years ago

Commit 5eb5aec1 parent 79d332e1 file · +537 −54Browse files

Unified · Split

libavcodec/arm/vp9itxfm_neon.S+537−54
@@ -74,6 +74,14 @@ endconst · 73 unmodified lines
7474 vrshrn.s32 \out2, \tmpq4, #14
7575 .endm
7676
77+@ Same as mbutterfly0 above, but treating the input in in2 as zero,
78+@ writing the same output into both out1 and out2.
79+.macro mbutterfly0_h out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4
80+ vmull.s16 \tmpq3, \in1, d0[0]
81+ vrshrn.s32 \out1, \tmpq3, #14
82+ vrshrn.s32 \out2, \tmpq3, #14
83+.endm
84+
7785 @ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
7886 @ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
7987 @ Same as mbutterfly0, but with input being 2 q registers, output
@@ -137,6 +145,23 @@ endconst · 57 unmodified lines
137145 vrshrn.s32 \inout2, \tmp2, #14
138146 .endm
139147
148+@ Same as mbutterfly above, but treating the input in inout2 as zero
149+.macro mbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2
150+ vmull.s16 \tmp1, \inout1, \coef1
151+ vmull.s16 \tmp2, \inout1, \coef2
152+ vrshrn.s32 \inout1, \tmp1, #14
153+ vrshrn.s32 \inout2, \tmp2, #14
154+.endm
155+
156+@ Same as mbutterfly above, but treating the input in inout1 as zero
157+.macro mbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2
158+ vmull.s16 \tmp1, \inout2, \coef2
159+ vmull.s16 \tmp2, \inout2, \coef1
160+ vneg.s32 \tmp1, \tmp1
161+ vrshrn.s32 \inout2, \tmp2, #14
162+ vrshrn.s32 \inout1, \tmp1, #14
163+.endm
164+
140165 @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14
141166 @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14
142167 @ inout are 4 d registers, tmp are 4 q registers
@@ -534,6 +559,33 @@ function idct16x16_dc_add_neon · 391 unmodified lines
534559 endfunc
535560 .ltorg
536561
562+.macro idct16_end
563+ butterfly d18, d7, d4, d7 @ d18 = t0a, d7 = t7a
564+ butterfly d19, d22, d5, d22 @ d19 = t1a, d22 = t6
565+ butterfly d4, d26, d20, d26 @ d4 = t2a, d26 = t5
566+ butterfly d5, d6, d28, d6 @ d5 = t3a, d6 = t4
567+ butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a
568+ butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10
569+ butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13
570+ butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a
571+
572+ mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a
573+ mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11
574+
575+ vswp d27, d29 @ d27 = t12, d29 = t13a
576+ vswp d28, d27 @ d28 = t12, d27 = t11
577+ butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15]
578+ butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14]
579+ butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6]
580+ butterfly d23, d24, d7, d20 @ d23 = out[7], d24 = out[8]
581+ butterfly d18, d29, d4, d29 @ d18 = out[2], d29 = out[13]
582+ butterfly d19, d28, d5, d28 @ d19 = out[3], d28 = out[12]
583+ vmov d4, d21 @ d4 = t10a
584+ butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11]
585+ butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10]
586+ bx lr
587+.endm
588+
537589 function idct16
538590 mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a
539591 mbutterfly d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a
@@ -556,31 +608,63 @@ function idct16 · 16 unmodified lines
556608 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a
557609 mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a
558610 mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a
611+ idct16_end
612+endfunc
559613
560− butterfly d18, d7, d4, d7 @ d18 = t0a, d7 = t7a
561− butterfly d19, d22, d5, d22 @ d19 = t1a, d22 = t6
562− butterfly d4, d26, d20, d26 @ d4 = t2a, d26 = t5
563− butterfly d5, d6, d28, d6 @ d5 = t3a, d6 = t4
564− butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a
565− butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10
566− butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13
567− butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a
614+function idct16_half
615+ mbutterfly0_h d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a
616+ mbutterfly_h1 d20, d28, d0[1], d0[2], q2, q3 @ d20 = t2a, d28 = t3a
617+ mbutterfly_h1 d18, d30, d0[3], d1[0], q2, q3 @ d18 = t4a, d30 = t7a
618+ mbutterfly_h2 d26, d22, d1[1], d1[2], q2, q3 @ d26 = t5a, d22 = t6a
619+ mbutterfly_h1 d17, d31, d1[3], d2[0], q2, q3 @ d17 = t8a, d31 = t15a
620+ mbutterfly_h2 d25, d23, d2[1], d2[2], q2, q3 @ d25 = t9a, d23 = t14a
621+ mbutterfly_h1 d21, d27, d2[3], d3[0], q2, q3 @ d21 = t10a, d27 = t13a
622+ mbutterfly_h2 d29, d19, d3[1], d3[2], q2, q3 @ d29 = t11a, d19 = t12a
568623
569− mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a
570− mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11
624+ butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3
625+ butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2
626+ butterfly d6, d26, d18, d26 @ d6 = t4, d26 = t5
627+ butterfly d7, d22, d30, d22 @ d7 = t7, d22 = t6
628+ butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9
629+ butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10
630+ butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13
631+ butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14
571632
572− vswp d27, d29 @ d27 = t12, d29 = t13a
573− vswp d28, d27 @ d28 = t12, d27 = t11
574− butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15]
575− butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14]
576− butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6]
577− butterfly d23, d24, d7, d20 @ d23 = out[7], d24 = out[8]
578− butterfly d18, d29, d4, d29 @ d18 = out[2], d29 = out[13]
579− butterfly d19, d28, d5, d28 @ d19 = out[3], d28 = out[12]
580− vmov d4, d21 @ d4 = t10a
581− butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11]
582− butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10]
583− bx lr
633+ mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a
634+ mbutterfly d23, d25, d0[1], d0[2], q9, q15 @ d23 = t9a, d25 = t14a
635+ mbutterfly d27, d21, d0[1], d0[2], q9, q15, neg=1 @ d27 = t13a, d21 = t10a
636+ idct16_end
637+endfunc
638+
639+function idct16_quarter
640+ vmull.s16 q12, d19, d3[2]
641+ vmull.s16 q2, d17, d1[3]
642+ vmull.s16 q3, d18, d1[0]
643+ vmull.s16 q15, d18, d0[3]
644+ vneg.s32 q12, q12
645+ vmull.s16 q14, d17, d2[0]
646+ vmull.s16 q13, d19, d3[1]
647+ vmull.s16 q11, d16, d0[0]
648+ vrshrn.s32 d24, q12, #14
649+ vrshrn.s32 d16, q2, #14
650+ vrshrn.s32 d7, q3, #14
651+ vrshrn.s32 d6, q15, #14
652+ vrshrn.s32 d29, q14, #14
653+ vrshrn.s32 d17, q13, #14
654+ vrshrn.s32 d28, q11, #14
655+
656+ mbutterfly_l q10, q11, d17, d24, d0[1], d0[2]
657+ mbutterfly_l q9, q15, d29, d16, d0[1], d0[2]
658+ vneg.s32 q11, q11
659+ vrshrn.s32 d27, q10, #14
660+ vrshrn.s32 d21, q11, #14
661+ vrshrn.s32 d23, q9, #14
662+ vrshrn.s32 d25, q15, #14
663+ vmov d4, d28
664+ vmov d5, d28
665+ mbutterfly0 d22, d26, d7, d6, d18, d30, q9, q15
666+ vmov d20, d28
667+ idct16_end
584668 endfunc
585669
586670 function iadst16
@@ -819,6 +903,13 @@ A and r7, sp, #15 · 232 unmodified lines
819903 vld1.16 {q0-q1}, [r12,:128]
820904 .endif
821905
906+.ifc \txfm1\()_\txfm2,idct_idct
907+ cmp r3, #10
908+ ble idct16x16_quarter_add_neon
909+ cmp r3, #38
910+ ble idct16x16_half_add_neon
911+.endif
912+
822913 .irp i, 0, 4, 8, 12
823914 add r0, sp, #(\i*32)
824915 .ifc \txfm1\()_\txfm2,idct_idct
@@ -877,6 +968,169 @@ itxfm_func16x16 idct, iadst · 52 unmodified lines
877968 itxfm_func16x16 iadst, iadst
878969 .ltorg
879970
971+function idct16_1d_4x16_pass1_quarter_neon
972+ push {lr}
973+ mov r12, #32
974+ vmov.s16 q2, #0
975+.irp i, 16, 17, 18, 19
976+ vld1.16 {d\i}, [r2,:64]
977+ vst1.16 {d4}, [r2,:64], r12
978+.endr
979+
980+ bl idct16_quarter
981+
982+ @ Do four 4x4 transposes. Originally, d16-d31 contain the
983+ @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31
984+ @ contain the transposed 4x4 blocks.
985+ transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
986+
987+ @ Store the transposed 4x4 blocks horizontally.
988+ @ The first 4x4 block is kept in registers for the second pass,
989+ @ store the rest in the temp buffer.
990+ add r0, r0, #8
991+ vst1.16 {d20}, [r0,:64]!
992+ vst1.16 {d24}, [r0,:64]!
993+ vst1.16 {d28}, [r0,:64]!
994+ add r0, r0, #8
995+ vst1.16 {d21}, [r0,:64]!
996+ vst1.16 {d25}, [r0,:64]!
997+ vst1.16 {d29}, [r0,:64]!
998+ add r0, r0, #8
999+ vst1.16 {d22}, [r0,:64]!
1000+ vst1.16 {d26}, [r0,:64]!
1001+ vst1.16 {d30}, [r0,:64]!
1002+ add r0, r0, #8
1003+ vst1.16 {d23}, [r0,:64]!
1004+ vst1.16 {d27}, [r0,:64]!
1005+ vst1.16 {d31}, [r0,:64]!
1006+ pop {pc}
1007+endfunc
1008+
1009+function idct16_1d_4x16_pass2_quarter_neon
1010+ push {lr}
1011+ @ Only load the top 4 lines, and only do it for the later slices.
1012+ @ For the first slice, d16-d19 is kept in registers from the first pass.
1013+ cmp r3, #0
1014+ beq 1f
1015+ mov r12, #32
1016+.irp i, 16, 17, 18, 19
1017+ vld1.16 {d\i}, [r2,:64], r12
1018+.endr
1019+1:
1020+
1021+ add r3, r0, r1
1022+ lsl r1, r1, #1
1023+ bl idct16_quarter
1024+
1025+ load_add_store q8, q9, q10, q11
1026+ load_add_store q12, q13, q14, q15
1027+
1028+ pop {pc}
1029+endfunc
1030+
1031+function idct16_1d_4x16_pass1_half_neon
1032+ push {lr}
1033+ mov r12, #32
1034+ vmov.s16 q2, #0
1035+.irp i, 16, 17, 18, 19, 20, 21, 22, 23
1036+ vld1.16 {d\i}, [r2,:64]
1037+ vst1.16 {d4}, [r2,:64], r12
1038+.endr
1039+
1040+ bl idct16_half
1041+
1042+ @ Do four 4x4 transposes. Originally, d16-d31 contain the
1043+ @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31
1044+ @ contain the transposed 4x4 blocks.
1045+ transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
1046+
1047+ @ Store the transposed 4x4 blocks horizontally.
1048+ cmp r1, #4
1049+ beq 1f
1050+.irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31
1051+ vst1.16 {d\i}, [r0,:64]!
1052+.endr
1053+ pop {pc}
1054+1:
1055+ @ Special case: For the second input column (r1 == 4),
1056+ @ which would be stored as the second row in the temp buffer,
1057+ @ don't store the first 4x4 block, but keep it in registers
1058+ @ for the first slice of the second pass (where it is the
1059+ @ second 4x4 block).
1060+ add r0, r0, #8
1061+ vst1.16 {d20}, [r0,:64]!
1062+ vst1.16 {d24}, [r0,:64]!
1063+ vst1.16 {d28}, [r0,:64]!
1064+ add r0, r0, #8
1065+ vst1.16 {d21}, [r0,:64]!
1066+ vst1.16 {d25}, [r0,:64]!
1067+ vst1.16 {d29}, [r0,:64]!
1068+ add r0, r0, #8
1069+ vst1.16 {d22}, [r0,:64]!
1070+ vst1.16 {d26}, [r0,:64]!
1071+ vst1.16 {d30}, [r0,:64]!
1072+ add r0, r0, #8
1073+ vst1.16 {d23}, [r0,:64]!
1074+ vst1.16 {d27}, [r0,:64]!
1075+ vst1.16 {d31}, [r0,:64]!
1076+ vmov d20, d16
1077+ vmov d21, d17
1078+ vmov d22, d18
1079+ vmov d23, d19
1080+ pop {pc}
1081+endfunc
1082+
1083+function idct16_1d_4x16_pass2_half_neon
1084+ push {lr}
1085+ mov r12, #32
1086+ cmp r3, #0
1087+.irp i, 16, 17, 18, 19
1088+ vld1.16 {d\i}, [r2,:64], r12
1089+.endr
1090+ beq 1f
1091+.irp i, 20, 21, 22, 23
1092+ vld1.16 {d\i}, [r2,:64], r12
1093+.endr
1094+1:
1095+
1096+ add r3, r0, r1
1097+ lsl r1, r1, #1
1098+ bl idct16_half
1099+
1100+ load_add_store q8, q9, q10, q11
1101+ load_add_store q12, q13, q14, q15
1102+
1103+ pop {pc}
1104+endfunc
1105+.purgem load_add_store
1106+
1107+.macro idct16_partial size
1108+function idct16x16_\size\()_add_neon
1109+ add r0, sp, #(0*32)
1110+ mov r1, #0
1111+ add r2, r6, #(0*2)
1112+ bl idct16_1d_4x16_pass1_\size\()_neon
1113+.ifc \size,half
1114+ add r0, sp, #(4*32)
1115+ mov r1, #4
1116+ add r2, r6, #(4*2)
1117+ bl idct16_1d_4x16_pass1_\size\()_neon
1118+.endif
1119+.irp i, 0, 4, 8, 12
1120+ add r0, r4, #(\i)
1121+ mov r1, r5
1122+ add r2, sp, #(\i*2)
1123+ mov r3, #\i
1124+ bl idct16_1d_4x16_pass2_\size\()_neon
1125+.endr
1126+
1127+ add sp, sp, r7
1128+ pop {r4-r8,pc}
1129+endfunc
1130+.endm
1131+
1132+idct16_partial quarter
1133+idct16_partial half
8801134
8811135 function idct32x32_dc_add_neon
8821136 movrel r12, idct_coeffs
@@ -913,6 +1167,38 @@ function idct32x32_dc_add_neon · 30 unmodified lines
9131167 bx lr
9141168 endfunc
9151169
1170+.macro idct32_end
1171+ butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a
1172+ butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18
1173+ butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a
1174+ butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21
1175+ butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a
1176+ butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26
1177+ butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a
1178+ butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29
1179+
1180+ mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a
1181+ mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28
1182+ mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20
1183+ mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a
1184+
1185+ butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24
1186+ butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a
1187+ butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16
1188+ butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a
1189+ butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21
1190+ butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a
1191+ butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26
1192+ butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20
1193+ vmov d29, d4 @ d29 = t29
1194+
1195+ mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20
1196+ mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a
1197+ mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22
1198+ mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a
1199+ bx lr
1200+.endm
1201+
9161202 function idct32_odd
9171203 movrel r12, idct_coeffs
9181204 add r12, r12, #32
@@ -943,38 +1229,91 @@ function idct32_odd · 24 unmodified lines
9431229 mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
9441230 mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a
9451231 mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1232+ idct32_end
1233+endfunc
9461234
947− butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a
948− butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18
949− butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a
950− butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21
951− butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a
952− butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26
953− butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a
954− butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29
1235+function idct32_odd_half
1236+ movrel r12, idct_coeffs
1237+ add r12, r12, #32
1238+ vld1.16 {q0-q1}, [r12,:128]
9551239
956− mbutterfly d27, d20, d0[1], d0[2], q12, q15 @ d27 = t18a, d20 = t29a
957− mbutterfly d29, d5, d0[1], d0[2], q12, q15 @ d29 = t19, d5 = t28
958− mbutterfly d28, d6, d0[1], d0[2], q12, q15, neg=1 @ d28 = t27, d6 = t20
959− mbutterfly d26, d21, d0[1], d0[2], q12, q15, neg=1 @ d26 = t26a, d21 = t21a
1240+ mbutterfly_h1 d16, d31, d0[0], d0[1], q2, q3 @ d16 = t16a, d31 = t31a
1241+ mbutterfly_h2 d24, d23, d0[2], d0[3], q2, q3 @ d24 = t17a, d23 = t30a
1242+ mbutterfly_h1 d20, d27, d1[0], d1[1], q2, q3 @ d20 = t18a, d27 = t29a
1243+ mbutterfly_h2 d28, d19, d1[2], d1[3], q2, q3 @ d28 = t19a, d19 = t28a
1244+ mbutterfly_h1 d18, d29, d2[0], d2[1], q2, q3 @ d18 = t20a, d29 = t27a
1245+ mbutterfly_h2 d26, d21, d2[2], d2[3], q2, q3 @ d26 = t21a, d21 = t26a
1246+ mbutterfly_h1 d22, d25, d3[0], d3[1], q2, q3 @ d22 = t22a, d25 = t25a
1247+ mbutterfly_h2 d30, d17, d3[2], d3[3], q2, q3 @ d30 = t23a, d17 = t24a
9601248
961− butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24
962− butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a
963− butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16
964− butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a
965− butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21
966− butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a
967− butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26
968− butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20
969− vmov d29, d4 @ d29 = t29
1249+ sub r12, r12, #32
1250+ vld1.16 {q0}, [r12,:128]
9701251
971− mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20
972− mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a
973− mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22
974− mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a
975− bx lr
1252+ butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17
1253+ butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18
1254+ butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21
1255+ butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22
1256+ butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25
1257+ butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26
1258+ butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30
1259+ butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29
1260+
1261+ mbutterfly d23, d24, d0[3], d1[0], q8, q9 @ d23 = t17a, d24 = t30a
1262+ mbutterfly d27, d20, d0[3], d1[0], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
1263+ mbutterfly d21, d26, d1[1], d1[2], q8, q9 @ d21 = t21a, d26 = t26a
1264+ mbutterfly d25, d22, d1[1], d1[2], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1265+
1266+ idct32_end
9761267 endfunc
9771268
1269+function idct32_odd_quarter
1270+ movrel r12, idct_coeffs
1271+ add r12, r12, #32
1272+ vld1.16 {q0-q1}, [r12,:128]
1273+
1274+ vmull.s16 q2, d16, d0[0]
1275+ vmull.s16 q14, d19, d1[3]
1276+ vmull.s16 q15, d16, d0[1]
1277+ vmull.s16 q11, d17, d3[2]
1278+ vmull.s16 q3, d17, d3[3]
1279+ vmull.s16 q13, d19, d1[2]
1280+ vmull.s16 q10, d18, d2[0]
1281+ vmull.s16 q12, d18, d2[1]
1282+
1283+ sub r12, r12, #32
1284+ vld1.16 {q0}, [r12,:128]
1285+
1286+ vneg.s32 q14, q14
1287+ vneg.s32 q3, q3
1288+
1289+ vrshrn.s32 d4, q2, #14
1290+ vrshrn.s32 d5, q14, #14
1291+ vrshrn.s32 d29, q15, #14
1292+ vrshrn.s32 d28, q11, #14
1293+ vrshrn.s32 d7, q3, #14
1294+ vrshrn.s32 d31, q13, #14
1295+ vrshrn.s32 d6, q10, #14
1296+ vrshrn.s32 d30, q12, #14
1297+
1298+ mbutterfly_l q8, q9, d29, d4, d0[3], d1[0]
1299+ mbutterfly_l q13, q10, d31, d5, d0[3], d1[0]
1300+ vrshrn.s32 d23, q8, #14
1301+ vrshrn.s32 d24, q9, #14
1302+ vneg.s32 q10, q10
1303+ vrshrn.s32 d27, q13, #14
1304+ vrshrn.s32 d20, q10, #14
1305+ mbutterfly_l q8, q9, d30, d6, d1[1], d1[2]
1306+ vrshrn.s32 d21, q8, #14
1307+ vrshrn.s32 d26, q9, #14
1308+ mbutterfly_l q8, q9, d28, d7, d1[1], d1[2]
1309+ vrshrn.s32 d25, q8, #14
1310+ vneg.s32 q9, q9
1311+ vrshrn.s32 d22, q9, #14
1312+
1313+ idct32_end
1314+endfunc
1315+
1316+.macro idct32_funcs suffix
9781317 @ Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix.
9791318 @ We don't have register space to do a single pass IDCT of 4x32 though,
9801319 @ but the 32-point IDCT can be decomposed into two 16-point IDCTs;
@@ -984,7 +1323,7 @@ endfunc · 3 unmodified lines
9841323 @ r0 = dst (temp buffer)
9851324 @ r1 = unused
9861325 @ r2 = src
987−function idct32_1d_4x32_pass1_neon
1326+function idct32_1d_4x32_pass1\suffix\()_neon
9881327 push {lr}
9891328
9901329 movrel r12, idct_coeffs
@@ -995,12 +1334,26 @@ function idct32_1d_4x32_pass1_neon · 4 unmodified lines
9951334 vmov.s16 d4, #0
9961335
9971336 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1337+.ifb \suffix
9981338 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
9991339 vld1.16 {d\i}, [r2,:64]
10001340 vst1.16 {d4}, [r2,:64], r12
10011341 .endr
1342+.endif
1343+.ifc \suffix,_quarter
1344+.irp i, 16, 17, 18, 19
1345+ vld1.16 {d\i}, [r2,:64]
1346+ vst1.16 {d4}, [r2,:64], r12
1347+.endr
1348+.endif
1349+.ifc \suffix,_half
1350+.irp i, 16, 17, 18, 19, 20, 21, 22, 23
1351+ vld1.16 {d\i}, [r2,:64]
1352+ vst1.16 {d4}, [r2,:64], r12
1353+.endr
1354+.endif
10021355
1003− bl idct16
1356+ bl idct16\suffix
10041357
10051358 @ Do four 4x4 transposes. Originally, d16-d31 contain the
10061359 @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31
@@ -1026,17 +1379,39 @@ function idct32_1d_4x32_pass1_neon · 19 unmodified lines
10261379
10271380 @ Move r2 back to the start of the input, and move
10281381 @ to the first odd row
1382+.ifb \suffix
10291383 sub r2, r2, r12, lsl #4
1384+.endif
1385+.ifc \suffix,_quarter
1386+ sub r2, r2, r12, lsl #2
1387+.endif
1388+.ifc \suffix,_half
1389+ sub r2, r2, r12, lsl #3
1390+.endif
10301391 add r2, r2, #64
10311392
10321393 vmov.s16 d4, #0
10331394 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1395+.ifb \suffix
10341396 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
10351397 vld1.16 {d\i}, [r2,:64]
10361398 vst1.16 {d4}, [r2,:64], r12
10371399 .endr
1400+.endif
1401+.ifc \suffix,_quarter
1402+.irp i, 16, 17, 18, 19
1403+ vld1.16 {d\i}, [r2,:64]
1404+ vst1.16 {d4}, [r2,:64], r12
1405+.endr
1406+.endif
1407+.ifc \suffix,_half
1408+.irp i, 16, 17, 18, 19, 20, 21, 22, 23
1409+ vld1.16 {d\i}, [r2,:64]
1410+ vst1.16 {d4}, [r2,:64], r12
1411+.endr
1412+.endif
10381413
1039− bl idct32_odd
1414+ bl idct32_odd\suffix
10401415
10411416 transpose16_q_4x_4x4 q15, q14, q13, q12, q11, q10, q9, q8, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16
10421417
@@ -1072,19 +1447,33 @@ endfunc · 29 unmodified lines
10721447 @ r0 = dst
10731448 @ r1 = dst stride
10741449 @ r2 = src (temp buffer)
1075−function idct32_1d_4x32_pass2_neon
1450+function idct32_1d_4x32_pass2\suffix\()_neon
10761451 push {lr}
10771452 movrel r12, idct_coeffs
10781453 vld1.16 {q0-q1}, [r12,:128]
10791454
10801455 mov r12, #128
10811456 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1457+.ifb \suffix
10821458 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
10831459 vld1.16 {d\i}, [r2,:64], r12
10841460 .endr
10851461 sub r2, r2, r12, lsl #4
1462+.endif
1463+.ifc \suffix,_quarter
1464+.irp i, 16, 17, 18, 19
1465+ vld1.16 {d\i}, [r2,:64], r12
1466+.endr
1467+ sub r2, r2, r12, lsl #2
1468+.endif
1469+.ifc \suffix,_half
1470+.irp i, 16, 17, 18, 19, 20, 21, 22, 23
1471+ vld1.16 {d\i}, [r2,:64], r12
1472+.endr
1473+ sub r2, r2, r12, lsl #3
1474+.endif
10861475
1087− bl idct16
1476+ bl idct16\suffix
10881477
10891478 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
10901479 vst1.16 {d\i}, [r2,:64], r12
@@ -1094,13 +1483,27 @@ function idct32_1d_4x32_pass2_neon · 3 unmodified lines
10941483 add r2, r2, #64
10951484
10961485 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1486+.ifb \suffix
10971487 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
10981488 vld1.16 {d\i}, [r2,:64], r12
10991489 .endr
11001490 sub r2, r2, r12, lsl #4
1491+.endif
1492+.ifc \suffix,_quarter
1493+.irp i, 16, 17, 18, 19
1494+ vld1.16 {d\i}, [r2,:64], r12
1495+.endr
1496+ sub r2, r2, r12, lsl #2
1497+.endif
1498+.ifc \suffix,_half
1499+.irp i, 16, 17, 18, 19, 20, 21, 22, 23
1500+ vld1.16 {d\i}, [r2,:64], r12
1501+.endr
1502+ sub r2, r2, r12, lsl #3
1503+.endif
11011504 sub r2, r2, #64
11021505
1103− bl idct32_odd
1506+ bl idct32_odd\suffix
11041507
11051508 mov r12, #128
11061509 .macro load_acc_store a, b, c, d, neg=0
@@ -1150,6 +1553,11 @@ function idct32_1d_4x32_pass2_neon · 43 unmodified lines
11501553 .purgem load_acc_store
11511554 pop {pc}
11521555 endfunc
1556+.endm
1557+
1558+idct32_funcs
1559+idct32_funcs _quarter
1560+idct32_funcs _half
11531561
11541562 const min_eob_idct_idct_32, align=4
11551563 .short 0, 9, 34, 70, 135, 240, 336, 448
@@ -1173,6 +1581,11 @@ A and r7, sp, #15 · 17 unmodified lines
11731581 mov r5, r1
11741582 mov r6, r2
11751583
1584+ cmp r3, #34
1585+ ble idct32x32_quarter_add_neon
1586+ cmp r3, #135
1587+ ble idct32x32_half_add_neon
1588+
11761589 .irp i, 0, 4, 8, 12, 16, 20, 24, 28
11771590 add r0, sp, #(\i*64)
11781591 .if \i > 0
@@ -1209,3 +1622,73 @@ A and r7, sp, #15 · 30 unmodified lines
12091622 vpop {q4-q7}
12101623 pop {r4-r8,pc}
12111624 endfunc
1625+
1626+function idct32x32_quarter_add_neon
1627+.irp i, 0, 4
1628+ add r0, sp, #(\i*64)
1629+.if \i == 4
1630+ cmp r3, #9
1631+ ble 1f
1632+.endif
1633+ add r2, r6, #(\i*2)
1634+ bl idct32_1d_4x32_pass1_quarter_neon
1635+.endr
1636+ b 3f
1637+
1638+1:
1639+ @ Write zeros to the temp buffer for pass 2
1640+ vmov.i16 q14, #0
1641+ vmov.i16 q15, #0
1642+.rept 8
1643+ vst1.16 {q14-q15}, [r0,:128]!
1644+.endr
1645+3:
1646+.irp i, 0, 4, 8, 12, 16, 20, 24, 28
1647+ add r0, r4, #(\i)
1648+ mov r1, r5
1649+ add r2, sp, #(\i*2)
1650+ bl idct32_1d_4x32_pass2_quarter_neon
1651+.endr
1652+
1653+ add sp, sp, r7
1654+ vpop {q4-q7}
1655+ pop {r4-r8,pc}
1656+endfunc
1657+
1658+function idct32x32_half_add_neon
1659+.irp i, 0, 4, 8, 12
1660+ add r0, sp, #(\i*64)
1661+.if \i > 0
1662+ ldrh_post r1, r8, #2
1663+ cmp r3, r1
1664+ it le
1665+ movle r1, #(16 - \i)/2
1666+ ble 1f
1667+.endif
1668+ add r2, r6, #(\i*2)
1669+ bl idct32_1d_4x32_pass1_half_neon
1670+.endr
1671+ b 3f
1672+
1673+1:
1674+ @ Write zeros to the temp buffer for pass 2
1675+ vmov.i16 q14, #0
1676+ vmov.i16 q15, #0
1677+2:
1678+ subs r1, r1, #1
1679+.rept 4
1680+ vst1.16 {q14-q15}, [r0,:128]!
1681+.endr
1682+ bne 2b
1683+3:
1684+.irp i, 0, 4, 8, 12, 16, 20, 24, 28
1685+ add r0, r4, #(\i)
1686+ mov r1, r5
1687+ add r2, sp, #(\i*2)
1688+ bl idct32_1d_4x32_pass2_half_neon
1689+.endr
1690+
1691+ add sp, sp, r7
1692+ vpop {q4-q7}
1693+ pop {r4-r8,pc}
1694+endfunc

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t