gecko/media/libyuv/source/rotate_neon.cc
Randell Jesup 5b18a38cd7 Bug 813645 - Move libyuv to media/libyuv r=glandium
--HG--
rename : media/webrtc/trunk/third_party/libyuv/AUTHORS => media/libyuv/AUTHORS
rename : media/webrtc/trunk/third_party/libyuv/Android.mk => media/libyuv/Android.mk
rename : media/webrtc/trunk/third_party/libyuv/DEPS => media/libyuv/DEPS
rename : media/webrtc/trunk/third_party/libyuv/LICENSE => media/libyuv/LICENSE
rename : media/webrtc/trunk/third_party/libyuv/LICENSE_THIRD_PARTY => media/libyuv/LICENSE_THIRD_PARTY
rename : media/webrtc/trunk/third_party/libyuv/OWNERS => media/libyuv/OWNERS
rename : media/webrtc/trunk/third_party/libyuv/PATENTS => media/libyuv/PATENTS
rename : media/webrtc/trunk/third_party/libyuv/README.chromium => media/libyuv/README.chromium
rename : media/webrtc/trunk/third_party/libyuv/all.gyp => media/libyuv/all.gyp
rename : media/webrtc/trunk/third_party/libyuv/codereview.settings => media/libyuv/codereview.settings
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv.h => media/libyuv/include/libyuv.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/basic_types.h => media/libyuv/include/libyuv/basic_types.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/compare.h => media/libyuv/include/libyuv/compare.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/convert.h => media/libyuv/include/libyuv/convert.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/convert_argb.h => media/libyuv/include/libyuv/convert_argb.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/convert_from.h => media/libyuv/include/libyuv/convert_from.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/convert_from_argb.h => media/libyuv/include/libyuv/convert_from_argb.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/cpu_id.h => media/libyuv/include/libyuv/cpu_id.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/format_conversion.h => media/libyuv/include/libyuv/format_conversion.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/mjpeg_decoder.h => media/libyuv/include/libyuv/mjpeg_decoder.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/planar_functions.h => media/libyuv/include/libyuv/planar_functions.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/rotate.h => media/libyuv/include/libyuv/rotate.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/rotate_argb.h => media/libyuv/include/libyuv/rotate_argb.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/row.h => media/libyuv/include/libyuv/row.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/scale.h => media/libyuv/include/libyuv/scale.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/scale_argb.h => media/libyuv/include/libyuv/scale_argb.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/scale_row.h => media/libyuv/include/libyuv/scale_row.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/version.h => media/libyuv/include/libyuv/version.h
rename : media/webrtc/trunk/third_party/libyuv/include/libyuv/video_common.h => media/libyuv/include/libyuv/video_common.h
rename : media/webrtc/trunk/third_party/libyuv/libyuv.gyp => media/libyuv/libyuv.gyp
rename : media/webrtc/trunk/third_party/libyuv/libyuv.gypi => media/libyuv/libyuv.gypi
rename : media/webrtc/trunk/third_party/libyuv/libyuv_nacl.gyp => media/libyuv/libyuv_nacl.gyp
rename : media/webrtc/trunk/third_party/libyuv/libyuv_test.gyp => media/libyuv/libyuv_test.gyp
rename : media/webrtc/trunk/third_party/libyuv/linux.mk => media/libyuv/linux.mk
rename : media/webrtc/trunk/third_party/libyuv/public.mk => media/libyuv/public.mk
rename : media/webrtc/trunk/third_party/libyuv/source/compare.cc => media/libyuv/source/compare.cc
rename : media/webrtc/trunk/third_party/libyuv/source/compare_common.cc => media/libyuv/source/compare_common.cc
rename : media/webrtc/trunk/third_party/libyuv/source/compare_neon.cc => media/libyuv/source/compare_neon.cc
rename : media/webrtc/trunk/third_party/libyuv/source/compare_posix.cc => media/libyuv/source/compare_posix.cc
rename : media/webrtc/trunk/third_party/libyuv/source/compare_win.cc => media/libyuv/source/compare_win.cc
rename : media/webrtc/trunk/third_party/libyuv/source/convert.cc => media/libyuv/source/convert.cc
rename : media/webrtc/trunk/third_party/libyuv/source/convert_argb.cc => media/libyuv/source/convert_argb.cc
rename : media/webrtc/trunk/third_party/libyuv/source/convert_from.cc => media/libyuv/source/convert_from.cc
rename : media/webrtc/trunk/third_party/libyuv/source/convert_from_argb.cc => media/libyuv/source/convert_from_argb.cc
rename : media/webrtc/trunk/third_party/libyuv/source/convert_jpeg.cc => media/libyuv/source/convert_jpeg.cc
rename : media/webrtc/trunk/third_party/libyuv/source/convert_to_argb.cc => media/libyuv/source/convert_to_argb.cc
rename : media/webrtc/trunk/third_party/libyuv/source/convert_to_i420.cc => media/libyuv/source/convert_to_i420.cc
rename : media/webrtc/trunk/third_party/libyuv/source/cpu_id.cc => media/libyuv/source/cpu_id.cc
rename : media/webrtc/trunk/third_party/libyuv/source/format_conversion.cc => media/libyuv/source/format_conversion.cc
rename : media/webrtc/trunk/third_party/libyuv/source/mjpeg_decoder.cc => media/libyuv/source/mjpeg_decoder.cc
rename : media/webrtc/trunk/third_party/libyuv/source/mjpeg_validate.cc => media/libyuv/source/mjpeg_validate.cc
rename : media/webrtc/trunk/third_party/libyuv/source/planar_functions.cc => media/libyuv/source/planar_functions.cc
rename : media/webrtc/trunk/third_party/libyuv/source/rotate.cc => media/libyuv/source/rotate.cc
rename : media/webrtc/trunk/third_party/libyuv/source/rotate_argb.cc => media/libyuv/source/rotate_argb.cc
rename : media/webrtc/trunk/third_party/libyuv/source/rotate_mips.cc => media/libyuv/source/rotate_mips.cc
rename : media/webrtc/trunk/third_party/libyuv/source/rotate_neon.cc => media/libyuv/source/rotate_neon.cc
rename : media/webrtc/trunk/third_party/libyuv/source/row_any.cc => media/libyuv/source/row_any.cc
rename : media/webrtc/trunk/third_party/libyuv/source/row_common.cc => media/libyuv/source/row_common.cc
rename : media/webrtc/trunk/third_party/libyuv/source/row_mips.cc => media/libyuv/source/row_mips.cc
rename : media/webrtc/trunk/third_party/libyuv/source/row_neon.cc => media/libyuv/source/row_neon.cc
rename : media/webrtc/trunk/third_party/libyuv/source/row_posix.cc => media/libyuv/source/row_posix.cc
rename : media/webrtc/trunk/third_party/libyuv/source/row_win.cc => media/libyuv/source/row_win.cc
rename : media/webrtc/trunk/third_party/libyuv/source/row_x86.asm => media/libyuv/source/row_x86.asm
rename : media/webrtc/trunk/third_party/libyuv/source/scale.cc => media/libyuv/source/scale.cc
rename : media/webrtc/trunk/third_party/libyuv/source/scale_argb.cc => media/libyuv/source/scale_argb.cc
rename : media/webrtc/trunk/third_party/libyuv/source/scale_common.cc => media/libyuv/source/scale_common.cc
rename : media/webrtc/trunk/third_party/libyuv/source/scale_mips.cc => media/libyuv/source/scale_mips.cc
rename : media/webrtc/trunk/third_party/libyuv/source/scale_neon.cc => media/libyuv/source/scale_neon.cc
rename : media/webrtc/trunk/third_party/libyuv/source/scale_posix.cc => media/libyuv/source/scale_posix.cc
rename : media/webrtc/trunk/third_party/libyuv/source/scale_win.cc => media/libyuv/source/scale_win.cc
rename : media/webrtc/trunk/third_party/libyuv/source/video_common.cc => media/libyuv/source/video_common.cc
rename : media/webrtc/trunk/third_party/libyuv/source/x86inc.asm => media/libyuv/source/x86inc.asm
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/libyuv_tests.bat => media/libyuv/tools/valgrind-libyuv/libyuv_tests.bat
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/libyuv_tests.py => media/libyuv/tools/valgrind-libyuv/libyuv_tests.py
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/libyuv_tests.sh => media/libyuv/tools/valgrind-libyuv/libyuv_tests.sh
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/memcheck/OWNERS => media/libyuv/tools/valgrind-libyuv/memcheck/OWNERS
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/memcheck/PRESUBMIT.py => media/libyuv/tools/valgrind-libyuv/memcheck/PRESUBMIT.py
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/memcheck/suppressions.txt => media/libyuv/tools/valgrind-libyuv/memcheck/suppressions.txt
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/memcheck/suppressions_mac.txt => media/libyuv/tools/valgrind-libyuv/memcheck/suppressions_mac.txt
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/memcheck/suppressions_win32.txt => media/libyuv/tools/valgrind-libyuv/memcheck/suppressions_win32.txt
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/tsan/OWNERS => media/libyuv/tools/valgrind-libyuv/tsan/OWNERS
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/tsan/PRESUBMIT.py => media/libyuv/tools/valgrind-libyuv/tsan/PRESUBMIT.py
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/tsan/suppressions.txt => media/libyuv/tools/valgrind-libyuv/tsan/suppressions.txt
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/tsan/suppressions_mac.txt => media/libyuv/tools/valgrind-libyuv/tsan/suppressions_mac.txt
rename : media/webrtc/trunk/third_party/libyuv/tools/valgrind-libyuv/tsan/suppressions_win32.txt => media/libyuv/tools/valgrind-libyuv/tsan/suppressions_win32.txt
rename : media/webrtc/trunk/third_party/libyuv/unit_test/basictypes_test.cc => media/libyuv/unit_test/basictypes_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/compare_test.cc => media/libyuv/unit_test/compare_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/convert_test.cc => media/libyuv/unit_test/convert_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/cpu_test.cc => media/libyuv/unit_test/cpu_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/math_test.cc => media/libyuv/unit_test/math_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/planar_test.cc => media/libyuv/unit_test/planar_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/rotate_argb_test.cc => media/libyuv/unit_test/rotate_argb_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/rotate_test.cc => media/libyuv/unit_test/rotate_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/scale_argb_test.cc => media/libyuv/unit_test/scale_argb_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/scale_test.cc => media/libyuv/unit_test/scale_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/testdata/arm_v7.txt => media/libyuv/unit_test/testdata/arm_v7.txt
rename : media/webrtc/trunk/third_party/libyuv/unit_test/testdata/tegra3.txt => media/libyuv/unit_test/testdata/tegra3.txt
rename : media/webrtc/trunk/third_party/libyuv/unit_test/unit_test.cc => media/libyuv/unit_test/unit_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/unit_test.h => media/libyuv/unit_test/unit_test.h
rename : media/webrtc/trunk/third_party/libyuv/unit_test/version_test.cc => media/libyuv/unit_test/version_test.cc
rename : media/webrtc/trunk/third_party/libyuv/unit_test/video_common_test.cc => media/libyuv/unit_test/video_common_test.cc
rename : media/webrtc/trunk/third_party/libyuv/util/Makefile => media/libyuv/util/Makefile
rename : media/webrtc/trunk/third_party/libyuv/util/compare.cc => media/libyuv/util/compare.cc
rename : media/webrtc/trunk/third_party/libyuv/util/convert.cc => media/libyuv/util/convert.cc
rename : media/webrtc/trunk/third_party/libyuv/util/cpuid.c => media/libyuv/util/cpuid.c
rename : media/webrtc/trunk/third_party/libyuv/util/psnr.cc => media/libyuv/util/psnr.cc
rename : media/webrtc/trunk/third_party/libyuv/util/psnr.h => media/libyuv/util/psnr.h
rename : media/webrtc/trunk/third_party/libyuv/util/psnr_main.cc => media/libyuv/util/psnr_main.cc
rename : media/webrtc/trunk/third_party/libyuv/util/ssim.cc => media/libyuv/util/ssim.cc
rename : media/webrtc/trunk/third_party/libyuv/util/ssim.h => media/libyuv/util/ssim.h
rename : media/webrtc/trunk/third_party/libyuv/winarm.mk => media/libyuv/winarm.mk
2014-01-30 19:55:04 -05:00

