summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJukka Ojanen <jukka.ojanen@linkotec.net>2016-03-28 13:57:47 +0300
committerJukka Ojanen <jukka.ojanen@linkotec.net>2016-03-28 13:57:47 +0300
commit2cf68165a461a9faf7069e094436d16c22990aff (patch)
treef91cf852ae9ac06d12ae84f64c66df6d5cb22385
parenta62bc084cad3ea82128c8060b17a488f2fce2587 (diff)
downloadffts-2cf68165a461a9faf7069e094436d16c22990aff.zip
ffts-2cf68165a461a9faf7069e094436d16c22990aff.tar.gz
Improve performance of small complex 2D Neon transform by 15%
-rw-r--r--src/ffts_nd.c69
-rw-r--r--src/neon.s1363
2 files changed, 714 insertions, 718 deletions
diff --git a/src/ffts_nd.c b/src/ffts_nd.c
index 72e21e7..2bde9c4 100644
--- a/src/ffts_nd.c
+++ b/src/ffts_nd.c
@@ -92,74 +92,17 @@ static void ffts_free_nd(ffts_plan_t *p)
static void ffts_transpose(uint64_t *in, uint64_t *out, int w, int h, uint64_t *buf)
{
#ifdef HAVE_NEON
- size_t i, j, k;
- int linebytes = 8 * w;
+#if 0
+ neon_transpose(in, out, w, h);
+#else
+ size_t i, j;
for (j = 0; j < h; j += 8) {
for (i = 0; i < w; i += 8) {
- neon_transpose_to_buf(in + j*w + i, buf, w);
-
- uint64_t *p = out + i*h + j;
- uint64_t *pbuf = buf;
- uint64_t *ptemp;
-
- __asm__ __volatile__(
- "mov %[ptemp], %[p]\n\t"
- "add %[p], %[p], %[w], lsl #3\n\t"
- "vld1.32 {q8,q9}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q10,q11}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q12,q13}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q14,q15}, [%[pbuf], :128]!\n\t"
- "vst1.32 {q8,q9}, [%[ptemp], :128]!\n\t"
- "vst1.32 {q10,q11}, [%[ptemp], :128]!\n\t"
- "mov %[ptemp], %[p]\n\t"
- "add %[p], %[p], %[w], lsl #3\n\t"
- "vst1.32 {q12,q13}, [%[ptemp], :128]!\n\t"
- "vst1.32 {q14,q15}, [%[ptemp], :128]!\n\t"
- "mov %[ptemp], %[p]\n\t"
- "add %[p], %[p], %[w], lsl #3\n\t"
- "vld1.32 {q8,q9}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q10,q11}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q12,q13}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q14,q15}, [%[pbuf], :128]!\n\t"
- "vst1.32 {q8,q9}, [%[ptemp], :128]!\n\t"
- "vst1.32 {q10,q11}, [%[ptemp], :128]!\n\t"
- "mov %[ptemp], %[p]\n\t"
- "add %[p], %[p], %[w], lsl #3\n\t"
- "vst1.32 {q12,q13}, [%[ptemp], :128]!\n\t"
- "vst1.32 {q14,q15}, [%[ptemp], :128]!\n\t"
- "mov %[ptemp], %[p]\n\t"
- "add %[p], %[p], %[w], lsl #3\n\t"
- "vld1.32 {q8,q9}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q10,q11}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q12,q13}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q14,q15}, [%[pbuf], :128]!\n\t"
- "vst1.32 {q8,q9}, [%[ptemp], :128]!\n\t"
- "vst1.32 {q10,q11}, [%[ptemp], :128]!\n\t"
- "mov %[ptemp], %[p]\n\t"
- "add %[p], %[p], %[w], lsl #3\n\t"
- "vst1.32 {q12,q13}, [%[ptemp], :128]!\n\t"
- "vst1.32 {q14,q15}, [%[ptemp], :128]!\n\t"
- "mov %[ptemp], %[p]\n\t"
- "add %[p], %[p], %[w], lsl #3\n\t"
- "vld1.32 {q8,q9}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q10,q11}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q12,q13}, [%[pbuf], :128]!\n\t"
- "vld1.32 {q14,q15}, [%[pbuf], :128]!\n\t"
- "vst1.32 {q8,q9}, [%[ptemp], :128]!\n\t"
- "vst1.32 {q10,q11}, [%[ptemp], :128]!\n\t"
- "mov %[ptemp], %[p]\n\t"
- "vst1.32 {q12,q13}, [%[ptemp], :128]!\n\t"
- "vst1.32 {q14,q15}, [%[ptemp], :128]!\n\t"
-
- : [p] "+r" (p), [pbuf] "+r" (pbuf), [ptemp] "+r" (ptemp)
- : [w] "r" (w)
- : "memory", "q8", "q9", "q10", "q11"
- );
-
- /* out[i*h + j] = in[j*w + i]; */
+ neon_transpose_to_buf(in + j*w + i, out + i*h + j, w);
}
}
+#endif
#else
#ifdef HAVE_SSE
uint64_t FFTS_ALIGN(64) tmp[TSIZE*TSIZE];
diff --git a/src/neon.s b/src/neon.s
index ec98250..1e7fb92 100644
--- a/src/neon.s
+++ b/src/neon.s
@@ -1,327 +1,323 @@
/*
-
- This file is part of FFTS -- The Fastest Fourier Transform in the South
-
- Copyright (c) 2012, Anthony M. Blake <amb@anthonix.com>
- Copyright (c) 2012, The University of Waikato
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the organization nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL ANTHONY M. BLAKE BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of FFTS -- The Fastest Fourier Transform in the South
+
+Copyright (c) 2016, Jukka Ojanen <jukka.ojanen@kolumbus.fi>
+Copyright (c) 2012, Anthony M. Blake <amb@anthonix.com>
+Copyright (c) 2012, The University of Waikato
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+* Neither the name of the organization nor the
+names of its contributors may be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANTHONY M. BLAKE BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- .fpu neon
+ .fpu neon
- .align 4
+ .align 4
#ifdef __APPLE__
- .globl _neon_x4
+ .globl _neon_x4
_neon_x4:
#else
- .globl neon_x4
+ .globl neon_x4
neon_x4:
#endif
-@ add r3, r0, #0
-
- vld1.32 {q8,q9}, [r0, :128]
- add r4, r0, r1, lsl #1
- vld1.32 {q10,q11}, [r4, :128]
- add r5, r0, r1, lsl #2
- vld1.32 {q12,q13}, [r5, :128]
- add r6, r4, r1, lsl #2
- vld1.32 {q14,q15}, [r6, :128]
- vld1.32 {q2,q3}, [r2, :128]
-
- vmul.f32 q0, q13, q3
- vmul.f32 q5, q12, q2
- vmul.f32 q1, q14, q2
- vmul.f32 q4, q14, q3
- vmul.f32 q14, q12, q3
- vmul.f32 q13, q13, q2
- vmul.f32 q12, q15, q3
- vmul.f32 q2, q15, q2
- vsub.f32 q0, q5, q0
- vadd.f32 q13, q13, q14
- vadd.f32 q12, q12, q1
- vsub.f32 q1, q2, q4
- vadd.f32 q15, q0, q12
- vsub.f32 q12, q0, q12
- vadd.f32 q14, q13, q1
- vsub.f32 q13, q13, q1
- vadd.f32 q0, q8, q15
- vadd.f32 q1, q9, q14
- vsub.f32 q2, q10, q13 @
- vsub.f32 q4, q8, q15
- vadd.f32 q3, q11, q12 @
- vst1.32 {q0,q1}, [r0, :128]
- vsub.f32 q5, q9, q14
- vadd.f32 q6, q10, q13 @
- vsub.f32 q7, q11, q12 @
- vst1.32 {q2,q3}, [r4, :128]
- vst1.32 {q4,q5}, [r5, :128]
- vst1.32 {q6,q7}, [r6, :128]
- bx lr
-
- .align 4
+ vld1.32 {q8, q9}, [r0, :128]
+ add r4, r0, r1, lsl #1
+ vld1.32 {q10, q11}, [r4, :128]
+ add r5, r0, r1, lsl #2
+ vld1.32 {q12, q13}, [r5, :128]
+ add r6, r4, r1, lsl #2
+ vld1.32 {q14, q15}, [r6, :128]
+ vld1.32 {q2, q3}, [r2, :128]
+
+ vmul.f32 q0, q13, q3
+ vmul.f32 q5, q12, q2
+ vmul.f32 q1, q14, q2
+ vmul.f32 q4, q14, q3
+ vmul.f32 q14, q12, q3
+ vmul.f32 q13, q13, q2
+ vmul.f32 q12, q15, q3
+ vmul.f32 q2, q15, q2
+ vsub.f32 q0, q5, q0
+ vadd.f32 q13, q13, q14
+ vadd.f32 q12, q12, q1
+ vsub.f32 q1, q2, q4
+ vadd.f32 q15, q0, q12
+ vsub.f32 q12, q0, q12
+ vadd.f32 q14, q13, q1
+ vsub.f32 q13, q13, q1
+ vadd.f32 q0, q8, q15
+ vadd.f32 q1, q9, q14
+ vsub.f32 q2, q10, q13
+ vsub.f32 q4, q8, q15
+ vadd.f32 q3, q11, q12
+ vst1.32 {q0, q1}, [r0, :128]
+ vsub.f32 q5, q9, q14
+ vadd.f32 q6, q10, q13
+ vsub.f32 q7, q11, q12
+ vst1.32 {q2, q3}, [r4, :128]
+ vst1.32 {q4, q5}, [r5, :128]
+ vst1.32 {q6, q7}, [r6, :128]
+ bx lr
+
+ .align 4
#ifdef __APPLE__
- .globl _neon_x8
+ .globl _neon_x8
_neon_x8:
#else
- .globl neon_x8
+ .globl neon_x8
neon_x8:
#endif
- mov r11, #0
- add r3, r0, #0 @ data0
- add r5, r0, r1, lsl #1 @ data2
- add r4, r0, r1 @ data1
- add r7, r5, r1, lsl #1 @ data4
- add r6, r5, r1 @ data3
- add r9, r7, r1, lsl #1 @ data6
- add r8, r7, r1 @ data5
- add r10, r9, r1 @ data7
- add r12, r2, #0 @ LUT
-
- sub r11, r11, r1, lsr #5
-neon_x8_loop:
- vld1.32 {q2,q3}, [r12, :128]!
- vld1.32 {q14,q15}, [r6, :128]
- vld1.32 {q10,q11}, [r5, :128]
- adds r11, r11, #1
- vmul.f32 q12, q15, q2
- vmul.f32 q8, q14, q3
- vmul.f32 q13, q14, q2
- vmul.f32 q9, q10, q3
- vmul.f32 q1, q10, q2
- vmul.f32 q0, q11, q2
- vmul.f32 q14, q11, q3
- vmul.f32 q15, q15, q3
- vld1.32 {q2,q3}, [r12, :128]!
- vsub.f32 q10, q12, q8
- vadd.f32 q11, q0, q9
- vadd.f32 q8, q15, q13
- vld1.32 {q12,q13}, [r4, :128]
- vsub.f32 q9, q1, q14
- vsub.f32 q15, q11, q10
- vsub.f32 q14, q9, q8
- vsub.f32 q4, q12, q15 @
- vadd.f32 q6, q12, q15 @
- vadd.f32 q5, q13, q14 @
- vsub.f32 q7, q13, q14 @
- vld1.32 {q14,q15}, [r9, :128]
- vld1.32 {q12,q13}, [r7, :128]
- vmul.f32 q1, q14, q2
- vmul.f32 q0, q14, q3
- vst1.32 {q4,q5}, [r4, :128]
- vmul.f32 q14, q15, q3
- vmul.f32 q4, q15, q2
- vadd.f32 q15, q9, q8
- vst1.32 {q6,q7}, [r6, :128]
- vmul.f32 q8, q12, q3
- vmul.f32 q5, q13, q3
- vmul.f32 q12, q12, q2
- vmul.f32 q9, q13, q2
- vadd.f32 q14, q14, q1
- vsub.f32 q13, q4, q0
- vadd.f32 q0, q9, q8
- vld1.32 {q8,q9}, [r3, :128]
- vadd.f32 q1, q11, q10
- vsub.f32 q12, q12, q5
- vadd.f32 q11, q8, q15
- vsub.f32 q8, q8, q15
- vadd.f32 q2, q12, q14
- vsub.f32 q10, q0, q13
- vadd.f32 q15, q0, q13
- vadd.f32 q13, q9, q1
- vsub.f32 q9, q9, q1
- vsub.f32 q12, q12, q14
- vadd.f32 q0, q11, q2
- vadd.f32 q1, q13, q15
- vsub.f32 q4, q11, q2
- vsub.f32 q2, q8, q10 @
- vadd.f32 q3, q9, q12 @
- vst1.32 {q0,q1}, [r3, :128]!
- vsub.f32 q5, q13, q15
- vld1.32 {q14,q15}, [r10, :128]
- vsub.f32 q7, q9, q12 @
- vld1.32 {q12,q13}, [r8, :128]
- vst1.32 {q2,q3}, [r5, :128]!
- vld1.32 {q2,q3}, [r12, :128]!
- vadd.f32 q6, q8, q10 @
- vmul.f32 q8, q14, q2
- vst1.32 {q4,q5}, [r7, :128]!
- vmul.f32 q10, q15, q3
- vmul.f32 q9, q13, q3
- vmul.f32 q11, q12, q2
- vmul.f32 q14, q14, q3
- vst1.32 {q6,q7}, [r9, :128]!
- vmul.f32 q15, q15, q2
- vmul.f32 q12, q12, q3
- vmul.f32 q13, q13, q2
- vadd.f32 q10, q10, q8
- vsub.f32 q11, q11, q9
- vld1.32 {q8,q9}, [r4, :128]
- vsub.f32 q14, q15, q14
- vadd.f32 q15, q13, q12
- vadd.f32 q13, q11, q10
- vadd.f32 q12, q15, q14
- vsub.f32 q15, q15, q14
- vsub.f32 q14, q11, q10
- vld1.32 {q10,q11}, [r6, :128]
- vadd.f32 q0, q8, q13
- vadd.f32 q1, q9, q12
- vsub.f32 q2, q10, q15 @
- vadd.f32 q3, q11, q14 @
- vsub.f32 q4, q8, q13
- vst1.32 {q0,q1}, [r4, :128]!
- vsub.f32 q5, q9, q12
- vadd.f32 q6, q10, q15 @
- vst1.32 {q2,q3}, [r6, :128]!
- vsub.f32 q7, q11, q14 @
- vst1.32 {q4,q5}, [r8, :128]!
- vst1.32 {q6,q7}, [r10, :128]!
- bne neon_x8_loop
-
- bx lr
-
- .align 4
+ mov r11, #0
+ add r3, r0, #0 @ data0
+ add r5, r0, r1, lsl #1 @ data2
+ add r4, r0, r1 @ data1
+ add r7, r5, r1, lsl #1 @ data4
+ add r6, r5, r1 @ data3
+ add r9, r7, r1, lsl #1 @ data6
+ add r8, r7, r1 @ data5
+ add r10, r9, r1 @ data7
+ add r12, r2, #0 @ LUT
+
+ sub r11, r11, r1, lsr #5
+1:
+ vld1.32 {q2, q3}, [r12, :128]!
+ vld1.32 {q14, q15}, [r6, :128]
+ vld1.32 {q10, q11}, [r5, :128]
+ adds r11, r11, #1
+ vmul.f32 q12, q15, q2
+ vmul.f32 q8, q14, q3
+ vmul.f32 q13, q14, q2
+ vmul.f32 q9, q10, q3
+ vmul.f32 q1, q10, q2
+ vmul.f32 q0, q11, q2
+ vmul.f32 q14, q11, q3
+ vmul.f32 q15, q15, q3
+ vld1.32 {q2, q3}, [r12, :128]!
+ vsub.f32 q10, q12, q8
+ vadd.f32 q11, q0, q9
+ vadd.f32 q8, q15, q13
+ vld1.32 {q12, q13}, [r4, :128]
+ vsub.f32 q9, q1, q14
+ vsub.f32 q15, q11, q10
+ vsub.f32 q14, q9, q8
+ vsub.f32 q4, q12, q15
+ vadd.f32 q6, q12, q15
+ vadd.f32 q5, q13, q14
+ vsub.f32 q7, q13, q14
+ vld1.32 {q14, q15}, [r9, :128]
+ vld1.32 {q12, q13}, [r7, :128]
+ vmul.f32 q1, q14, q2
+ vmul.f32 q0, q14, q3
+ vst1.32 {q4, q5}, [r4, :128]
+ vmul.f32 q14, q15, q3
+ vmul.f32 q4, q15, q2
+ vadd.f32 q15, q9, q8
+ vst1.32 {q6, q7}, [r6, :128]
+ vmul.f32 q8, q12, q3
+ vmul.f32 q5, q13, q3
+ vmul.f32 q12, q12, q2
+ vmul.f32 q9, q13, q2
+ vadd.f32 q14, q14, q1
+ vsub.f32 q13, q4, q0
+ vadd.f32 q0, q9, q8
+ vld1.32 {q8, q9}, [r3, :128]
+ vadd.f32 q1, q11, q10
+ vsub.f32 q12, q12, q5
+ vadd.f32 q11, q8, q15
+ vsub.f32 q8, q8, q15
+ vadd.f32 q2, q12, q14
+ vsub.f32 q10, q0, q13
+ vadd.f32 q15, q0, q13
+ vadd.f32 q13, q9, q1
+ vsub.f32 q9, q9, q1
+ vsub.f32 q12, q12, q14
+ vadd.f32 q0, q11, q2
+ vadd.f32 q1, q13, q15
+ vsub.f32 q4, q11, q2
+ vsub.f32 q2, q8, q10
+ vadd.f32 q3, q9, q12
+ vst1.32 {q0, q1}, [r3, :128]!
+ vsub.f32 q5, q13, q15
+ vld1.32 {q14, q15}, [r10, :128]
+ vsub.f32 q7, q9, q12
+ vld1.32 {q12, q13}, [r8, :128]
+ vst1.32 {q2, q3}, [r5, :128]!
+ vld1.32 {q2, q3}, [r12, :128]!
+ vadd.f32 q6, q8, q10
+ vmul.f32 q8, q14, q2
+ vst1.32 {q4, q5}, [r7, :128]!
+ vmul.f32 q10, q15, q3
+ vmul.f32 q9, q13, q3
+ vmul.f32 q11, q12, q2
+ vmul.f32 q14, q14, q3
+ vst1.32 {q6, q7}, [r9, :128]!
+ vmul.f32 q15, q15, q2
+ vmul.f32 q12, q12, q3
+ vmul.f32 q13, q13, q2
+ vadd.f32 q10, q10, q8
+ vsub.f32 q11, q11, q9
+ vld1.32 {q8, q9}, [r4, :128]
+ vsub.f32 q14, q15, q14
+ vadd.f32 q15, q13, q12
+ vadd.f32 q13, q11, q10
+ vadd.f32 q12, q15, q14
+ vsub.f32 q15, q15, q14
+ vsub.f32 q14, q11, q10
+ vld1.32 {q10, q11}, [r6, :128]
+ vadd.f32 q0, q8, q13
+ vadd.f32 q1, q9, q12
+ vsub.f32 q2, q10, q15
+ vadd.f32 q3, q11, q14
+ vsub.f32 q4, q8, q13
+ vst1.32 {q0, q1}, [r4, :128]!
+ vsub.f32 q5, q9, q12
+ vadd.f32 q6, q10, q15
+ vst1.32 {q2, q3}, [r6, :128]!
+ vsub.f32 q7, q11, q14
+ vst1.32 {q4, q5}, [r8, :128]!
+ vst1.32 {q6, q7}, [r10, :128]!
+ bne 1b
+ bx lr
+
+ .align 4
#ifdef __APPLE__
- .globl _neon_x8_t
+ .globl _neon_x8_t
_neon_x8_t:
#else
- .globl neon_x8_t
+ .globl neon_x8_t
neon_x8_t:
#endif
- mov r11, #0
- add r3, r0, #0 @ data0
- add r5, r0, r1, lsl #1 @ data2
- add r4, r0, r1 @ data1
- add r7, r5, r1, lsl #1 @ data4
- add r6, r5, r1 @ data3
- add r9, r7, r1, lsl #1 @ data6
- add r8, r7, r1 @ data5
- add r10, r9, r1 @ data7
- add r12, r2, #0 @ LUT
-
- sub r11, r11, r1, lsr #5
-neon_x8_t_loop:
- vld1.32 {q2,q3}, [r12, :128]!
- vld1.32 {q14,q15}, [r6, :128]
- vld1.32 {q10,q11}, [r5, :128]
- adds r11, r11, #1
- vmul.f32 q12, q15, q2
- vmul.f32 q8, q14, q3
- vmul.f32 q13, q14, q2
- vmul.f32 q9, q10, q3
- vmul.f32 q1, q10, q2
- vmul.f32 q0, q11, q2
- vmul.f32 q14, q11, q3
- vmul.f32 q15, q15, q3
- vld1.32 {q2,q3}, [r12, :128]!
- vsub.f32 q10, q12, q8
- vadd.f32 q11, q0, q9
- vadd.f32 q8, q15, q13
- vld1.32 {q12,q13}, [r4, :128]
- vsub.f32 q9, q1, q14
- vsub.f32 q15, q11, q10
- vsub.f32 q14, q9, q8
- vsub.f32 q4, q12, q15 @
- vadd.f32 q6, q12, q15 @
- vadd.f32 q5, q13, q14 @
- vsub.f32 q7, q13, q14 @
- vld1.32 {q14,q15}, [r9, :128]
- vld1.32 {q12,q13}, [r7, :128]
- vmul.f32 q1, q14, q2
- vmul.f32 q0, q14, q3
- vst1.32 {q4,q5}, [r4, :128]
- vmul.f32 q14, q15, q3
- vmul.f32 q4, q15, q2
- vadd.f32 q15, q9, q8
- vst1.32 {q6,q7}, [r6, :128]
- vmul.f32 q8, q12, q3
- vmul.f32 q5, q13, q3
- vmul.f32 q12, q12, q2
- vmul.f32 q9, q13, q2
- vadd.f32 q14, q14, q1
- vsub.f32 q13, q4, q0
- vadd.f32 q0, q9, q8
- vld1.32 {q8,q9}, [r3, :128]
- vadd.f32 q1, q11, q10
- vsub.f32 q12, q12, q5
- vadd.f32 q11, q8, q15
- vsub.f32 q8, q8, q15
- vadd.f32 q2, q12, q14
- vsub.f32 q10, q0, q13
- vadd.f32 q15, q0, q13
- vadd.f32 q13, q9, q1
- vsub.f32 q9, q9, q1
- vsub.f32 q12, q12, q14
- vadd.f32 q0, q11, q2
- vadd.f32 q1, q13, q15
- vsub.f32 q4, q11, q2
- vsub.f32 q2, q8, q10 @
- vadd.f32 q3, q9, q12 @
- vst2.32 {q0,q1}, [r3, :128]!
- vsub.f32 q5, q13, q15
- vld1.32 {q14,q15}, [r10, :128]
- vsub.f32 q7, q9, q12 @
- vld1.32 {q12,q13}, [r8, :128]
- vst2.32 {q2,q3}, [r5, :128]!
- vld1.32 {q2,q3}, [r12, :128]!
- vadd.f32 q6, q8, q10 @
- vmul.f32 q8, q14, q2
- vst2.32 {q4,q5}, [r7, :128]!
- vmul.f32 q10, q15, q3
- vmul.f32 q9, q13, q3
- vmul.f32 q11, q12, q2
- vmul.f32 q14, q14, q3
- vst2.32 {q6,q7}, [r9, :128]!
- vmul.f32 q15, q15, q2
- vmul.f32 q12, q12, q3
- vmul.f32 q13, q13, q2
- vadd.f32 q10, q10, q8
- vsub.f32 q11, q11, q9
- vld1.32 {q8,q9}, [r4, :128]
- vsub.f32 q14, q15, q14
- vadd.f32 q15, q13, q12
- vadd.f32 q13, q11, q10
- vadd.f32 q12, q15, q14
- vsub.f32 q15, q15, q14
- vsub.f32 q14, q11, q10
- vld1.32 {q10,q11}, [r6, :128]
- vadd.f32 q0, q8, q13
- vadd.f32 q1, q9, q12
- vsub.f32 q2, q10, q15 @
- vadd.f32 q3, q11, q14 @
- vsub.f32 q4, q8, q13
- vst2.32 {q0,q1}, [r4, :128]!
- vsub.f32 q5, q9, q12
- vadd.f32 q6, q10, q15 @
- vst2.32 {q2,q3}, [r6, :128]!
- vsub.f32 q7, q11, q14 @
- vst2.32 {q4,q5}, [r8, :128]!
- vst2.32 {q6,q7}, [r10, :128]!
- bne neon_x8_t_loop
-
- @bx lr
+ mov r11, #0
+ add r3, r0, #0 @ data0
+ add r5, r0, r1, lsl #1 @ data2
+ add r4, r0, r1 @ data1
+ add r7, r5, r1, lsl #1 @ data4
+ add r6, r5, r1 @ data3
+ add r9, r7, r1, lsl #1 @ data6
+ add r8, r7, r1 @ data5
+ add r10, r9, r1 @ data7
+ add r12, r2, #0 @ LUT
+
+ sub r11, r11, r1, lsr #5
+1:
+ vld1.32 {q2, q3}, [r12, :128]!
+ vld1.32 {q14, q15}, [r6, :128]
+ vld1.32 {q10, q11}, [r5, :128]
+ adds r11, r11, #1
+ vmul.f32 q12, q15, q2
+ vmul.f32 q8, q14, q3
+ vmul.f32 q13, q14, q2
+ vmul.f32 q9, q10, q3
+ vmul.f32 q1, q10, q2
+ vmul.f32 q0, q11, q2
+ vmul.f32 q14, q11, q3
+ vmul.f32 q15, q15, q3
+ vld1.32 {q2, q3}, [r12, :128]!
+ vsub.f32 q10, q12, q8
+ vadd.f32 q11, q0, q9
+ vadd.f32 q8, q15, q13
+ vld1.32 {q12, q13}, [r4, :128]
+ vsub.f32 q9, q1, q14
+ vsub.f32 q15, q11, q10
+ vsub.f32 q14, q9, q8
+ vsub.f32 q4, q12, q15
+ vadd.f32 q6, q12, q15
+ vadd.f32 q5, q13, q14
+ vsub.f32 q7, q13, q14
+ vld1.32 {q14, q15}, [r9, :128]
+ vld1.32 {q12, q13}, [r7, :128]
+ vmul.f32 q1, q14, q2
+ vmul.f32 q0, q14, q3
+ vst1.32 {q4, q5}, [r4, :128]
+ vmul.f32 q14, q15, q3
+ vmul.f32 q4, q15, q2
+ vadd.f32 q15, q9, q8
+ vst1.32 {q6, q7}, [r6, :128]
+ vmul.f32 q8, q12, q3
+ vmul.f32 q5, q13, q3
+ vmul.f32 q12, q12, q2
+ vmul.f32 q9, q13, q2
+ vadd.f32 q14, q14, q1
+ vsub.f32 q13, q4, q0
+ vadd.f32 q0, q9, q8
+ vld1.32 {q8, q9}, [r3, :128]
+ vadd.f32 q1, q11, q10
+ vsub.f32 q12, q12, q5
+ vadd.f32 q11, q8, q15
+ vsub.f32 q8, q8, q15
+ vadd.f32 q2, q12, q14
+ vsub.f32 q10, q0, q13
+ vadd.f32 q15, q0, q13
+ vadd.f32 q13, q9, q1
+ vsub.f32 q9, q9, q1
+ vsub.f32 q12, q12, q14
+ vadd.f32 q0, q11, q2
+ vadd.f32 q1, q13, q15
+ vsub.f32 q4, q11, q2
+ vsub.f32 q2, q8, q10
+ vadd.f32 q3, q9, q12
+ vst2.32 {q0, q1}, [r3, :128]!
+ vsub.f32 q5, q13, q15
+ vld1.32 {q14, q15}, [r10, :128]
+ vsub.f32 q7, q9, q12
+ vld1.32 {q12, q13}, [r8, :128]
+ vst2.32 {q2, q3}, [r5, :128]!
+ vld1.32 {q2, q3}, [r12, :128]!
+ vadd.f32 q6, q8, q10
+ vmul.f32 q8, q14, q2
+ vst2.32 {q4, q5}, [r7, :128]!
+ vmul.f32 q10, q15, q3
+ vmul.f32 q9, q13, q3
+ vmul.f32 q11, q12, q2
+ vmul.f32 q14, q14, q3
+ vst2.32 {q6, q7}, [r9, :128]!
+ vmul.f32 q15, q15, q2
+ vmul.f32 q12, q12, q3
+ vmul.f32 q13, q13, q2
+ vadd.f32 q10, q10, q8
+ vsub.f32 q11, q11, q9
+ vld1.32 {q8, q9}, [r4, :128]
+ vsub.f32 q14, q15, q14
+ vadd.f32 q15, q13, q12
+ vadd.f32 q13, q11, q10
+ vadd.f32 q12, q15, q14
+ vsub.f32 q15, q15, q14
+ vsub.f32 q14, q11, q10
+ vld1.32 {q10, q11}, [r6, :128]
+ vadd.f32 q0, q8, q13
+ vadd.f32 q1, q9, q12
+ vsub.f32 q2, q10, q15
+ vadd.f32 q3, q11, q14
+ vsub.f32 q4, q8, q13
+ vst2.32 {q0, q1}, [r4, :128]!
+ vsub.f32 q5, q9, q12
+ vadd.f32 q6, q10, q15
+ vst2.32 {q2, q3}, [r6, :128]!
+ vsub.f32 q7, q11, q14
+ vst2.32 {q4, q5}, [r8, :128]!
+ vst2.32 {q6, q7}, [r10, :128]!
+ bne 1b
@ assumes r0 = out
@ r1 = in ?
@@ -330,80 +326,80 @@ neon_x8_t_loop:
@ r3-r10 = data pointers
@ r11 = loop iterations
@ r2 & lr = temps
- .align 4
+ .align 4
#ifdef __APPLE__
- .globl _neon_ee
+ .globl _neon_ee
_neon_ee:
#else
- .globl neon_ee
+ .globl neon_ee
neon_ee:
#endif
- vld1.32 {d16, d17}, [r2, :128]
-_neon_ee_loop:
- vld2.32 {q15}, [r10, :128]!
- vld2.32 {q13}, [r8, :128]!
- vld2.32 {q14}, [r7, :128]!
- vld2.32 {q9}, [r4, :128]!
- vld2.32 {q10}, [r3, :128]!
- vld2.32 {q11}, [r6, :128]!
- vld2.32 {q12}, [r5, :128]!
- vsub.f32 q1, q14, q13
- vld2.32 {q0}, [r9, :128]!
- subs r11, r11, #1
- vsub.f32 q2, q0, q15
- vadd.f32 q0, q0, q15
- vmul.f32 d10, d2, d17
- vmul.f32 d11, d3, d16
- vmul.f32 d12, d3, d17
- vmul.f32 d6, d4, d17
- vmul.f32 d7, d5, d16
- vmul.f32 d8, d4, d16
- vmul.f32 d9, d5, d17
- vmul.f32 d13, d2, d16
- vsub.f32 d7, d7, d6
- vadd.f32 d11, d11, d10
- vsub.f32 q1, q12, q11
- vsub.f32 q2, q10, q9
- vadd.f32 d6, d9, d8
- vadd.f32 q4, q14, q13
- vadd.f32 q11, q12, q11
- vadd.f32 q12, q10, q9
- vsub.f32 d10, d13, d12
- vsub.f32 q7, q4, q0
- vsub.f32 q9, q12, q11
- vsub.f32 q13, q5, q3
- vadd.f32 d29, d5, d2 @
- vadd.f32 q5, q5, q3
- vadd.f32 q10, q4, q0
- vadd.f32 q11, q12, q11
- vsub.f32 d31, d5, d2 @
- vsub.f32 d28, d4, d3 @
- vadd.f32 d30, d4, d3 @
- vadd.f32 d5, d19, d14 @-
- vadd.f32 d7, d31, d26 @-
- vadd.f32 q1, q14, q5
- vadd.f32 q0, q11, q10
- vsub.f32 d6, d30, d27 @-
- vsub.f32 d4, d18, d15 @-
- vsub.f32 d13, d19, d14 @-
- vadd.f32 d12, d18, d15 @-
- vsub.f32 d15, d31, d26 @-
- ldr r2, [r12], #4
- vtrn.32 q1, q3
- ldr lr, [r12], #4
- vtrn.32 q0, q2
- add r2, r0, r2, lsl #2
- vsub.f32 q4, q11, q10
- add lr, r0, lr, lsl #2
- vsub.f32 q5, q14, q5
- vadd.f32 d14, d30, d27 @-
- vst2.32 {q0,q1}, [r2, :128]!
- vst2.32 {q2,q3}, [lr, :128]!
- vtrn.32 q4, q6
- vtrn.32 q5, q7
- vst2.32 {q4,q5}, [r2, :128]!
- vst2.32 {q6,q7}, [lr, :128]!
- bne _neon_ee_loop
+ vld1.32 {d16, d17}, [r2, :128]
+1:
+ vld2.32 {q15}, [r10, :128]!
+ vld2.32 {q13}, [r8, :128]!
+ vld2.32 {q14}, [r7, :128]!
+ vld2.32 {q9}, [r4, :128]!
+ vld2.32 {q10}, [r3, :128]!
+ vld2.32 {q11}, [r6, :128]!
+ vld2.32 {q12}, [r5, :128]!
+ vsub.f32 q1, q14, q13
+ vld2.32 {q0}, [r9, :128]!
+ subs r11, r11, #1
+ vsub.f32 q2, q0, q15
+ vadd.f32 q0, q0, q15
+ vmul.f32 d10, d2, d17
+ vmul.f32 d11, d3, d16
+ vmul.f32 d12, d3, d17
+ vmul.f32 d6, d4, d17
+ vmul.f32 d7, d5, d16
+ vmul.f32 d8, d4, d16
+ vmul.f32 d9, d5, d17
+ vmul.f32 d13, d2, d16
+ vsub.f32 d7, d7, d6
+ vadd.f32 d11, d11, d10
+ vsub.f32 q1, q12, q11
+ vsub.f32 q2, q10, q9
+ vadd.f32 d6, d9, d8
+ vadd.f32 q4, q14, q13
+ vadd.f32 q11, q12, q11
+ vadd.f32 q12, q10, q9
+ vsub.f32 d10, d13, d12
+ vsub.f32 q7, q4, q0
+ vsub.f32 q9, q12, q11
+ vsub.f32 q13, q5, q3
+ vadd.f32 d29, d5, d2
+ vadd.f32 q5, q5, q3
+ vadd.f32 q10, q4, q0
+ vadd.f32 q11, q12, q11
+ vsub.f32 d31, d5, d2
+ vsub.f32 d28, d4, d3
+ vadd.f32 d30, d4, d3
+ vadd.f32 d5, d19, d14
+ vadd.f32 d7, d31, d26
+ vadd.f32 q1, q14, q5
+ vadd.f32 q0, q11, q10
+ vsub.f32 d6, d30, d27
+ vsub.f32 d4, d18, d15
+ vsub.f32 d13, d19, d14
+ vadd.f32 d12, d18, d15
+ vsub.f32 d15, d31, d26
+ ldr r2, [r12], #4
+ vtrn.32 q1, q3
+ ldr lr, [r12], #4
+ vtrn.32 q0, q2
+ add r2, r0, r2, lsl #2
+ vsub.f32 q4, q11, q10
+ add lr, r0, lr, lsl #2
+ vsub.f32 q5, q14, q5
+ vadd.f32 d14, d30, d27
+ vst2.32 {q0, q1}, [r2, :128]!
+ vst2.32 {q2, q3}, [lr, :128]!
+ vtrn.32 q4, q6
+ vtrn.32 q5, q7
+ vst2.32 {q4, q5}, [r2, :128]!
+ vst2.32 {q6, q7}, [lr, :128]!
+ bne 1b
@ assumes r0 = out
@
@@ -411,57 +407,57 @@ _neon_ee_loop:
@ r3-r10 = data pointers
@ r11 = loop iterations
@ r2 & lr = temps
- .align 4
+ .align 4
#ifdef __APPLE__
- .globl _neon_oo
+ .globl _neon_oo
_neon_oo:
#else
- .globl neon_oo
+ .globl neon_oo
neon_oo:
#endif
-_neon_oo_loop:
- vld2.32 {q8}, [r6, :128]!
- vld2.32 {q9}, [r5, :128]!
- vld2.32 {q10}, [r4, :128]!
- vld2.32 {q13}, [r3, :128]!
- vadd.f32 q11, q9, q8
- vsub.f32 q8, q9, q8
- vsub.f32 q9, q13, q10
- vadd.f32 q12, q13, q10
- subs r11, r11, #1
- vld2.32 {q10}, [r7, :128]!
- vld2.32 {q13}, [r9, :128]!
- vsub.f32 q2, q12, q11
- vsub.f32 d7, d19, d16 @
- vadd.f32 d3, d19, d16 @
- vadd.f32 d6, d18, d17 @
- vsub.f32 d2, d18, d17 @
- vld2.32 {q9}, [r8, :128]!
- vld2.32 {q8}, [r10, :128]!
- vadd.f32 q0, q12, q11
- vadd.f32 q11, q13, q8
- vadd.f32 q12, q10, q9
- vsub.f32 q8, q13, q8
- vsub.f32 q9, q10, q9
- vsub.f32 q6, q12, q11
- vadd.f32 q4, q12, q11
- vtrn.32 q0, q2
- ldr r2, [r12], #4
- vsub.f32 d15, d19, d16 @
- ldr lr, [r12], #4
- vadd.f32 d11, d19, d16 @
- vadd.f32 d14, d18, d17 @
- vsub.f32 d10, d18, d17 @
- add r2, r0, r2, lsl #2
- vtrn.32 q1, q3
- add lr, r0, lr, lsl #2
- vst2.32 {q0,q1}, [r2, :128]!
- vst2.32 {q2,q3}, [lr, :128]!
- vtrn.32 q4, q6
- vtrn.32 q5, q7
- vst2.32 {q4,q5}, [r2, :128]!
- vst2.32 {q6,q7}, [lr, :128]!
- bne _neon_oo_loop
+1:
+ vld2.32 {q8}, [r6, :128]!
+ vld2.32 {q9}, [r5, :128]!
+ vld2.32 {q10}, [r4, :128]!
+ vld2.32 {q13}, [r3, :128]!
+ vadd.f32 q11, q9, q8
+ vsub.f32 q8, q9, q8
+ vsub.f32 q9, q13, q10
+ vadd.f32 q12, q13, q10
+ subs r11, r11, #1
+ vld2.32 {q10}, [r7, :128]!
+ vld2.32 {q13}, [r9, :128]!
+ vsub.f32 q2, q12, q11
+ vsub.f32 d7, d19, d16
+ vadd.f32 d3, d19, d16
+ vadd.f32 d6, d18, d17
+ vsub.f32 d2, d18, d17
+ vld2.32 {q9}, [r8, :128]!
+ vld2.32 {q8}, [r10, :128]!
+ vadd.f32 q0, q12, q11
+ vadd.f32 q11, q13, q8
+ vadd.f32 q12, q10, q9
+ vsub.f32 q8, q13, q8
+ vsub.f32 q9, q10, q9
+ vsub.f32 q6, q12, q11
+ vadd.f32 q4, q12, q11
+ vtrn.32 q0, q2
+ ldr r2, [r12], #4
+ vsub.f32 d15, d19, d16
+ ldr lr, [r12], #4
+ vadd.f32 d11, d19, d16
+ vadd.f32 d14, d18, d17
+ vsub.f32 d10, d18, d17
+ add r2, r0, r2, lsl #2
+ vtrn.32 q1, q3
+ add lr, r0, lr, lsl #2
+ vst2.32 {q0, q1}, [r2, :128]!
+ vst2.32 {q2, q3}, [lr, :128]!
+ vtrn.32 q4, q6
+ vtrn.32 q5, q7
+ vst2.32 {q4, q5}, [r2, :128]!
+ vst2.32 {q6, q7}, [lr, :128]!
+ bne 1b
@ assumes r0 = out
@
@@ -469,81 +465,80 @@ _neon_oo_loop:
@ r3-r10 = data pointers
@ r11 = addr of twiddle
@ r2 & lr = temps
- .align 4
+ .align 4
#ifdef __APPLE__
- .globl _neon_eo
+ .globl _neon_eo
_neon_eo:
#else
- .globl neon_eo
+ .globl neon_eo
neon_eo:
#endif
- vld2.32 {q9}, [r5, :128]! @tag2
- vld2.32 {q13}, [r3, :128]! @tag0
- vld2.32 {q12}, [r4, :128]! @tag1
- vld2.32 {q0}, [r7, :128]! @tag4
- vsub.f32 q11, q13, q12
- vld2.32 {q8}, [r6, :128]! @tag3
- vadd.f32 q12, q13, q12
- vsub.f32 q10, q9, q8
- vadd.f32 q8, q9, q8
- vadd.f32 q9, q12, q8
- vadd.f32 d9, d23, d20 @
- vsub.f32 d11, d23, d20 @
- vsub.f32 q8, q12, q8
- vsub.f32 d8, d22, d21 @
- vadd.f32 d10, d22, d21 @
- ldr r2, [r12], #4
- vld1.32 {d20, d21}, [r11, :128]
- ldr lr, [r12], #4
- vtrn.32 q9, q4
- add r2, r0, r2, lsl #2
- vtrn.32 q8, q5
- add lr, r0, lr, lsl #2
- vswp d9,d10
- vst1.32 {d8,d9,d10,d11}, [lr, :128]!
- vld2.32 {q13}, [r10, :128]! @tag7
- vld2.32 {q15}, [r9, :128]! @tag6
- vld2.32 {q11}, [r8, :128]! @tag5
- vsub.f32 q14, q15, q13
- vsub.f32 q12, q0, q11
- vadd.f32 q11, q0, q11
- vadd.f32 q13, q15, q13
- vadd.f32 d13, d29, d24 @
- vadd.f32 q15, q13, q11
- vsub.f32 d12, d28, d25 @
- vsub.f32 d15, d29, d24 @
- vadd.f32 d14, d28, d25 @
- vtrn.32 q15, q6
- vsub.f32 q15, q13, q11
- vtrn.32 q15, q7
- vswp d13, d14
- vst1.32 {d12,d13,d14,d15}, [lr, :128]!
- vtrn.32 q13, q14
- vtrn.32 q11, q12
- vmul.f32 d24, d26, d21
- vmul.f32 d28, d27, d20
- vmul.f32 d25, d26, d20
- vmul.f32 d26, d27, d21
- vmul.f32 d27, d22, d21
- vmul.f32 d30, d23, d20
- vmul.f32 d29, d23, d21
- vmul.f32 d22, d22, d20
- vsub.f32 d21, d28, d24
- vadd.f32 d20, d26, d25
- vadd.f32 d25, d30, d27
- vsub.f32 d24, d22, d29
- vadd.f32 q11, q12, q10
- vsub.f32 q10, q12, q10
- vadd.f32 q0, q9, q11
- vsub.f32 q2, q9, q11
- vadd.f32 d3, d17, d20 @
- vsub.f32 d7, d17, d20 @
- vsub.f32 d2, d16, d21 @
- vadd.f32 d6, d16, d21 @
- vswp d1, d2
- vswp d5, d6
- vstmia r2!, {q0-q3}
-
+ vld2.32 {q9}, [r5, :128]!
+ vld2.32 {q13}, [r3, :128]!
+ vld2.32 {q12}, [r4, :128]!
+ vld2.32 {q0}, [r7, :128]!
+ vsub.f32 q11, q13, q12
+ vld2.32 {q8}, [r6, :128]!
+ vadd.f32 q12, q13, q12
+ vsub.f32 q10, q9, q8
+ vadd.f32 q8, q9, q8
+ vadd.f32 q9, q12, q8
+ vadd.f32 d9, d23, d20
+ vsub.f32 d11, d23, d20
+ vsub.f32 q8, q12, q8
+ vsub.f32 d8, d22, d21
+ vadd.f32 d10, d22, d21
+ ldr r2, [r12], #4
+ vld1.32 {d20, d21}, [r11, :128]
+ ldr lr, [r12], #4
+ vtrn.32 q9, q4
+ add r2, r0, r2, lsl #2
+ vtrn.32 q8, q5
+ add lr, r0, lr, lsl #2
+ vswp d9, d10
+ vst1.32 {d8, d9, d10, d11}, [lr, :128]!
+ vld2.32 {q13}, [r10, :128]!
+ vld2.32 {q15}, [r9, :128]!
+ vld2.32 {q11}, [r8, :128]!
+ vsub.f32 q14, q15, q13
+ vsub.f32 q12, q0, q11
+ vadd.f32 q11, q0, q11
+ vadd.f32 q13, q15, q13
+ vadd.f32 d13, d29, d24
+ vadd.f32 q15, q13, q11
+ vsub.f32 d12, d28, d25
+ vsub.f32 d15, d29, d24
+ vadd.f32 d14, d28, d25
+ vtrn.32 q15, q6
+ vsub.f32 q15, q13, q11
+ vtrn.32 q15, q7
+ vswp d13, d14
+ vst1.32 {d12, d13, d14, d15}, [lr, :128]!
+ vtrn.32 q13, q14
+ vtrn.32 q11, q12
+ vmul.f32 d24, d26, d21
+ vmul.f32 d28, d27, d20
+ vmul.f32 d25, d26, d20
+ vmul.f32 d26, d27, d21
+ vmul.f32 d27, d22, d21
+ vmul.f32 d30, d23, d20
+ vmul.f32 d29, d23, d21
+ vmul.f32 d22, d22, d20
+ vsub.f32 d21, d28, d24
+ vadd.f32 d20, d26, d25
+ vadd.f32 d25, d30, d27
+ vsub.f32 d24, d22, d29
+ vadd.f32 q11, q12, q10
+ vsub.f32 q10, q12, q10
+ vadd.f32 q0, q9, q11
+ vsub.f32 q2, q9, q11
+ vadd.f32 d3, d17, d20
+ vsub.f32 d7, d17, d20
+ vsub.f32 d2, d16, d21
+ vadd.f32 d6, d16, d21
+ vswp d1, d2
+ vswp d5, d6
+ vstmia r2!, {q0-q3}
@ assumes r0 = out
@
@@ -551,189 +546,247 @@ neon_eo:
@ r3-r10 = data pointers
@ r11 = addr of twiddle
@ r2 & lr = temps
- .align 4
+ .align 4
#ifdef __APPLE__
- .globl _neon_oe
+ .globl _neon_oe
_neon_oe:
#else
- .globl neon_oe
+ .globl neon_oe
neon_oe:
#endif
- vld1.32 {q8}, [r5, :128]!
- vld1.32 {q10}, [r6, :128]!
- vld2.32 {q11}, [r4, :128]!
- vld2.32 {q13}, [r3, :128]!
- vld2.32 {q15}, [r10, :128]!
- vorr d25, d17, d17
- vorr d24, d20, d20
- vorr d20, d16, d16
- vsub.f32 q9, q13, q11
- vadd.f32 q11, q13, q11
- ldr r2, [r12], #4
- vtrn.32 d24, d25
- ldr lr, [r12], #4
- vtrn.32 d20, d21
- add r2, r0, r2, lsl #2
- vsub.f32 q8, q10, q12
- add lr, r0, lr, lsl #2
- vadd.f32 q10, q10, q12
- vadd.f32 q0, q11, q10
- vadd.f32 d25, d19, d16 @
- vsub.f32 d27, d19, d16 @
- vsub.f32 q1, q11, q10
- vsub.f32 d24, d18, d17 @
- vadd.f32 d26, d18, d17 @
- vtrn.32 q0, q12
- vtrn.32 q1, q13
- vld1.32 {d24, d25}, [r11, :128]
- vswp d1, d2
- vst1.32 {q0, q1}, [r2, :128]!
- vld2.32 {q0}, [r9, :128]!
- vadd.f32 q1, q0, q15
- vld2.32 {q13}, [r8, :128]!
- vld2.32 {q14}, [r7, :128]!
- vsub.f32 q15, q0, q15
- vsub.f32 q0, q14, q13
- vadd.f32 q3, q14, q13
- vadd.f32 q2, q3, q1
- vadd.f32 d29, d1, d30 @
- vsub.f32 d27, d1, d30 @
- vsub.f32 q3, q3, q1
- vsub.f32 d28, d0, d31 @
- vadd.f32 d26, d0, d31 @
- vtrn.32 q2, q14
- vtrn.32 q3, q13
- vswp d5, d6
- vst1.32 {q2, q3}, [r2, :128]!
- vtrn.32 q11, q9
- vtrn.32 q10, q8
- vmul.f32 d20, d18, d25
- vmul.f32 d22, d19, d24
- vmul.f32 d21, d19, d25
- vmul.f32 d18, d18, d24
- vmul.f32 d19, d16, d25
- vmul.f32 d30, d17, d24
- vmul.f32 d23, d16, d24
- vmul.f32 d24, d17, d25
- vadd.f32 d17, d22, d20
- vsub.f32 d16, d18, d21
- vsub.f32 d21, d30, d19
- vadd.f32 d20, d24, d23
- vadd.f32 q9, q8, q10
- vsub.f32 q8, q8, q10
- vadd.f32 q4, q14, q9
- vsub.f32 q6, q14, q9
- vadd.f32 d11, d27, d16 @
- vsub.f32 d15, d27, d16 @
- vsub.f32 d10, d26, d17 @
- vadd.f32 d14, d26, d17 @
- vswp d9, d10
- vswp d13, d14
- vstmia lr!, {q4-q7}
-
-
- .align 4
+ vld1.32 {q8}, [r5, :128]!
+ vld1.32 {q10}, [r6, :128]!
+ vld2.32 {q11}, [r4, :128]!
+ vld2.32 {q13}, [r3, :128]!
+ vld2.32 {q15}, [r10, :128]!
+ vorr d25, d17, d17
+ vorr d24, d20, d20
+ vorr d20, d16, d16
+ vsub.f32 q9, q13, q11
+ vadd.f32 q11, q13, q11
+ ldr r2, [r12], #4
+ vtrn.32 d24, d25
+ ldr lr, [r12], #4
+ vtrn.32 d20, d21
+ add r2, r0, r2, lsl #2
+ vsub.f32 q8, q10, q12
+ add lr, r0, lr, lsl #2
+ vadd.f32 q10, q10, q12
+ vadd.f32 q0, q11, q10
+ vadd.f32 d25, d19, d16
+ vsub.f32 d27, d19, d16
+ vsub.f32 q1, q11, q10
+ vsub.f32 d24, d18, d17
+ vadd.f32 d26, d18, d17
+ vtrn.32 q0, q12
+ vtrn.32 q1, q13
+ vld1.32 {d24, d25}, [r11, :128]
+ vswp d1, d2
+ vst1.32 {q0, q1}, [r2, :128]!
+ vld2.32 {q0}, [r9, :128]!
+ vadd.f32 q1, q0, q15
+ vld2.32 {q13}, [r8, :128]!
+ vld2.32 {q14}, [r7, :128]!
+ vsub.f32 q15, q0, q15
+ vsub.f32 q0, q14, q13
+ vadd.f32 q3, q14, q13
+ vadd.f32 q2, q3, q1
+ vadd.f32 d29, d1, d30
+ vsub.f32 d27, d1, d30
+ vsub.f32 q3, q3, q1
+ vsub.f32 d28, d0, d31
+ vadd.f32 d26, d0, d31
+ vtrn.32 q2, q14
+ vtrn.32 q3, q13
+ vswp d5, d6
+ vst1.32 {q2, q3}, [r2, :128]!
+ vtrn.32 q11, q9
+ vtrn.32 q10, q8
+ vmul.f32 d20, d18, d25
+ vmul.f32 d22, d19, d24
+ vmul.f32 d21, d19, d25
+ vmul.f32 d18, d18, d24
+ vmul.f32 d19, d16, d25
+ vmul.f32 d30, d17, d24
+ vmul.f32 d23, d16, d24
+ vmul.f32 d24, d17, d25
+ vadd.f32 d17, d22, d20
+ vsub.f32 d16, d18, d21
+ vsub.f32 d21, d30, d19
+ vadd.f32 d20, d24, d23
+ vadd.f32 q9, q8, q10
+ vsub.f32 q8, q8, q10
+ vadd.f32 q4, q14, q9
+ vsub.f32 q6, q14, q9
+ vadd.f32 d11, d27, d16
+ vsub.f32 d15, d27, d16
+ vsub.f32 d10, d26, d17
+ vadd.f32 d14, d26, d17
+ vswp d9, d10
+ vswp d13, d14
+ vstmia lr!, {q4-q7}
+
+ .align 4
#ifdef __APPLE__
- .globl _neon_end
+ .globl _neon_end
_neon_end:
#else
- .globl neon_end
+ .globl neon_end
neon_end:
#endif
- bx lr
+ bx lr
-
- .align 4
+ .align 4
#ifdef __APPLE__
- .globl _neon_transpose
+ .globl _neon_transpose
_neon_transpose:
#else
- .globl neon_transpose
+ .globl neon_transpose
neon_transpose:
#endif
- push {r4-r8}
- @ vpush {q8-q9}
- mov r5, r3
-_neon_transpose_col:
- mov r7, r1
- add r8, r1, r3, lsl #3
- mov r4, r2
- add r6, r0, r2, lsl #3
-_neon_transpose_row:
- vld1.32 {q8,q9}, [r0, :128]!
-@ vld1.32 {q10,q11}, [r0, :128]!
- vld1.32 {q12,q13}, [r6, :128]!
-@ vld1.32 {q14,q15}, [r6, :128]!
- sub r4, r4, #4
- cmp r4, #0
- vswp d17,d24
- vswp d19,d26
- vswp d21,d28
- vswp d23,d30
- vst1.32 {q8}, [r7, :128]
- vst1.32 {q12}, [r8, :128]
- add r7, r7, r3, lsl #4
- add r8, r8, r3, lsl #4
- vst1.32 {q9}, [r7, :128]
- vst1.32 {q13}, [r8, :128]
- add r7, r7, r3, lsl #4
- add r8, r8, r3, lsl #4
-@@vst1.32 {q10}, [r7, :128]
-@@vst1.32 {q14}, [r8, :128]
-@@add r7, r7, r3, lsl #4
-@@add r8, r8, r3, lsl #4
-@@vst1.32 {q11}, [r7, :128]
-@@vst1.32 {q15}, [r8, :128]
-@@add r7, r7, r3, lsl #4
-@@add r8, r8, r3, lsl #4
- bne _neon_transpose_row
- sub r5, r5, #2
- cmp r5, #0
- add r0, r0, r2, lsl #3
- add r1, r1, #16
- bne _neon_transpose_col
- @ vpop {q8-q9}
- pop {r4-r8}
- bx lr
-
- .align 4
+ push {r4-r6, lr}
+ mov r5, r3
+1:
+ mov ip, r1
+ add lr, r1, r3, lsl #3
+ mov r4, r2
+ add r6, r0, r2, lsl #3
+2:
+ vld1.32 {q8, q9}, [r0, :128]!
+ vld1.32 {q12,q13}, [r6, :128]!
+ subs r4, r4, #4
+ vswp d17, d24
+ vswp d19, d26
+ vswp d21, d28
+ vswp d23, d30
+ vst1.32 {q8}, [ip, :128]
+ vst1.32 {q12}, [lr, :128]
+ add ip, ip, r3, lsl #4
+ add lr, lr, r3, lsl #4
+ vst1.32 {q9}, [ip, :128]
+ vst1.32 {q13}, [lr, :128]
+ add ip, ip, r3, lsl #4
+ add lr, lr, r3, lsl #4
+ bne 2b
+ subs r5, r5, #2
+ add r0, r0, r2, lsl #3
+ add r1, r1, #16
+ bne 1b
+ pop {r4-r6, pc}
+
+ .align 4
#ifdef __APPLE__
- .globl _neon_transpose_to_buf
+ .globl _neon_transpose_to_buf
_neon_transpose_to_buf:
#else
- .globl neon_transpose_to_buf
+ .globl neon_transpose_to_buf
neon_transpose_to_buf:
#endif
- push {r4-r10}
- mov r5, #8
-_neon_transpose_to_buf_col:
- mov r4, #8
- add r6, r0, r2, lsl #3
- mov r7, r1
- add r8, r1, #64
- add r9, r1, #128
- add r10, r1, #192
-_neon_transpose_to_buf_row:
- vld1.32 {q8,q9}, [r0, :128]!
- vld1.32 {q12,q13}, [r6, :128]!
- sub r4, r4, #4
- cmp r4, #0
- vswp d17,d24
- vswp d19,d26
- vst1.32 {q8}, [r7, :128]
- vst1.32 {q12}, [r8, :128]
- vst1.32 {q9}, [r9, :128]
- vst1.32 {q13}, [r10, :128]
- add r7, r7, #256
- add r8, r8, #256
- add r9, r9, #256
- add r10, r10, #256
- bne _neon_transpose_to_buf_row
- sub r5, r5, #2
- cmp r5, #0
- sub r0, r0, #64
- add r0, r0, r2, lsl #4
- add r1, r1, #16
- bne _neon_transpose_to_buf_col
- pop {r4-r10}
- bx lr
+ push {r4-r8, lr}
+ vpush {q4-q7}
+
+ @ initialize and preload (TODO: optimize)
+ pld [r0]
+ add r4, r0, r2, lsl #3
+ lsl ip, r2, #4
+ pld [r4]
+ pld [r0, ip]
+ add r6, r1, r2, lsl #3
+ pld [r4, ip]
+ add r7, r6, r2, lsl #3
+ pld [r0, ip, lsl #1]
+ pld [r0, ip, lsl #2]
+ add r8, r7, r2, lsl #3
+ pld [r4, ip, lsl #1]
+ pld [r4, ip, lsl #2]
+ sub ip, ip, #32
+ lsl r3, ip, #1
+ add r3, r3, #16
+
+ @ matrix 0&2 row 0-1
+ vld1.32 {q0, q1}, [r0, :128]!
+ vld1.32 {q2, q3}, [r4, :128]!
+ vswp d1, d4
+ vswp d3, d6
+ vst1.32 {q0}, [r1, :128]!
+ vst1.32 {q2}, [r6, :128]!
+ vst1.32 {q1}, [r7, :128]!
+ vst1.32 {q3}, [r8, :128]!
+
+ @ matrix 1&3 row 0-1
+ vld1.32 {q4, q5}, [r0, :128], ip
+ vld1.32 {q6, q7}, [r4, :128], ip
+ vswp d9, d12
+ vswp d11, d14
+
+ @ matrix 0&2, row 2-3
+ vld1.32 {q0, q1}, [r0, :128]!
+ vld1.32 {q2, q3}, [r4, :128]!
+ vswp d1, d4
+ vswp d3, d6
+ vst1.32 {q0}, [r1, :128]!
+ vst1.32 {q2}, [r6, :128]!
+ vst1.32 {q1}, [r7, :128]!
+ vst1.32 {q3}, [r8, :128]!
+
+ @ matrix 1&3, row 2-3
+ vld1.32 {q8, q9}, [r0, :128], ip
+ vld1.32 {q10, q11}, [r4, :128], ip
+ vswp d17, d20
+ vswp d19, d22
+
+ @ matrix 0&2, row 4-5
+ vld1.32 {q0, q1}, [r0, :128]!
+ vld1.32 {q2, q3}, [r4, :128]!
+ vswp d1, d4
+ vswp d3, d6
+ vst1.32 {q0}, [r1, :128]!
+ vst1.32 {q2}, [r6, :128]!
+ vst1.32 {q1}, [r7, :128]!
+ vst1.32 {q3}, [r8, :128]!
+
+ @ matrix 1&3, row 4-5
+ vld1.32 {q12, q13}, [r0, :128], ip
+ vld1.32 {q14, q15}, [r4, :128], ip
+ vswp d25, d28
+ vswp d27, d30
+
+ @ matrix 0&2, row 6-7
+ vld1.32 {q0, q1}, [r0, :128]!
+ vld1.32 {q2, q3}, [r4, :128]!
+ vswp d1, d4
+ vswp d3, d6
+ vst1.32 {q0}, [r1, :128], r3
+ vst1.32 {q2}, [r6, :128], r3
+ vst1.32 {q1}, [r7, :128], r3
+ vst1.32 {q3}, [r8, :128], r3
+
+ @ matrix 1&3, row 6-7
+ vld1.32 {q0, q1}, [r0, :128]
+ vld1.32 {q2, q3}, [r4, :128]
+ vswp d1, d4
+ vswp d3, d6
+
+ @ these could be replaced with VSTM, but that requires swaps
+ vst1.32 {q4}, [r1, :128]!
+ vst1.32 {q8}, [r1, :128]!
+ vst1.32 {q12}, [r1, :128]!
+ vst1.32 {q0}, [r1, :128]
+
+ vst1.32 {q6}, [r6, :128]!
+ vst1.32 {q10}, [r6, :128]!
+ vst1.32 {q14}, [r6, :128]!
+ vst1.32 {q2}, [r6, :128]
+
+ vst1.32 {q5}, [r7, :128]!
+ vst1.32 {q9}, [r7, :128]!
+ vst1.32 {q13}, [r7, :128]!
+ vst1.32 {q1}, [r7, :128]
+
+ vst1.32 {q7}, [r8, :128]!
+ vst1.32 {q11}, [r8, :128]!
+ vst1.32 {q15}, [r8, :128]!
+ vst1.32 {q3}, [r8, :128]
+
+ vpop {q4-q7}
+ pop {r4-r8, pc}
OpenPOWER on IntegriCloud