| 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"
 | 
| 
 |