406 lines
16 KiB
C++

/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* 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
* be found in the AUTHORS file in the root of the source tree.
*/
#include "libyuv/row.h"
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__)
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) {
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"
// handle 8x8 blocks. this should be the majority of the plane
".p2align 2 \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"
"vtrn.8 d1, d0 \n"
"vtrn.8 d3, d2 \n"
"vtrn.8 d5, d4 \n"
"vtrn.8 d7, d6 \n"
"vtrn.16 d1, d3 \n"
"vtrn.16 d0, d2 \n"
"vtrn.16 d5, d7 \n"
"vtrn.16 d4, d6 \n"
"vtrn.32 d1, d5 \n"
"vtrn.32 d0, d4 \n"
"vtrn.32 d3, d7 \n"
"vtrn.32 d2, d6 \n"
"vrev16.8 q0, q0 \n"
"vrev16.8 q1, q1 \n"
"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
"bge 1b \n"
// add 8 back to counter. if the result is 0 there are
// no residuals.
"adds %4, #8 \n"
"beq 4f \n"
// some residual, so between 1 and 7 lines left to transpose
"cmp %4, #2 \n"
"blt 3f \n"
"cmp %4, #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"
"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(frkoenig): 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
"beq 4f \n"
// some residual, check to see if it includes a 2x8 block,
// or less
"cmp %4, #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"
"vtrn.8 d0, d1 \n"
"mov r9, %2 \n"
"vst1.64 {d0}, [r9], %3 \n"
"vst1.64 {d1}, [r9] \n"
"add %0, #2 \n" // src += 2
"add %2, %2, %3, lsl #1 \n" // dst += 2 * dst_stride
"subs %4, #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"
"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"
);
}
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) {
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"
// handle 8x8 blocks. this should be the majority of the plane
".p2align 2 \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"
"vtrn.8 q1, q0 \n"
"vtrn.8 q3, q2 \n"
"vtrn.8 q9, q8 \n"
"vtrn.8 q11, q10 \n"
"vtrn.16 q1, q3 \n"
"vtrn.16 q0, q2 \n"
"vtrn.16 q9, q11 \n"
"vtrn.16 q8, q10 \n"
"vtrn.32 q1, q9 \n"
"vtrn.32 q0, q8 \n"
"vtrn.32 q3, q11 \n"
"vtrn.32 q2, q10 \n"
"vrev16.8 q0, q0 \n"
"vrev16.8 q1, q1 \n"
"vrev16.8 q2, q2 \n"
"vrev16.8 q3, q3 \n"
"vrev16.8 q8, q8 \n"
"vrev16.8 q9, q9 \n"
"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
"bge 1b \n"
// add 8 back to counter. if the result is 0 there are
// no residuals.
"adds %6, #8 \n"
"beq 4f \n"
// some residual, so between 1 and 7 lines left to transpose
"cmp %6, #2 \n"
"blt 3f \n"
"cmp %6, #4 \n"
"blt 2f \n"
//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"
"vtrn.8 q0, q1 \n"
"vtrn.8 q2, q3 \n"
"vtbl.8 d16, {d0, d1}, d30 \n"
"vtbl.8 d17, {d0, d1}, d31 \n"
"vtbl.8 d18, {d2, d3}, d30 \n"
"vtbl.8 d19, {d2, d3}, d31 \n"
"vtbl.8 d20, {d4, d5}, d30 \n"
"vtbl.8 d21, {d4, d5}, d31 \n"
"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
"beq 4f \n"
// some residual, check to see if it includes a 2x8 block,
// or less
"cmp %6, #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"
"vtrn.8 d0, d1 \n"
"vtrn.8 d2, d3 \n"
"mov r9, %2 \n"
"vst1.64 {d0}, [r9], %3 \n"
"vst1.64 {d2}, [r9] \n"
"mov r9, %4 \n"
"vst1.64 {d1}, [r9], %5 \n"
"vst1.64 {d3}, [r9] \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
"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"
"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",
"q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"
);
}
#endif
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif