[x265] [PATCH] arm: Implement sad_x3 and sad_x4 ARM NEON asm
dnyaneshwar at multicorewareinc.com
dnyaneshwar at multicorewareinc.com
Tue Feb 16 06:04:17 CET 2016
# HG changeset patch
# User Dnyaneshwar G <dnyaneshwar at multicorewareinc.com>
# Date 1455598958 -19800
# Tue Feb 16 10:32:38 2016 +0530
# Node ID ac6c535109a43e9cdb69f30db1143c06400a19f4
# Parent e3902c96c3c268ec4ab1a4976ee2feae7348b36f
arm: Implement sad_x3 and sad_x4 ARM NEON asm
diff -r e3902c96c3c2 -r ac6c535109a4 source/common/arm/asm-primitives.cpp
--- a/source/common/arm/asm-primitives.cpp Thu Feb 11 15:00:20 2016 +0530
+++ b/source/common/arm/asm-primitives.cpp Tue Feb 16 10:32:38 2016 +0530
@@ -41,6 +41,7 @@
{
if (cpuMask & X265_CPU_NEON)
{
+ // blockcopy
p.pu[LUMA_16x16].copy_pp = PFX(blockcopy_pp_16x16_neon);
p.pu[LUMA_8x4].copy_pp = PFX(blockcopy_pp_8x4_neon);
p.pu[LUMA_8x8].copy_pp = PFX(blockcopy_pp_8x8_neon);
@@ -66,11 +67,65 @@
p.pu[LUMA_64x32].copy_pp = PFX(blockcopy_pp_64x32_neon);
p.pu[LUMA_64x48].copy_pp = PFX(blockcopy_pp_64x48_neon);
p.pu[LUMA_64x64].copy_pp = PFX(blockcopy_pp_64x64_neon);
+
+ // sad_x3
+ p.pu[LUMA_4x4].sad_x3 = PFX(sad_x3_4x4_neon);
+ p.pu[LUMA_4x8].sad_x3 = PFX(sad_x3_4x8_neon);
+ p.pu[LUMA_4x16].sad_x3 = PFX(sad_x3_4x16_neon);
+ p.pu[LUMA_8x4].sad_x3 = PFX(sad_x3_8x4_neon);
+ p.pu[LUMA_8x8].sad_x3 = PFX(sad_x3_8x8_neon);
+ p.pu[LUMA_8x16].sad_x3 = PFX(sad_x3_8x16_neon);
+ p.pu[LUMA_8x32].sad_x3 = PFX(sad_x3_8x32_neon);
+ p.pu[LUMA_12x16].sad_x3 = PFX(sad_x3_12x16_neon);
+ p.pu[LUMA_16x4].sad_x3 = PFX(sad_x3_16x4_neon);
+ p.pu[LUMA_16x8].sad_x3 = PFX(sad_x3_16x8_neon);
+ p.pu[LUMA_16x12].sad_x3 = PFX(sad_x3_16x12_neon);
+ p.pu[LUMA_16x16].sad_x3 = PFX(sad_x3_16x16_neon);
+ p.pu[LUMA_16x32].sad_x3 = PFX(sad_x3_16x32_neon);
+ p.pu[LUMA_16x64].sad_x3 = PFX(sad_x3_16x64_neon);
+ p.pu[LUMA_24x32].sad_x3 = PFX(sad_x3_24x32_neon);
+ p.pu[LUMA_32x8].sad_x3 = PFX(sad_x3_32x8_neon);
+ p.pu[LUMA_32x16].sad_x3 = PFX(sad_x3_32x16_neon);
+ p.pu[LUMA_32x24].sad_x3 = PFX(sad_x3_32x24_neon);
+ p.pu[LUMA_32x32].sad_x3 = PFX(sad_x3_32x32_neon);
+ p.pu[LUMA_32x64].sad_x3 = PFX(sad_x3_32x64_neon);
+ p.pu[LUMA_48x64].sad_x3 = PFX(sad_x3_48x64_neon);
+ p.pu[LUMA_64x16].sad_x3 = PFX(sad_x3_64x16_neon);
+ p.pu[LUMA_64x32].sad_x3 = PFX(sad_x3_64x32_neon);
+ p.pu[LUMA_64x48].sad_x3 = PFX(sad_x3_64x48_neon);
+ p.pu[LUMA_64x64].sad_x3 = PFX(sad_x3_64x64_neon);
+
+ // sad_x4
+ p.pu[LUMA_4x4].sad_x4 = PFX(sad_x4_4x4_neon);
+ p.pu[LUMA_4x8].sad_x4 = PFX(sad_x4_4x8_neon);
+ p.pu[LUMA_4x16].sad_x4 = PFX(sad_x4_4x16_neon);
+ p.pu[LUMA_8x4].sad_x4 = PFX(sad_x4_8x4_neon);
+ p.pu[LUMA_8x8].sad_x4 = PFX(sad_x4_8x8_neon);
+ p.pu[LUMA_8x16].sad_x4 = PFX(sad_x4_8x16_neon);
+ p.pu[LUMA_8x32].sad_x4 = PFX(sad_x4_8x32_neon);
+ p.pu[LUMA_12x16].sad_x4 = PFX(sad_x4_12x16_neon);
+ p.pu[LUMA_16x4].sad_x4 = PFX(sad_x4_16x4_neon);
+ p.pu[LUMA_16x8].sad_x4 = PFX(sad_x4_16x8_neon);
+ p.pu[LUMA_16x12].sad_x4 = PFX(sad_x4_16x12_neon);
+ p.pu[LUMA_16x16].sad_x4 = PFX(sad_x4_16x16_neon);
+ p.pu[LUMA_16x32].sad_x4 = PFX(sad_x4_16x32_neon);
+ p.pu[LUMA_16x64].sad_x4 = PFX(sad_x4_16x64_neon);
+ p.pu[LUMA_24x32].sad_x4 = PFX(sad_x4_24x32_neon);
+ p.pu[LUMA_32x8].sad_x4 = PFX(sad_x4_32x8_neon);
+ p.pu[LUMA_32x16].sad_x4 = PFX(sad_x4_32x16_neon);
+ p.pu[LUMA_32x24].sad_x4 = PFX(sad_x4_32x24_neon);
+ p.pu[LUMA_32x32].sad_x4 = PFX(sad_x4_32x32_neon);
+ p.pu[LUMA_32x64].sad_x4 = PFX(sad_x4_32x64_neon);
+ p.pu[LUMA_48x64].sad_x4 = PFX(sad_x4_48x64_neon);
+ p.pu[LUMA_64x16].sad_x4 = PFX(sad_x4_64x16_neon);
+ p.pu[LUMA_64x32].sad_x4 = PFX(sad_x4_64x32_neon);
+ p.pu[LUMA_64x48].sad_x4 = PFX(sad_x4_64x48_neon);
+ p.pu[LUMA_64x64].sad_x4 = PFX(sad_x4_64x64_neon);
}
if (cpuMask & X265_CPU_ARMV6)
{
- p.pu[LUMA_4x4].sad=PFX(pixel_sad_4x4_armv6);
- p.pu[LUMA_4x8].sad=PFX(pixel_sad_4x8_armv6);
+ p.pu[LUMA_4x4].sad = PFX(pixel_sad_4x4_armv6);
+ p.pu[LUMA_4x8].sad = PFX(pixel_sad_4x8_armv6);
}
}
} // namespace X265_NS
diff -r e3902c96c3c2 -r ac6c535109a4 source/common/arm/asm.S
--- a/source/common/arm/asm.S Thu Feb 11 15:00:20 2016 +0530
+++ b/source/common/arm/asm.S Tue Feb 16 10:32:38 2016 +0530
@@ -108,7 +108,7 @@
#define JOIN(a, b) GLUE(a, b)
#define X(s) JOIN(EXTERN_ASM, s)
-#define FENC_STRIDE 16
+#define FENC_STRIDE 64
#define FDEC_STRIDE 32
.macro HORIZ_ADD dest, a, b
diff -r e3902c96c3c2 -r ac6c535109a4 source/common/arm/mc-a.S
--- a/source/common/arm/mc-a.S Thu Feb 11 15:00:20 2016 +0530
+++ b/source/common/arm/mc-a.S Tue Feb 16 10:32:38 2016 +0530
@@ -34,7 +34,7 @@
* r0 - dst
* r1 - dstStride
* r2 - src
- * d3 - srcStride */
+ * r3 - srcStride */
function x265_blockcopy_pp_16x16_neon
vld1.8 {q0}, [r2]
vst1.8 {q0}, [r0]
diff -r e3902c96c3c2 -r ac6c535109a4 source/common/arm/pixel.h
--- a/source/common/arm/pixel.h Thu Feb 11 15:00:20 2016 +0530
+++ b/source/common/arm/pixel.h Tue Feb 16 10:32:38 2016 +0530
@@ -7,7 +7,7 @@
* Authors: Laurent Aimar <fenrir at via.ecp.fr>
* Loren Merritt <lorenm at u.washington.edu>
* Fiona Glaser <fiona at x264.com>
-;* Min Chen <chenm003 at 163.com>
+ * Min Chen <chenm003 at 163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +29,60 @@
#ifndef X265_I386_PIXEL_ARM_H
#define X265_I386_PIXEL_ARM_H
+
int x265_pixel_sad_4x4_armv6(const pixel* dst, intptr_t dstStride, const pixel* src, intptr_t srcStride);
int x265_pixel_sad_4x8_armv6(const pixel* dst, intptr_t dstStride, const pixel* src, intptr_t srcStride);
+
+void x265_sad_x3_4x4_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_4x8_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_4x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_8x4_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_8x8_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_8x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_8x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_12x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_16x4_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_16x8_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_16x12_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_16x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_16x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_16x64_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_24x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_32x8_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_32x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_32x24_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_32x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_32x64_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_48x64_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_64x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_64x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_64x48_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+void x265_sad_x3_64x64_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, intptr_t frefstride, int32_t* res);
+
+void x265_sad_x4_4x4_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_4x8_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_4x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_8x4_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_8x8_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_8x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_8x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_12x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_16x4_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_16x8_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_16x12_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_16x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_16x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_16x64_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_24x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_32x8_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_32x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_32x24_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_32x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_32x64_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_48x64_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_64x16_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_64x32_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_64x48_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+void x265_sad_x4_64x64_neon(const pixel* fenc, const pixel* fref0, const pixel* fref1, const pixel* fref2, const pixel* fref3, intptr_t frefstride, int32_t* res);
+
#endif // ifndef X265_I386_PIXEL_ARM_H
diff -r e3902c96c3c2 -r ac6c535109a4 source/common/arm/sad-a.S
--- a/source/common/arm/sad-a.S Thu Feb 11 15:00:20 2016 +0530
+++ b/source/common/arm/sad-a.S Tue Feb 16 10:32:38 2016 +0530
@@ -1,8 +1,9 @@
/*****************************************************************************
* Copyright (C) 2016 x265 project
*
- * Authors:David Conrad <lessen42 at gmail.com>
+ * Authors: David Conrad <lessen42 at gmail.com>
* Janne Grunau <janne-x264 at jannau.net>
+ * Dnyaneshwar G <dnyaneshwar at multicorewareinc.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,6 +28,8 @@
.section .rodata
.align 4
+sad12_mask:
+.byte 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0
.text
@@ -35,7 +38,7 @@
* r0 - dst
* r1 - dstStride
* r2 - src
- * d3 - srcStride */
+ * r3 - srcStride */
.macro SAD4_ARMV6 h
function x265_pixel_sad_4x\h\()_armv6
@@ -61,3 +64,968 @@
SAD4_ARMV6 4
SAD4_ARMV6 8
+// SAD_X3 and SAD_X4 code start
+
+.macro SAD_X_START_4 x
+ vld1.32 {d0[]}, [r0], r12
+ vld1.32 {d1[]}, [r1], r4
+ vld1.32 {d2[]}, [r2], r4
+ vld1.32 {d3[]}, [r3], r4
+.if \x == 4
+ vld1.32 {d4[]}, [lr], r4
+.endif
+ vabdl.u8 q8, d0, d1
+ vabdl.u8 q9, d0, d2
+ vabdl.u8 q10, d0, d3
+.if \x == 4
+ vabdl.u8 q11, d0, d4
+.endif
+.endm
+
+.macro SAD_X_4 x
+ vld1.32 {d0[]}, [r0], r12
+ vld1.32 {d1[]}, [r1], r4
+ vld1.32 {d2[]}, [r2], r4
+ vld1.32 {d3[]}, [r3], r4
+.if \x == 4
+ vld1.32 {d4[]}, [lr], r4
+.endif
+ vabal.u8 q8, d0, d1
+ vabal.u8 q9, d0, d2
+ vabal.u8 q10, d0, d3
+.if \x == 4
+ vabal.u8 q11, d0, d4
+.endif
+.endm
+
+.macro SAD_X_4xN x, h
+function x265_sad_x\x\()_4x\h\()_neon
+ push {r4, r5, lr}
+.if \x == 3
+ ldrd r4, r5, [sp, #12]
+.else
+ ldr lr, [sp, #12]
+ ldrd r4, r5, [sp, #16]
+.endif
+ mov r12, #FENC_STRIDE
+
+ SAD_X_START_4 \x
+.rept \h - 1
+ SAD_X_4 \x
+.endr
+ vpadd.u16 d0, d16, d18
+ vpadd.u16 d1, d20, d22
+ vpaddl.u16 q0, q0
+.if \x == 3
+ vst1.32 {d0}, [r5]!
+ vst1.32 {d1[0]}, [r5, :32]
+.else
+ vst1.32 {d0-d1}, [r5]
+.endif
+ pop {r4, r5, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_4xN 3 4
+SAD_X_4xN 3 8
+SAD_X_4xN 3 16
+
+SAD_X_4xN 4 4
+SAD_X_4xN 4 8
+SAD_X_4xN 4 16
+
+.macro SAD_X_START_8 x
+ vld1.8 {d0}, [r0], r12
+ vld1.8 {d1}, [r1], r4
+ vld1.8 {d2}, [r2], r4
+ vld1.8 {d3}, [r3], r4
+.if \x == 4
+ vld1.8 {d4}, [lr], r4
+.endif
+ vabdl.u8 q8, d0, d1
+ vabdl.u8 q9, d0, d2
+ vabdl.u8 q10, d0, d3
+.if \x == 4
+ vabdl.u8 q11, d0, d4
+.endif
+.endm
+
+.macro SAD_X_8 x
+ vld1.8 {d0}, [r0], r12
+ vld1.8 {d1}, [r1], r4
+ vld1.8 {d2}, [r2], r4
+ vld1.8 {d3}, [r3], r4
+.if \x == 4
+ vld1.8 {d4}, [lr], r4
+.endif
+ vabal.u8 q8, d0, d1
+ vabal.u8 q9, d0, d2
+ vabal.u8 q10, d0, d3
+.if \x == 4
+ vabal.u8 q11, d0, d4
+.endif
+.endm
+
+.macro SAD_X_8xN x, h
+function x265_sad_x\x\()_8x\h\()_neon
+ push {r4, r5, lr}
+.if \x == 3
+ ldrd r4, r5, [sp, #12]
+.else
+ ldr lr, [sp, #12]
+ ldrd r4, r5, [sp, #16]
+.endif
+ mov r12, #FENC_STRIDE
+ SAD_X_START_8 \x
+.rept \h - 1
+ SAD_X_8 \x
+.endr
+ vadd.u16 d16, d16, d17
+ vadd.u16 d18, d18, d19
+ vadd.u16 d20, d20, d21
+ vadd.u16 d22, d22, d23
+
+ vpadd.u16 d0, d16, d18
+ vpadd.u16 d1, d20, d22
+ vpaddl.u16 q0, q0
+.if \x == 3
+ vst1.32 {d0}, [r5]!
+ vst1.32 {d1[0]}, [r5, :32]
+.else
+ vst1.32 {d0-d1}, [r5]
+.endif
+ pop {r4, r5, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_8xN 3 4
+SAD_X_8xN 3 8
+SAD_X_8xN 3 16
+SAD_X_8xN 3 32
+
+SAD_X_8xN 4 4
+SAD_X_8xN 4 8
+SAD_X_8xN 4 16
+SAD_X_8xN 4 32
+
+.macro SAD_X_START_16 x
+ vld1.8 {q0}, [r0], r12
+ vld1.8 {q1}, [r1], r4
+ vld1.8 {q2}, [r2], r4
+ vld1.8 {q3}, [r3], r4
+ vabdl.u8 q8, d0, d2
+ vabdl.u8 q9, d1, d3
+ vabdl.u8 q10, d0, d4
+ vabdl.u8 q11, d1, d5
+ vabdl.u8 q12, d0, d6
+ vabdl.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr], r4
+ vabdl.u8 q14, d0, d6
+ vabdl.u8 q15, d1, d7
+.endif
+.endm
+
+.macro SAD_X_16 x
+ vld1.8 {q0}, [r0], r12
+ vld1.8 {q1}, [r1], r4
+ vld1.8 {q2}, [r2], r4
+ vld1.8 {q3}, [r3], r4
+ vabal.u8 q8, d0, d2
+ vabal.u8 q9, d1, d3
+ vabal.u8 q10, d0, d4
+ vabal.u8 q11, d1, d5
+ vabal.u8 q12, d0, d6
+ vabal.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr], r4
+ vabal.u8 q14, d0, d6
+ vabal.u8 q15, d1, d7
+.endif
+.endm
+
+.macro SAD_X_16xN x, h
+function x265_sad_x\x\()_16x\h\()_neon
+ push {r4, r5, lr}
+.if \x == 3
+ ldrd r4, r5, [sp, #12]
+.else
+ ldr lr, [sp, #12]
+ ldrd r4, r5, [sp, #16]
+.endif
+ mov r12, #FENC_STRIDE
+ SAD_X_START_16 \x
+.rept \h - 1
+ SAD_X_16 \x
+.endr
+ vadd.u16 q8, q8, q9
+ vadd.u16 q10, q10, q11
+ vadd.u16 q12, q12, q13
+.if \x == 4
+ vadd.u16 q14, q14, q15
+.endif
+ vadd.u16 d16, d16, d17
+ vadd.u16 d20, d20, d21
+ vadd.u16 d24, d24, d25
+.if \x == 4
+ vadd.u16 d28, d28, d29
+.endif
+
+.if \h <= 32
+ vpadd.u16 d0, d16, d20
+ vpadd.u16 d1, d24, d28
+ vpaddl.u16 q0, q0
+ .if \x == 3
+ vst1.32 {d0}, [r5]!
+ vst1.32 {d1[0]}, [r5, :32]
+ .else
+ vst1.32 {d0-d1}, [r5]
+ .endif
+.else
+ vpaddl.u16 d16, d16
+ vpaddl.u16 d20, d20
+ vpaddl.u16 d24, d24
+ .if \x == 4
+ vpaddl.u16 d28, d28
+ .endif
+ vpaddl.u32 d16, d16
+ vpaddl.u32 d20, d20
+ vpaddl.u32 d24, d24
+ .if \x == 4
+ vpaddl.u32 d28, d28
+ .endif
+ vst1.32 {d16[0]}, [r5]!
+ vst1.32 {d20[0]}, [r5]!
+ .if \x == 3
+ vst1.32 {d24[0]}, [r5]
+ .endif
+ .if \x == 4
+ vst1.32 {d24[0]}, [r5]!
+ vst1.32 {d28[0]}, [r5]
+ .endif
+.endif
+ pop {r4, r5, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_16xN 3 4
+SAD_X_16xN 3 12
+
+SAD_X_16xN 4 4
+SAD_X_16xN 4 12
+
+.macro SAD_X_16xN_LOOP x, h
+function x265_sad_x\x\()_16x\h\()_neon
+ push {r4-r6, lr}
+.if \x == 3
+ ldrd r4, r5, [sp, #16]
+.else
+ ldr lr, [sp, #16]
+ ldrd r4, r5, [sp, #20]
+.endif
+ mov r12, #FENC_STRIDE
+ mov r6, #\h/8
+ veor.u8 q8, q8
+ veor.u8 q9, q9
+ veor.u8 q10, q10
+ veor.u8 q11, q11
+ veor.u8 q12, q12
+ veor.u8 q13, q13
+.if \x == 4
+ veor.u8 q14, q14
+ veor.u8 q15, q15
+.endif
+
+.loop_sad_x\x\()_16x\h:
+.rept 8
+ SAD_X_16 \x
+.endr
+ subs r6, #1
+ bne .loop_sad_x\x\()_16x\h
+
+ vadd.u16 q8, q8, q9
+ vadd.u16 q10, q10, q11
+ vadd.u16 q12, q12, q13
+.if \x == 4
+ vadd.u16 q14, q14, q15
+.endif
+ vadd.u16 d16, d16, d17
+ vadd.u16 d20, d20, d21
+ vadd.u16 d24, d24, d25
+.if \x == 4
+ vadd.u16 d28, d28, d29
+.endif
+
+.if \h <= 32
+ vpadd.u16 d0, d16, d20
+ vpadd.u16 d1, d24, d28
+ vpaddl.u16 q0, q0
+ .if \x == 3
+ vst1.32 {d0}, [r5]!
+ vst1.32 {d1[0]}, [r5, :32]
+ .else
+ vst1.32 {d0-d1}, [r5]
+ .endif
+.else
+ vpaddl.u16 d16, d16
+ vpaddl.u16 d20, d20
+ vpaddl.u16 d24, d24
+ .if \x == 4
+ vpaddl.u16 d28, d28
+ .endif
+ vpaddl.u32 d16, d16
+ vpaddl.u32 d20, d20
+ vpaddl.u32 d24, d24
+ .if \x == 4
+ vpaddl.u32 d28, d28
+ .endif
+ vst1.32 {d16[0]}, [r5]!
+ vst1.32 {d20[0]}, [r5]!
+ .if \x == 3
+ vst1.32 {d24[0]}, [r5]
+ .endif
+ .if \x == 4
+ vst1.32 {d24[0]}, [r5]!
+ vst1.32 {d28[0]}, [r5]
+ .endif
+.endif
+ pop {r4-r6, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_16xN_LOOP 3 8
+SAD_X_16xN_LOOP 3 16
+SAD_X_16xN_LOOP 3 32
+SAD_X_16xN_LOOP 3 64
+
+SAD_X_16xN_LOOP 4 8
+SAD_X_16xN_LOOP 4 16
+SAD_X_16xN_LOOP 4 32
+SAD_X_16xN_LOOP 4 64
+
+.macro SAD_X_32 x
+ vld1.8 {q0}, [r0]!
+ vld1.8 {q1}, [r1]!
+ vld1.8 {q2}, [r2]!
+ vld1.8 {q3}, [r3]!
+ vabal.u8 q8, d0, d2
+ vabal.u8 q9, d1, d3
+ vabal.u8 q10, d0, d4
+ vabal.u8 q11, d1, d5
+ vabal.u8 q12, d0, d6
+ vabal.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr]!
+ vabal.u8 q14, d0, d6
+ vabal.u8 q15, d1, d7
+.endif
+ vld1.8 {q0}, [r0], r12
+ vld1.8 {q1}, [r1], r4
+ vld1.8 {q2}, [r2], r4
+ vld1.8 {q3}, [r3], r4
+ vabal.u8 q8, d0, d2
+ vabal.u8 q9, d1, d3
+ vabal.u8 q10, d0, d4
+ vabal.u8 q11, d1, d5
+ vabal.u8 q12, d0, d6
+ vabal.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr], r4
+ vabal.u8 q14, d0, d6
+ vabal.u8 q15, d1, d7
+.endif
+.endm
+
+.macro SAD_X_32xN x, h
+function x265_sad_x\x\()_32x\h\()_neon
+ push {r4-r6, lr}
+.if \x == 3
+ ldrd r4, r5, [sp, #16]
+.else
+ ldr lr, [sp, #16]
+ ldrd r4, r5, [sp, #20]
+.endif
+ mov r12, #FENC_STRIDE
+ sub r12, #16
+ sub r4, #16
+ mov r6, #\h/8
+ veor.u8 q8, q8
+ veor.u8 q9, q9
+ veor.u8 q10, q10
+ veor.u8 q11, q11
+ veor.u8 q12, q12
+ veor.u8 q13, q13
+.if \x == 4
+ veor.u8 q14, q14
+ veor.u8 q15, q15
+.endif
+
+loop_sad_x\x\()_32x\h:
+.rept 8
+ SAD_X_32 \x
+.endr
+ subs r6, #1
+ bgt loop_sad_x\x\()_32x\h
+
+.if \h <= 32
+ vadd.u16 q8, q8, q9
+ vadd.u16 q10, q10, q11
+ vadd.u16 q12, q12, q13
+ .if \x == 4
+ vadd.u16 q14, q14, q15
+ .endif
+ vadd.u16 d16, d16, d17
+ vadd.u16 d20, d20, d21
+ vadd.u16 d24, d24, d25
+ .if \x == 4
+ vadd.u16 d28, d28, d29
+ .endif
+.else
+ vpaddl.u16 q8, q8
+ vpaddl.u16 q9, q9
+ vpaddl.u16 q10, q10
+ vpaddl.u16 q11, q11
+ vpaddl.u16 q12, q12
+ vpaddl.u16 q13, q13
+ .if \x == 4
+ vpaddl.u16 q14, q14
+ vpaddl.u16 q15, q15
+ .endif
+ vadd.u32 q8, q8, q9
+ vadd.u32 q10, q10, q11
+ vadd.u32 q12, q12, q13
+ .if \x == 4
+ vadd.u32 q14, q14, q15
+ .endif
+ vadd.u32 d16, d16, d17
+ vadd.u32 d20, d20, d21
+ vadd.u32 d24, d24, d25
+ .if \x == 4
+ vadd.u32 d28, d28, d29
+ .endif
+.endif
+
+.if \h <= 16
+ vpadd.u16 d0, d16, d20
+ vpadd.u16 d1, d24, d28
+ vpaddl.u16 q0, q0
+ .if \x == 3
+ vst1.32 {d0}, [r5]!
+ vst1.32 {d1[0]}, [r5, :32]
+ .else
+ vst1.32 {d0-d1}, [r5]
+ .endif
+.elseif \h <= 32
+ vpaddl.u16 d16, d16
+ vpaddl.u16 d20, d20
+ vpaddl.u16 d24, d24
+ .if \x == 4
+ vpaddl.u16 d28, d28
+ .endif
+ vpaddl.u32 d16, d16
+ vpaddl.u32 d20, d20
+ vpaddl.u32 d24, d24
+ .if \x == 4
+ vpaddl.u32 d28, d28
+ .endif
+ vst1.32 {d16[0]}, [r5]!
+ vst1.32 {d20[0]}, [r5]!
+ .if \x == 3
+ vst1.32 {d24[0]}, [r5]
+ .endif
+ .if \x == 4
+ vst1.32 {d24[0]}, [r5]!
+ vst1.32 {d28[0]}, [r5]
+ .endif
+.elseif \h <= 64
+ vpaddl.u32 d16, d16
+ vpaddl.u32 d20, d20
+ vpaddl.u32 d24, d24
+ .if \x == 4
+ vpaddl.u32 d28, d28
+ .endif
+ vst1.32 {d16[0]}, [r5]!
+ vst1.32 {d20[0]}, [r5]!
+ .if \x == 3
+ vst1.32 {d24[0]}, [r5]
+ .endif
+ .if \x == 4
+ vst1.32 {d24[0]}, [r5]!
+ vst1.32 {d28[0]}, [r5]
+ .endif
+.endif
+ pop {r4-r6, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_32xN 3 8
+SAD_X_32xN 3 16
+SAD_X_32xN 3 24
+SAD_X_32xN 3 32
+SAD_X_32xN 3 64
+
+SAD_X_32xN 4 8
+SAD_X_32xN 4 16
+SAD_X_32xN 4 24
+SAD_X_32xN 4 32
+SAD_X_32xN 4 64
+
+.macro SAD_X_64 x
+.rept 3
+ vld1.8 {q0}, [r0]!
+ vld1.8 {q1}, [r1]!
+ vld1.8 {q2}, [r2]!
+ vld1.8 {q3}, [r3]!
+ vabal.u8 q8, d0, d2
+ vabal.u8 q9, d1, d3
+ vabal.u8 q10, d0, d4
+ vabal.u8 q11, d1, d5
+ vabal.u8 q12, d0, d6
+ vabal.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr]!
+ vabal.u8 q14, d0, d6
+ vabal.u8 q15, d1, d7
+.endif
+.endr
+ vld1.8 {q0}, [r0], r12
+ vld1.8 {q1}, [r1], r4
+ vld1.8 {q2}, [r2], r4
+ vld1.8 {q3}, [r3], r4
+ vabal.u8 q8, d0, d2
+ vabal.u8 q9, d1, d3
+ vabal.u8 q10, d0, d4
+ vabal.u8 q11, d1, d5
+ vabal.u8 q12, d0, d6
+ vabal.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr], r4
+ vabal.u8 q14, d0, d6
+ vabal.u8 q15, d1, d7
+.endif
+.endm
+
+.macro SAD_X_64xN x, h
+function x265_sad_x\x\()_64x\h\()_neon
+ push {r4-r6, lr}
+.if \x == 3
+ ldrd r4, r5, [sp, #16]
+.else
+ ldr lr, [sp, #16]
+ ldrd r4, r5, [sp, #20]
+.endif
+ mov r12, #FENC_STRIDE
+ sub r12, #48
+ sub r4, #48
+ mov r6, #\h/8
+ veor.u8 q8, q8
+ veor.u8 q9, q9
+ veor.u8 q10, q10
+ veor.u8 q11, q11
+ veor.u8 q12, q12
+ veor.u8 q13, q13
+.if \x == 4
+ veor.u8 q14, q14
+ veor.u8 q15, q15
+.endif
+.loop_sad_x\x\()_64x\h:
+.rept 8
+ SAD_X_64 \x
+.endr
+ subs r6, #1
+ bne .loop_sad_x\x\()_64x\h
+
+.if \h <= 16
+ vadd.u16 q8, q8, q9
+ vadd.u16 q10, q10, q11
+ vadd.u16 q12, q12, q13
+ .if \x == 4
+ vadd.u16 q14, q14, q15
+ .endif
+ vadd.u16 d16, d16, d17
+ vadd.u16 d20, d20, d21
+ vadd.u16 d24, d24, d25
+ .if \x == 4
+ vadd.u16 d28, d28, d29
+ .endif
+.else
+ vpaddl.u16 q8, q8
+ vpaddl.u16 q9, q9
+ vpaddl.u16 q10, q10
+ vpaddl.u16 q11, q11
+ vpaddl.u16 q12, q12
+ vpaddl.u16 q13, q13
+ .if \x == 4
+ vpaddl.u16 q14, q14
+ vpaddl.u16 q15, q15
+ .endif
+ vadd.u32 q8, q8, q9
+ vadd.u32 q10, q10, q11
+ vadd.u32 q12, q12, q13
+ .if \x == 4
+ vadd.u32 q14, q14, q15
+ .endif
+ vadd.u32 d16, d16, d17
+ vadd.u32 d20, d20, d21
+ vadd.u32 d24, d24, d25
+ .if \x == 4
+ vadd.u32 d28, d28, d29
+ .endif
+.endif
+
+.if \h <= 16
+ vpaddl.u16 d16, d16
+ vpaddl.u16 d20, d20
+ vpaddl.u16 d24, d24
+ .if \x == 4
+ vpaddl.u16 d28, d28
+ .endif
+.endif
+ vpaddl.u32 d16, d16
+ vpaddl.u32 d20, d20
+ vpaddl.u32 d24, d24
+.if \x == 4
+ vpaddl.u32 d28, d28
+.endif
+ vst1.32 {d16[0]}, [r5]!
+ vst1.32 {d20[0]}, [r5]!
+.if \x == 3
+ vst1.32 {d24[0]}, [r5]
+.endif
+.if \x == 4
+ vst1.32 {d24[0]}, [r5]!
+ vst1.32 {d28[0]}, [r5]
+.endif
+ pop {r4-r6, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_64xN 3 16
+SAD_X_64xN 3 32
+SAD_X_64xN 3 48
+SAD_X_64xN 3 64
+
+SAD_X_64xN 4 16
+SAD_X_64xN 4 32
+SAD_X_64xN 4 48
+SAD_X_64xN 4 64
+
+.macro SAD_X_48 x
+.rept 2
+ vld1.8 {q0}, [r0]!
+ vld1.8 {q1}, [r1]!
+ vld1.8 {q2}, [r2]!
+ vld1.8 {q3}, [r3]!
+ vabal.u8 q8, d0, d2
+ vabal.u8 q9, d1, d3
+ vabal.u8 q10, d0, d4
+ vabal.u8 q11, d1, d5
+ vabal.u8 q12, d0, d6
+ vabal.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr]!
+ vabal.u8 q14, d0, d6
+ vabal.u8 q15, d1, d7
+.endif
+.endr
+ vld1.8 {q0}, [r0], r12
+ vld1.8 {q1}, [r1], r4
+ vld1.8 {q2}, [r2], r4
+ vld1.8 {q3}, [r3], r4
+ vabal.u8 q8, d0, d2
+ vabal.u8 q9, d1, d3
+ vabal.u8 q10, d0, d4
+ vabal.u8 q11, d1, d5
+ vabal.u8 q12, d0, d6
+ vabal.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr], r4
+ vabal.u8 q14, d0, d6
+ vabal.u8 q15, d1, d7
+.endif
+.endm
+
+.macro SAD_X_48x64 x
+function x265_sad_x\x\()_48x64_neon
+ push {r4-r6, lr}
+.if \x == 3
+ ldrd r4, r5, [sp, #16]
+.else
+ ldr lr, [sp, #16]
+ ldrd r4, r5, [sp, #20]
+.endif
+ mov r12, #FENC_STRIDE
+ sub r12, #32
+ sub r4, #32
+ mov r6, #8
+ veor.u8 q8, q8
+ veor.u8 q9, q9
+ veor.u8 q10, q10
+ veor.u8 q11, q11
+ veor.u8 q12, q12
+ veor.u8 q13, q13
+.if \x == 4
+ veor.u8 q14, q14
+ veor.u8 q15, q15
+.endif
+
+.loop_sad_x\x\()_48x64:
+.rept 8
+ SAD_X_48 \x
+.endr
+ subs r6, #1
+ bne .loop_sad_x\x\()_48x64
+
+ vpaddl.u16 q8, q8
+ vpaddl.u16 q9, q9
+ vpaddl.u16 q10, q10
+ vpaddl.u16 q11, q11
+ vpaddl.u16 q12, q12
+ vpaddl.u16 q13, q13
+.if \x == 4
+ vpaddl.u16 q14, q14
+ vpaddl.u16 q15, q15
+.endif
+ vadd.u32 q8, q8, q9
+ vadd.u32 q10, q10, q11
+ vadd.u32 q12, q12, q13
+.if \x == 4
+ vadd.u32 q14, q14, q15
+.endif
+ vadd.u32 d16, d16, d17
+ vadd.u32 d20, d20, d21
+ vadd.u32 d24, d24, d25
+.if \x == 4
+ vadd.u32 d28, d28, d29
+.endif
+ vpaddl.u32 d16, d16
+ vpaddl.u32 d20, d20
+ vpaddl.u32 d24, d24
+ vpaddl.u32 d28, d28
+.if \x == 4
+ vpaddl.u32 d28, d28
+.endif
+ vst1.32 {d16[0]}, [r5]!
+ vst1.32 {d20[0]}, [r5]!
+.if \x == 3
+ vst1.32 {d24[0]}, [r5]
+.endif
+.if \x == 4
+ vst1.32 {d24[0]}, [r5]!
+ vst1.32 {d28[0]}, [r5]
+.endif
+ pop {r4-r6, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_48x64 3
+SAD_X_48x64 4
+
+.macro SAD_X_24 x
+ vld1.8 {q0}, [r0]!
+ vld1.8 {q1}, [r1]!
+ vld1.8 {q2}, [r2]!
+ vld1.8 {q3}, [r3]!
+ vabal.u8 q8, d0, d2
+ vabal.u8 q9, d1, d3
+ vabal.u8 q10, d0, d4
+ vabal.u8 q11, d1, d5
+ vabal.u8 q12, d0, d6
+ vabal.u8 q13, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr]!
+ vabal.u8 q14, d0, d6
+ vabal.u8 q15, d1, d7
+.endif
+ vld1.8 {d0}, [r0], r12
+ vld1.8 {d1}, [r1], r4
+ vld1.8 {d2}, [r2], r4
+ vld1.8 {d3}, [r3], r4
+.if \x == 4
+ vld1.8 {d8}, [lr], r4
+.endif
+ vabal.u8 q8, d0, d1
+ vabal.u8 q10, d0, d2
+ vabal.u8 q12, d0, d3
+.if \x == 4
+ vabal.u8 q14, d0, d8
+.endif
+.endm
+
+.macro SAD_X_24x32 x
+function x265_sad_x\x\()_24x32_neon
+ push {r4-r6, lr}
+.if \x == 3
+ ldrd r4, r5, [sp, #16]
+.else
+ ldr lr, [sp, #16]
+ ldrd r4, r5, [sp, #20]
+.endif
+ mov r12, #FENC_STRIDE
+ sub r12, #16
+ sub r4, #16
+ mov r6, #4
+ veor.u8 q8, q8
+ veor.u8 q9, q9
+ veor.u8 q10, q10
+ veor.u8 q11, q11
+ veor.u8 q12, q12
+ veor.u8 q13, q13
+.if \x == 4
+ veor.u8 q14, q14
+ veor.u8 q15, q15
+.endif
+
+.loop_sad_x\x\()_24x32:
+.rept 8
+ SAD_X_24 \x
+.endr
+ subs r6, #1
+ bne .loop_sad_x\x\()_24x32
+
+ vadd.u16 q8, q8, q9
+ vadd.u16 q10, q10, q11
+ vadd.u16 q12, q12, q13
+.if \x == 4
+ vadd.u16 q14, q14, q15
+.endif
+ vadd.u16 d16, d16, d17
+ vadd.u16 d20, d20, d21
+ vadd.u16 d24, d24, d25
+.if \x == 4
+ vadd.u16 d28, d28, d29
+.endif
+ vpaddl.u16 d16, d16
+ vpaddl.u16 d20, d20
+ vpaddl.u16 d24, d24
+.if \x == 4
+ vpaddl.u16 d28, d28
+.endif
+ vpaddl.u32 d16, d16
+ vpaddl.u32 d20, d20
+ vpaddl.u32 d24, d24
+.if \x == 4
+ vpaddl.u32 d28, d28
+.endif
+.if \x == 4
+ vpaddl.u32 d28, d28
+.endif
+ vst1.32 {d16[0]}, [r5]!
+ vst1.32 {d20[0]}, [r5]!
+.if \x == 3
+ vst1.32 {d24[0]}, [r5]
+.endif
+.if \x == 4
+ vst1.32 {d24[0]}, [r5]!
+ vst1.32 {d28[0]}, [r5]
+.endif
+ pop {r4-r6, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_24x32 3
+SAD_X_24x32 4
+
+// SAD_X3 and SAD_X4 code end
+
+.macro SAD_X_START_12 x
+ vld1.8 {q0}, [r0], r12
+ vld1.8 {q1}, [r1], r4
+ vld1.8 {q2}, [r2], r4
+ vld1.8 {q3}, [r3], r4
+ vand.u8 q0, q15
+ vand.u8 q1, q15
+ vand.u8 q2, q15
+ vand.u8 q3, q15
+ vabdl.u8 q5, d0, d2
+ vabdl.u8 q8, d1, d3
+ vabdl.u8 q9, d0, d4
+ vabdl.u8 q10, d1, d5
+ vabdl.u8 q11, d0, d6
+ vabdl.u8 q12, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr], r4
+ vand.u8 q3, q15
+ vabdl.u8 q13, d0, d6
+ vabdl.u8 q14, d1, d7
+.endif
+.endm
+
+.macro SAD_X_12 x
+ vld1.8 {q0}, [r0], r12
+ vld1.8 {q1}, [r1], r4
+ vld1.8 {q2}, [r2], r4
+ vld1.8 {q3}, [r3], r4
+ vand.u8 q0, q15
+ vand.u8 q1, q15
+ vand.u8 q2, q15
+ vand.u8 q3, q15
+ vabal.u8 q5, d0, d2
+ vabal.u8 q8, d1, d3
+ vabal.u8 q9, d0, d4
+ vabal.u8 q10, d1, d5
+ vabal.u8 q11, d0, d6
+ vabal.u8 q12, d1, d7
+.if \x == 4
+ vld1.8 {q3}, [lr], r4
+ vand.u8 q3, q15
+ vabal.u8 q13, d0, d6
+ vabal.u8 q14, d1, d7
+.endif
+.endm
+
+.macro SAD_X_12x16 x
+function x265_sad_x\x\()_12x16_neon
+ push {r4-r5, lr}
+ vpush {q5}
+.if \x == 3
+ ldrd r4, r5, [sp, #28]
+.else
+ ldr lr, [sp, #28]
+ ldrd r4, r5, [sp, #32]
+.endif
+ movrel r12, sad12_mask
+ vld1.8 {q15}, [r12]
+ mov r12, #FENC_STRIDE
+
+ SAD_X_START_12 \x
+.rept 15
+ SAD_X_12 \x
+.endr
+ vadd.u16 q5, q5, q8
+ vadd.u16 q9, q9, q10
+ vadd.u16 q11, q11, q12
+.if \x == 4
+ vadd.u16 q13, q13, q14
+.endif
+ vadd.u16 d10, d10, d11
+ vadd.u16 d18, d18, d19
+ vadd.u16 d22, d22, d23
+.if \x == 4
+ vadd.u16 d26, d26, d27
+.endif
+ vpadd.u16 d0, d10, d18
+ vpadd.u16 d1, d22, d26
+ vpaddl.u16 q0, q0
+.if \x == 3
+ vst1.32 {d0}, [r5]!
+ vst1.32 {d1[0]}, [r5, :32]
+.else
+ vst1.32 {d0-d1}, [r5]
+.endif
+ vpop {q5}
+ pop {r4-r5, lr}
+ bx lr
+endfunc
+.endm
+
+SAD_X_12x16 3
+SAD_X_12x16 4
More information about the x265-devel
mailing list