aboutsummaryrefslogtreecommitdiff
path: root/files/source/rotate_neon.cc
diff options
context:
space:
mode:
Diffstat (limited to 'files/source/rotate_neon.cc')
-rw-r--r--files/source/rotate_neon.cc565
1 files changed, 346 insertions, 219 deletions
diff --git a/files/source/rotate_neon.cc b/files/source/rotate_neon.cc
index 49b30032..1c22b472 100644
--- a/files/source/rotate_neon.cc
+++ b/files/source/rotate_neon.cc
@@ -4,11 +4,12 @@
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
+ * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "libyuv/row.h"
+#include "libyuv/rotate_row.h"
#include "libyuv/basic_types.h"
@@ -17,33 +18,42 @@ namespace libyuv {
extern "C" {
#endif
-#if !defined(YUV_DISABLE_ASM) && defined(__ARM_NEON__)
+#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) && \
+ !defined(__aarch64__)
-static const uvec8 kVTbl4x4Transpose =
+static uvec8 kVTbl4x4Transpose =
{ 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 };
void TransposeWx8_NEON(const uint8* src, int src_stride,
uint8* dst, int dst_stride,
int width) {
+ const uint8* src_temp;
asm volatile (
// loops are on blocks of 8. loop will stop when
// counter gets to or below 0. starting the counter
// at w-8 allow for this
- "sub %4, #8 \n"
+ "sub %5, #8 \n"
// handle 8x8 blocks. this should be the majority of the plane
- ".p2align 4 \n"
"1: \n"
- "mov r9, %0 \n"
-
- "vld1.8 {d0}, [r9], %1 \n"
- "vld1.8 {d1}, [r9], %1 \n"
- "vld1.8 {d2}, [r9], %1 \n"
- "vld1.8 {d3}, [r9], %1 \n"
- "vld1.8 {d4}, [r9], %1 \n"
- "vld1.8 {d5}, [r9], %1 \n"
- "vld1.8 {d6}, [r9], %1 \n"
- "vld1.8 {d7}, [r9] \n"
+ "mov %0, %1 \n"
+
+ MEMACCESS(0)
+ "vld1.8 {d0}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.8 {d1}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.8 {d2}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.8 {d3}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.8 {d4}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.8 {d5}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.8 {d6}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.8 {d7}, [%0] \n"
"vtrn.8 d1, d0 \n"
"vtrn.8 d3, d2 \n"
@@ -65,152 +75,205 @@ void TransposeWx8_NEON(const uint8* src, int src_stride,
"vrev16.8 q2, q2 \n"
"vrev16.8 q3, q3 \n"
- "mov r9, %2 \n"
-
- "vst1.8 {d1}, [r9], %3 \n"
- "vst1.8 {d0}, [r9], %3 \n"
- "vst1.8 {d3}, [r9], %3 \n"
- "vst1.8 {d2}, [r9], %3 \n"
- "vst1.8 {d5}, [r9], %3 \n"
- "vst1.8 {d4}, [r9], %3 \n"
- "vst1.8 {d7}, [r9], %3 \n"
- "vst1.8 {d6}, [r9] \n"
-
- "add %0, #8 \n" // src += 8
- "add %2, %2, %3, lsl #3 \n" // dst += 8 * dst_stride
- "subs %4, #8 \n" // w -= 8
+ "mov %0, %3 \n"
+
+ MEMACCESS(0)
+ "vst1.8 {d1}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d0}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d3}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d2}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d5}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d4}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d7}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d6}, [%0] \n"
+
+ "add %1, #8 \n" // src += 8
+ "add %3, %3, %4, lsl #3 \n" // dst += 8 * dst_stride
+ "subs %5, #8 \n" // w -= 8
"bge 1b \n"
// add 8 back to counter. if the result is 0 there are
// no residuals.
- "adds %4, #8 \n"
+ "adds %5, #8 \n"
"beq 4f \n"
// some residual, so between 1 and 7 lines left to transpose
- "cmp %4, #2 \n"
+ "cmp %5, #2 \n"
"blt 3f \n"
- "cmp %4, #4 \n"
+ "cmp %5, #4 \n"
"blt 2f \n"
// 4x8 block
- "mov r9, %0 \n"
- "vld1.32 {d0[0]}, [r9], %1 \n"
- "vld1.32 {d0[1]}, [r9], %1 \n"
- "vld1.32 {d1[0]}, [r9], %1 \n"
- "vld1.32 {d1[1]}, [r9], %1 \n"
- "vld1.32 {d2[0]}, [r9], %1 \n"
- "vld1.32 {d2[1]}, [r9], %1 \n"
- "vld1.32 {d3[0]}, [r9], %1 \n"
- "vld1.32 {d3[1]}, [r9] \n"
-
- "mov r9, %2 \n"
-
- "vld1.8 {q3}, [%5] \n"
+ "mov %0, %1 \n"
+ MEMACCESS(0)
+ "vld1.32 {d0[0]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.32 {d0[1]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.32 {d1[0]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.32 {d1[1]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.32 {d2[0]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.32 {d2[1]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.32 {d3[0]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.32 {d3[1]}, [%0] \n"
+
+ "mov %0, %3 \n"
+
+ MEMACCESS(6)
+ "vld1.8 {q3}, [%6] \n"
"vtbl.8 d4, {d0, d1}, d6 \n"
"vtbl.8 d5, {d0, d1}, d7 \n"
"vtbl.8 d0, {d2, d3}, d6 \n"
"vtbl.8 d1, {d2, d3}, d7 \n"
- // TODO: rework shuffle above to write
- // out with 4 instead of 8 writes
- "vst1.32 {d4[0]}, [r9], %3 \n"
- "vst1.32 {d4[1]}, [r9], %3 \n"
- "vst1.32 {d5[0]}, [r9], %3 \n"
- "vst1.32 {d5[1]}, [r9] \n"
-
- "add r9, %2, #4 \n"
- "vst1.32 {d0[0]}, [r9], %3 \n"
- "vst1.32 {d0[1]}, [r9], %3 \n"
- "vst1.32 {d1[0]}, [r9], %3 \n"
- "vst1.32 {d1[1]}, [r9] \n"
-
- "add %0, #4 \n" // src += 4
- "add %2, %2, %3, lsl #2 \n" // dst += 4 * dst_stride
- "subs %4, #4 \n" // w -= 4
+ // TODO(frkoenig): Rework shuffle above to
+ // write out with 4 instead of 8 writes.
+ MEMACCESS(0)
+ "vst1.32 {d4[0]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d4[1]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d5[0]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d5[1]}, [%0] \n"
+
+ "add %0, %3, #4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d0[0]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d0[1]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d1[0]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d1[1]}, [%0] \n"
+
+ "add %1, #4 \n" // src += 4
+ "add %3, %3, %4, lsl #2 \n" // dst += 4 * dst_stride
+ "subs %5, #4 \n" // w -= 4
"beq 4f \n"
// some residual, check to see if it includes a 2x8 block,
// or less
- "cmp %4, #2 \n"
+ "cmp %5, #2 \n"
"blt 3f \n"
// 2x8 block
"2: \n"
- "mov r9, %0 \n"
- "vld1.16 {d0[0]}, [r9], %1 \n"
- "vld1.16 {d1[0]}, [r9], %1 \n"
- "vld1.16 {d0[1]}, [r9], %1 \n"
- "vld1.16 {d1[1]}, [r9], %1 \n"
- "vld1.16 {d0[2]}, [r9], %1 \n"
- "vld1.16 {d1[2]}, [r9], %1 \n"
- "vld1.16 {d0[3]}, [r9], %1 \n"
- "vld1.16 {d1[3]}, [r9] \n"
+ "mov %0, %1 \n"
+ MEMACCESS(0)
+ "vld1.16 {d0[0]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.16 {d1[0]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.16 {d0[1]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.16 {d1[1]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.16 {d0[2]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.16 {d1[2]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.16 {d0[3]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.16 {d1[3]}, [%0] \n"
"vtrn.8 d0, d1 \n"
- "mov r9, %2 \n"
+ "mov %0, %3 \n"
- "vst1.64 {d0}, [r9], %3 \n"
- "vst1.64 {d1}, [r9] \n"
+ MEMACCESS(0)
+ "vst1.64 {d0}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.64 {d1}, [%0] \n"
- "add %0, #2 \n" // src += 2
- "add %2, %2, %3, lsl #1 \n" // dst += 2 * dst_stride
- "subs %4, #2 \n" // w -= 2
+ "add %1, #2 \n" // src += 2
+ "add %3, %3, %4, lsl #1 \n" // dst += 2 * dst_stride
+ "subs %5, #2 \n" // w -= 2
"beq 4f \n"
// 1x8 block
"3: \n"
- "vld1.8 {d0[0]}, [%0], %1 \n"
- "vld1.8 {d0[1]}, [%0], %1 \n"
- "vld1.8 {d0[2]}, [%0], %1 \n"
- "vld1.8 {d0[3]}, [%0], %1 \n"
- "vld1.8 {d0[4]}, [%0], %1 \n"
- "vld1.8 {d0[5]}, [%0], %1 \n"
- "vld1.8 {d0[6]}, [%0], %1 \n"
- "vld1.8 {d0[7]}, [%0] \n"
-
- "vst1.64 {d0}, [%2] \n"
+ MEMACCESS(1)
+ "vld1.8 {d0[0]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld1.8 {d0[1]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld1.8 {d0[2]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld1.8 {d0[3]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld1.8 {d0[4]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld1.8 {d0[5]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld1.8 {d0[6]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld1.8 {d0[7]}, [%1] \n"
+
+ MEMACCESS(3)
+ "vst1.64 {d0}, [%3] \n"
"4: \n"
- : "+r"(src), // %0
- "+r"(src_stride), // %1
- "+r"(dst), // %2
- "+r"(dst_stride), // %3
- "+r"(width) // %4
- : "r"(&kVTbl4x4Transpose) // %5
- : "memory", "cc", "r9", "q0", "q1", "q2", "q3"
+ : "=&r"(src_temp), // %0
+ "+r"(src), // %1
+ "+r"(src_stride), // %2
+ "+r"(dst), // %3
+ "+r"(dst_stride), // %4
+ "+r"(width) // %5
+ : "r"(&kVTbl4x4Transpose) // %6
+ : "memory", "cc", "q0", "q1", "q2", "q3"
);
}
-static const uvec8 kVTbl4x4TransposeDi =
+static uvec8 kVTbl4x4TransposeDi =
{ 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 };
void TransposeUVWx8_NEON(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b,
int width) {
+ const uint8* src_temp;
asm volatile (
// loops are on blocks of 8. loop will stop when
// counter gets to or below 0. starting the counter
// at w-8 allow for this
- "sub %6, #8 \n"
+ "sub %7, #8 \n"
// handle 8x8 blocks. this should be the majority of the plane
- ".p2align 4 \n"
"1: \n"
- "mov r9, %0 \n"
-
- "vld2.8 {d0, d1}, [r9], %1 \n"
- "vld2.8 {d2, d3}, [r9], %1 \n"
- "vld2.8 {d4, d5}, [r9], %1 \n"
- "vld2.8 {d6, d7}, [r9], %1 \n"
- "vld2.8 {d16, d17}, [r9], %1 \n"
- "vld2.8 {d18, d19}, [r9], %1 \n"
- "vld2.8 {d20, d21}, [r9], %1 \n"
- "vld2.8 {d22, d23}, [r9] \n"
+ "mov %0, %1 \n"
+
+ MEMACCESS(0)
+ "vld2.8 {d0, d1}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.8 {d2, d3}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.8 {d4, d5}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.8 {d6, d7}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.8 {d16, d17}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.8 {d18, d19}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.8 {d20, d21}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.8 {d22, d23}, [%0] \n"
"vtrn.8 q1, q0 \n"
"vtrn.8 q3, q2 \n"
@@ -236,59 +299,84 @@ void TransposeUVWx8_NEON(const uint8* src, int src_stride,
"vrev16.8 q10, q10 \n"
"vrev16.8 q11, q11 \n"
- "mov r9, %2 \n"
-
- "vst1.8 {d2}, [r9], %3 \n"
- "vst1.8 {d0}, [r9], %3 \n"
- "vst1.8 {d6}, [r9], %3 \n"
- "vst1.8 {d4}, [r9], %3 \n"
- "vst1.8 {d18}, [r9], %3 \n"
- "vst1.8 {d16}, [r9], %3 \n"
- "vst1.8 {d22}, [r9], %3 \n"
- "vst1.8 {d20}, [r9] \n"
-
- "mov r9, %4 \n"
-
- "vst1.8 {d3}, [r9], %5 \n"
- "vst1.8 {d1}, [r9], %5 \n"
- "vst1.8 {d7}, [r9], %5 \n"
- "vst1.8 {d5}, [r9], %5 \n"
- "vst1.8 {d19}, [r9], %5 \n"
- "vst1.8 {d17}, [r9], %5 \n"
- "vst1.8 {d23}, [r9], %5 \n"
- "vst1.8 {d21}, [r9] \n"
-
- "add %0, #8*2 \n" // src += 8*2
- "add %2, %2, %3, lsl #3 \n" // dst_a += 8 * dst_stride_a
- "add %4, %4, %5, lsl #3 \n" // dst_b += 8 * dst_stride_b
- "subs %6, #8 \n" // w -= 8
+ "mov %0, %3 \n"
+
+ MEMACCESS(0)
+ "vst1.8 {d2}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d0}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d6}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d4}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d18}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d16}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d22}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.8 {d20}, [%0] \n"
+
+ "mov %0, %5 \n"
+
+ MEMACCESS(0)
+ "vst1.8 {d3}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.8 {d1}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.8 {d7}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.8 {d5}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.8 {d19}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.8 {d17}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.8 {d23}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.8 {d21}, [%0] \n"
+
+ "add %1, #8*2 \n" // src += 8*2
+ "add %3, %3, %4, lsl #3 \n" // dst_a += 8 * dst_stride_a
+ "add %5, %5, %6, lsl #3 \n" // dst_b += 8 * dst_stride_b
+ "subs %7, #8 \n" // w -= 8
"bge 1b \n"
// add 8 back to counter. if the result is 0 there are
// no residuals.
- "adds %6, #8 \n"
+ "adds %7, #8 \n"
"beq 4f \n"
// some residual, so between 1 and 7 lines left to transpose
- "cmp %6, #2 \n"
+ "cmp %7, #2 \n"
"blt 3f \n"
- "cmp %6, #4 \n"
+ "cmp %7, #4 \n"
"blt 2f \n"
- //TODO(frkoenig) : clean this up
+ // TODO(frkoenig): Clean this up
// 4x8 block
- "mov r9, %0 \n"
- "vld1.64 {d0}, [r9], %1 \n"
- "vld1.64 {d1}, [r9], %1 \n"
- "vld1.64 {d2}, [r9], %1 \n"
- "vld1.64 {d3}, [r9], %1 \n"
- "vld1.64 {d4}, [r9], %1 \n"
- "vld1.64 {d5}, [r9], %1 \n"
- "vld1.64 {d6}, [r9], %1 \n"
- "vld1.64 {d7}, [r9] \n"
-
- "vld1.8 {q15}, [%7] \n"
+ "mov %0, %1 \n"
+ MEMACCESS(0)
+ "vld1.64 {d0}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.64 {d1}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.64 {d2}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.64 {d3}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.64 {d4}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.64 {d5}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.64 {d6}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld1.64 {d7}, [%0] \n"
+
+ MEMACCESS(8)
+ "vld1.8 {q15}, [%8] \n"
"vtrn.8 q0, q1 \n"
"vtrn.8 q2, q3 \n"
@@ -302,103 +390,142 @@ void TransposeUVWx8_NEON(const uint8* src, int src_stride,
"vtbl.8 d22, {d6, d7}, d30 \n"
"vtbl.8 d23, {d6, d7}, d31 \n"
- "mov r9, %2 \n"
-
- "vst1.32 {d16[0]}, [r9], %3 \n"
- "vst1.32 {d16[1]}, [r9], %3 \n"
- "vst1.32 {d17[0]}, [r9], %3 \n"
- "vst1.32 {d17[1]}, [r9], %3 \n"
-
- "add r9, %2, #4 \n"
- "vst1.32 {d20[0]}, [r9], %3 \n"
- "vst1.32 {d20[1]}, [r9], %3 \n"
- "vst1.32 {d21[0]}, [r9], %3 \n"
- "vst1.32 {d21[1]}, [r9] \n"
-
- "mov r9, %4 \n"
-
- "vst1.32 {d18[0]}, [r9], %5 \n"
- "vst1.32 {d18[1]}, [r9], %5 \n"
- "vst1.32 {d19[0]}, [r9], %5 \n"
- "vst1.32 {d19[1]}, [r9], %5 \n"
-
- "add r9, %4, #4 \n"
- "vst1.32 {d22[0]}, [r9], %5 \n"
- "vst1.32 {d22[1]}, [r9], %5 \n"
- "vst1.32 {d23[0]}, [r9], %5 \n"
- "vst1.32 {d23[1]}, [r9] \n"
-
- "add %0, #4*2 \n" // src += 4 * 2
- "add %2, %2, %3, lsl #2 \n" // dst_a += 4 * dst_stride_a
- "add %4, %4, %5, lsl #2 \n" // dst_b += 4 * dst_stride_b
- "subs %6, #4 \n" // w -= 4
+ "mov %0, %3 \n"
+
+ MEMACCESS(0)
+ "vst1.32 {d16[0]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d16[1]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d17[0]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d17[1]}, [%0], %4 \n"
+
+ "add %0, %3, #4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d20[0]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d20[1]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d21[0]}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d21[1]}, [%0] \n"
+
+ "mov %0, %5 \n"
+
+ MEMACCESS(0)
+ "vst1.32 {d18[0]}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.32 {d18[1]}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.32 {d19[0]}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.32 {d19[1]}, [%0], %6 \n"
+
+ "add %0, %5, #4 \n"
+ MEMACCESS(0)
+ "vst1.32 {d22[0]}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.32 {d22[1]}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.32 {d23[0]}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.32 {d23[1]}, [%0] \n"
+
+ "add %1, #4*2 \n" // src += 4 * 2
+ "add %3, %3, %4, lsl #2 \n" // dst_a += 4 * dst_stride_a
+ "add %5, %5, %6, lsl #2 \n" // dst_b += 4 * dst_stride_b
+ "subs %7, #4 \n" // w -= 4
"beq 4f \n"
// some residual, check to see if it includes a 2x8 block,
// or less
- "cmp %6, #2 \n"
+ "cmp %7, #2 \n"
"blt 3f \n"
// 2x8 block
"2: \n"
- "mov r9, %0 \n"
- "vld2.16 {d0[0], d2[0]}, [r9], %1 \n"
- "vld2.16 {d1[0], d3[0]}, [r9], %1 \n"
- "vld2.16 {d0[1], d2[1]}, [r9], %1 \n"
- "vld2.16 {d1[1], d3[1]}, [r9], %1 \n"
- "vld2.16 {d0[2], d2[2]}, [r9], %1 \n"
- "vld2.16 {d1[2], d3[2]}, [r9], %1 \n"
- "vld2.16 {d0[3], d2[3]}, [r9], %1 \n"
- "vld2.16 {d1[3], d3[3]}, [r9] \n"
+ "mov %0, %1 \n"
+ MEMACCESS(0)
+ "vld2.16 {d0[0], d2[0]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.16 {d1[0], d3[0]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.16 {d0[1], d2[1]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.16 {d1[1], d3[1]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.16 {d0[2], d2[2]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.16 {d1[2], d3[2]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.16 {d0[3], d2[3]}, [%0], %2 \n"
+ MEMACCESS(0)
+ "vld2.16 {d1[3], d3[3]}, [%0] \n"
"vtrn.8 d0, d1 \n"
"vtrn.8 d2, d3 \n"
- "mov r9, %2 \n"
+ "mov %0, %3 \n"
- "vst1.64 {d0}, [r9], %3 \n"
- "vst1.64 {d2}, [r9] \n"
+ MEMACCESS(0)
+ "vst1.64 {d0}, [%0], %4 \n"
+ MEMACCESS(0)
+ "vst1.64 {d2}, [%0] \n"
- "mov r9, %4 \n"
+ "mov %0, %5 \n"
- "vst1.64 {d1}, [r9], %5 \n"
- "vst1.64 {d3}, [r9] \n"
+ MEMACCESS(0)
+ "vst1.64 {d1}, [%0], %6 \n"
+ MEMACCESS(0)
+ "vst1.64 {d3}, [%0] \n"
- "add %0, #2*2 \n" // src += 2 * 2
- "add %2, %2, %3, lsl #1 \n" // dst_a += 2 * dst_stride_a
- "add %4, %4, %5, lsl #1 \n" // dst_b += 2 * dst_stride_b
- "subs %6, #2 \n" // w -= 2
+ "add %1, #2*2 \n" // src += 2 * 2
+ "add %3, %3, %4, lsl #1 \n" // dst_a += 2 * dst_stride_a
+ "add %5, %5, %6, lsl #1 \n" // dst_b += 2 * dst_stride_b
+ "subs %7, #2 \n" // w -= 2
"beq 4f \n"
// 1x8 block
"3: \n"
- "vld2.8 {d0[0], d1[0]}, [%0], %1 \n"
- "vld2.8 {d0[1], d1[1]}, [%0], %1 \n"
- "vld2.8 {d0[2], d1[2]}, [%0], %1 \n"
- "vld2.8 {d0[3], d1[3]}, [%0], %1 \n"
- "vld2.8 {d0[4], d1[4]}, [%0], %1 \n"
- "vld2.8 {d0[5], d1[5]}, [%0], %1 \n"
- "vld2.8 {d0[6], d1[6]}, [%0], %1 \n"
- "vld2.8 {d0[7], d1[7]}, [%0] \n"
-
- "vst1.64 {d0}, [%2] \n"
- "vst1.64 {d1}, [%4] \n"
+ MEMACCESS(1)
+ "vld2.8 {d0[0], d1[0]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld2.8 {d0[1], d1[1]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld2.8 {d0[2], d1[2]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld2.8 {d0[3], d1[3]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld2.8 {d0[4], d1[4]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld2.8 {d0[5], d1[5]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld2.8 {d0[6], d1[6]}, [%1], %2 \n"
+ MEMACCESS(1)
+ "vld2.8 {d0[7], d1[7]}, [%1] \n"
+
+ MEMACCESS(3)
+ "vst1.64 {d0}, [%3] \n"
+ MEMACCESS(5)
+ "vst1.64 {d1}, [%5] \n"
"4: \n"
- : "+r"(src), // %0
- "+r"(src_stride), // %1
- "+r"(dst_a), // %2
- "+r"(dst_stride_a), // %3
- "+r"(dst_b), // %4
- "+r"(dst_stride_b), // %5
- "+r"(width) // %6
- : "r"(&kVTbl4x4TransposeDi) // %7
- : "memory", "cc", "r9",
+ : "=&r"(src_temp), // %0
+ "+r"(src), // %1
+ "+r"(src_stride), // %2
+ "+r"(dst_a), // %3
+ "+r"(dst_stride_a), // %4
+ "+r"(dst_b), // %5
+ "+r"(dst_stride_b), // %6
+ "+r"(width) // %7
+ : "r"(&kVTbl4x4TransposeDi) // %8
+ : "memory", "cc",
"q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"
);
}
-#endif
+#endif // defined(__ARM_NEON__) && !defined(__aarch64__)
#ifdef __cplusplus
} // extern "C"