| Index: source/libvpx/third_party/libyuv/source/row_neon.cc
|
| diff --git a/source/libvpx/third_party/libyuv/source/row_neon.cc b/source/libvpx/third_party/libyuv/source/row_neon.cc
|
| index 1392cf5fcc3b218508c90b5fa6a2f5c5e67b440c..8badc5a9b94bf776b663f501b775f68411af08df 100644
|
| --- a/source/libvpx/third_party/libyuv/source/row_neon.cc
|
| +++ b/source/libvpx/third_party/libyuv/source/row_neon.cc
|
| @@ -16,7 +16,8 @@ extern "C" {
|
| #endif
|
|
|
| // This module is for GCC Neon
|
| -#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__)
|
| +#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) && \
|
| + !defined(__aarch64__)
|
|
|
| // Read 8 Y, 4 U and 4 V from 422
|
| #define READYUV422 \
|
| @@ -92,36 +93,73 @@ extern "C" {
|
| "vuzp.u8 d2, d3 \n" \
|
| "vtrn.u32 d2, d3 \n"
|
|
|
| +#define YUV422TORGB_SETUP_REG \
|
| + "vld1.8 {d24}, [%[kUVToRB]] \n" \
|
| + "vld1.8 {d25}, [%[kUVToG]] \n" \
|
| + "vld1.16 {d26[], d27[]}, [%[kUVBiasBGR]]! \n" \
|
| + "vld1.16 {d8[], d9[]}, [%[kUVBiasBGR]]! \n" \
|
| + "vld1.16 {d28[], d29[]}, [%[kUVBiasBGR]] \n" \
|
| + "vld1.32 {d30[], d31[]}, [%[kYToRgb]] \n"
|
| +
|
| #define YUV422TORGB \
|
| - "veor.u8 d2, d26 \n"/*subtract 128 from u and v*/\
|
| - "vmull.s8 q8, d2, d24 \n"/* u/v B/R component */\
|
| - "vmull.s8 q9, d2, d25 \n"/* u/v G component */\
|
| - "vmov.u8 d1, #0 \n"/* split odd/even y apart */\
|
| - "vtrn.u8 d0, d1 \n" \
|
| - "vsub.s16 q0, q0, q15 \n"/* offset y */\
|
| - "vmul.s16 q0, q0, q14 \n" \
|
| + "vmull.u8 q8, d2, d24 \n" /* u/v B/R component */\
|
| + "vmull.u8 q9, d2, d25 \n" /* u/v G component */\
|
| + "vmovl.u8 q0, d0 \n" /* Y */\
|
| + "vmovl.s16 q10, d1 \n" \
|
| + "vmovl.s16 q0, d0 \n" \
|
| + "vmul.s32 q10, q10, q15 \n" \
|
| + "vmul.s32 q0, q0, q15 \n" \
|
| + "vqshrun.s32 d0, q0, #16 \n" \
|
| + "vqshrun.s32 d1, q10, #16 \n" /* Y */\
|
| "vadd.s16 d18, d19 \n" \
|
| - "vqadd.s16 d20, d0, d16 \n" /* B */ \
|
| - "vqadd.s16 d21, d1, d16 \n" \
|
| - "vqadd.s16 d22, d0, d17 \n" /* R */ \
|
| - "vqadd.s16 d23, d1, d17 \n" \
|
| - "vqadd.s16 d16, d0, d18 \n" /* G */ \
|
| - "vqadd.s16 d17, d1, d18 \n" \
|
| - "vqshrun.s16 d0, q10, #6 \n" /* B */ \
|
| - "vqshrun.s16 d1, q11, #6 \n" /* G */ \
|
| - "vqshrun.s16 d2, q8, #6 \n" /* R */ \
|
| - "vmovl.u8 q10, d0 \n"/* set up for reinterleave*/\
|
| - "vmovl.u8 q11, d1 \n" \
|
| - "vmovl.u8 q8, d2 \n" \
|
| - "vtrn.u8 d20, d21 \n" \
|
| - "vtrn.u8 d22, d23 \n" \
|
| - "vtrn.u8 d16, d17 \n" \
|
| - "vmov.u8 d21, d16 \n"
|
| -
|
| -static vec8 kUVToRB = { 127, 127, 127, 127, 102, 102, 102, 102,
|
| - 0, 0, 0, 0, 0, 0, 0, 0 };
|
| -static vec8 kUVToG = { -25, -25, -25, -25, -52, -52, -52, -52,
|
| - 0, 0, 0, 0, 0, 0, 0, 0 };
|
| + "vshll.u16 q1, d16, #16 \n" /* Replicate u * UB */\
|
| + "vshll.u16 q10, d17, #16 \n" /* Replicate v * VR */\
|
| + "vshll.u16 q3, d18, #16 \n" /* Replicate (v*VG + u*UG)*/\
|
| + "vaddw.u16 q1, q1, d16 \n" \
|
| + "vaddw.u16 q10, q10, d17 \n" \
|
| + "vaddw.u16 q3, q3, d18 \n" \
|
| + "vqadd.s16 q8, q0, q13 \n" /* B */ \
|
| + "vqadd.s16 q9, q0, q14 \n" /* R */ \
|
| + "vqadd.s16 q0, q0, q4 \n" /* G */ \
|
| + "vqadd.s16 q8, q8, q1 \n" /* B */ \
|
| + "vqadd.s16 q9, q9, q10 \n" /* R */ \
|
| + "vqsub.s16 q0, q0, q3 \n" /* G */ \
|
| + "vqshrun.s16 d20, q8, #6 \n" /* B */ \
|
| + "vqshrun.s16 d22, q9, #6 \n" /* R */ \
|
| + "vqshrun.s16 d21, q0, #6 \n" /* G */
|
| +
|
| +// YUV to RGB conversion constants.
|
| +// Y contribution to R,G,B. Scale and bias.
|
| +#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */
|
| +#define YGB 1160 /* 1.164 * 64 * 16 - adjusted for even error distribution */
|
| +
|
| +// U and V contributions to R,G,B.
|
| +#define UB -128 /* -min(128, round(2.018 * 64)) */
|
| +#define UG 25 /* -round(-0.391 * 64) */
|
| +#define VG 52 /* -round(-0.813 * 64) */
|
| +#define VR -102 /* -round(1.596 * 64) */
|
| +
|
| +// Bias values to subtract 16 from Y and 128 from U and V.
|
| +#define BB (UB * 128 - YGB)
|
| +#define BG (UG * 128 + VG * 128 - YGB)
|
| +#define BR (VR * 128 - YGB)
|
| +
|
| +static uvec8 kUVToRB = { 128, 128, 128, 128, 102, 102, 102, 102,
|
| + 0, 0, 0, 0, 0, 0, 0, 0 };
|
| +static uvec8 kUVToG = { 25, 25, 25, 25, 52, 52, 52, 52,
|
| + 0, 0, 0, 0, 0, 0, 0, 0 };
|
| +static vec16 kUVBiasBGR = { BB, BG, BR, 0, 0, 0, 0, 0 };
|
| +static vec32 kYToRgb = { 0x0101 * YG, 0, 0, 0 };
|
| +
|
| +#undef YG
|
| +#undef YGB
|
| +#undef UB
|
| +#undef UG
|
| +#undef VG
|
| +#undef VR
|
| +#undef BB
|
| +#undef BG
|
| +#undef BR
|
|
|
| void I444ToARGBRow_NEON(const uint8* src_y,
|
| const uint8* src_u,
|
| @@ -129,13 +167,7 @@ void I444ToARGBRow_NEON(const uint8* src_y,
|
| uint8* dst_argb,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV444
|
| @@ -150,8 +182,10 @@ void I444ToARGBRow_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_argb), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -163,13 +197,7 @@ void I422ToARGBRow_NEON(const uint8* src_y,
|
| uint8* dst_argb,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV422
|
| @@ -184,8 +212,10 @@ void I422ToARGBRow_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_argb), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -197,13 +227,7 @@ void I411ToARGBRow_NEON(const uint8* src_y,
|
| uint8* dst_argb,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV411
|
| @@ -218,8 +242,10 @@ void I411ToARGBRow_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_argb), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -231,13 +257,7 @@ void I422ToBGRARow_NEON(const uint8* src_y,
|
| uint8* dst_bgra,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV422
|
| @@ -253,8 +273,10 @@ void I422ToBGRARow_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_bgra), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -266,13 +288,7 @@ void I422ToABGRRow_NEON(const uint8* src_y,
|
| uint8* dst_abgr,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV422
|
| @@ -288,8 +304,10 @@ void I422ToABGRRow_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_abgr), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -301,13 +319,7 @@ void I422ToRGBARow_NEON(const uint8* src_y,
|
| uint8* dst_rgba,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV422
|
| @@ -322,8 +334,10 @@ void I422ToRGBARow_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_rgba), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -335,13 +349,7 @@ void I422ToRGB24Row_NEON(const uint8* src_y,
|
| uint8* dst_rgb24,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV422
|
| @@ -355,8 +363,10 @@ void I422ToRGB24Row_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_rgb24), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -368,13 +378,7 @@ void I422ToRAWRow_NEON(const uint8* src_y,
|
| uint8* dst_raw,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV422
|
| @@ -389,8 +393,10 @@ void I422ToRAWRow_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_raw), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -414,13 +420,7 @@ void I422ToRGB565Row_NEON(const uint8* src_y,
|
| uint8* dst_rgb565,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV422
|
| @@ -435,8 +435,10 @@ void I422ToRGB565Row_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_rgb565), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -463,13 +465,7 @@ void I422ToARGB1555Row_NEON(const uint8* src_y,
|
| uint8* dst_argb1555,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV422
|
| @@ -485,8 +481,10 @@ void I422ToARGB1555Row_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_argb1555), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -507,13 +505,7 @@ void I422ToARGB4444Row_NEON(const uint8* src_y,
|
| uint8* dst_argb4444,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(5)
|
| - "vld1.8 {d24}, [%5] \n"
|
| - MEMACCESS(6)
|
| - "vld1.8 {d25}, [%6] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| "vmov.u8 d4, #0x0f \n" // bits to clear with vbic.
|
| ".p2align 2 \n"
|
| "1: \n"
|
| @@ -530,8 +522,10 @@ void I422ToARGB4444Row_NEON(const uint8* src_y,
|
| "+r"(src_v), // %2
|
| "+r"(dst_argb4444), // %3
|
| "+r"(width) // %4
|
| - : "r"(&kUVToRB), // %5
|
| - "r"(&kUVToG) // %6
|
| + : [kUVToRB]"r"(&kUVToRB), // %5
|
| + [kUVToG]"r"(&kUVToG), // %6
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -541,13 +535,7 @@ void YToARGBRow_NEON(const uint8* src_y,
|
| uint8* dst_argb,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(3)
|
| - "vld1.8 {d24}, [%3] \n"
|
| - MEMACCESS(4)
|
| - "vld1.8 {d25}, [%4] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUV400
|
| @@ -560,8 +548,10 @@ void YToARGBRow_NEON(const uint8* src_y,
|
| : "+r"(src_y), // %0
|
| "+r"(dst_argb), // %1
|
| "+r"(width) // %2
|
| - : "r"(&kUVToRB), // %3
|
| - "r"(&kUVToG) // %4
|
| + : [kUVToRB]"r"(&kUVToRB), // %3
|
| + [kUVToG]"r"(&kUVToG), // %4
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -595,13 +585,7 @@ void NV12ToARGBRow_NEON(const uint8* src_y,
|
| uint8* dst_argb,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(4)
|
| - "vld1.8 {d24}, [%4] \n"
|
| - MEMACCESS(5)
|
| - "vld1.8 {d25}, [%5] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READNV12
|
| @@ -615,8 +599,10 @@ void NV12ToARGBRow_NEON(const uint8* src_y,
|
| "+r"(src_uv), // %1
|
| "+r"(dst_argb), // %2
|
| "+r"(width) // %3
|
| - : "r"(&kUVToRB), // %4
|
| - "r"(&kUVToG) // %5
|
| + : [kUVToRB]"r"(&kUVToRB), // %4
|
| + [kUVToG]"r"(&kUVToG), // %5
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -627,13 +613,7 @@ void NV21ToARGBRow_NEON(const uint8* src_y,
|
| uint8* dst_argb,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(4)
|
| - "vld1.8 {d24}, [%4] \n"
|
| - MEMACCESS(5)
|
| - "vld1.8 {d25}, [%5] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READNV21
|
| @@ -647,8 +627,10 @@ void NV21ToARGBRow_NEON(const uint8* src_y,
|
| "+r"(src_uv), // %1
|
| "+r"(dst_argb), // %2
|
| "+r"(width) // %3
|
| - : "r"(&kUVToRB), // %4
|
| - "r"(&kUVToG) // %5
|
| + : [kUVToRB]"r"(&kUVToRB), // %4
|
| + [kUVToG]"r"(&kUVToG), // %5
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -659,13 +641,7 @@ void NV12ToRGB565Row_NEON(const uint8* src_y,
|
| uint8* dst_rgb565,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(4)
|
| - "vld1.8 {d24}, [%4] \n"
|
| - MEMACCESS(5)
|
| - "vld1.8 {d25}, [%5] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READNV12
|
| @@ -679,8 +655,10 @@ void NV12ToRGB565Row_NEON(const uint8* src_y,
|
| "+r"(src_uv), // %1
|
| "+r"(dst_rgb565), // %2
|
| "+r"(width) // %3
|
| - : "r"(&kUVToRB), // %4
|
| - "r"(&kUVToG) // %5
|
| + : [kUVToRB]"r"(&kUVToRB), // %4
|
| + [kUVToG]"r"(&kUVToG), // %5
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -691,13 +669,7 @@ void NV21ToRGB565Row_NEON(const uint8* src_y,
|
| uint8* dst_rgb565,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(4)
|
| - "vld1.8 {d24}, [%4] \n"
|
| - MEMACCESS(5)
|
| - "vld1.8 {d25}, [%5] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READNV21
|
| @@ -711,8 +683,10 @@ void NV21ToRGB565Row_NEON(const uint8* src_y,
|
| "+r"(src_uv), // %1
|
| "+r"(dst_rgb565), // %2
|
| "+r"(width) // %3
|
| - : "r"(&kUVToRB), // %4
|
| - "r"(&kUVToG) // %5
|
| + : [kUVToRB]"r"(&kUVToRB), // %4
|
| + [kUVToG]"r"(&kUVToG), // %5
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -722,13 +696,7 @@ void YUY2ToARGBRow_NEON(const uint8* src_yuy2,
|
| uint8* dst_argb,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(3)
|
| - "vld1.8 {d24}, [%3] \n"
|
| - MEMACCESS(4)
|
| - "vld1.8 {d25}, [%4] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READYUY2
|
| @@ -741,8 +709,10 @@ void YUY2ToARGBRow_NEON(const uint8* src_yuy2,
|
| : "+r"(src_yuy2), // %0
|
| "+r"(dst_argb), // %1
|
| "+r"(width) // %2
|
| - : "r"(&kUVToRB), // %3
|
| - "r"(&kUVToG) // %4
|
| + : [kUVToRB]"r"(&kUVToRB), // %3
|
| + [kUVToG]"r"(&kUVToG), // %4
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -752,13 +722,7 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy,
|
| uint8* dst_argb,
|
| int width) {
|
| asm volatile (
|
| - MEMACCESS(3)
|
| - "vld1.8 {d24}, [%3] \n"
|
| - MEMACCESS(4)
|
| - "vld1.8 {d25}, [%4] \n"
|
| - "vmov.u8 d26, #128 \n"
|
| - "vmov.u16 q14, #74 \n"
|
| - "vmov.u16 q15, #16 \n"
|
| + YUV422TORGB_SETUP_REG
|
| ".p2align 2 \n"
|
| "1: \n"
|
| READUYVY
|
| @@ -771,8 +735,10 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy,
|
| : "+r"(src_uyvy), // %0
|
| "+r"(dst_argb), // %1
|
| "+r"(width) // %2
|
| - : "r"(&kUVToRB), // %3
|
| - "r"(&kUVToG) // %4
|
| + : [kUVToRB]"r"(&kUVToRB), // %3
|
| + [kUVToG]"r"(&kUVToG), // %4
|
| + [kUVBiasBGR]"r"(&kUVBiasBGR),
|
| + [kYToRgb]"r"(&kYToRgb)
|
| : "cc", "memory", "q0", "q1", "q2", "q3",
|
| "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| @@ -844,30 +810,36 @@ void CopyRow_NEON(const uint8* src, uint8* dst, int count) {
|
| );
|
| }
|
|
|
| -// SetRow8 writes 'count' bytes using a 32 bit value repeated.
|
| -void SetRow_NEON(uint8* dst, uint32 v32, int count) {
|
| +// SetRow writes 'count' bytes using an 8 bit value repeated.
|
| +void SetRow_NEON(uint8* dst, uint8 v8, int count) {
|
| asm volatile (
|
| - "vdup.u32 q0, %2 \n" // duplicate 4 ints
|
| - "1: \n"
|
| + "vdup.8 q0, %2 \n" // duplicate 16 bytes
|
| + "1: \n"
|
| "subs %1, %1, #16 \n" // 16 bytes per loop
|
| MEMACCESS(0)
|
| "vst1.8 {q0}, [%0]! \n" // store
|
| "bgt 1b \n"
|
| : "+r"(dst), // %0
|
| "+r"(count) // %1
|
| - : "r"(v32) // %2
|
| + : "r"(v8) // %2
|
| : "cc", "memory", "q0"
|
| );
|
| }
|
|
|
| -// TODO(fbarchard): Make fully assembler
|
| -// SetRow32 writes 'count' words using a 32 bit value repeated.
|
| -void ARGBSetRows_NEON(uint8* dst, uint32 v32, int width,
|
| - int dst_stride, int height) {
|
| - for (int y = 0; y < height; ++y) {
|
| - SetRow_NEON(dst, v32, width << 2);
|
| - dst += dst_stride;
|
| - }
|
| +// ARGBSetRow writes 'count' pixels using an 32 bit value repeated.
|
| +void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) {
|
| + asm volatile (
|
| + "vdup.u32 q0, %2 \n" // duplicate 4 ints
|
| + "1: \n"
|
| + "subs %1, %1, #4 \n" // 4 pixels per loop
|
| + MEMACCESS(0)
|
| + "vst1.8 {q0}, [%0]! \n" // store
|
| + "bgt 1b \n"
|
| + : "+r"(dst), // %0
|
| + "+r"(count) // %1
|
| + : "r"(v32) // %2
|
| + : "cc", "memory", "q0"
|
| + );
|
| }
|
|
|
| void MirrorRow_NEON(const uint8* src, uint8* dst, int width) {
|
| @@ -1273,53 +1245,6 @@ void UYVYToUVRow_NEON(const uint8* src_uyvy, int stride_uyvy,
|
| );
|
| }
|
|
|
| -void HalfRow_NEON(const uint8* src_uv, int src_uv_stride,
|
| - uint8* dst_uv, int pix) {
|
| - asm volatile (
|
| - // change the stride to row 2 pointer
|
| - "add %1, %0 \n"
|
| - "1: \n"
|
| - MEMACCESS(0)
|
| - "vld1.8 {q0}, [%0]! \n" // load row 1 16 pixels.
|
| - "subs %3, %3, #16 \n" // 16 processed per loop
|
| - MEMACCESS(1)
|
| - "vld1.8 {q1}, [%1]! \n" // load row 2 16 pixels.
|
| - "vrhadd.u8 q0, q1 \n" // average row 1 and 2
|
| - MEMACCESS(2)
|
| - "vst1.8 {q0}, [%2]! \n"
|
| - "bgt 1b \n"
|
| - : "+r"(src_uv), // %0
|
| - "+r"(src_uv_stride), // %1
|
| - "+r"(dst_uv), // %2
|
| - "+r"(pix) // %3
|
| - :
|
| - : "cc", "memory", "q0", "q1" // Clobber List
|
| - );
|
| -}
|
| -
|
| -// Select 2 channels from ARGB on alternating pixels. e.g. BGBGBGBG
|
| -void ARGBToBayerRow_NEON(const uint8* src_argb, uint8* dst_bayer,
|
| - uint32 selector, int pix) {
|
| - asm volatile (
|
| - "vmov.u32 d6[0], %3 \n" // selector
|
| - "1: \n"
|
| - MEMACCESS(0)
|
| - "vld1.8 {q0, q1}, [%0]! \n" // load row 8 pixels.
|
| - "subs %2, %2, #8 \n" // 8 processed per loop
|
| - "vtbl.8 d4, {d0, d1}, d6 \n" // look up 4 pixels
|
| - "vtbl.8 d5, {d2, d3}, d6 \n" // look up 4 pixels
|
| - "vtrn.u32 d4, d5 \n" // combine 8 pixels
|
| - MEMACCESS(1)
|
| - "vst1.8 {d4}, [%1]! \n" // store 8.
|
| - "bgt 1b \n"
|
| - : "+r"(src_argb), // %0
|
| - "+r"(dst_bayer), // %1
|
| - "+r"(pix) // %2
|
| - : "r"(selector) // %3
|
| - : "cc", "memory", "q0", "q1", "q2", "q3" // Clobber List
|
| - );
|
| -}
|
| -
|
| // Select G channels from ARGB. e.g. GGGGGGGG
|
| void ARGBToBayerGGRow_NEON(const uint8* src_argb, uint8* dst_bayer,
|
| uint32 /*selector*/, int pix) {
|
| @@ -2832,7 +2757,7 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
|
| "vmovl.u8 q8, d16 \n" // b (0 .. 255) 16 bit
|
| "vmovl.u8 q9, d18 \n" // g
|
| "vmovl.u8 q10, d20 \n" // r
|
| - "vmovl.u8 q15, d22 \n" // a
|
| + "vmovl.u8 q11, d22 \n" // a
|
| "vmul.s16 q12, q8, d0[0] \n" // B = B * Matrix B
|
| "vmul.s16 q13, q8, d1[0] \n" // G = B * Matrix G
|
| "vmul.s16 q14, q8, d2[0] \n" // R = B * Matrix R
|
| @@ -2853,10 +2778,10 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
|
| "vqadd.s16 q13, q13, q5 \n" // Accumulate G
|
| "vqadd.s16 q14, q14, q6 \n" // Accumulate R
|
| "vqadd.s16 q15, q15, q7 \n" // Accumulate A
|
| - "vmul.s16 q4, q15, d0[3] \n" // B += A * Matrix B
|
| - "vmul.s16 q5, q15, d1[3] \n" // G += A * Matrix G
|
| - "vmul.s16 q6, q15, d2[3] \n" // R += A * Matrix R
|
| - "vmul.s16 q7, q15, d3[3] \n" // A += A * Matrix A
|
| + "vmul.s16 q4, q11, d0[3] \n" // B += A * Matrix B
|
| + "vmul.s16 q5, q11, d1[3] \n" // G += A * Matrix G
|
| + "vmul.s16 q6, q11, d2[3] \n" // R += A * Matrix R
|
| + "vmul.s16 q7, q11, d3[3] \n" // A += A * Matrix A
|
| "vqadd.s16 q12, q12, q4 \n" // Accumulate B
|
| "vqadd.s16 q13, q13, q5 \n" // Accumulate G
|
| "vqadd.s16 q14, q14, q6 \n" // Accumulate R
|
| @@ -2872,7 +2797,7 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
|
| "+r"(dst_argb), // %1
|
| "+r"(width) // %2
|
| : "r"(matrix_argb) // %3
|
| - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9",
|
| + : "cc", "memory", "q0", "q1", "q2", "q4", "q5", "q6", "q7", "q8", "q9",
|
| "q10", "q11", "q12", "q13", "q14", "q15"
|
| );
|
| }
|
| @@ -3140,7 +3065,7 @@ void SobelYRow_NEON(const uint8* src_y0, const uint8* src_y1,
|
| : "cc", "memory", "q0", "q1" // Clobber List
|
| );
|
| }
|
| -#endif // __ARM_NEON__
|
| +#endif // defined(__ARM_NEON__) && !defined(__aarch64__)
|
|
|
| #ifdef __cplusplus
|
| } // extern "C"
|
|
|