Changeset 5699


Ignore:
Timestamp:
Nov 21, 2017 9:25:11 AM (7 years ago)
Author:
riza
Message:

Close #2065: Update libyuv to fix linker error when building libyuv as dll on Visual Studio 2015.

Location:
pjproject/trunk/third_party
Files:
39 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/third_party/build/yuv/Notes.txt

    r5633 r5699  
    11Notes: 
    22 
    3 * Source code for libyuv from https://chromium.googlesource.com/libyuv/libyuv/ dated 27 July 2017. 
     3* Source code for libyuv from https://chromium.googlesource.com/libyuv/libyuv/ dated 17 November 2017. 
    44 
    5 * All code is compilable, except for compare_win.cc 
    6   - Use older version (https://chromium.googlesource.com/libyuv/libyuv/+/baf6a3c1bd385e7ffe6b7634560e71fb49e4f589%5E%21/) 
    7     Since there's a compiler error on: 
    8     -------------------------------------------------------------------------------------- 
    9     pmulld      xmm0,xmm6 
    10     -------------------------------------------------------------------------------------- 
    11  
    12   - On VS2015, error C2024: 'alignas' attribute applies to variables, data members and tag types only 
    13     -------------------------------------------------------------------------------------- 
    14     __declspec(naked) __declspec(align(16)) 
    15  
    16     Change to : 
    17  
    18     __declspec(naked) 
    19     -------------------------------------------------------------------------------------- 
    20  
    21 * Added these lines to file include/libyuv/basic_types.h: 
    22   -- 
    23   #if _MSC_VER==1400 
    24   #   include <stdint.h>  // for uint8_t 
    25   #endif 
    26   ... 
    27   #if defined(_MSC_VER) 
    28   #  pragma warning(disable:4996) // This function or variable may be unsafe. 
    29   #endif 
    30   -- 
  • pjproject/trunk/third_party/yuv/include/libyuv/basic_types.h

    r5633 r5699  
    1515 
    1616#if defined(_MSC_VER) && (_MSC_VER < 1600) 
    17 #if _MSC_VER==1400 
    18 #   include <stdint.h>  // for uint8_t 
    19 #endif 
    2017#include <sys/types.h>  // for uintptr_t on x86 
    2118#else 
    2219#include <stdint.h>  // for uintptr_t 
    23 #endif 
    24  
    25 #if defined(_MSC_VER) 
    26 #  pragma warning(disable:4996) // This function or variable may be unsafe. 
    2720#endif 
    2821 
  • pjproject/trunk/third_party/yuv/include/libyuv/compare_row.h

    r5633 r5699  
    2020 
    2121#if defined(__pnacl__) || defined(__CLR_VER) || \ 
    22     (defined(__i386__) && !defined(__SSE2__)) 
     22    (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) 
    2323#define LIBYUV_DISABLE_X86 
    2424#endif 
     
    4343#endif  // __clang__ 
    4444 
     45// The following are available for Visual C: 
    4546#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && \ 
    4647    (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2)) 
     
    5354#define HAS_HASHDJB2_SSE41 
    5455#define HAS_SUMSQUAREERROR_SSE2 
    55 #define HAS_HAMMINGDISTANCE_X86 
     56#define HAS_HAMMINGDISTANCE_SSE42 
    5657#endif 
    5758 
     
    6364#endif 
    6465 
     66// The following are available for GCC and clangcl 64 bit: 
     67#if !defined(LIBYUV_DISABLE_X86) && \ 
     68    (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) 
     69#define HAS_HAMMINGDISTANCE_SSSE3 
     70#endif 
     71 
     72// The following are available for GCC and clangcl 64 bit: 
     73#if !defined(LIBYUV_DISABLE_X86) && defined(CLANG_HAS_AVX2) && \ 
     74    (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) 
     75#define HAS_HAMMINGDISTANCE_AVX2 
     76#endif 
     77 
    6578// The following are available for Neon: 
    6679#if !defined(LIBYUV_DISABLE_NEON) && \ 
     
    7083#endif 
    7184 
     85#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) 
     86#define HAS_HAMMINGDISTANCE_MSA 
     87#define HAS_SUMSQUAREERROR_MSA 
     88#endif 
     89 
    7290uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count); 
    73 uint32 HammingDistance_X86(const uint8* src_a, const uint8* src_b, int count); 
     91uint32 HammingDistance_SSE42(const uint8* src_a, const uint8* src_b, int count); 
     92uint32 HammingDistance_SSSE3(const uint8* src_a, const uint8* src_b, int count); 
     93uint32 HammingDistance_AVX2(const uint8* src_a, const uint8* src_b, int count); 
    7494uint32 HammingDistance_NEON(const uint8* src_a, const uint8* src_b, int count); 
     95uint32 HammingDistance_MSA(const uint8* src_a, const uint8* src_b, int count); 
    7596 
    7697uint32 SumSquareError_C(const uint8* src_a, const uint8* src_b, int count); 
     
    7899uint32 SumSquareError_AVX2(const uint8* src_a, const uint8* src_b, int count); 
    79100uint32 SumSquareError_NEON(const uint8* src_a, const uint8* src_b, int count); 
     101uint32 SumSquareError_MSA(const uint8* src_a, const uint8* src_b, int count); 
    80102 
    81103uint32 HashDjb2_C(const uint8* src, int count, uint32 seed); 
  • pjproject/trunk/third_party/yuv/include/libyuv/convert_from.h

    r5633 r5699  
    179179LIBYUV_API 
    180180int I420ToRAW(const uint8* src_y, 
     181              int src_stride_y, 
     182              const uint8* src_u, 
     183              int src_stride_u, 
     184              const uint8* src_v, 
     185              int src_stride_v, 
     186              uint8* dst_frame, 
     187              int dst_stride_frame, 
     188              int width, 
     189              int height); 
     190 
     191LIBYUV_API 
     192int H420ToRGB24(const uint8* src_y, 
     193                int src_stride_y, 
     194                const uint8* src_u, 
     195                int src_stride_u, 
     196                const uint8* src_v, 
     197                int src_stride_v, 
     198                uint8* dst_frame, 
     199                int dst_stride_frame, 
     200                int width, 
     201                int height); 
     202 
     203LIBYUV_API 
     204int H420ToRAW(const uint8* src_y, 
    181205              int src_stride_y, 
    182206              const uint8* src_u, 
  • pjproject/trunk/third_party/yuv/include/libyuv/cpu_id.h

    r5633 r5699  
    3737static const int kCpuHasERMS = 0x800; 
    3838static const int kCpuHasFMA3 = 0x1000; 
    39 static const int kCpuHasAVX3 = 0x2000; 
    40 static const int kCpuHasF16C = 0x4000; 
    41  
    42 // 0x8000 reserved for future X86 flags. 
     39static const int kCpuHasF16C = 0x2000; 
     40static const int kCpuHasGFNI = 0x4000; 
     41static const int kCpuHasAVX512BW = 0x8000; 
     42static const int kCpuHasAVX512VL = 0x10000; 
     43static const int kCpuHasAVX512VBMI = 0x20000; 
     44static const int kCpuHasAVX512VBMI2 = 0x40000; 
     45static const int kCpuHasAVX512VBITALG = 0x80000; 
     46static const int kCpuHasAVX512VPOPCNTDQ = 0x100000; 
    4347 
    4448// These flags are only valid on MIPS processors. 
    45 static const int kCpuHasMIPS = 0x10000; 
    46 static const int kCpuHasDSPR2 = 0x20000; 
    47 static const int kCpuHasMSA = 0x40000; 
     49static const int kCpuHasMIPS = 0x200000; 
     50static const int kCpuHasDSPR2 = 0x400000; 
     51static const int kCpuHasMSA = 0x800000; 
    4852 
    4953// Optional init function. TestCpuFlag does an auto-init. 
  • pjproject/trunk/third_party/yuv/include/libyuv/planar_functions.h

    r5633 r5699  
    6969                  int width, 
    7070                  int height); 
     71 
     72// Split interleaved RGB plane into separate R, G and B planes. 
     73LIBYUV_API 
     74void SplitRGBPlane(const uint8* src_rgb, 
     75                   int src_stride_rgb, 
     76                   uint8* dst_r, 
     77                   int dst_stride_r, 
     78                   uint8* dst_g, 
     79                   int dst_stride_g, 
     80                   uint8* dst_b, 
     81                   int dst_stride_b, 
     82                   int width, 
     83                   int height); 
     84 
     85// Merge separate R, G and B planes into one interleaved RGB plane. 
     86LIBYUV_API 
     87void MergeRGBPlane(const uint8* src_r, 
     88                   int src_stride_r, 
     89                   const uint8* src_g, 
     90                   int src_stride_g, 
     91                   const uint8* src_b, 
     92                   int src_stride_b, 
     93                   uint8* dst_rgb, 
     94                   int dst_stride_rgb, 
     95                   int width, 
     96                   int height); 
    7197 
    7298// Copy I400.  Supports inverting. 
     
    721747 
    722748#if defined(__pnacl__) || defined(__CLR_VER) || \ 
    723     (defined(__i386__) && !defined(__SSE2__)) 
     749    (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) 
    724750#define LIBYUV_DISABLE_X86 
    725751#endif 
  • pjproject/trunk/third_party/yuv/include/libyuv/rotate_row.h

    r5633 r5699  
    2020 
    2121#if defined(__pnacl__) || defined(__CLR_VER) || \ 
    22     (defined(__i386__) && !defined(__SSE2__)) 
     22    (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) 
    2323#define LIBYUV_DISABLE_X86 
    2424#endif 
     
    3030#endif 
    3131// The following are available for Visual C and clangcl 32 bit: 
    32 #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) 
     32#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) 
    3333#define HAS_TRANSPOSEWX8_SSSE3 
    3434#define HAS_TRANSPOSEUVWX8_SSE2 
  • pjproject/trunk/third_party/yuv/include/libyuv/row.h

    r5633 r5699  
    3232 
    3333#if defined(__pnacl__) || defined(__CLR_VER) || \ 
    34     (defined(__i386__) && !defined(__SSE2__)) 
     34    (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) 
    3535#define LIBYUV_DISABLE_X86 
    3636#endif 
     
    265265#endif 
    266266 
     267// The following are available for gcc/clang x86 platforms: 
     268// TODO(fbarchard): Port to Visual C 
     269#if !defined(LIBYUV_DISABLE_X86) && \ 
     270    (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) 
     271#define HAS_MERGERGBROW_SSSE3 
     272#define HAS_SPLITRGBROW_SSSE3 
     273#endif 
     274 
     275// The following are available for AVX2 gcc/clang x86 platforms: 
     276// TODO(fbarchard): Port to Visual C 
     277#if !defined(LIBYUV_DISABLE_X86) &&                                       \ 
     278    (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) && \ 
     279    (defined(CLANG_HAS_AVX2) || defined(GCC_HAS_AVX2)) 
     280#define HAS_MERGEUVROW_16_AVX2 
     281#define HAS_MULTIPLYROW_16_AVX2 
     282#endif 
     283 
    267284// The following are available on Neon platforms: 
    268285#if !defined(LIBYUV_DISABLE_NEON) && \ 
     
    324341#define HAS_RGBATOYROW_NEON 
    325342#define HAS_SETROW_NEON 
     343#define HAS_SPLITRGBROW_NEON 
    326344#define HAS_SPLITUVROW_NEON 
    327345#define HAS_UYVYTOARGBROW_NEON 
     
    353371#define HAS_SOBELXYROW_NEON 
    354372#define HAS_SOBELYROW_NEON 
     373#endif 
     374 
     375// The following are available on AArch64 platforms: 
     376#if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) 
     377#define HAS_SCALESUMSAMPLES_NEON 
    355378#endif 
    356379 
     
    386409 
    387410#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) 
     411#define HAS_ABGRTOUVROW_MSA 
     412#define HAS_ABGRTOYROW_MSA 
     413#define HAS_ARGB1555TOARGBROW_MSA 
     414#define HAS_ARGB1555TOUVROW_MSA 
     415#define HAS_ARGB1555TOYROW_MSA 
     416#define HAS_ARGB4444TOARGBROW_MSA 
     417#define HAS_ARGBADDROW_MSA 
     418#define HAS_ARGBATTENUATEROW_MSA 
     419#define HAS_ARGBBLENDROW_MSA 
     420#define HAS_ARGBCOLORMATRIXROW_MSA 
     421#define HAS_ARGBEXTRACTALPHAROW_MSA 
     422#define HAS_ARGBGRAYROW_MSA 
    388423#define HAS_ARGBMIRRORROW_MSA 
     424#define HAS_ARGBMULTIPLYROW_MSA 
     425#define HAS_ARGBQUANTIZEROW_MSA 
     426#define HAS_ARGBSEPIAROW_MSA 
     427#define HAS_ARGBSETROW_MSA 
     428#define HAS_ARGBSHADEROW_MSA 
     429#define HAS_ARGBSHUFFLEROW_MSA 
     430#define HAS_ARGBSUBTRACTROW_MSA 
     431#define HAS_ARGBTOARGB1555ROW_MSA 
     432#define HAS_ARGBTOARGB4444ROW_MSA 
     433#define HAS_ARGBTORAWROW_MSA 
     434#define HAS_ARGBTORGB24ROW_MSA 
     435#define HAS_ARGBTORGB565DITHERROW_MSA 
     436#define HAS_ARGBTORGB565ROW_MSA 
     437#define HAS_ARGBTOUV444ROW_MSA 
     438#define HAS_ARGBTOUVJROW_MSA 
     439#define HAS_ARGBTOUVROW_MSA 
     440#define HAS_ARGBTOYJROW_MSA 
     441#define HAS_ARGBTOYROW_MSA 
     442#define HAS_BGRATOUVROW_MSA 
     443#define HAS_BGRATOYROW_MSA 
     444#define HAS_HALFFLOATROW_MSA 
     445#define HAS_I400TOARGBROW_MSA 
     446#define HAS_I422ALPHATOARGBROW_MSA 
     447#define HAS_I422TOARGBROW_MSA 
     448#define HAS_I422TORGB24ROW_MSA 
     449#define HAS_I422TORGBAROW_MSA 
    389450#define HAS_I422TOUYVYROW_MSA 
    390451#define HAS_I422TOYUY2ROW_MSA 
     452#define HAS_I444TOARGBROW_MSA 
     453#define HAS_INTERPOLATEROW_MSA 
     454#define HAS_J400TOARGBROW_MSA 
     455#define HAS_MERGEUVROW_MSA 
    391456#define HAS_MIRRORROW_MSA 
     457#define HAS_MIRRORUVROW_MSA 
     458#define HAS_NV12TOARGBROW_MSA 
     459#define HAS_NV12TORGB565ROW_MSA 
     460#define HAS_NV21TOARGBROW_MSA 
     461#define HAS_RAWTOARGBROW_MSA 
     462#define HAS_RAWTORGB24ROW_MSA 
     463#define HAS_RAWTOUVROW_MSA 
     464#define HAS_RAWTOYROW_MSA 
     465#define HAS_RGB24TOARGBROW_MSA 
     466#define HAS_RGB24TOUVROW_MSA 
     467#define HAS_RGB24TOYROW_MSA 
     468#define HAS_RGB565TOARGBROW_MSA 
     469#define HAS_RGB565TOUVROW_MSA 
     470#define HAS_RGB565TOYROW_MSA 
     471#define HAS_RGBATOUVROW_MSA 
     472#define HAS_RGBATOYROW_MSA 
     473#define HAS_SETROW_MSA 
     474#define HAS_SOBELROW_MSA 
     475#define HAS_SOBELTOPLANEROW_MSA 
     476#define HAS_SOBELXROW_MSA 
     477#define HAS_SOBELXYROW_MSA 
     478#define HAS_SOBELYROW_MSA 
     479#define HAS_SPLITUVROW_MSA 
     480#define HAS_UYVYTOARGBROW_MSA 
    392481#define HAS_UYVYTOUVROW_MSA 
    393482#define HAS_UYVYTOYROW_MSA 
     483#define HAS_YUY2TOARGBROW_MSA 
    394484#define HAS_YUY2TOUV422ROW_MSA 
    395485#define HAS_YUY2TOUVROW_MSA 
    396486#define HAS_YUY2TOYROW_MSA 
    397 #define HAS_ARGB4444TOARGBROW_MSA 
    398 #define HAS_ARGBTOYROW_MSA 
    399 #define HAS_ARGBTOUVROW_MSA 
    400 #define HAS_I422TOARGBROW_MSA 
    401 #define HAS_I422TORGBAROW_MSA 
    402 #define HAS_I422ALPHATOARGBROW_MSA 
    403 #define HAS_I422TORGB24ROW_MSA 
    404 #define HAS_ARGBTORGB24ROW_MSA 
    405 #define HAS_ARGBTORAWROW_MSA 
    406 #define HAS_ARGBTORGB565ROW_MSA 
    407 #define HAS_ARGBTOARGB1555ROW_MSA 
    408 #define HAS_ARGBTOARGB4444ROW_MSA 
    409 #define HAS_ARGBTOUV444ROW_MSA 
    410 #define HAS_ARGBMULTIPLYROW_MSA 
    411 #define HAS_ARGBADDROW_MSA 
    412 #define HAS_ARGBSUBTRACTROW_MSA 
    413 #define HAS_ARGBATTENUATEROW_MSA 
    414 #define HAS_ARGBTORGB565DITHERROW_MSA 
    415 #define HAS_ARGBSHUFFLEROW_MSA 
    416 #define HAS_ARGBSHADEROW_MSA 
    417 #define HAS_ARGBGRAYROW_MSA 
    418 #define HAS_ARGBSEPIAROW_MSA 
    419 #define HAS_ARGB1555TOARGBROW_MSA 
    420 #define HAS_RGB565TOARGBROW_MSA 
    421 #define HAS_RGB24TOARGBROW_MSA 
    422 #define HAS_RAWTOARGBROW_MSA 
    423 #define HAS_ARGB1555TOYROW_MSA 
    424 #define HAS_RGB565TOYROW_MSA 
    425 #define HAS_RGB24TOYROW_MSA 
    426 #define HAS_RAWTOYROW_MSA 
    427 #define HAS_ARGB1555TOUVROW_MSA 
    428 #define HAS_RGB565TOUVROW_MSA 
    429 #define HAS_RGB24TOUVROW_MSA 
    430 #define HAS_RAWTOUVROW_MSA 
    431 #define HAS_NV12TOARGBROW_MSA 
    432 #define HAS_NV12TORGB565ROW_MSA 
    433 #define HAS_NV21TOARGBROW_MSA 
    434 #define HAS_SOBELROW_MSA 
    435 #define HAS_SOBELTOPLANEROW_MSA 
    436 #define HAS_SOBELXYROW_MSA 
    437 #define HAS_ARGBTOYJROW_MSA 
    438 #define HAS_BGRATOYROW_MSA 
    439 #define HAS_ABGRTOYROW_MSA 
    440 #define HAS_RGBATOYROW_MSA 
    441 #define HAS_ARGBTOUVJROW_MSA 
    442 #define HAS_BGRATOUVROW_MSA 
    443 #define HAS_ABGRTOUVROW_MSA 
    444 #define HAS_RGBATOUVROW_MSA 
    445 #define HAS_I444TOARGBROW_MSA 
    446 #define HAS_I400TOARGBROW_MSA 
    447 #define HAS_J400TOARGBROW_MSA 
    448 #define HAS_YUY2TOARGBROW_MSA 
    449 #define HAS_UYVYTOARGBROW_MSA 
    450 #define HAS_INTERPOLATEROW_MSA 
    451 #define HAS_ARGBSETROW_MSA 
    452 #define HAS_RAWTORGB24ROW_MSA 
    453 #define HAS_MERGEUVROW_MSA 
    454487#endif 
    455488 
     
    13461379                       uint8* dst_v, 
    13471380                       int width); 
     1381void MirrorUVRow_MSA(const uint8* src_uv, 
     1382                     uint8* dst_u, 
     1383                     uint8* dst_v, 
     1384                     int width); 
    13481385void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width); 
    13491386 
     
    13751412                      uint8* dst_v, 
    13761413                      int width); 
     1414void SplitUVRow_MSA(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width); 
    13771415void SplitUVRow_Any_SSE2(const uint8* src_uv, 
    13781416                         uint8* dst_u, 
     
    13911429                          uint8* dst_v, 
    13921430                          int width); 
     1431void SplitUVRow_Any_MSA(const uint8* src_uv, 
     1432                        uint8* dst_u, 
     1433                        uint8* dst_v, 
     1434                        int width); 
    13931435 
    13941436void MergeUVRow_C(const uint8* src_u, 
     
    14291471                        int width); 
    14301472 
     1473void SplitRGBRow_C(const uint8* src_rgb, 
     1474                   uint8* dst_r, 
     1475                   uint8* dst_g, 
     1476                   uint8* dst_b, 
     1477                   int width); 
     1478void SplitRGBRow_SSSE3(const uint8* src_rgb, 
     1479                       uint8* dst_r, 
     1480                       uint8* dst_g, 
     1481                       uint8* dst_b, 
     1482                       int width); 
     1483void SplitRGBRow_NEON(const uint8* src_rgb, 
     1484                      uint8* dst_r, 
     1485                      uint8* dst_g, 
     1486                      uint8* dst_b, 
     1487                      int width); 
     1488void SplitRGBRow_Any_SSSE3(const uint8* src_rgb, 
     1489                           uint8* dst_r, 
     1490                           uint8* dst_g, 
     1491                           uint8* dst_b, 
     1492                           int width); 
     1493void SplitRGBRow_Any_NEON(const uint8* src_rgb, 
     1494                          uint8* dst_r, 
     1495                          uint8* dst_g, 
     1496                          uint8* dst_b, 
     1497                          int width); 
     1498 
     1499void MergeRGBRow_C(const uint8* src_r, 
     1500                   const uint8* src_g, 
     1501                   const uint8* src_b, 
     1502                   uint8* dst_rgb, 
     1503                   int width); 
     1504void MergeRGBRow_SSSE3(const uint8* src_r, 
     1505                       const uint8* src_g, 
     1506                       const uint8* src_b, 
     1507                       uint8* dst_rgb, 
     1508                       int width); 
     1509void MergeRGBRow_NEON(const uint8* src_r, 
     1510                      const uint8* src_g, 
     1511                      const uint8* src_b, 
     1512                      uint8* dst_rgb, 
     1513                      int width); 
     1514void MergeRGBRow_Any_SSSE3(const uint8* src_r, 
     1515                           const uint8* src_g, 
     1516                           const uint8* src_b, 
     1517                           uint8* dst_rgb, 
     1518                           int width); 
     1519void MergeRGBRow_Any_NEON(const uint8* src_r, 
     1520                          const uint8* src_g, 
     1521                          const uint8* src_b, 
     1522                          uint8* dst_rgb, 
     1523                          int width); 
     1524 
     1525void MergeUVRow_16_C(const uint16* src_u, 
     1526                     const uint16* src_v, 
     1527                     uint16* dst_uv, 
     1528                     int scale, /* 64 for 10 bit */ 
     1529                     int width); 
     1530void MergeUVRow_16_AVX2(const uint16* src_u, 
     1531                        const uint16* src_v, 
     1532                        uint16* dst_uv, 
     1533                        int scale, 
     1534                        int width); 
     1535 
     1536void MultiplyRow_16_AVX2(const uint16* src_y, 
     1537                         uint16* dst_y, 
     1538                         int scale, 
     1539                         int width); 
     1540void MultiplyRow_16_C(const uint16* src_y, uint16* dst_y, int scale, int width); 
     1541 
    14311542void CopyRow_SSE2(const uint8* src, uint8* dst, int count); 
    14321543void CopyRow_AVX(const uint8* src, uint8* dst, int count); 
     
    14551566void ARGBExtractAlphaRow_AVX2(const uint8* src_argb, uint8* dst_a, int width); 
    14561567void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width); 
     1568void ARGBExtractAlphaRow_MSA(const uint8* src_argb, uint8* dst_a, int width); 
    14571569void ARGBExtractAlphaRow_Any_SSE2(const uint8* src_argb, 
    14581570                                  uint8* dst_a, 
     
    14641576                                  uint8* dst_a, 
    14651577                                  int width); 
     1578void ARGBExtractAlphaRow_Any_MSA(const uint8* src_argb, 
     1579                                 uint8* dst_a, 
     1580                                 int width); 
    14661581 
    14671582void ARGBCopyYToAlphaRow_C(const uint8* src_y, uint8* dst_argb, int width); 
     
    14761591 
    14771592void SetRow_C(uint8* dst, uint8 v8, int count); 
     1593void SetRow_MSA(uint8* dst, uint8 v8, int count); 
    14781594void SetRow_X86(uint8* dst, uint8 v8, int count); 
    14791595void SetRow_ERMS(uint8* dst, uint8 v8, int count); 
     
    21232239                       uint8* dst_argb, 
    21242240                       int width); 
     2241void ARGBBlendRow_MSA(const uint8* src_argb, 
     2242                      const uint8* src_argb1, 
     2243                      uint8* dst_argb, 
     2244                      int width); 
    21252245void ARGBBlendRow_C(const uint8* src_argb, 
    21262246                    const uint8* src_argb1, 
     
    28362956                             const int8* matrix_argb, 
    28372957                             int width); 
     2958void ARGBColorMatrixRow_MSA(const uint8* src_argb, 
     2959                            uint8* dst_argb, 
     2960                            const int8* matrix_argb, 
     2961                            int width); 
    28382962 
    28392963void ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width); 
     
    28582982                          int interval_offset, 
    28592983                          int width); 
     2984void ARGBQuantizeRow_MSA(uint8* dst_argb, 
     2985                         int scale, 
     2986                         int interval_size, 
     2987                         int interval_offset, 
     2988                         int width); 
    28602989 
    28612990void ARGBShadeRow_C(const uint8* src_argb, 
     
    29913120                    uint8* dst_sobelx, 
    29923121                    int width); 
     3122void SobelXRow_MSA(const uint8* src_y0, 
     3123                   const uint8* src_y1, 
     3124                   const uint8* src_y2, 
     3125                   uint8* dst_sobelx, 
     3126                   int width); 
    29933127void SobelYRow_C(const uint8* src_y0, 
    29943128                 const uint8* src_y1, 
     
    30033137                    uint8* dst_sobely, 
    30043138                    int width); 
     3139void SobelYRow_MSA(const uint8* src_y0, 
     3140                   const uint8* src_y1, 
     3141                   uint8* dst_sobely, 
     3142                   int width); 
    30053143void SobelRow_C(const uint8* src_sobelx, 
    30063144                const uint8* src_sobely, 
     
    31333271                            float scale, 
    31343272                            int width); 
     3273void HalfFloatRow_MSA(const uint16* src, uint16* dst, float scale, int width); 
     3274void HalfFloatRow_Any_MSA(const uint16* src, 
     3275                          uint16* dst, 
     3276                          float scale, 
     3277                          int width); 
    31353278 
    31363279void ARGBLumaColorTableRow_C(const uint8* src_argb, 
     
    31453288                                 uint32 lumacoeff); 
    31463289 
     3290float ScaleMaxSamples_C(const float* src, float* dst, float scale, int width); 
     3291float ScaleMaxSamples_NEON(const float* src, 
     3292                           float* dst, 
     3293                           float scale, 
     3294                           int width); 
     3295float ScaleSumSamples_C(const float* src, float* dst, float scale, int width); 
     3296float ScaleSumSamples_NEON(const float* src, 
     3297                           float* dst, 
     3298                           float scale, 
     3299                           int width); 
     3300void ScaleSamples_C(const float* src, float* dst, float scale, int width); 
     3301void ScaleSamples_NEON(const float* src, float* dst, float scale, int width); 
     3302 
    31473303#ifdef __cplusplus 
    31483304}  // extern "C" 
  • pjproject/trunk/third_party/yuv/include/libyuv/scale_row.h

    r5633 r5699  
    2121 
    2222#if defined(__pnacl__) || defined(__CLR_VER) || \ 
    23     (defined(__i386__) && !defined(__SSE2__)) 
     23    (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) 
    2424#define LIBYUV_DISABLE_X86 
    2525#endif 
     
    106106 
    107107#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) 
     108#define HAS_SCALEADDROW_MSA 
     109#define HAS_SCALEARGBCOLS_MSA 
     110#define HAS_SCALEARGBFILTERCOLS_MSA 
    108111#define HAS_SCALEARGBROWDOWN2_MSA 
    109112#define HAS_SCALEARGBROWDOWNEVEN_MSA 
     113#define HAS_SCALEFILTERCOLS_MSA 
    110114#define HAS_SCALEROWDOWN2_MSA 
     115#define HAS_SCALEROWDOWN34_MSA 
     116#define HAS_SCALEROWDOWN38_MSA 
    111117#define HAS_SCALEROWDOWN4_MSA 
    112 #define HAS_SCALEROWDOWN38_MSA 
    113 #define HAS_SCALEADDROW_MSA 
    114118#endif 
    115119 
     
    547551                            int x, 
    548552                            int dx); 
     553void ScaleARGBFilterCols_MSA(uint8* dst_argb, 
     554                             const uint8* src_argb, 
     555                             int dst_width, 
     556                             int x, 
     557                             int dx); 
     558void ScaleARGBCols_MSA(uint8* dst_argb, 
     559                       const uint8* src_argb, 
     560                       int dst_width, 
     561                       int x, 
     562                       int dx); 
     563void ScaleARGBFilterCols_Any_MSA(uint8* dst_argb, 
     564                                 const uint8* src_argb, 
     565                                 int dst_width, 
     566                                 int x, 
     567                                 int dx); 
     568void ScaleARGBCols_Any_MSA(uint8* dst_argb, 
     569                           const uint8* src_argb, 
     570                           int dst_width, 
     571                           int x, 
     572                           int dx); 
    549573 
    550574// ARGB Row functions 
     
    886910                              int dst_width); 
    887911void ScaleAddRow_MSA(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); 
     912void ScaleFilterCols_MSA(uint8* dst_ptr, 
     913                         const uint8* src_ptr, 
     914                         int dst_width, 
     915                         int x, 
     916                         int dx); 
     917void ScaleRowDown34_MSA(const uint8* src_ptr, 
     918                        ptrdiff_t src_stride, 
     919                        uint8* dst_ptr, 
     920                        int dst_width); 
     921void ScaleRowDown34_0_Box_MSA(const uint8* src_ptr, 
     922                              ptrdiff_t src_stride, 
     923                              uint8* dst_ptr, 
     924                              int dst_width); 
     925void ScaleRowDown34_1_Box_MSA(const uint8* src_ptr, 
     926                              ptrdiff_t src_stride, 
     927                              uint8* dst_ptr, 
     928                              int dst_width); 
     929 
    888930void ScaleRowDown2_Any_MSA(const uint8_t* src_ptr, 
    889931                           ptrdiff_t src_stride, 
     
    921963                         uint16_t* dst_ptr, 
    922964                         int src_width); 
     965void ScaleFilterCols_Any_MSA(uint8* dst_ptr, 
     966                             const uint8* src_ptr, 
     967                             int dst_width, 
     968                             int x, 
     969                             int dx); 
     970void ScaleRowDown34_Any_MSA(const uint8* src_ptr, 
     971                            ptrdiff_t src_stride, 
     972                            uint8* dst_ptr, 
     973                            int dst_width); 
     974void ScaleRowDown34_0_Box_Any_MSA(const uint8* src_ptr, 
     975                                  ptrdiff_t src_stride, 
     976                                  uint8* dst_ptr, 
     977                                  int dst_width); 
     978void ScaleRowDown34_1_Box_Any_MSA(const uint8* src_ptr, 
     979                                  ptrdiff_t src_stride, 
     980                                  uint8* dst_ptr, 
     981                                  int dst_width); 
    923982 
    924983#ifdef __cplusplus 
  • pjproject/trunk/third_party/yuv/include/libyuv/version.h

    r5633 r5699  
    1212#define INCLUDE_LIBYUV_VERSION_H_ 
    1313 
    14 #define LIBYUV_VERSION 1662 
     14#define LIBYUV_VERSION 1678 
    1515 
    1616#endif  // INCLUDE_LIBYUV_VERSION_H_ 
  • pjproject/trunk/third_party/yuv/source/compare.cc

    r5633 r5699  
    111111} 
    112112 
     113// NEON version accumulates in 16 bit shorts which overflow at 65536 bytes. 
     114// So actual maximum is 1 less loop, which is 64436 - 32 bytes. 
     115 
    113116LIBYUV_API 
    114117uint64 ComputeHammingDistance(const uint8* src_a, 
    115118                              const uint8* src_b, 
    116119                              int count) { 
    117   const int kBlockSize = 65536; 
    118   int remainder = count & (kBlockSize - 1) & ~31; 
     120  const int kBlockSize = 1 << 15;  // 32768; 
     121  const int kSimdSize = 64; 
     122  // SIMD for multiple of 64, and C for remainder 
     123  int remainder = count & (kBlockSize - 1) & ~(kSimdSize - 1); 
    119124  uint64 diff = 0; 
    120125  int i; 
     
    126131  } 
    127132#endif 
    128 #if defined(HAS_HAMMINGDISTANCE_X86) 
    129   if (TestCpuFlag(kCpuHasX86)) { 
    130     HammingDistance = HammingDistance_X86; 
     133#if defined(HAS_HAMMINGDISTANCE_SSSE3) 
     134  if (TestCpuFlag(kCpuHasSSSE3)) { 
     135    HammingDistance = HammingDistance_SSSE3; 
     136  } 
     137#endif 
     138#if defined(HAS_HAMMINGDISTANCE_SSE42) 
     139  if (TestCpuFlag(kCpuHasSSE42)) { 
     140    HammingDistance = HammingDistance_SSE42; 
    131141  } 
    132142#endif 
     
    136146  } 
    137147#endif 
     148#if defined(HAS_HAMMINGDISTANCE_MSA) 
     149  if (TestCpuFlag(kCpuHasMSA)) { 
     150    HammingDistance = HammingDistance_MSA; 
     151  } 
     152#endif 
    138153#ifdef _OPENMP 
    139154#pragma omp parallel for reduction(+ : diff) 
     
    149164    src_b += remainder; 
    150165  } 
    151   remainder = count & 31; 
     166  remainder = count & (kSimdSize - 1); 
    152167  if (remainder) { 
    153168    diff += HammingDistance_C(src_a, src_b, remainder); 
     
    185200    // Note only used for multiples of 32 so count is not checked. 
    186201    SumSquareError = SumSquareError_AVX2; 
     202  } 
     203#endif 
     204#if defined(HAS_SUMSQUAREERROR_MSA) 
     205  if (TestCpuFlag(kCpuHasMSA)) { 
     206    SumSquareError = SumSquareError_MSA; 
    187207  } 
    188208#endif 
  • pjproject/trunk/third_party/yuv/source/compare_common.cc

    r5633 r5699  
    1919 
    2020#if ORIGINAL_OPT 
    21 uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) { 
     21uint32 HammingDistance_C1(const uint8* src_a, const uint8* src_b, int count) { 
    2222  uint32 diff = 0u; 
    2323 
     
    5959    src_b += 4; 
    6060  } 
     61 
     62  for (; i < count; ++i) { 
     63    uint32 x = *src_a ^ *src_b; 
     64    uint32 u = x - ((x >> 1) & 0x55); 
     65    u = ((u >> 2) & 0x33) + (u & 0x33); 
     66    diff += (u + (u >> 4)) & 0x0f; 
     67    src_a += 1; 
     68    src_b += 1; 
     69  } 
     70 
    6171  return diff; 
    6272} 
  • pjproject/trunk/third_party/yuv/source/compare_gcc.cc

    r5633 r5699  
    2323    (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) 
    2424 
    25 uint32 HammingDistance_X86(const uint8* src_a, const uint8* src_b, int count) { 
     25#if defined(__x86_64__) 
     26uint32 HammingDistance_SSE42(const uint8* src_a, 
     27                             const uint8* src_b, 
     28                             int count) { 
     29  uint64 diff = 0u; 
     30 
     31  asm volatile( 
     32      "xor        %3,%3                          \n" 
     33      "xor        %%r8,%%r8                      \n" 
     34      "xor        %%r9,%%r9                      \n" 
     35      "xor        %%r10,%%r10                    \n" 
     36 
     37      // Process 32 bytes per loop. 
     38      LABELALIGN 
     39      "1:                                        \n" 
     40      "mov        (%0),%%rcx                     \n" 
     41      "mov        0x8(%0),%%rdx                  \n" 
     42      "xor        (%1),%%rcx                     \n" 
     43      "xor        0x8(%1),%%rdx                  \n" 
     44      "popcnt     %%rcx,%%rcx                    \n" 
     45      "popcnt     %%rdx,%%rdx                    \n" 
     46      "mov        0x10(%0),%%rsi                 \n" 
     47      "mov        0x18(%0),%%rdi                 \n" 
     48      "xor        0x10(%1),%%rsi                 \n" 
     49      "xor        0x18(%1),%%rdi                 \n" 
     50      "popcnt     %%rsi,%%rsi                    \n" 
     51      "popcnt     %%rdi,%%rdi                    \n" 
     52      "add        $0x20,%0                       \n" 
     53      "add        $0x20,%1                       \n" 
     54      "add        %%rcx,%3                       \n" 
     55      "add        %%rdx,%%r8                     \n" 
     56      "add        %%rsi,%%r9                     \n" 
     57      "add        %%rdi,%%r10                    \n" 
     58      "sub        $0x20,%2                       \n" 
     59      "jg         1b                             \n" 
     60 
     61      "add        %%r8, %3                       \n" 
     62      "add        %%r9, %3                       \n" 
     63      "add        %%r10, %3                      \n" 
     64      : "+r"(src_a),  // %0 
     65        "+r"(src_b),  // %1 
     66        "+r"(count),  // %2 
     67        "=r"(diff)    // %3 
     68      : 
     69      : "memory", "cc", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10"); 
     70 
     71  return static_cast<uint32>(diff); 
     72} 
     73#else 
     74uint32 HammingDistance_SSE42(const uint8* src_a, 
     75                             const uint8* src_b, 
     76                             int count) { 
    2677  uint32 diff = 0u; 
    2778 
    28   int i; 
    29   for (i = 0; i < count - 7; i += 8) { 
    30     uint64 x = *((uint64*)src_a) ^ *((uint64*)src_b); 
    31     src_a += 8; 
    32     src_b += 8; 
    33     diff += __builtin_popcountll(x); 
    34   } 
     79  asm volatile( 
     80      // Process 16 bytes per loop. 
     81      LABELALIGN 
     82      "1:                                        \n" 
     83      "mov        (%0),%%ecx                     \n" 
     84      "mov        0x4(%0),%%edx                  \n" 
     85      "xor        (%1),%%ecx                     \n" 
     86      "xor        0x4(%1),%%edx                  \n" 
     87      "popcnt     %%ecx,%%ecx                    \n" 
     88      "add        %%ecx,%3                       \n" 
     89      "popcnt     %%edx,%%edx                    \n" 
     90      "add        %%edx,%3                       \n" 
     91      "mov        0x8(%0),%%ecx                  \n" 
     92      "mov        0xc(%0),%%edx                  \n" 
     93      "xor        0x8(%1),%%ecx                  \n" 
     94      "xor        0xc(%1),%%edx                  \n" 
     95      "popcnt     %%ecx,%%ecx                    \n" 
     96      "add        %%ecx,%3                       \n" 
     97      "popcnt     %%edx,%%edx                    \n" 
     98      "add        %%edx,%3                       \n" 
     99      "add        $0x10,%0                       \n" 
     100      "add        $0x10,%1                       \n" 
     101      "sub        $0x10,%2                       \n" 
     102      "jg         1b                             \n" 
     103      : "+r"(src_a),  // %0 
     104        "+r"(src_b),  // %1 
     105        "+r"(count),  // %2 
     106        "+r"(diff)    // %3 
     107      : 
     108      : "memory", "cc", "ecx", "edx"); 
     109 
    35110  return diff; 
    36111} 
     112#endif 
     113 
     114static vec8 kNibbleMask = {15, 15, 15, 15, 15, 15, 15, 15, 
     115                           15, 15, 15, 15, 15, 15, 15, 15}; 
     116static vec8 kBitCount = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; 
     117 
     118uint32 HammingDistance_SSSE3(const uint8* src_a, 
     119                             const uint8* src_b, 
     120                             int count) { 
     121  uint32 diff = 0u; 
     122 
     123  asm volatile( 
     124      "movdqa     %4,%%xmm2                      \n" 
     125      "movdqa     %5,%%xmm3                      \n" 
     126      "pxor       %%xmm0,%%xmm0                  \n" 
     127      "pxor       %%xmm1,%%xmm1                  \n" 
     128      "sub        %0,%1                          \n" 
     129 
     130      LABELALIGN 
     131      "1:                                        \n" 
     132      "movdqa     (%0),%%xmm4                    \n" 
     133      "movdqa     0x10(%0), %%xmm5               \n" 
     134      "pxor       (%0,%1), %%xmm4                \n" 
     135      "movdqa     %%xmm4,%%xmm6                  \n" 
     136      "pand       %%xmm2,%%xmm6                  \n" 
     137      "psrlw      $0x4,%%xmm4                    \n" 
     138      "movdqa     %%xmm3,%%xmm7                  \n" 
     139      "pshufb     %%xmm6,%%xmm7                  \n" 
     140      "pand       %%xmm2,%%xmm4                  \n" 
     141      "movdqa     %%xmm3,%%xmm6                  \n" 
     142      "pshufb     %%xmm4,%%xmm6                  \n" 
     143      "paddb      %%xmm7,%%xmm6                  \n" 
     144      "pxor       0x10(%0,%1),%%xmm5             \n" 
     145      "add        $0x20,%0                       \n" 
     146      "movdqa     %%xmm5,%%xmm4                  \n" 
     147      "pand       %%xmm2,%%xmm5                  \n" 
     148      "psrlw      $0x4,%%xmm4                    \n" 
     149      "movdqa     %%xmm3,%%xmm7                  \n" 
     150      "pshufb     %%xmm5,%%xmm7                  \n" 
     151      "pand       %%xmm2,%%xmm4                  \n" 
     152      "movdqa     %%xmm3,%%xmm5                  \n" 
     153      "pshufb     %%xmm4,%%xmm5                  \n" 
     154      "paddb      %%xmm7,%%xmm5                  \n" 
     155      "paddb      %%xmm5,%%xmm6                  \n" 
     156      "psadbw     %%xmm1,%%xmm6                  \n" 
     157      "paddd      %%xmm6,%%xmm0                  \n" 
     158      "sub        $0x20,%2                       \n" 
     159      "jg         1b                             \n" 
     160 
     161      "pshufd     $0xaa,%%xmm0,%%xmm1            \n" 
     162      "paddd      %%xmm1,%%xmm0                  \n" 
     163      "movd       %%xmm0, %3                     \n" 
     164      : "+r"(src_a),       // %0 
     165        "+r"(src_b),       // %1 
     166        "+r"(count),       // %2 
     167        "=r"(diff)         // %3 
     168      : "m"(kNibbleMask),  // %4 
     169        "m"(kBitCount)     // %5 
     170      : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", 
     171        "xmm7"); 
     172 
     173  return diff; 
     174} 
     175 
     176#ifdef HAS_HAMMINGDISTANCE_AVX2 
     177uint32 HammingDistance_AVX2(const uint8* src_a, const uint8* src_b, int count) { 
     178  uint32 diff = 0u; 
     179 
     180  asm volatile( 
     181      "vbroadcastf128 %4,%%ymm2                  \n" 
     182      "vbroadcastf128 %5,%%ymm3                  \n" 
     183      "vpxor      %%ymm0,%%ymm0,%%ymm0           \n" 
     184      "vpxor      %%ymm1,%%ymm1,%%ymm1           \n" 
     185      "sub        %0,%1                          \n" 
     186 
     187      LABELALIGN 
     188      "1:                                        \n" 
     189      "vmovdqa    (%0),%%ymm4                    \n" 
     190      "vmovdqa    0x20(%0), %%ymm5               \n" 
     191      "vpxor      (%0,%1), %%ymm4, %%ymm4        \n" 
     192      "vpand      %%ymm2,%%ymm4,%%ymm6           \n" 
     193      "vpsrlw     $0x4,%%ymm4,%%ymm4             \n" 
     194      "vpshufb    %%ymm6,%%ymm3,%%ymm6           \n" 
     195      "vpand      %%ymm2,%%ymm4,%%ymm4           \n" 
     196      "vpshufb    %%ymm4,%%ymm3,%%ymm4           \n" 
     197      "vpaddb     %%ymm4,%%ymm6,%%ymm6           \n" 
     198      "vpxor      0x20(%0,%1),%%ymm5,%%ymm4      \n" 
     199      "add        $0x40,%0                       \n" 
     200      "vpand      %%ymm2,%%ymm4,%%ymm5           \n" 
     201      "vpsrlw     $0x4,%%ymm4,%%ymm4             \n" 
     202      "vpshufb    %%ymm5,%%ymm3,%%ymm5           \n" 
     203      "vpand      %%ymm2,%%ymm4,%%ymm4           \n" 
     204      "vpshufb    %%ymm4,%%ymm3,%%ymm4           \n" 
     205      "vpaddb     %%ymm5,%%ymm4,%%ymm4           \n" 
     206      "vpaddb     %%ymm6,%%ymm4,%%ymm4           \n" 
     207      "vpsadbw    %%ymm1,%%ymm4,%%ymm4           \n" 
     208      "vpaddd     %%ymm0,%%ymm4,%%ymm0           \n" 
     209      "sub        $0x40,%2                       \n" 
     210      "jg         1b                             \n" 
     211 
     212      "vpermq     $0xb1,%%ymm0,%%ymm1            \n" 
     213      "vpaddd     %%ymm1,%%ymm0,%%ymm0           \n" 
     214      "vpermq     $0xaa,%%ymm0,%%ymm1            \n" 
     215      "vpaddd     %%ymm1,%%ymm0,%%ymm0           \n" 
     216      "vmovd      %%xmm0, %3                     \n" 
     217      "vzeroupper                                \n" 
     218      : "+r"(src_a),       // %0 
     219        "+r"(src_b),       // %1 
     220        "+r"(count),       // %2 
     221        "=r"(diff)         // %3 
     222      : "m"(kNibbleMask),  // %4 
     223        "m"(kBitCount)     // %5 
     224      : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); 
     225 
     226  return diff; 
     227} 
     228#endif  // HAS_HAMMINGDISTANCE_AVX2 
    37229 
    38230uint32 SumSquareError_SSE2(const uint8* src_a, const uint8* src_b, int count) { 
  • pjproject/trunk/third_party/yuv/source/compare_neon.cc

    r5633 r5699  
    2727  uint32 diff; 
    2828 
    29   asm volatile ( 
    30     "vmov.u16   q4, #0                         \n"  // accumulator 
     29  asm volatile( 
     30      "vmov.u16   q4, #0                         \n"  // accumulator 
    3131 
    32   "1:                                          \n" 
    33     "vld1.8     {q0, q1}, [%0]!                \n" 
    34     "vld1.8     {q2, q3}, [%1]!                \n" 
    35     "veor.32    q0, q0, q2                     \n" 
    36     "veor.32    q1, q1, q3                     \n" 
    37     "vcnt.i8    q0, q0                         \n" 
    38     "vcnt.i8    q1, q1                         \n" 
    39     "subs       %2, %2, #32                    \n" 
    40     "vadd.u8    q0, q0, q1                     \n"  // 16 byte counts 
    41     "vpadal.u8  q4, q0                         \n"  // 8 shorts 
    42     "bgt        1b                             \n" 
     32      "1:                                        \n" 
     33      "vld1.8     {q0, q1}, [%0]!                \n" 
     34      "vld1.8     {q2, q3}, [%1]!                \n" 
     35      "veor.32    q0, q0, q2                     \n" 
     36      "veor.32    q1, q1, q3                     \n" 
     37      "vcnt.i8    q0, q0                         \n" 
     38      "vcnt.i8    q1, q1                         \n" 
     39      "subs       %2, %2, #32                    \n" 
     40      "vadd.u8    q0, q0, q1                     \n"  // 16 byte counts 
     41      "vpadal.u8  q4, q0                         \n"  // 8 shorts 
     42      "bgt        1b                             \n" 
    4343 
    44     "vpaddl.u16 q0, q4                         \n"  // 4 ints 
    45     "vpadd.u32  d0, d0, d1                     \n" 
    46     "vpadd.u32  d0, d0, d0                     \n" 
    47     "vmov.32    %3, d0[0]                      \n" 
    48   
    49     : "+r"(src_a), 
    50       "+r"(src_b), 
    51       "+r"(count), 
    52       "=r"(diff) 
    53     : 
    54     :  "cc", "q0", "q1", "q2", "q3", "q4"); 
     44      "vpaddl.u16 q0, q4                         \n"  // 4 ints 
     45      "vpadd.u32  d0, d0, d1                     \n" 
     46      "vpadd.u32  d0, d0, d0                     \n" 
     47      "vmov.32    %3, d0[0]                      \n" 
     48 
     49      : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(diff) 
     50      : 
     51      : "cc", "q0", "q1", "q2", "q3", "q4"); 
    5552  return diff; 
    5653} 
     
    5855uint32 SumSquareError_NEON(const uint8* src_a, const uint8* src_b, int count) { 
    5956  uint32 sse; 
    60   asm volatile ( 
    61     "vmov.u8    q8, #0                         \n" 
    62     "vmov.u8    q10, #0                        \n" 
    63     "vmov.u8    q9, #0                         \n" 
    64     "vmov.u8    q11, #0                        \n" 
     57  asm volatile( 
     58      "vmov.u8    q8, #0                         \n" 
     59      "vmov.u8    q10, #0                        \n" 
     60      "vmov.u8    q9, #0                         \n" 
     61      "vmov.u8    q11, #0                        \n" 
    6562 
    66   "1:                                          \n" 
    67     "vld1.8     {q0}, [%0]!                    \n" 
    68     "vld1.8     {q1}, [%1]!                    \n" 
    69     "subs       %2, %2, #16                    \n" 
    70     "vsubl.u8   q2, d0, d2                     \n" 
    71     "vsubl.u8   q3, d1, d3                     \n" 
    72     "vmlal.s16  q8, d4, d4                     \n" 
    73     "vmlal.s16  q9, d6, d6                     \n" 
    74     "vmlal.s16  q10, d5, d5                    \n" 
    75     "vmlal.s16  q11, d7, d7                    \n" 
    76     "bgt        1b                             \n" 
     63      "1:                                        \n" 
     64      "vld1.8     {q0}, [%0]!                    \n" 
     65      "vld1.8     {q1}, [%1]!                    \n" 
     66      "subs       %2, %2, #16                    \n" 
     67      "vsubl.u8   q2, d0, d2                     \n" 
     68      "vsubl.u8   q3, d1, d3                     \n" 
     69      "vmlal.s16  q8, d4, d4                     \n" 
     70      "vmlal.s16  q9, d6, d6                     \n" 
     71      "vmlal.s16  q10, d5, d5                    \n" 
     72      "vmlal.s16  q11, d7, d7                    \n" 
     73      "bgt        1b                             \n" 
    7774 
    78     "vadd.u32   q8, q8, q9                     \n" 
    79     "vadd.u32   q10, q10, q11                  \n" 
    80     "vadd.u32   q11, q8, q10                   \n" 
    81     "vpaddl.u32 q1, q11                        \n" 
    82     "vadd.u64   d0, d2, d3                     \n" 
    83     "vmov.32    %3, d0[0]                      \n" 
    84     : "+r"(src_a), 
    85       "+r"(src_b), 
    86       "+r"(count), 
    87       "=r"(sse) 
    88     : 
    89     : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"); 
     75      "vadd.u32   q8, q8, q9                     \n" 
     76      "vadd.u32   q10, q10, q11                  \n" 
     77      "vadd.u32   q11, q8, q10                   \n" 
     78      "vpaddl.u32 q1, q11                        \n" 
     79      "vadd.u64   d0, d2, d3                     \n" 
     80      "vmov.32    %3, d0[0]                      \n" 
     81      : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(sse) 
     82      : 
     83      : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"); 
    9084  return sse; 
    9185} 
  • pjproject/trunk/third_party/yuv/source/compare_neon64.cc

    r5633 r5699  
    2525uint32 HammingDistance_NEON(const uint8* src_a, const uint8* src_b, int count) { 
    2626  uint32 diff; 
    27   asm volatile ( 
    28     "movi       v4.8h, #0                      \n" 
     27  asm volatile( 
     28      "movi       v4.8h, #0                      \n" 
    2929 
    30   "1:                                          \n" 
    31     "ld1        {v0.16b, v1.16b}, [%0], #32    \n" 
    32     "ld1        {v2.16b, v3.16b}, [%1], #32    \n" 
    33     "eor        v0.16b, v0.16b, v2.16b         \n" 
    34     "eor        v1.16b, v1.16b, v3.16b         \n"  
    35     "cnt        v0.16b, v0.16b                 \n" 
    36     "cnt        v1.16b, v1.16b                 \n" 
    37     "subs       %w2, %w2, #32                  \n" 
    38     "add        v0.16b, v0.16b, v1.16b         \n" 
    39     "uadalp     v4.8h, v0.16b                  \n" 
    40     "b.gt       1b                             \n" 
     30      "1:                                        \n" 
     31      "ld1        {v0.16b, v1.16b}, [%0], #32    \n" 
     32      "ld1        {v2.16b, v3.16b}, [%1], #32    \n" 
     33      "eor        v0.16b, v0.16b, v2.16b         \n" 
     34      "eor        v1.16b, v1.16b, v3.16b         \n" 
     35      "cnt        v0.16b, v0.16b                 \n" 
     36      "cnt        v1.16b, v1.16b                 \n" 
     37      "subs       %w2, %w2, #32                  \n" 
     38      "add        v0.16b, v0.16b, v1.16b         \n" 
     39      "uadalp     v4.8h, v0.16b                  \n" 
     40      "b.gt       1b                             \n" 
    4141 
    42     "uaddlv     s4, v4.8h                      \n" 
    43     "fmov       %w3, s4                        \n" 
    44     : "+r"(src_a), 
    45       "+r"(src_b), 
    46       "+r"(count), 
    47       "=r"(diff) 
    48     : 
    49     : "cc", "v0", "v1", "v2", "v3", "v4"); 
     42      "uaddlv     s4, v4.8h                      \n" 
     43      "fmov       %w3, s4                        \n" 
     44      : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(diff) 
     45      : 
     46      : "cc", "v0", "v1", "v2", "v3", "v4"); 
    5047  return diff; 
    5148} 
     
    5350uint32 SumSquareError_NEON(const uint8* src_a, const uint8* src_b, int count) { 
    5451  uint32 sse; 
    55   asm volatile ( 
    56     "eor        v16.16b, v16.16b, v16.16b      \n" 
    57     "eor        v18.16b, v18.16b, v18.16b      \n" 
    58     "eor        v17.16b, v17.16b, v17.16b      \n" 
    59     "eor        v19.16b, v19.16b, v19.16b      \n" 
     52  asm volatile( 
     53      "eor        v16.16b, v16.16b, v16.16b      \n" 
     54      "eor        v18.16b, v18.16b, v18.16b      \n" 
     55      "eor        v17.16b, v17.16b, v17.16b      \n" 
     56      "eor        v19.16b, v19.16b, v19.16b      \n" 
    6057 
    61   "1:                                          \n" 
    62     "ld1        {v0.16b}, [%0], #16            \n" 
    63     "ld1        {v1.16b}, [%1], #16            \n" 
    64     "subs       %w2, %w2, #16                  \n" 
    65     "usubl      v2.8h, v0.8b, v1.8b            \n" 
    66     "usubl2     v3.8h, v0.16b, v1.16b          \n" 
    67     "smlal      v16.4s, v2.4h, v2.4h           \n" 
    68     "smlal      v17.4s, v3.4h, v3.4h           \n" 
    69     "smlal2     v18.4s, v2.8h, v2.8h           \n" 
    70     "smlal2     v19.4s, v3.8h, v3.8h           \n" 
    71     "b.gt       1b                             \n" 
     58      "1:                                        \n" 
     59      "ld1        {v0.16b}, [%0], #16            \n" 
     60      "ld1        {v1.16b}, [%1], #16            \n" 
     61      "subs       %w2, %w2, #16                  \n" 
     62      "usubl      v2.8h, v0.8b, v1.8b            \n" 
     63      "usubl2     v3.8h, v0.16b, v1.16b          \n" 
     64      "smlal      v16.4s, v2.4h, v2.4h           \n" 
     65      "smlal      v17.4s, v3.4h, v3.4h           \n" 
     66      "smlal2     v18.4s, v2.8h, v2.8h           \n" 
     67      "smlal2     v19.4s, v3.8h, v3.8h           \n" 
     68      "b.gt       1b                             \n" 
    7269 
    73     "add        v16.4s, v16.4s, v17.4s         \n" 
    74     "add        v18.4s, v18.4s, v19.4s         \n" 
    75     "add        v19.4s, v16.4s, v18.4s         \n" 
    76     "addv       s0, v19.4s                     \n" 
    77     "fmov       %w3, s0                        \n" 
    78     : "+r"(src_a), 
    79       "+r"(src_b), 
    80       "+r"(count), 
    81       "=r"(sse) 
    82     : 
    83     : "cc", "v0", "v1", "v2", "v3", "v16", "v17", "v18", "v19"); 
     70      "add        v16.4s, v16.4s, v17.4s         \n" 
     71      "add        v18.4s, v18.4s, v19.4s         \n" 
     72      "add        v19.4s, v16.4s, v18.4s         \n" 
     73      "addv       s0, v19.4s                     \n" 
     74      "fmov       %w3, s0                        \n" 
     75      : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(sse) 
     76      : 
     77      : "cc", "v0", "v1", "v2", "v3", "v16", "v17", "v18", "v19"); 
    8478  return sse; 
    8579} 
  • pjproject/trunk/third_party/yuv/source/compare_win.cc

    r5358 r5699  
    1010 
    1111#include "libyuv/basic_types.h" 
     12 
     13#include "libyuv/compare_row.h" 
    1214#include "libyuv/row.h" 
     15 
     16#if defined(_MSC_VER) 
     17#include <intrin.h>  // For __popcnt 
     18#endif 
    1319 
    1420#ifdef __cplusplus 
     
    1723#endif 
    1824 
     25// This module is for 32 bit Visual C x86 and clangcl 
    1926#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) 
    20 #if (_MSC_VER >= 1900) 
    21 __declspec(naked) 
    22 #else 
    23 __declspec(naked) __declspec(align(16)) 
    24 #endif 
    25 uint32 SumSquareError_SSE2(const uint8* src_a, const uint8* src_b, int count) { 
    26   __asm { 
    27     mov        eax, [esp + 4]    // src_a 
    28     mov        edx, [esp + 8]    // src_b 
    29     mov        ecx, [esp + 12]   // count 
     27 
     28uint32 HammingDistance_SSE42(const uint8* src_a, 
     29                             const uint8* src_b, 
     30                             int count) { 
     31  uint32 diff = 0u; 
     32 
     33  int i; 
     34  for (i = 0; i < count - 3; i += 4) { 
     35    uint32 x = *((uint32*)src_a) ^ *((uint32*)src_b); 
     36    src_a += 4; 
     37    src_b += 4; 
     38    diff += __popcnt(x); 
     39  } 
     40  return diff; 
     41} 
     42 
     43__declspec(naked) uint32 
     44    SumSquareError_SSE2(const uint8* src_a, const uint8* src_b, int count) { 
     45  __asm { 
     46    mov        eax, [esp + 4]  // src_a 
     47    mov        edx, [esp + 8]  // src_b 
     48    mov        ecx, [esp + 12]  // count 
    3049    pxor       xmm0, xmm0 
    3150    pxor       xmm5, xmm5 
    3251 
    33     align      4 
    34   wloop: 
    35     movdqa     xmm1, [eax] 
     52  wloop: 
     53    movdqu     xmm1, [eax] 
    3654    lea        eax,  [eax + 16] 
    37     movdqa     xmm2, [edx] 
     55    movdqu     xmm2, [edx] 
    3856    lea        edx,  [edx + 16] 
    39     sub        ecx, 16 
    4057    movdqa     xmm3, xmm1  // abs trick 
    4158    psubusb    xmm1, xmm2 
     
    4966    paddd      xmm0, xmm1 
    5067    paddd      xmm0, xmm2 
     68    sub        ecx, 16 
    5169    jg         wloop 
    5270 
     
    6381#if _MSC_VER >= 1700 
    6482// C4752: found Intel(R) Advanced Vector Extensions; consider using /arch:AVX. 
    65 #pragma warning(disable: 4752) 
    66 #if (_MSC_VER >= 1900) 
    67 __declspec(naked) 
    68 #else 
    69 __declspec(naked) __declspec(align(16)) 
    70 #endif 
    71 uint32 SumSquareError_AVX2(const uint8* src_a, const uint8* src_b, int count) { 
    72   __asm { 
    73     mov        eax, [esp + 4]    // src_a 
    74     mov        edx, [esp + 8]    // src_b 
    75     mov        ecx, [esp + 12]   // count 
     83#pragma warning(disable : 4752) 
     84__declspec(naked) uint32 
     85    SumSquareError_AVX2(const uint8* src_a, const uint8* src_b, int count) { 
     86  __asm { 
     87    mov        eax, [esp + 4]  // src_a 
     88    mov        edx, [esp + 8]  // src_b 
     89    mov        ecx, [esp + 12]  // count 
    7690    vpxor      ymm0, ymm0, ymm0  // sum 
    7791    vpxor      ymm5, ymm5, ymm5  // constant 0 for unpck 
    7892    sub        edx, eax 
    7993 
    80     align      4 
    8194  wloop: 
    8295    vmovdqu    ymm1, [eax] 
    8396    vmovdqu    ymm2, [eax + edx] 
    8497    lea        eax,  [eax + 32] 
    85     sub        ecx, 32 
    8698    vpsubusb   ymm3, ymm1, ymm2  // abs difference trick 
    8799    vpsubusb   ymm2, ymm2, ymm1 
     
    93105    vpaddd     ymm0, ymm0, ymm1 
    94106    vpaddd     ymm0, ymm0, ymm2 
     107    sub        ecx, 32 
    95108    jg         wloop 
    96109 
     
    108121#endif  // _MSC_VER >= 1700 
    109122 
    110 #define HAS_HASHDJB2_SSE41 
    111 static uvec32 kHash16x33 = { 0x92d9e201, 0, 0, 0 };  // 33 ^ 16 
    112 static uvec32 kHashMul0 = { 
    113   0x0c3525e1,  // 33 ^ 15 
    114   0xa3476dc1,  // 33 ^ 14 
    115   0x3b4039a1,  // 33 ^ 13 
    116   0x4f5f0981,  // 33 ^ 12 
    117 }; 
    118 static uvec32 kHashMul1 = { 
    119   0x30f35d61,  // 33 ^ 11 
    120   0x855cb541,  // 33 ^ 10 
    121   0x040a9121,  // 33 ^ 9 
    122   0x747c7101,  // 33 ^ 8 
    123 }; 
    124 static uvec32 kHashMul2 = { 
    125   0xec41d4e1,  // 33 ^ 7 
    126   0x4cfa3cc1,  // 33 ^ 6 
    127   0x025528a1,  // 33 ^ 5 
    128   0x00121881,  // 33 ^ 4 
    129 }; 
    130 static uvec32 kHashMul3 = { 
    131   0x00008c61,  // 33 ^ 3 
    132   0x00000441,  // 33 ^ 2 
    133   0x00000021,  // 33 ^ 1 
    134   0x00000001,  // 33 ^ 0 
    135 }; 
    136  
    137 // 27: 66 0F 38 40 C6     pmulld      xmm0,xmm6 
    138 // 44: 66 0F 38 40 DD     pmulld      xmm3,xmm5 
    139 // 59: 66 0F 38 40 E5     pmulld      xmm4,xmm5 
    140 // 72: 66 0F 38 40 D5     pmulld      xmm2,xmm5 
    141 // 83: 66 0F 38 40 CD     pmulld      xmm1,xmm5 
    142 #define pmulld(reg) _asm _emit 0x66 _asm _emit 0x0F _asm _emit 0x38 \ 
    143     _asm _emit 0x40 _asm _emit reg 
    144  
    145 #if (_MSC_VER >= 1900) 
    146 __declspec(naked) 
    147 #else 
    148 __declspec(naked) __declspec(align(16)) 
    149 #endif 
    150 uint32 HashDjb2_SSE41(const uint8* src, int count, uint32 seed) { 
    151   __asm { 
    152     mov        eax, [esp + 4]    // src 
    153     mov        ecx, [esp + 8]    // count 
     123uvec32 kHash16x33 = {0x92d9e201, 0, 0, 0};  // 33 ^ 16 
     124uvec32 kHashMul0 = { 
     125    0x0c3525e1,  // 33 ^ 15 
     126    0xa3476dc1,  // 33 ^ 14 
     127    0x3b4039a1,  // 33 ^ 13 
     128    0x4f5f0981,  // 33 ^ 12 
     129}; 
     130uvec32 kHashMul1 = { 
     131    0x30f35d61,  // 33 ^ 11 
     132    0x855cb541,  // 33 ^ 10 
     133    0x040a9121,  // 33 ^ 9 
     134    0x747c7101,  // 33 ^ 8 
     135}; 
     136uvec32 kHashMul2 = { 
     137    0xec41d4e1,  // 33 ^ 7 
     138    0x4cfa3cc1,  // 33 ^ 6 
     139    0x025528a1,  // 33 ^ 5 
     140    0x00121881,  // 33 ^ 4 
     141}; 
     142uvec32 kHashMul3 = { 
     143    0x00008c61,  // 33 ^ 3 
     144    0x00000441,  // 33 ^ 2 
     145    0x00000021,  // 33 ^ 1 
     146    0x00000001,  // 33 ^ 0 
     147}; 
     148 
     149__declspec(naked) uint32 
     150    HashDjb2_SSE41(const uint8* src, int count, uint32 seed) { 
     151  __asm { 
     152    mov        eax, [esp + 4]  // src 
     153    mov        ecx, [esp + 8]  // count 
    154154    movd       xmm0, [esp + 12]  // seed 
    155155 
    156     pxor       xmm7, xmm7        // constant 0 for unpck 
    157     movdqa     xmm6, kHash16x33 
    158  
    159     align      4 
    160   wloop: 
    161     movdqu     xmm1, [eax]       // src[0-15] 
     156    pxor       xmm7, xmm7  // constant 0 for unpck 
     157    movdqa     xmm6, xmmword ptr kHash16x33 
     158 
     159  wloop: 
     160    movdqu     xmm1, [eax]  // src[0-15] 
    162161    lea        eax, [eax + 16] 
    163     pmulld(0xc6)                 // pmulld      xmm0,xmm6 hash *= 33 ^ 16 
    164     movdqa     xmm5, kHashMul0 
     162    pmulld     xmm0, xmm6  // hash *= 33 ^ 16 
     163    movdqa     xmm5, xmmword ptr kHashMul0 
    165164    movdqa     xmm2, xmm1 
    166     punpcklbw  xmm2, xmm7        // src[0-7] 
     165    punpcklbw  xmm2, xmm7  // src[0-7] 
    167166    movdqa     xmm3, xmm2 
    168     punpcklwd  xmm3, xmm7        // src[0-3] 
    169     pmulld(0xdd)                 // pmulld     xmm3, xmm5 
    170     movdqa     xmm5, kHashMul1 
     167    punpcklwd  xmm3, xmm7  // src[0-3] 
     168    pmulld     xmm3, xmm5 
     169    movdqa     xmm5, xmmword ptr kHashMul1 
    171170    movdqa     xmm4, xmm2 
    172     punpckhwd  xmm4, xmm7        // src[4-7] 
    173     pmulld(0xe5)                 // pmulld     xmm4, xmm5 
    174     movdqa     xmm5, kHashMul2 
    175     punpckhbw  xmm1, xmm7        // src[8-15] 
     171    punpckhwd  xmm4, xmm7  // src[4-7] 
     172    pmulld     xmm4, xmm5 
     173    movdqa     xmm5, xmmword ptr kHashMul2 
     174    punpckhbw  xmm1, xmm7  // src[8-15] 
    176175    movdqa     xmm2, xmm1 
    177     punpcklwd  xmm2, xmm7        // src[8-11] 
    178     pmulld(0xd5)                 // pmulld     xmm2, xmm5 
    179     movdqa     xmm5, kHashMul3 
    180     punpckhwd  xmm1, xmm7        // src[12-15] 
    181     pmulld(0xcd)                 // pmulld     xmm1, xmm5 
    182     paddd      xmm3, xmm4        // add 16 results 
     176    punpcklwd  xmm2, xmm7  // src[8-11] 
     177    pmulld     xmm2, xmm5 
     178    movdqa     xmm5, xmmword ptr kHashMul3 
     179    punpckhwd  xmm1, xmm7  // src[12-15] 
     180    pmulld     xmm1, xmm5 
     181    paddd      xmm3, xmm4  // add 16 results 
    183182    paddd      xmm1, xmm2 
    184     sub        ecx, 16 
    185183    paddd      xmm1, xmm3 
    186184 
     
    190188    paddd      xmm1, xmm2 
    191189    paddd      xmm0, xmm1 
    192     jg         wloop 
    193  
    194     movd       eax, xmm0         // return hash 
     190    sub        ecx, 16 
     191    jg         wloop 
     192 
     193    movd       eax, xmm0  // return hash 
    195194    ret 
    196195  } 
     
    199198// Visual C 2012 required for AVX2. 
    200199#if _MSC_VER >= 1700 
    201 #if (_MSC_VER >= 1900) 
    202 __declspec(naked) 
    203 #else 
    204 __declspec(naked) __declspec(align(16)) 
    205 #endif 
    206 uint32 HashDjb2_AVX2(const uint8* src, int count, uint32 seed) { 
    207   __asm { 
    208     mov        eax, [esp + 4]    // src 
    209     mov        ecx, [esp + 8]    // count 
    210     movd       xmm0, [esp + 12]  // seed 
    211     movdqa     xmm6, kHash16x33 
    212  
    213     align      4 
    214   wloop: 
    215     vpmovzxbd  xmm3, dword ptr [eax]  // src[0-3] 
    216     pmulld     xmm0, xmm6  // hash *= 33 ^ 16 
    217     vpmovzxbd  xmm4, dword ptr [eax + 4]  // src[4-7] 
    218     pmulld     xmm3, kHashMul0 
    219     vpmovzxbd  xmm2, dword ptr [eax + 8]  // src[8-11] 
    220     pmulld     xmm4, kHashMul1 
    221     vpmovzxbd  xmm1, dword ptr [eax + 12]  // src[12-15] 
    222     pmulld     xmm2, kHashMul2 
     200__declspec(naked) uint32 
     201    HashDjb2_AVX2(const uint8* src, int count, uint32 seed) { 
     202  __asm { 
     203    mov        eax, [esp + 4]  // src 
     204    mov        ecx, [esp + 8]  // count 
     205    vmovd      xmm0, [esp + 12]  // seed 
     206 
     207  wloop: 
     208    vpmovzxbd  xmm3, [eax]  // src[0-3] 
     209    vpmulld    xmm0, xmm0, xmmword ptr kHash16x33  // hash *= 33 ^ 16 
     210    vpmovzxbd  xmm4, [eax + 4]  // src[4-7] 
     211    vpmulld    xmm3, xmm3, xmmword ptr kHashMul0 
     212    vpmovzxbd  xmm2, [eax + 8]  // src[8-11] 
     213    vpmulld    xmm4, xmm4, xmmword ptr kHashMul1 
     214    vpmovzxbd  xmm1, [eax + 12]  // src[12-15] 
     215    vpmulld    xmm2, xmm2, xmmword ptr kHashMul2 
    223216    lea        eax, [eax + 16] 
    224     pmulld     xmm1, kHashMul3 
    225     paddd      xmm3, xmm4        // add 16 results 
    226     paddd      xmm1, xmm2 
     217    vpmulld    xmm1, xmm1, xmmword ptr kHashMul3 
     218    vpaddd     xmm3, xmm3, xmm4  // add 16 results 
     219    vpaddd     xmm1, xmm1, xmm2 
     220    vpaddd     xmm1, xmm1, xmm3 
     221    vpshufd    xmm2, xmm1, 0x0e  // upper 2 dwords 
     222    vpaddd     xmm1, xmm1,xmm2 
     223    vpshufd    xmm2, xmm1, 0x01 
     224    vpaddd     xmm1, xmm1, xmm2 
     225    vpaddd     xmm0, xmm0, xmm1 
    227226    sub        ecx, 16 
    228     paddd      xmm1, xmm3 
    229     pshufd     xmm2, xmm1, 0x0e  // upper 2 dwords 
    230     paddd      xmm1, xmm2 
    231     pshufd     xmm2, xmm1, 0x01 
    232     paddd      xmm1, xmm2 
    233     paddd      xmm0, xmm1 
    234     jg         wloop 
    235  
    236     movd       eax, xmm0         // return hash 
     227    jg         wloop 
     228 
     229    vmovd      eax, xmm0  // return hash 
     230    vzeroupper 
    237231    ret 
    238232  } 
     
    240234#endif  // _MSC_VER >= 1700 
    241235 
    242 #endif  // !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) 
     236#endif  // !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) 
    243237 
    244238#ifdef __cplusplus 
  • pjproject/trunk/third_party/yuv/source/convert_from.cc

    r5633 r5699  
    658658} 
    659659 
     660// Convert H420 to RGB24. 
     661LIBYUV_API 
     662int H420ToRGB24(const uint8* src_y, 
     663                int src_stride_y, 
     664                const uint8* src_u, 
     665                int src_stride_u, 
     666                const uint8* src_v, 
     667                int src_stride_v, 
     668                uint8* dst_rgb24, 
     669                int dst_stride_rgb24, 
     670                int width, 
     671                int height) { 
     672  return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, 
     673                           src_stride_v, dst_rgb24, dst_stride_rgb24, 
     674                           &kYuvH709Constants, width, height); 
     675} 
     676 
     677// Convert H420 to RAW. 
     678LIBYUV_API 
     679int H420ToRAW(const uint8* src_y, 
     680              int src_stride_y, 
     681              const uint8* src_u, 
     682              int src_stride_u, 
     683              const uint8* src_v, 
     684              int src_stride_v, 
     685              uint8* dst_raw, 
     686              int dst_stride_raw, 
     687              int width, 
     688              int height) { 
     689  return I420ToRGB24Matrix(src_y, src_stride_y, src_v, 
     690                           src_stride_v,  // Swap U and V 
     691                           src_u, src_stride_u, dst_raw, dst_stride_raw, 
     692                           &kYvuH709Constants,  // Use Yvu matrix 
     693                           width, height); 
     694} 
     695 
    660696// Convert I420 to ARGB1555. 
    661697LIBYUV_API 
     
    10761112      I422ToARGBRow(src_y, src_u, src_v, row_argb, &kYuvI601Constants, width); 
    10771113      ARGBToRGB565DitherRow(row_argb, dst_rgb565, 
    1078                             *(uint32*)(dither4x4 + ((y & 3) << 2)), 
    1079                             width);  // NOLINT 
     1114                            *(uint32*)(dither4x4 + ((y & 3) << 2)),  // NOLINT 
     1115                            width);                                  // NOLINT 
    10801116      dst_rgb565 += dst_stride_rgb565; 
    10811117      src_y += src_stride_y; 
  • pjproject/trunk/third_party/yuv/source/cpu_id.cc

    r5633 r5699  
    125125  int xcr0 = 0; 
    126126#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219) 
    127   xcr0 = _xgetbv(0);  // VS2010 SP1 required. 
     127  xcr0 = (int)_xgetbv(0);  // VS2010 SP1 required.  NOLINT 
    128128#elif defined(__i386__) || defined(__x86_64__) 
    129129  asm(".byte 0x0f, 0x01, 0xd0" : "=a"(xcr0) : "c"(0) : "%edx"); 
     
    243243    // Detect AVX512bw 
    244244    if ((GetXCR0() & 0xe0) == 0xe0) { 
    245       cpu_info |= (cpu_info7[1] & 0x40000000) ? kCpuHasAVX3 : 0; 
    246     } 
    247   } 
    248  
     245      cpu_info |= (cpu_info7[1] & 0x40000000) ? kCpuHasAVX512BW : 0; 
     246      cpu_info |= (cpu_info7[1] & 0x80000000) ? kCpuHasAVX512VL : 0; 
     247      cpu_info |= (cpu_info7[2] & 0x00000002) ? kCpuHasAVX512VBMI : 0; 
     248      cpu_info |= (cpu_info7[2] & 0x00000040) ? kCpuHasAVX512VBMI2 : 0; 
     249      cpu_info |= (cpu_info7[2] & 0x00001000) ? kCpuHasAVX512VBITALG : 0; 
     250      cpu_info |= (cpu_info7[2] & 0x00004000) ? kCpuHasAVX512VPOPCNTDQ : 0; 
     251      cpu_info |= (cpu_info7[2] & 0x00000100) ? kCpuHasGFNI : 0; 
     252    } 
     253  } 
     254 
     255  // TODO(fbarchard): Consider moving these to gtest 
    249256  // Environment variable overrides for testing. 
    250257  if (TestEnv("LIBYUV_DISABLE_X86")) { 
     
    275282    cpu_info &= ~kCpuHasFMA3; 
    276283  } 
    277   if (TestEnv("LIBYUV_DISABLE_AVX3")) { 
    278     cpu_info &= ~kCpuHasAVX3; 
    279   } 
    280284  if (TestEnv("LIBYUV_DISABLE_F16C")) { 
    281285    cpu_info &= ~kCpuHasF16C; 
     286  } 
     287  if (TestEnv("LIBYUV_DISABLE_AVX512BW")) { 
     288    cpu_info &= ~kCpuHasAVX512BW; 
    282289  } 
    283290 
  • pjproject/trunk/third_party/yuv/source/mjpeg_decoder.cc

    r5633 r5699  
    1313#ifdef HAVE_JPEG 
    1414#include <assert.h> 
    15  
    16 #ifdef __cplusplus 
    17 #include <new> 
    18 #endif 
    1915 
    2016#if !defined(__pnacl__) && !defined(__CLR_VER) && \ 
  • pjproject/trunk/third_party/yuv/source/mjpeg_validate.cc

    r5633 r5699  
    2525    while (it < end) { 
    2626      // TODO(fbarchard): scan for 0xd9 instead. 
    27       it = static_cast<const uint8*>(memchr(it, 0xff, end - it)); 
     27      it = (const uint8*)(memchr(it, 0xff, end - it)); 
    2828      if (it == NULL) { 
    2929        break; 
  • pjproject/trunk/third_party/yuv/source/planar_functions.cc

    r5633 r5699  
    322322  } 
    323323#endif 
     324#if defined(HAS_SPLITUVROW_MSA) 
     325  if (TestCpuFlag(kCpuHasMSA)) { 
     326    SplitUVRow = SplitUVRow_Any_MSA; 
     327    if (IS_ALIGNED(width, 32)) { 
     328      SplitUVRow = SplitUVRow_MSA; 
     329    } 
     330  } 
     331#endif 
    324332 
    325333  for (y = 0; y < height; ++y) { 
     
    397405    src_v += src_stride_v; 
    398406    dst_uv += dst_stride_uv; 
     407  } 
     408} 
     409 
     410// Support function for NV12 etc RGB channels. 
     411// Width and height are plane sizes (typically half pixel width). 
     412LIBYUV_API 
     413void SplitRGBPlane(const uint8* src_rgb, 
     414                   int src_stride_rgb, 
     415                   uint8* dst_r, 
     416                   int dst_stride_r, 
     417                   uint8* dst_g, 
     418                   int dst_stride_g, 
     419                   uint8* dst_b, 
     420                   int dst_stride_b, 
     421                   int width, 
     422                   int height) { 
     423  int y; 
     424  void (*SplitRGBRow)(const uint8* src_rgb, uint8* dst_r, uint8* dst_g, 
     425                      uint8* dst_b, int width) = SplitRGBRow_C; 
     426  // Negative height means invert the image. 
     427  if (height < 0) { 
     428    height = -height; 
     429    dst_r = dst_r + (height - 1) * dst_stride_r; 
     430    dst_g = dst_g + (height - 1) * dst_stride_g; 
     431    dst_b = dst_b + (height - 1) * dst_stride_b; 
     432    dst_stride_r = -dst_stride_r; 
     433    dst_stride_g = -dst_stride_g; 
     434    dst_stride_b = -dst_stride_b; 
     435  } 
     436  // Coalesce rows. 
     437  if (src_stride_rgb == width * 3 && dst_stride_r == width && 
     438      dst_stride_g == width && dst_stride_b == width) { 
     439    width *= height; 
     440    height = 1; 
     441    src_stride_rgb = dst_stride_r = dst_stride_g = dst_stride_b = 0; 
     442  } 
     443#if defined(HAS_SPLITRGBROW_SSSE3) 
     444  if (TestCpuFlag(kCpuHasSSSE3)) { 
     445    SplitRGBRow = SplitRGBRow_Any_SSSE3; 
     446    if (IS_ALIGNED(width, 16)) { 
     447      SplitRGBRow = SplitRGBRow_SSSE3; 
     448    } 
     449  } 
     450#endif 
     451#if defined(HAS_SPLITRGBROW_NEON) 
     452  if (TestCpuFlag(kCpuHasNEON)) { 
     453    SplitRGBRow = SplitRGBRow_Any_NEON; 
     454    if (IS_ALIGNED(width, 16)) { 
     455      SplitRGBRow = SplitRGBRow_NEON; 
     456    } 
     457  } 
     458#endif 
     459 
     460  for (y = 0; y < height; ++y) { 
     461    // Copy a row of RGB. 
     462    SplitRGBRow(src_rgb, dst_r, dst_g, dst_b, width); 
     463    dst_r += dst_stride_r; 
     464    dst_g += dst_stride_g; 
     465    dst_b += dst_stride_b; 
     466    src_rgb += src_stride_rgb; 
     467  } 
     468} 
     469 
     470LIBYUV_API 
     471void MergeRGBPlane(const uint8* src_r, 
     472                   int src_stride_r, 
     473                   const uint8* src_g, 
     474                   int src_stride_g, 
     475                   const uint8* src_b, 
     476                   int src_stride_b, 
     477                   uint8* dst_rgb, 
     478                   int dst_stride_rgb, 
     479                   int width, 
     480                   int height) { 
     481  int y; 
     482  void (*MergeRGBRow)(const uint8* src_r, const uint8* src_g, 
     483                      const uint8* src_b, uint8* dst_rgb, int width) = 
     484      MergeRGBRow_C; 
     485  // Coalesce rows. 
     486  // Negative height means invert the image. 
     487  if (height < 0) { 
     488    height = -height; 
     489    dst_rgb = dst_rgb + (height - 1) * dst_stride_rgb; 
     490    dst_stride_rgb = -dst_stride_rgb; 
     491  } 
     492  // Coalesce rows. 
     493  if (src_stride_r == width && src_stride_g == width && src_stride_b == width && 
     494      dst_stride_rgb == width * 3) { 
     495    width *= height; 
     496    height = 1; 
     497    src_stride_r = src_stride_g = src_stride_b = dst_stride_rgb = 0; 
     498  } 
     499#if defined(HAS_MERGERGBROW_SSSE3) 
     500  if (TestCpuFlag(kCpuHasSSSE3)) { 
     501    MergeRGBRow = MergeRGBRow_Any_SSSE3; 
     502    if (IS_ALIGNED(width, 16)) { 
     503      MergeRGBRow = MergeRGBRow_SSSE3; 
     504    } 
     505  } 
     506#endif 
     507#if defined(HAS_MERGERGBROW_NEON) 
     508  if (TestCpuFlag(kCpuHasNEON)) { 
     509    MergeRGBRow = MergeRGBRow_Any_NEON; 
     510    if (IS_ALIGNED(width, 16)) { 
     511      MergeRGBRow = MergeRGBRow_NEON; 
     512    } 
     513  } 
     514#endif 
     515 
     516  for (y = 0; y < height; ++y) { 
     517    // Merge a row of U and V into a row of RGB. 
     518    MergeRGBRow(src_r, src_g, src_b, dst_rgb, width); 
     519    src_r += src_stride_r; 
     520    src_g += src_stride_g; 
     521    src_b += src_stride_b; 
     522    dst_rgb += dst_stride_rgb; 
    399523  } 
    400524} 
     
    845969  if (TestCpuFlag(kCpuHasNEON)) { 
    846970    ARGBBlendRow = ARGBBlendRow_NEON; 
     971  } 
     972#endif 
     973#if defined(HAS_ARGBBLENDROW_MSA) 
     974  if (TestCpuFlag(kCpuHasMSA)) { 
     975    ARGBBlendRow = ARGBBlendRow_MSA; 
    847976  } 
    848977#endif 
     
    15751704  } 
    15761705#endif 
     1706#if defined(HAS_SETROW_MSA) 
     1707  if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 16)) { 
     1708    SetRow = SetRow_MSA; 
     1709  } 
     1710#endif 
    15771711 
    15781712  // Set plane 
     
    19752109  } 
    19762110#endif 
     2111#if defined(HAS_ARGBCOLORMATRIXROW_MSA) 
     2112  if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { 
     2113    ARGBColorMatrixRow = ARGBColorMatrixRow_MSA; 
     2114  } 
     2115#endif 
    19772116  for (y = 0; y < height; ++y) { 
    19782117    ARGBColorMatrixRow(src_argb, dst_argb, matrix_argb, width); 
     
    21332272  if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 
    21342273    ARGBQuantizeRow = ARGBQuantizeRow_NEON; 
     2274  } 
     2275#endif 
     2276#if defined(HAS_ARGBQUANTIZEROW_MSA) 
     2277  if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { 
     2278    ARGBQuantizeRow = ARGBQuantizeRow_MSA; 
    21352279  } 
    21362280#endif 
     
    26202764  } 
    26212765#endif 
     2766#if defined(HAS_SOBELYROW_MSA) 
     2767  if (TestCpuFlag(kCpuHasMSA)) { 
     2768    SobelYRow = SobelYRow_MSA; 
     2769  } 
     2770#endif 
    26222771#if defined(HAS_SOBELXROW_SSE2) 
    26232772  if (TestCpuFlag(kCpuHasSSE2)) { 
     
    26282777  if (TestCpuFlag(kCpuHasNEON)) { 
    26292778    SobelXRow = SobelXRow_NEON; 
     2779  } 
     2780#endif 
     2781#if defined(HAS_SOBELXROW_MSA) 
     2782  if (TestCpuFlag(kCpuHasMSA)) { 
     2783    SobelXRow = SobelXRow_MSA; 
    26302784  } 
    26312785#endif 
     
    29043058  } 
    29053059#endif 
     3060#if defined(HAS_HALFFLOATROW_MSA) 
     3061  if (TestCpuFlag(kCpuHasMSA)) { 
     3062    HalfFloatRow = HalfFloatRow_Any_MSA; 
     3063    if (IS_ALIGNED(width, 32)) { 
     3064      HalfFloatRow = HalfFloatRow_MSA; 
     3065    } 
     3066  } 
     3067#endif 
    29063068 
    29073069  for (y = 0; y < height; ++y) { 
     
    30473209    ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_NEON 
    30483210                                                : ARGBExtractAlphaRow_Any_NEON; 
     3211  } 
     3212#endif 
     3213#if defined(HAS_ARGBEXTRACTALPHAROW_MSA) 
     3214  if (TestCpuFlag(kCpuHasMSA)) { 
     3215    ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_MSA 
     3216                                                : ARGBExtractAlphaRow_Any_MSA; 
    30493217  } 
    30503218#endif 
     
    31583326    if (IS_ALIGNED(width, 16)) { 
    31593327      SplitUVRow = SplitUVRow_NEON; 
     3328    } 
     3329  } 
     3330#endif 
     3331#if defined(HAS_SPLITUVROW_MSA) 
     3332  if (TestCpuFlag(kCpuHasMSA)) { 
     3333    SplitUVRow = SplitUVRow_Any_MSA; 
     3334    if (IS_ALIGNED(width, 32)) { 
     3335      SplitUVRow = SplitUVRow_MSA; 
    31603336    } 
    31613337  } 
     
    32693445  } 
    32703446#endif 
     3447#if defined(HAS_SPLITUVROW_MSA) 
     3448  if (TestCpuFlag(kCpuHasMSA)) { 
     3449    SplitUVRow = SplitUVRow_Any_MSA; 
     3450    if (IS_ALIGNED(width, 32)) { 
     3451      SplitUVRow = SplitUVRow_MSA; 
     3452    } 
     3453  } 
     3454#endif 
    32713455#if defined(HAS_INTERPOLATEROW_SSSE3) 
    32723456  if (TestCpuFlag(kCpuHasSSSE3)) { 
  • pjproject/trunk/third_party/yuv/source/rotate.cc

    r5633 r5699  
    360360      IS_ALIGNED(src_stride, 4)) { 
    361361    MirrorUVRow = MirrorUVRow_DSPR2; 
     362  } 
     363#endif 
     364#if defined(HAS_MIRRORUVROW_MSA) 
     365  if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 32)) { 
     366    MirrorUVRow = MirrorUVRow_MSA; 
    362367  } 
    363368#endif 
  • pjproject/trunk/third_party/yuv/source/rotate_neon64.cc

    r5633 r5699  
    3131                       int width) { 
    3232  const uint8* src_temp; 
    33   asm volatile ( 
    34     // loops are on blocks of 8. loop will stop when 
    35     // counter gets to or below 0. starting the counter 
    36     // at w-8 allow for this 
    37     "sub         %w3, %w3, #8                     \n" 
    38  
    39     // handle 8x8 blocks. this should be the majority of the plane 
    40     "1:                                          \n" 
     33  asm volatile( 
     34      // loops are on blocks of 8. loop will stop when 
     35      // counter gets to or below 0. starting the counter 
     36      // at w-8 allow for this 
     37      "sub         %w3, %w3, #8                     \n" 
     38 
     39      // handle 8x8 blocks. this should be the majority of the plane 
     40      "1:                                          \n" 
    4141      "mov         %0, %1                        \n" 
    4242 
     
    9393      "b.ge        1b                            \n" 
    9494 
    95     // add 8 back to counter. if the result is 0 there are 
    96     // no residuals. 
    97     "adds        %w3, %w3, #8                    \n" 
    98     "b.eq        4f                              \n" 
    99  
    100     // some residual, so between 1 and 7 lines left to transpose 
    101     "cmp         %w3, #2                          \n" 
    102     "b.lt        3f                              \n" 
    103  
    104     "cmp         %w3, #4                          \n" 
    105     "b.lt        2f                              \n" 
    106  
    107     // 4x8 block 
    108     "mov         %0, %1                          \n" 
    109     "ld1     {v0.s}[0], [%0], %5                 \n" 
    110     "ld1     {v0.s}[1], [%0], %5                 \n" 
    111     "ld1     {v0.s}[2], [%0], %5                 \n" 
    112     "ld1     {v0.s}[3], [%0], %5                 \n" 
    113     "ld1     {v1.s}[0], [%0], %5                 \n" 
    114     "ld1     {v1.s}[1], [%0], %5                 \n" 
    115     "ld1     {v1.s}[2], [%0], %5                 \n" 
    116     "ld1     {v1.s}[3], [%0]                     \n" 
    117  
    118     "mov         %0, %2                          \n" 
    119  
    120     "ld1      {v2.16b}, [%4]                     \n" 
    121  
    122     "tbl      v3.16b, {v0.16b}, v2.16b           \n" 
    123     "tbl      v0.16b, {v1.16b}, v2.16b           \n" 
    124  
    125     // TODO(frkoenig): Rework shuffle above to 
    126     // write out with 4 instead of 8 writes. 
    127     "st1 {v3.s}[0], [%0], %6                     \n" 
    128     "st1 {v3.s}[1], [%0], %6                     \n" 
    129     "st1 {v3.s}[2], [%0], %6                     \n" 
    130     "st1 {v3.s}[3], [%0]                         \n" 
    131  
    132     "add         %0, %2, #4                      \n" 
    133     "st1 {v0.s}[0], [%0], %6                     \n" 
    134     "st1 {v0.s}[1], [%0], %6                     \n" 
    135     "st1 {v0.s}[2], [%0], %6                     \n" 
    136     "st1 {v0.s}[3], [%0]                         \n" 
    137  
    138     "add         %1, %1, #4                      \n"  // src += 4 
    139     "add         %2, %2, %6, lsl #2              \n"  // dst += 4 * dst_stride 
    140     "subs        %w3, %w3, #4                    \n"  // w   -= 4 
    141     "b.eq        4f                              \n" 
    142  
    143     // some residual, check to see if it includes a 2x8 block, 
    144     // or less 
    145     "cmp         %w3, #2                         \n" 
    146     "b.lt        3f                              \n" 
    147  
    148     // 2x8 block 
    149     "2:                                          \n" 
    150     "mov         %0, %1                          \n" 
    151     "ld1     {v0.h}[0], [%0], %5                 \n" 
    152     "ld1     {v1.h}[0], [%0], %5                 \n" 
    153     "ld1     {v0.h}[1], [%0], %5                 \n" 
    154     "ld1     {v1.h}[1], [%0], %5                 \n" 
    155     "ld1     {v0.h}[2], [%0], %5                 \n" 
    156     "ld1     {v1.h}[2], [%0], %5                 \n" 
    157     "ld1     {v0.h}[3], [%0], %5                 \n" 
    158     "ld1     {v1.h}[3], [%0]                     \n" 
    159  
    160     "trn2    v2.8b, v0.8b, v1.8b                 \n" 
    161     "trn1    v3.8b, v0.8b, v1.8b                 \n" 
    162  
    163     "mov         %0, %2                          \n" 
    164  
    165     "st1     {v3.8b}, [%0], %6                   \n" 
    166     "st1     {v2.8b}, [%0]                       \n" 
    167  
    168     "add         %1, %1, #2                      \n"  // src += 2 
    169     "add         %2, %2, %6, lsl #1              \n"  // dst += 2 * dst_stride 
    170     "subs        %w3, %w3,  #2                   \n"  // w   -= 2 
    171     "b.eq        4f                              \n" 
    172  
    173     // 1x8 block 
    174     "3:                                          \n" 
    175     "ld1         {v0.b}[0], [%1], %5             \n" 
    176     "ld1         {v0.b}[1], [%1], %5             \n" 
    177     "ld1         {v0.b}[2], [%1], %5             \n" 
    178     "ld1         {v0.b}[3], [%1], %5             \n" 
    179     "ld1         {v0.b}[4], [%1], %5             \n" 
    180     "ld1         {v0.b}[5], [%1], %5             \n" 
    181     "ld1         {v0.b}[6], [%1], %5             \n" 
    182     "ld1         {v0.b}[7], [%1]                 \n" 
    183  
    184     "st1         {v0.8b}, [%2]                   \n" 
    185  
    186     "4:                                          \n" 
    187  
    188     : "=&r"(src_temp),                            // %0 
    189       "+r"(src),                                  // %1 
    190       "+r"(dst),                                  // %2 
    191       "+r"(width)                                 // %3 
    192     : "r"(&kVTbl4x4Transpose),                    // %4 
    193       "r"(static_cast<ptrdiff_t>(src_stride)),    // %5 
    194       "r"(static_cast<ptrdiff_t>(dst_stride))     // %6 
    195     : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", 
    196       "v17", "v18", "v19", "v20", "v21", "v22", "v23" 
    197   ); 
     95      // add 8 back to counter. if the result is 0 there are 
     96      // no residuals. 
     97      "adds        %w3, %w3, #8                    \n" 
     98      "b.eq        4f                              \n" 
     99 
     100      // some residual, so between 1 and 7 lines left to transpose 
     101      "cmp         %w3, #2                          \n" 
     102      "b.lt        3f                              \n" 
     103 
     104      "cmp         %w3, #4                          \n" 
     105      "b.lt        2f                              \n" 
     106 
     107      // 4x8 block 
     108      "mov         %0, %1                          \n" 
     109      "ld1     {v0.s}[0], [%0], %5                 \n" 
     110      "ld1     {v0.s}[1], [%0], %5                 \n" 
     111      "ld1     {v0.s}[2], [%0], %5                 \n" 
     112      "ld1     {v0.s}[3], [%0], %5                 \n" 
     113      "ld1     {v1.s}[0], [%0], %5                 \n" 
     114      "ld1     {v1.s}[1], [%0], %5                 \n" 
     115      "ld1     {v1.s}[2], [%0], %5                 \n" 
     116      "ld1     {v1.s}[3], [%0]                     \n" 
     117 
     118      "mov         %0, %2                          \n" 
     119 
     120      "ld1      {v2.16b}, [%4]                     \n" 
     121 
     122      "tbl      v3.16b, {v0.16b}, v2.16b           \n" 
     123      "tbl      v0.16b, {v1.16b}, v2.16b           \n" 
     124 
     125      // TODO(frkoenig): Rework shuffle above to 
     126      // write out with 4 instead of 8 writes. 
     127      "st1 {v3.s}[0], [%0], %6                     \n" 
     128      "st1 {v3.s}[1], [%0], %6                     \n" 
     129      "st1 {v3.s}[2], [%0], %6                     \n" 
     130      "st1 {v3.s}[3], [%0]                         \n" 
     131 
     132      "add         %0, %2, #4                      \n" 
     133      "st1 {v0.s}[0], [%0], %6                     \n" 
     134      "st1 {v0.s}[1], [%0], %6                     \n" 
     135      "st1 {v0.s}[2], [%0], %6                     \n" 
     136      "st1 {v0.s}[3], [%0]                         \n" 
     137 
     138      "add         %1, %1, #4                      \n"  // src += 4 
     139      "add         %2, %2, %6, lsl #2              \n"  // dst += 4 * dst_stride 
     140      "subs        %w3, %w3, #4                    \n"  // w   -= 4 
     141      "b.eq        4f                              \n" 
     142 
     143      // some residual, check to see if it includes a 2x8 block, 
     144      // or less 
     145      "cmp         %w3, #2                         \n" 
     146      "b.lt        3f                              \n" 
     147 
     148      // 2x8 block 
     149      "2:                                          \n" 
     150      "mov         %0, %1                          \n" 
     151      "ld1     {v0.h}[0], [%0], %5                 \n" 
     152      "ld1     {v1.h}[0], [%0], %5                 \n" 
     153      "ld1     {v0.h}[1], [%0], %5                 \n" 
     154      "ld1     {v1.h}[1], [%0], %5                 \n" 
     155      "ld1     {v0.h}[2], [%0], %5                 \n" 
     156      "ld1     {v1.h}[2], [%0], %5                 \n" 
     157      "ld1     {v0.h}[3], [%0], %5                 \n" 
     158      "ld1     {v1.h}[3], [%0]                     \n" 
     159 
     160      "trn2    v2.8b, v0.8b, v1.8b                 \n" 
     161      "trn1    v3.8b, v0.8b, v1.8b                 \n" 
     162 
     163      "mov         %0, %2                          \n" 
     164 
     165      "st1     {v3.8b}, [%0], %6                   \n" 
     166      "st1     {v2.8b}, [%0]                       \n" 
     167 
     168      "add         %1, %1, #2                      \n"  // src += 2 
     169      "add         %2, %2, %6, lsl #1              \n"  // dst += 2 * dst_stride 
     170      "subs        %w3, %w3,  #2                   \n"  // w   -= 2 
     171      "b.eq        4f                              \n" 
     172 
     173      // 1x8 block 
     174      "3:                                          \n" 
     175      "ld1         {v0.b}[0], [%1], %5             \n" 
     176      "ld1         {v0.b}[1], [%1], %5             \n" 
     177      "ld1         {v0.b}[2], [%1], %5             \n" 
     178      "ld1         {v0.b}[3], [%1], %5             \n" 
     179      "ld1         {v0.b}[4], [%1], %5             \n" 
     180      "ld1         {v0.b}[5], [%1], %5             \n" 
     181      "ld1         {v0.b}[6], [%1], %5             \n" 
     182      "ld1         {v0.b}[7], [%1]                 \n" 
     183 
     184      "st1         {v0.8b}, [%2]                   \n" 
     185 
     186      "4:                                          \n" 
     187 
     188      : "=&r"(src_temp),                          // %0 
     189        "+r"(src),                                // %1 
     190        "+r"(dst),                                // %2 
     191        "+r"(width)                               // %3 
     192      : "r"(&kVTbl4x4Transpose),                  // %4 
     193        "r"(static_cast<ptrdiff_t>(src_stride)),  // %5 
     194        "r"(static_cast<ptrdiff_t>(dst_stride))   // %6 
     195      : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", 
     196        "v17", "v18", "v19", "v20", "v21", "v22", "v23"); 
    198197} 
    199198 
     
    210209                         int width) { 
    211210  const uint8* src_temp; 
    212   asm volatile ( 
    213     // loops are on blocks of 8. loop will stop when 
    214     // counter gets to or below 0. starting the counter 
    215     // at w-8 allow for this 
    216     "sub       %w4, %w4, #8                    \n" 
    217  
    218     // handle 8x8 blocks. this should be the majority of the plane 
    219     "1:                                        \n" 
    220     "mov       %0, %1                          \n" 
    221  
    222     "ld1       {v0.16b}, [%0], %5              \n" 
    223     "ld1       {v1.16b}, [%0], %5              \n" 
    224     "ld1       {v2.16b}, [%0], %5              \n" 
    225     "ld1       {v3.16b}, [%0], %5              \n" 
    226     "ld1       {v4.16b}, [%0], %5              \n" 
    227     "ld1       {v5.16b}, [%0], %5              \n" 
    228     "ld1       {v6.16b}, [%0], %5              \n" 
    229     "ld1       {v7.16b}, [%0]                  \n" 
    230  
    231     "trn1      v16.16b, v0.16b, v1.16b         \n" 
    232     "trn2      v17.16b, v0.16b, v1.16b         \n" 
    233     "trn1      v18.16b, v2.16b, v3.16b         \n" 
    234     "trn2      v19.16b, v2.16b, v3.16b         \n" 
    235     "trn1      v20.16b, v4.16b, v5.16b         \n" 
    236     "trn2      v21.16b, v4.16b, v5.16b         \n" 
    237     "trn1      v22.16b, v6.16b, v7.16b         \n" 
    238     "trn2      v23.16b, v6.16b, v7.16b         \n" 
    239  
    240     "trn1      v0.8h, v16.8h, v18.8h           \n" 
    241     "trn2      v1.8h, v16.8h, v18.8h           \n" 
    242     "trn1      v2.8h, v20.8h, v22.8h           \n" 
    243     "trn2      v3.8h, v20.8h, v22.8h           \n" 
    244     "trn1      v4.8h, v17.8h, v19.8h           \n" 
    245     "trn2      v5.8h, v17.8h, v19.8h           \n" 
    246     "trn1      v6.8h, v21.8h, v23.8h           \n" 
    247     "trn2      v7.8h, v21.8h, v23.8h           \n" 
    248  
    249     "trn1      v16.4s, v0.4s, v2.4s            \n" 
    250     "trn2      v17.4s, v0.4s, v2.4s            \n" 
    251     "trn1      v18.4s, v1.4s, v3.4s            \n" 
    252     "trn2      v19.4s, v1.4s, v3.4s            \n" 
    253     "trn1      v20.4s, v4.4s, v6.4s            \n" 
    254     "trn2      v21.4s, v4.4s, v6.4s            \n" 
    255     "trn1      v22.4s, v5.4s, v7.4s            \n" 
    256     "trn2      v23.4s, v5.4s, v7.4s            \n" 
    257  
    258     "mov       %0, %2                          \n" 
    259  
    260     "st1       {v16.d}[0], [%0], %6            \n" 
    261     "st1       {v18.d}[0], [%0], %6            \n" 
    262     "st1       {v17.d}[0], [%0], %6            \n" 
    263     "st1       {v19.d}[0], [%0], %6            \n" 
    264     "st1       {v16.d}[1], [%0], %6            \n" 
    265     "st1       {v18.d}[1], [%0], %6            \n" 
    266     "st1       {v17.d}[1], [%0], %6            \n" 
    267     "st1       {v19.d}[1], [%0]                \n" 
    268  
    269     "mov       %0, %3                          \n" 
    270  
    271     "st1       {v20.d}[0], [%0], %7            \n" 
    272     "st1       {v22.d}[0], [%0], %7            \n" 
    273     "st1       {v21.d}[0], [%0], %7            \n" 
    274     "st1       {v23.d}[0], [%0], %7            \n" 
    275     "st1       {v20.d}[1], [%0], %7            \n" 
    276     "st1       {v22.d}[1], [%0], %7            \n" 
    277     "st1       {v21.d}[1], [%0], %7            \n" 
    278     "st1       {v23.d}[1], [%0]                \n" 
    279  
    280     "add       %1, %1, #16                     \n"  // src   += 8*2 
    281     "add       %2, %2, %6, lsl #3              \n"  // dst_a += 8 * dst_stride_a 
    282     "add       %3, %3, %7, lsl #3              \n"  // dst_b += 8 * dst_stride_b 
    283     "subs      %w4, %w4,  #8                   \n"  // w     -= 8 
    284     "b.ge      1b                              \n" 
    285  
    286     // add 8 back to counter. if the result is 0 there are 
    287     // no residuals. 
    288     "adds      %w4, %w4, #8                    \n" 
    289     "b.eq      4f                              \n" 
    290  
    291     // some residual, so between 1 and 7 lines left to transpose 
    292     "cmp       %w4, #2                         \n" 
    293     "b.lt      3f                              \n" 
    294  
    295     "cmp       %w4, #4                         \n" 
    296     "b.lt      2f                              \n" 
    297  
    298     // TODO(frkoenig): Clean this up 
    299     // 4x8 block 
    300     "mov       %0, %1                          \n" 
    301     "ld1       {v0.8b}, [%0], %5               \n" 
    302     "ld1       {v1.8b}, [%0], %5               \n" 
    303     "ld1       {v2.8b}, [%0], %5               \n" 
    304     "ld1       {v3.8b}, [%0], %5               \n" 
    305     "ld1       {v4.8b}, [%0], %5               \n" 
    306     "ld1       {v5.8b}, [%0], %5               \n" 
    307     "ld1       {v6.8b}, [%0], %5               \n" 
    308     "ld1       {v7.8b}, [%0]                   \n" 
    309  
    310     "ld1       {v30.16b}, [%8], #16            \n" 
    311     "ld1       {v31.16b}, [%8]                 \n" 
    312  
    313     "tbl       v16.16b, {v0.16b, v1.16b, v2.16b, v3.16b}, v30.16b  \n" 
    314     "tbl       v17.16b, {v0.16b, v1.16b, v2.16b, v3.16b}, v31.16b  \n" 
    315     "tbl       v18.16b, {v4.16b, v5.16b, v6.16b, v7.16b}, v30.16b  \n" 
    316     "tbl       v19.16b, {v4.16b, v5.16b, v6.16b, v7.16b}, v31.16b  \n" 
    317  
    318     "mov       %0, %2                          \n" 
    319  
    320     "st1       {v16.s}[0],  [%0], %6           \n" 
    321     "st1       {v16.s}[1],  [%0], %6           \n" 
    322     "st1       {v16.s}[2],  [%0], %6           \n" 
    323     "st1       {v16.s}[3],  [%0], %6           \n" 
    324  
    325     "add       %0, %2, #4                      \n" 
    326     "st1       {v18.s}[0], [%0], %6            \n" 
    327     "st1       {v18.s}[1], [%0], %6            \n" 
    328     "st1       {v18.s}[2], [%0], %6            \n" 
    329     "st1       {v18.s}[3], [%0]                \n" 
    330  
    331     "mov       %0, %3                          \n" 
    332  
    333     "st1       {v17.s}[0], [%0], %7            \n" 
    334     "st1       {v17.s}[1], [%0], %7            \n" 
    335     "st1       {v17.s}[2], [%0], %7            \n" 
    336     "st1       {v17.s}[3], [%0], %7            \n" 
    337  
    338     "add       %0, %3, #4                      \n" 
    339     "st1       {v19.s}[0],  [%0], %7           \n" 
    340     "st1       {v19.s}[1],  [%0], %7           \n" 
    341     "st1       {v19.s}[2],  [%0], %7           \n" 
    342     "st1       {v19.s}[3],  [%0]               \n" 
    343  
    344     "add       %1, %1, #8                      \n"  // src   += 4 * 2 
    345     "add       %2, %2, %6, lsl #2              \n"  // dst_a += 4 * dst_stride_a 
    346     "add       %3, %3, %7, lsl #2              \n"  // dst_b += 4 * dst_stride_b 
    347     "subs      %w4,  %w4,  #4                  \n"  // w     -= 4 
    348     "b.eq      4f                              \n" 
    349  
    350     // some residual, check to see if it includes a 2x8 block, 
    351     // or less 
    352     "cmp       %w4, #2                         \n" 
    353     "b.lt      3f                              \n" 
    354  
    355     // 2x8 block 
    356     "2:                                        \n" 
    357     "mov       %0, %1                          \n" 
    358     "ld2       {v0.h, v1.h}[0], [%0], %5       \n" 
    359     "ld2       {v2.h, v3.h}[0], [%0], %5       \n" 
    360     "ld2       {v0.h, v1.h}[1], [%0], %5       \n" 
    361     "ld2       {v2.h, v3.h}[1], [%0], %5       \n" 
    362     "ld2       {v0.h, v1.h}[2], [%0], %5       \n" 
    363     "ld2       {v2.h, v3.h}[2], [%0], %5       \n" 
    364     "ld2       {v0.h, v1.h}[3], [%0], %5       \n" 
    365     "ld2       {v2.h, v3.h}[3], [%0]           \n" 
    366  
    367     "trn1      v4.8b, v0.8b, v2.8b             \n" 
    368     "trn2      v5.8b, v0.8b, v2.8b             \n" 
    369     "trn1      v6.8b, v1.8b, v3.8b             \n" 
    370     "trn2      v7.8b, v1.8b, v3.8b             \n" 
    371  
    372     "mov       %0, %2                          \n" 
    373  
    374     "st1       {v4.d}[0], [%0], %6             \n" 
    375     "st1       {v6.d}[0], [%0]                 \n" 
    376  
    377     "mov       %0, %3                          \n" 
    378  
    379     "st1       {v5.d}[0], [%0], %7             \n" 
    380     "st1       {v7.d}[0], [%0]                 \n" 
    381  
    382     "add       %1, %1, #4                      \n"  // src   += 2 * 2 
    383     "add       %2, %2, %6, lsl #1              \n"  // dst_a += 2 * dst_stride_a 
    384     "add       %3, %3, %7, lsl #1              \n"  // dst_b += 2 * dst_stride_b 
    385     "subs      %w4,  %w4,  #2                  \n"  // w     -= 2 
    386     "b.eq      4f                              \n" 
    387  
    388     // 1x8 block 
    389     "3:                                        \n" 
    390     "ld2       {v0.b, v1.b}[0], [%1], %5       \n" 
    391     "ld2       {v0.b, v1.b}[1], [%1], %5       \n" 
    392     "ld2       {v0.b, v1.b}[2], [%1], %5       \n" 
    393     "ld2       {v0.b, v1.b}[3], [%1], %5       \n" 
    394     "ld2       {v0.b, v1.b}[4], [%1], %5       \n" 
    395     "ld2       {v0.b, v1.b}[5], [%1], %5       \n" 
    396     "ld2       {v0.b, v1.b}[6], [%1], %5       \n" 
    397     "ld2       {v0.b, v1.b}[7], [%1]           \n" 
    398  
    399     "st1       {v0.d}[0], [%2]                 \n" 
    400     "st1       {v1.d}[0], [%3]                 \n" 
    401  
    402     "4:                                        \n" 
    403  
    404     : "=&r"(src_temp),                            // %0 
    405       "+r"(src),                                  // %1 
    406       "+r"(dst_a),                                // %2 
    407       "+r"(dst_b),                                // %3 
    408       "+r"(width)                                 // %4 
    409     : "r"(static_cast<ptrdiff_t>(src_stride)),    // %5 
    410       "r"(static_cast<ptrdiff_t>(dst_stride_a)),  // %6 
    411       "r"(static_cast<ptrdiff_t>(dst_stride_b)),  // %7 
    412       "r"(&kVTbl4x4TransposeDi)                   // %8 
    413     : "memory", "cc", 
    414       "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 
    415       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 
    416       "v30", "v31" 
    417   ); 
     211  asm volatile( 
     212      // loops are on blocks of 8. loop will stop when 
     213      // counter gets to or below 0. starting the counter 
     214      // at w-8 allow for this 
     215      "sub       %w4, %w4, #8                    \n" 
     216 
     217      // handle 8x8 blocks. this should be the majority of the plane 
     218      "1:                                        \n" 
     219      "mov       %0, %1                          \n" 
     220 
     221      "ld1       {v0.16b}, [%0], %5              \n" 
     222      "ld1       {v1.16b}, [%0], %5              \n" 
     223      "ld1       {v2.16b}, [%0], %5              \n" 
     224      "ld1       {v3.16b}, [%0], %5              \n" 
     225      "ld1       {v4.16b}, [%0], %5              \n" 
     226      "ld1       {v5.16b}, [%0], %5              \n" 
     227      "ld1       {v6.16b}, [%0], %5              \n" 
     228      "ld1       {v7.16b}, [%0]                  \n" 
     229 
     230      "trn1      v16.16b, v0.16b, v1.16b         \n" 
     231      "trn2      v17.16b, v0.16b, v1.16b         \n" 
     232      "trn1      v18.16b, v2.16b, v3.16b         \n" 
     233      "trn2      v19.16b, v2.16b, v3.16b         \n" 
     234      "trn1      v20.16b, v4.16b, v5.16b         \n" 
     235      "trn2      v21.16b, v4.16b, v5.16b         \n" 
     236      "trn1      v22.16b, v6.16b, v7.16b         \n" 
     237      "trn2      v23.16b, v6.16b, v7.16b         \n" 
     238 
     239      "trn1      v0.8h, v16.8h, v18.8h           \n" 
     240      "trn2      v1.8h, v16.8h, v18.8h           \n" 
     241      "trn1      v2.8h, v20.8h, v22.8h           \n" 
     242      "trn2      v3.8h, v20.8h, v22.8h           \n" 
     243      "trn1      v4.8h, v17.8h, v19.8h           \n" 
     244      "trn2      v5.8h, v17.8h, v19.8h           \n" 
     245      "trn1      v6.8h, v21.8h, v23.8h           \n" 
     246      "trn2      v7.8h, v21.8h, v23.8h           \n" 
     247 
     248      "trn1      v16.4s, v0.4s, v2.4s            \n" 
     249      "trn2      v17.4s, v0.4s, v2.4s            \n" 
     250      "trn1      v18.4s, v1.4s, v3.4s            \n" 
     251      "trn2      v19.4s, v1.4s, v3.4s            \n" 
     252      "trn1      v20.4s, v4.4s, v6.4s            \n" 
     253      "trn2      v21.4s, v4.4s, v6.4s            \n" 
     254      "trn1      v22.4s, v5.4s, v7.4s            \n" 
     255      "trn2      v23.4s, v5.4s, v7.4s            \n" 
     256 
     257      "mov       %0, %2                          \n" 
     258 
     259      "st1       {v16.d}[0], [%0], %6            \n" 
     260      "st1       {v18.d}[0], [%0], %6            \n" 
     261      "st1       {v17.d}[0], [%0], %6            \n" 
     262      "st1       {v19.d}[0], [%0], %6            \n" 
     263      "st1       {v16.d}[1], [%0], %6            \n" 
     264      "st1       {v18.d}[1], [%0], %6            \n" 
     265      "st1       {v17.d}[1], [%0], %6            \n" 
     266      "st1       {v19.d}[1], [%0]                \n" 
     267 
     268      "mov       %0, %3                          \n" 
     269 
     270      "st1       {v20.d}[0], [%0], %7            \n" 
     271      "st1       {v22.d}[0], [%0], %7            \n" 
     272      "st1       {v21.d}[0], [%0], %7            \n" 
     273      "st1       {v23.d}[0], [%0], %7            \n" 
     274      "st1       {v20.d}[1], [%0], %7            \n" 
     275      "st1       {v22.d}[1], [%0], %7            \n" 
     276      "st1       {v21.d}[1], [%0], %7            \n" 
     277      "st1       {v23.d}[1], [%0]                \n" 
     278 
     279      "add       %1, %1, #16                     \n"  // src   += 8*2 
     280      "add       %2, %2, %6, lsl #3              \n"  // dst_a += 8 * 
     281                                                      // dst_stride_a 
     282      "add       %3, %3, %7, lsl #3              \n"  // dst_b += 8 * 
     283                                                      // dst_stride_b 
     284      "subs      %w4, %w4,  #8                   \n"  // w     -= 8 
     285      "b.ge      1b                              \n" 
     286 
     287      // add 8 back to counter. if the result is 0 there are 
     288      // no residuals. 
     289      "adds      %w4, %w4, #8                    \n" 
     290      "b.eq      4f                              \n" 
     291 
     292      // some residual, so between 1 and 7 lines left to transpose 
     293      "cmp       %w4, #2                         \n" 
     294      "b.lt      3f                              \n" 
     295 
     296      "cmp       %w4, #4                         \n" 
     297      "b.lt      2f                              \n" 
     298 
     299      // TODO(frkoenig): Clean this up 
     300      // 4x8 block 
     301      "mov       %0, %1                          \n" 
     302      "ld1       {v0.8b}, [%0], %5               \n" 
     303      "ld1       {v1.8b}, [%0], %5               \n" 
     304      "ld1       {v2.8b}, [%0], %5               \n" 
     305      "ld1       {v3.8b}, [%0], %5               \n" 
     306      "ld1       {v4.8b}, [%0], %5               \n" 
     307      "ld1       {v5.8b}, [%0], %5               \n" 
     308      "ld1       {v6.8b}, [%0], %5               \n" 
     309      "ld1       {v7.8b}, [%0]                   \n" 
     310 
     311      "ld1       {v30.16b}, [%8], #16            \n" 
     312      "ld1       {v31.16b}, [%8]                 \n" 
     313 
     314      "tbl       v16.16b, {v0.16b, v1.16b, v2.16b, v3.16b}, v30.16b  \n" 
     315      "tbl       v17.16b, {v0.16b, v1.16b, v2.16b, v3.16b}, v31.16b  \n" 
     316      "tbl       v18.16b, {v4.16b, v5.16b, v6.16b, v7.16b}, v30.16b  \n" 
     317      "tbl       v19.16b, {v4.16b, v5.16b, v6.16b, v7.16b}, v31.16b  \n" 
     318 
     319      "mov       %0, %2                          \n" 
     320 
     321      "st1       {v16.s}[0],  [%0], %6           \n" 
     322      "st1       {v16.s}[1],  [%0], %6           \n" 
     323      "st1       {v16.s}[2],  [%0], %6           \n" 
     324      "st1       {v16.s}[3],  [%0], %6           \n" 
     325 
     326      "add       %0, %2, #4                      \n" 
     327      "st1       {v18.s}[0], [%0], %6            \n" 
     328      "st1       {v18.s}[1], [%0], %6            \n" 
     329      "st1       {v18.s}[2], [%0], %6            \n" 
     330      "st1       {v18.s}[3], [%0]                \n" 
     331 
     332      "mov       %0, %3                          \n" 
     333 
     334      "st1       {v17.s}[0], [%0], %7            \n" 
     335      "st1       {v17.s}[1], [%0], %7            \n" 
     336      "st1       {v17.s}[2], [%0], %7            \n" 
     337      "st1       {v17.s}[3], [%0], %7            \n" 
     338 
     339      "add       %0, %3, #4                      \n" 
     340      "st1       {v19.s}[0],  [%0], %7           \n" 
     341      "st1       {v19.s}[1],  [%0], %7           \n" 
     342      "st1       {v19.s}[2],  [%0], %7           \n" 
     343      "st1       {v19.s}[3],  [%0]               \n" 
     344 
     345      "add       %1, %1, #8                      \n"  // src   += 4 * 2 
     346      "add       %2, %2, %6, lsl #2              \n"  // dst_a += 4 * 
     347                                                      // dst_stride_a 
     348      "add       %3, %3, %7, lsl #2              \n"  // dst_b += 4 * 
     349                                                      // dst_stride_b 
     350      "subs      %w4,  %w4,  #4                  \n"  // w     -= 4 
     351      "b.eq      4f                              \n" 
     352 
     353      // some residual, check to see if it includes a 2x8 block, 
     354      // or less 
     355      "cmp       %w4, #2                         \n" 
     356      "b.lt      3f                              \n" 
     357 
     358      // 2x8 block 
     359      "2:                                        \n" 
     360      "mov       %0, %1                          \n" 
     361      "ld2       {v0.h, v1.h}[0], [%0], %5       \n" 
     362      "ld2       {v2.h, v3.h}[0], [%0], %5       \n" 
     363      "ld2       {v0.h, v1.h}[1], [%0], %5       \n" 
     364      "ld2       {v2.h, v3.h}[1], [%0], %5       \n" 
     365      "ld2       {v0.h, v1.h}[2], [%0], %5       \n" 
     366      "ld2       {v2.h, v3.h}[2], [%0], %5       \n" 
     367      "ld2       {v0.h, v1.h}[3], [%0], %5       \n" 
     368      "ld2       {v2.h, v3.h}[3], [%0]           \n" 
     369 
     370      "trn1      v4.8b, v0.8b, v2.8b             \n" 
     371      "trn2      v5.8b, v0.8b, v2.8b             \n" 
     372      "trn1      v6.8b, v1.8b, v3.8b             \n" 
     373      "trn2      v7.8b, v1.8b, v3.8b             \n" 
     374 
     375      "mov       %0, %2                          \n" 
     376 
     377      "st1       {v4.d}[0], [%0], %6             \n" 
     378      "st1       {v6.d}[0], [%0]                 \n" 
     379 
     380      "mov       %0, %3                          \n" 
     381 
     382      "st1       {v5.d}[0], [%0], %7             \n" 
     383      "st1       {v7.d}[0], [%0]                 \n" 
     384 
     385      "add       %1, %1, #4                      \n"  // src   += 2 * 2 
     386      "add       %2, %2, %6, lsl #1              \n"  // dst_a += 2 * 
     387                                                      // dst_stride_a 
     388      "add       %3, %3, %7, lsl #1              \n"  // dst_b += 2 * 
     389                                                      // dst_stride_b 
     390      "subs      %w4,  %w4,  #2                  \n"  // w     -= 2 
     391      "b.eq      4f                              \n" 
     392 
     393      // 1x8 block 
     394      "3:                                        \n" 
     395      "ld2       {v0.b, v1.b}[0], [%1], %5       \n" 
     396      "ld2       {v0.b, v1.b}[1], [%1], %5       \n" 
     397      "ld2       {v0.b, v1.b}[2], [%1], %5       \n" 
     398      "ld2       {v0.b, v1.b}[3], [%1], %5       \n" 
     399      "ld2       {v0.b, v1.b}[4], [%1], %5       \n" 
     400      "ld2       {v0.b, v1.b}[5], [%1], %5       \n" 
     401      "ld2       {v0.b, v1.b}[6], [%1], %5       \n" 
     402      "ld2       {v0.b, v1.b}[7], [%1]           \n" 
     403 
     404      "st1       {v0.d}[0], [%2]                 \n" 
     405      "st1       {v1.d}[0], [%3]                 \n" 
     406 
     407      "4:                                        \n" 
     408 
     409      : "=&r"(src_temp),                            // %0 
     410        "+r"(src),                                  // %1 
     411        "+r"(dst_a),                                // %2 
     412        "+r"(dst_b),                                // %3 
     413        "+r"(width)                                 // %4 
     414      : "r"(static_cast<ptrdiff_t>(src_stride)),    // %5 
     415        "r"(static_cast<ptrdiff_t>(dst_stride_a)),  // %6 
     416        "r"(static_cast<ptrdiff_t>(dst_stride_b)),  // %7 
     417        "r"(&kVTbl4x4TransposeDi)                   // %8 
     418      : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", 
     419        "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v30", "v31"); 
    418420} 
    419421#endif  // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) 
  • pjproject/trunk/third_party/yuv/source/rotate_win.cc

    r5633 r5699  
    1818 
    1919// This module is for 32 bit Visual C x86 and clangcl 
    20 #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) 
     20#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) 
    2121 
    2222__declspec(naked) void TransposeWx8_SSSE3(const uint8* src, 
     
    173173    lea       eax, [eax + 8 * edi + 16] 
    174174    neg       edi 
    175     // Second round of bit swap. 
     175        // Second round of bit swap. 
    176176    movdqa    xmm5, xmm0 
    177177    punpcklwd xmm0, xmm2 
     
    193193    movdqa    xmm7, xmm6 
    194194 
    195     // Third round of bit swap. 
    196     // Write to the destination pointer. 
     195        // Third round of bit swap. 
     196        // Write to the destination pointer. 
    197197    movdqa    xmm6, xmm0 
    198198    punpckldq xmm0, xmm4 
  • pjproject/trunk/third_party/yuv/source/row_any.cc

    r5633 r5699  
    8585           SS(r, DUVSHIFT) * BPP);                                         \ 
    8686  } 
     87 
     88// Merge functions. 
     89#ifdef HAS_MERGERGBROW_SSSE3 
     90ANY31(MergeRGBRow_Any_SSSE3, MergeRGBRow_SSSE3, 0, 0, 3, 15) 
     91#endif 
     92#ifdef HAS_MERGERGBROW_NEON 
     93ANY31(MergeRGBRow_Any_NEON, MergeRGBRow_NEON, 0, 0, 3, 15) 
     94#endif 
    8795#ifdef HAS_I422TOYUY2ROW_SSE2 
    8896ANY31(I422ToYUY2Row_Any_SSE2, I422ToYUY2Row_SSE2, 1, 1, 4, 15) 
     
    622630ANY11(ARGBExtractAlphaRow_Any_NEON, ARGBExtractAlphaRow_NEON, 0, 4, 1, 15) 
    623631#endif 
     632#ifdef HAS_ARGBEXTRACTALPHAROW_MSA 
     633ANY11(ARGBExtractAlphaRow_Any_MSA, ARGBExtractAlphaRow_MSA, 0, 4, 1, 15) 
     634#endif 
    624635#undef ANY11 
    625636 
     
    746757ANY11P16(HalfFloatRow_Any_NEON, HalfFloatRow_NEON, float, 2, 2, 7) 
    747758ANY11P16(HalfFloat1Row_Any_NEON, HalfFloat1Row_NEON, float, 2, 2, 7) 
     759#endif 
     760#ifdef HAS_HALFFLOATROW_MSA 
     761ANY11P16(HalfFloatRow_Any_MSA, HalfFloatRow_MSA, float, 2, 2, 31) 
    748762#endif 
    749763#undef ANY11P16 
     
    912926ANY12(SplitUVRow_Any_DSPR2, SplitUVRow_DSPR2, 0, 2, 0, 15) 
    913927#endif 
     928#ifdef HAS_SPLITUVROW_MSA 
     929ANY12(SplitUVRow_Any_MSA, SplitUVRow_MSA, 0, 2, 0, 31) 
     930#endif 
    914931#ifdef HAS_ARGBTOUV444ROW_SSSE3 
    915932ANY12(ARGBToUV444Row_Any_SSSE3, ARGBToUV444Row_SSSE3, 0, 4, 0, 15) 
     
    934951#endif 
    935952#undef ANY12 
     953 
     954// Any 1 to 3.  Outputs RGB planes. 
     955#define ANY13(NAMEANY, ANY_SIMD, BPP, MASK)                                    \ 
     956  void NAMEANY(const uint8* src_ptr, uint8* dst_r, uint8* dst_g, uint8* dst_b, \ 
     957               int width) {                                                    \ 
     958    SIMD_ALIGNED(uint8 temp[16 * 6]);                                          \ 
     959    memset(temp, 0, 16 * 3); /* for msan */                                    \ 
     960    int r = width & MASK;                                                      \ 
     961    int n = width & ~MASK;                                                     \ 
     962    if (n > 0) {                                                               \ 
     963      ANY_SIMD(src_ptr, dst_r, dst_g, dst_b, n);                               \ 
     964    }                                                                          \ 
     965    memcpy(temp, src_ptr + n * BPP, r * BPP);                                  \ 
     966    ANY_SIMD(temp, temp + 16 * 3, temp + 16 * 4, temp + 16 * 5, MASK + 1);     \ 
     967    memcpy(dst_r + n, temp + 16 * 3, r);                                       \ 
     968    memcpy(dst_g + n, temp + 16 * 4, r);                                       \ 
     969    memcpy(dst_b + n, temp + 16 * 5, r);                                       \ 
     970  } 
     971 
     972#ifdef HAS_SPLITRGBROW_SSSE3 
     973ANY13(SplitRGBRow_Any_SSSE3, SplitRGBRow_SSSE3, 3, 15) 
     974#endif 
     975#ifdef HAS_SPLITRGBROW_NEON 
     976ANY13(SplitRGBRow_Any_NEON, SplitRGBRow_NEON, 3, 15) 
     977#endif 
    936978 
    937979// Any 1 to 2 with source stride (2 rows of source).  Outputs UV planes. 
  • pjproject/trunk/third_party/yuv/source/row_common.cc

    r5633 r5699  
    17711771} 
    17721772 
     1773void SplitRGBRow_C(const uint8* src_rgb, 
     1774                   uint8* dst_r, 
     1775                   uint8* dst_g, 
     1776                   uint8* dst_b, 
     1777                   int width) { 
     1778  int x; 
     1779  for (x = 0; x < width; ++x) { 
     1780    dst_r[x] = src_rgb[0]; 
     1781    dst_g[x] = src_rgb[1]; 
     1782    dst_b[x] = src_rgb[2]; 
     1783    src_rgb += 3; 
     1784  } 
     1785} 
     1786 
     1787void MergeRGBRow_C(const uint8* src_r, 
     1788                   const uint8* src_g, 
     1789                   const uint8* src_b, 
     1790                   uint8* dst_rgb, 
     1791                   int width) { 
     1792  int x; 
     1793  for (x = 0; x < width; ++x) { 
     1794    dst_rgb[0] = src_r[x]; 
     1795    dst_rgb[1] = src_g[x]; 
     1796    dst_rgb[2] = src_b[x]; 
     1797    dst_rgb += 3; 
     1798  } 
     1799} 
     1800 
     1801void MergeUVRow_16_C(const uint16* src_u, 
     1802                     const uint16* src_v, 
     1803                     uint16* dst_uv, 
     1804                     int scale, 
     1805                     int width) { 
     1806  int x; 
     1807  for (x = 0; x < width - 1; x += 2) { 
     1808    dst_uv[0] = src_u[x] * scale; 
     1809    dst_uv[1] = src_v[x] * scale; 
     1810    dst_uv[2] = src_u[x + 1] * scale; 
     1811    dst_uv[3] = src_v[x + 1] * scale; 
     1812    dst_uv += 4; 
     1813  } 
     1814  if (width & 1) { 
     1815    dst_uv[0] = src_u[width - 1] * scale; 
     1816    dst_uv[1] = src_v[width - 1] * scale; 
     1817  } 
     1818} 
     1819 
     1820void MultiplyRow_16_C(const uint16* src_y, 
     1821                      uint16* dst_y, 
     1822                      int scale, 
     1823                      int width) { 
     1824  int x; 
     1825  for (x = 0; x < width; ++x) { 
     1826    dst_y[x] = src_y[x] * scale; 
     1827  } 
     1828} 
     1829 
    17731830void CopyRow_C(const uint8* src, uint8* dst, int count) { 
    17741831  memcpy(dst, src, count); 
     
    26402697#endif 
    26412698 
     2699float ScaleSumSamples_C(const float* src, float* dst, float scale, int width) { 
     2700  float fsum = 0.f; 
     2701  int i; 
     2702#if defined(__clang__) 
     2703#pragma clang loop vectorize_width(4) 
     2704#endif 
     2705  for (i = 0; i < width; ++i) { 
     2706    float v = *src++; 
     2707    fsum += v * v; 
     2708    *dst++ = v * scale; 
     2709  } 
     2710  return fsum; 
     2711} 
     2712 
     2713float ScaleMaxSamples_C(const float* src, float* dst, float scale, int width) { 
     2714  float fmax = 0.f; 
     2715  int i; 
     2716  for (i = 0; i < width; ++i) { 
     2717    float v = *src++; 
     2718    float vs = v * scale; 
     2719    fmax = (v > fmax) ? v : fmax; 
     2720    *dst++ = vs; 
     2721  } 
     2722  return fmax; 
     2723} 
     2724 
     2725void ScaleSamples_C(const float* src, float* dst, float scale, int width) { 
     2726  int i; 
     2727  for (i = 0; i < width; ++i) { 
     2728    *dst++ = *src++ * scale; 
     2729  } 
     2730} 
     2731 
     2732void GaussRow_C(const uint32* src, uint16* dst, int width) { 
     2733  int i; 
     2734  for (i = 0; i < width; ++i) { 
     2735    *dst++ = 
     2736        (src[0] + src[1] * 4 + src[2] * 6 + src[3] * 4 + src[4] + 128) >> 8; 
     2737    ++src; 
     2738  } 
     2739} 
     2740 
     2741// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. 
     2742void GaussCol_C(const uint16* src0, 
     2743                const uint16* src1, 
     2744                const uint16* src2, 
     2745                const uint16* src3, 
     2746                const uint16* src4, 
     2747                uint32* dst, 
     2748                int width) { 
     2749  int i; 
     2750  for (i = 0; i < width; ++i) { 
     2751    *dst++ = *src0++ + *src1++ * 4 + *src2++ * 6 + *src3++ * 4 + *src4++; 
     2752  } 
     2753} 
     2754 
    26422755#ifdef __cplusplus 
    26432756}  // extern "C" 
  • pjproject/trunk/third_party/yuv/source/row_gcc.cc

    r5633 r5699  
    3939                         127, -84, -43, 0, 127, -84, -43, 0}; 
    4040 
    41 static vec8 kARGBToV = { 
    42     -18, -94, 112, 0, -18, -94, 112, 0, -18, -94, 112, 0, -18, -94, 112, 0, 
    43 }; 
     41static vec8 kARGBToV = {-18, -94, 112, 0, -18, -94, 112, 0, 
     42                        -18, -94, 112, 0, -18, -94, 112, 0}; 
    4443 
    4544static vec8 kARGBToVJ = {-20, -107, 127, 0, -20, -107, 127, 0, 
     
    27542753} 
    27552754#endif  // HAS_MERGEUVROW_SSE2 
     2755 
     2756// Use scale to convert lsb formats to msb, depending how many bits there are: 
     2757// 128 = 9 bits 
     2758// 64 = 10 bits 
     2759// 16 = 12 bits 
     2760// 1 = 16 bits 
     2761#ifdef HAS_MERGEUVROW_16_AVX2 
     2762void MergeUVRow_16_AVX2(const uint16* src_u, 
     2763                        const uint16* src_v, 
     2764                        uint16* dst_uv, 
     2765                        int scale, 
     2766                        int width) { 
     2767  // clang-format off 
     2768  asm volatile ( 
     2769    "vmovd      %4,%%xmm3                      \n" 
     2770    "vpunpcklwd %%xmm3,%%xmm3,%%xmm3           \n" 
     2771    "vbroadcastss %%xmm3,%%ymm3                \n" 
     2772    "sub       %0,%1                           \n" 
     2773 
     2774    // 16 pixels per loop. 
     2775    LABELALIGN 
     2776    "1:                                        \n" 
     2777    "vmovdqu   (%0),%%ymm0                     \n" 
     2778    "vmovdqu   (%0,%1,1),%%ymm1                \n" 
     2779    "add        $0x20,%0                       \n" 
     2780 
     2781    "vpmullw   %%ymm3,%%ymm0,%%ymm0            \n" 
     2782    "vpmullw   %%ymm3,%%ymm1,%%ymm1            \n" 
     2783    "vpunpcklwd %%ymm1,%%ymm0,%%ymm2           \n"  // mutates 
     2784    "vpunpckhwd %%ymm1,%%ymm0,%%ymm0           \n" 
     2785    "vextractf128 $0x0,%%ymm2,(%2)             \n" 
     2786    "vextractf128 $0x0,%%ymm0,0x10(%2)         \n" 
     2787    "vextractf128 $0x1,%%ymm2,0x20(%2)         \n" 
     2788    "vextractf128 $0x1,%%ymm0,0x30(%2)         \n" 
     2789    "add       $0x40,%2                        \n" 
     2790    "sub       $0x10,%3                        \n" 
     2791    "jg        1b                              \n" 
     2792    "vzeroupper                                \n" 
     2793  : "+r"(src_u),   // %0 
     2794    "+r"(src_v),   // %1 
     2795    "+r"(dst_uv),  // %2 
     2796    "+r"(width)    // %3 
     2797  : "r"(scale)     // %4 
     2798  : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3"); 
     2799  // clang-format on 
     2800} 
     2801#endif  // HAS_MERGEUVROW_AVX2 
     2802 
     2803#ifdef HAS_MULTIPLYROW_16_AVX2 
     2804void MultiplyRow_16_AVX2(const uint16* src_y, 
     2805                         uint16* dst_y, 
     2806                         int scale, 
     2807                         int width) { 
     2808  // clang-format off 
     2809  asm volatile ( 
     2810    "vmovd      %3,%%xmm3                      \n" 
     2811    "vpunpcklwd %%xmm3,%%xmm3,%%xmm3           \n" 
     2812    "vbroadcastss %%xmm3,%%ymm3                \n" 
     2813    "sub       %0,%1                           \n" 
     2814 
     2815    // 16 pixels per loop. 
     2816    LABELALIGN 
     2817    "1:                                        \n" 
     2818    "vmovdqu   (%0),%%ymm0                     \n" 
     2819    "vmovdqu   0x20(%0),%%ymm1                 \n" 
     2820    "vpmullw   %%ymm3,%%ymm0,%%ymm0            \n" 
     2821    "vpmullw   %%ymm3,%%ymm1,%%ymm1            \n" 
     2822    "vmovdqu   %%ymm0,(%0,%1)                  \n" 
     2823    "vmovdqu   %%ymm1,0x20(%0,%1)              \n" 
     2824    "add        $0x40,%0                       \n" 
     2825    "sub       $0x20,%2                        \n" 
     2826    "jg        1b                              \n" 
     2827    "vzeroupper                                \n" 
     2828  : "+r"(src_y),   // %0 
     2829    "+r"(dst_y),   // %1 
     2830    "+r"(width)    // %2 
     2831  : "r"(scale)     // %3 
     2832  : "memory", "cc", "xmm0", "xmm1", "xmm3"); 
     2833  // clang-format on 
     2834} 
     2835#endif  // HAS_MULTIPLYROW_16_AVX2 
     2836 
     2837#ifdef HAS_SPLITRGBROW_SSSE3 
     2838 
     2839// Shuffle table for converting RGB to Planar. 
     2840static uvec8 kShuffleMaskRGBToR0 = {0u,   3u,   6u,   9u,   12u,  15u, 
     2841                                    128u, 128u, 128u, 128u, 128u, 128u, 
     2842                                    128u, 128u, 128u, 128u}; 
     2843static uvec8 kShuffleMaskRGBToR1 = {128u, 128u, 128u, 128u, 128u, 128u, 
     2844                                    2u,   5u,   8u,   11u,  14u,  128u, 
     2845                                    128u, 128u, 128u, 128u}; 
     2846static uvec8 kShuffleMaskRGBToR2 = {128u, 128u, 128u, 128u, 128u, 128u, 
     2847                                    128u, 128u, 128u, 128u, 128u, 1u, 
     2848                                    4u,   7u,   10u,  13u}; 
     2849 
     2850static uvec8 kShuffleMaskRGBToG0 = {1u,   4u,   7u,   10u,  13u,  128u, 
     2851                                    128u, 128u, 128u, 128u, 128u, 128u, 
     2852                                    128u, 128u, 128u, 128u}; 
     2853static uvec8 kShuffleMaskRGBToG1 = {128u, 128u, 128u, 128u, 128u, 0u, 
     2854                                    3u,   6u,   9u,   12u,  15u,  128u, 
     2855                                    128u, 128u, 128u, 128u}; 
     2856static uvec8 kShuffleMaskRGBToG2 = {128u, 128u, 128u, 128u, 128u, 128u, 
     2857                                    128u, 128u, 128u, 128u, 128u, 2u, 
     2858                                    5u,   8u,   11u,  14u}; 
     2859 
     2860static uvec8 kShuffleMaskRGBToB0 = {2u,   5u,   8u,   11u,  14u,  128u, 
     2861                                    128u, 128u, 128u, 128u, 128u, 128u, 
     2862                                    128u, 128u, 128u, 128u}; 
     2863static uvec8 kShuffleMaskRGBToB1 = {128u, 128u, 128u, 128u, 128u, 1u, 
     2864                                    4u,   7u,   10u,  13u,  128u, 128u, 
     2865                                    128u, 128u, 128u, 128u}; 
     2866static uvec8 kShuffleMaskRGBToB2 = {128u, 128u, 128u, 128u, 128u, 128u, 
     2867                                    128u, 128u, 128u, 128u, 0u,   3u, 
     2868                                    6u,   9u,   12u,  15u}; 
     2869 
     2870void SplitRGBRow_SSSE3(const uint8* src_rgb, 
     2871                       uint8* dst_r, 
     2872                       uint8* dst_g, 
     2873                       uint8* dst_b, 
     2874                       int width) { 
     2875  asm volatile ( 
     2876    LABELALIGN 
     2877    "1:                                        \n" 
     2878    "movdqu     " MEMACCESS(0) ",%%xmm0        \n" 
     2879    "movdqu     " MEMACCESS2(0x10,0) ",%%xmm1  \n" 
     2880    "movdqu     " MEMACCESS2(0x20,0) ",%%xmm2  \n" 
     2881    "pshufb     %5, %%xmm0                     \n" 
     2882    "pshufb     %6, %%xmm1                     \n" 
     2883    "pshufb     %7, %%xmm2                     \n" 
     2884    "por        %%xmm1,%%xmm0                  \n" 
     2885    "por        %%xmm2,%%xmm0                  \n" 
     2886    "movdqu     %%xmm0," MEMACCESS(1) "        \n" 
     2887    "lea        " MEMLEA(0x10,1) ",%1          \n" 
     2888 
     2889    "movdqu     " MEMACCESS(0) ",%%xmm0        \n" 
     2890    "movdqu     " MEMACCESS2(0x10,0) ",%%xmm1  \n" 
     2891    "movdqu     " MEMACCESS2(0x20,0) ",%%xmm2  \n" 
     2892    "pshufb     %8, %%xmm0                     \n" 
     2893    "pshufb     %9, %%xmm1                     \n" 
     2894    "pshufb     %10, %%xmm2                    \n" 
     2895    "por        %%xmm1,%%xmm0                  \n" 
     2896    "por        %%xmm2,%%xmm0                  \n" 
     2897    "movdqu     %%xmm0," MEMACCESS(2) "        \n" 
     2898    "lea        " MEMLEA(0x10,2) ",%2          \n" 
     2899 
     2900    "movdqu     " MEMACCESS(0) ",%%xmm0        \n" 
     2901    "movdqu     " MEMACCESS2(0x10,0) ",%%xmm1  \n" 
     2902    "movdqu     " MEMACCESS2(0x20,0) ",%%xmm2  \n" 
     2903    "pshufb     %11, %%xmm0                    \n" 
     2904    "pshufb     %12, %%xmm1                    \n" 
     2905    "pshufb     %13, %%xmm2                    \n" 
     2906    "por        %%xmm1,%%xmm0                  \n" 
     2907    "por        %%xmm2,%%xmm0                  \n" 
     2908    "movdqu     %%xmm0," MEMACCESS(3) "        \n" 
     2909    "lea        " MEMLEA(0x10,3) ",%3          \n" 
     2910    "lea        " MEMLEA(0x30,0) ",%0          \n" 
     2911    "sub        $0x10,%4                       \n" 
     2912    "jg         1b                             \n" 
     2913  : "+r"(src_rgb),              // %0 
     2914    "+r"(dst_r),                // %1 
     2915    "+r"(dst_g),                // %2 
     2916    "+r"(dst_b),                // %3 
     2917    "+r"(width)                 // %4 
     2918  : "m"(kShuffleMaskRGBToR0),   // %5 
     2919    "m"(kShuffleMaskRGBToR1),   // %6 
     2920    "m"(kShuffleMaskRGBToR2),   // %7 
     2921    "m"(kShuffleMaskRGBToG0),   // %8 
     2922    "m"(kShuffleMaskRGBToG1),   // %9 
     2923    "m"(kShuffleMaskRGBToG2),   // %10 
     2924    "m"(kShuffleMaskRGBToB0),   // %11 
     2925    "m"(kShuffleMaskRGBToB1),   // %12 
     2926    "m"(kShuffleMaskRGBToB2)    // %13 
     2927  : "memory", "cc", NACL_R14 
     2928    "xmm0", "xmm1", "xmm2" 
     2929  ); 
     2930} 
     2931#endif  // HAS_SPLITRGBROW_SSSE3 
     2932 
     2933#ifdef HAS_MERGERGBROW_SSSE3 
     2934 
     2935// Shuffle table for converting RGB to Planar. 
     2936static uvec8 kShuffleMaskRToRGB0 = {0u, 128u, 128u, 1u, 128u, 128u, 
     2937                                    2u, 128u, 128u, 3u, 128u, 128u, 
     2938                                    4u, 128u, 128u, 5u}; 
     2939static uvec8 kShuffleMaskGToRGB0 = {128u, 0u, 128u, 128u, 1u, 128u, 
     2940                                    128u, 2u, 128u, 128u, 3u, 128u, 
     2941                                    128u, 4u, 128u, 128u}; 
     2942static uvec8 kShuffleMaskBToRGB0 = {128u, 128u, 0u, 128u, 128u, 1u, 
     2943                                    128u, 128u, 2u, 128u, 128u, 3u, 
     2944                                    128u, 128u, 4u, 128u}; 
     2945 
     2946static uvec8 kShuffleMaskGToRGB1 = {5u, 128u, 128u, 6u, 128u, 128u, 
     2947                                    7u, 128u, 128u, 8u, 128u, 128u, 
     2948                                    9u, 128u, 128u, 10u}; 
     2949static uvec8 kShuffleMaskBToRGB1 = {128u, 5u, 128u, 128u, 6u, 128u, 
     2950                                    128u, 7u, 128u, 128u, 8u, 128u, 
     2951                                    128u, 9u, 128u, 128u}; 
     2952static uvec8 kShuffleMaskRToRGB1 = {128u, 128u, 6u,  128u, 128u, 7u, 
     2953                                    128u, 128u, 8u,  128u, 128u, 9u, 
     2954                                    128u, 128u, 10u, 128u}; 
     2955 
     2956static uvec8 kShuffleMaskBToRGB2 = {10u, 128u, 128u, 11u, 128u, 128u, 
     2957                                    12u, 128u, 128u, 13u, 128u, 128u, 
     2958                                    14u, 128u, 128u, 15u}; 
     2959static uvec8 kShuffleMaskRToRGB2 = {128u, 11u, 128u, 128u, 12u, 128u, 
     2960                                    128u, 13u, 128u, 128u, 14u, 128u, 
     2961                                    128u, 15u, 128u, 128u}; 
     2962static uvec8 kShuffleMaskGToRGB2 = {128u, 128u, 11u, 128u, 128u, 12u, 
     2963                                    128u, 128u, 13u, 128u, 128u, 14u, 
     2964                                    128u, 128u, 15u, 128u}; 
     2965 
     2966void MergeRGBRow_SSSE3(const uint8* src_r, 
     2967                       const uint8* src_g, 
     2968                       const uint8* src_b, 
     2969                       uint8* dst_rgb, 
     2970                       int width) { 
     2971  asm volatile ( 
     2972    LABELALIGN 
     2973    "1:                                        \n" 
     2974    "movdqu     " MEMACCESS(0) ",%%xmm0        \n" 
     2975    "movdqu     " MEMACCESS(1) ",%%xmm1        \n" 
     2976    "movdqu     " MEMACCESS(2) ",%%xmm2        \n" 
     2977    "pshufb     %5, %%xmm0                     \n" 
     2978    "pshufb     %6, %%xmm1                     \n" 
     2979    "pshufb     %7, %%xmm2                     \n" 
     2980    "por        %%xmm1,%%xmm0                  \n" 
     2981    "por        %%xmm2,%%xmm0                  \n" 
     2982    "movdqu     %%xmm0," MEMACCESS(3) "        \n" 
     2983 
     2984    "movdqu     " MEMACCESS(0) ",%%xmm0        \n" 
     2985    "movdqu     " MEMACCESS(1) ",%%xmm1        \n" 
     2986    "movdqu     " MEMACCESS(2) ",%%xmm2        \n" 
     2987    "pshufb     %8, %%xmm0                     \n" 
     2988    "pshufb     %9, %%xmm1                     \n" 
     2989    "pshufb     %10, %%xmm2                    \n" 
     2990    "por        %%xmm1,%%xmm0                  \n" 
     2991    "por        %%xmm2,%%xmm0                  \n" 
     2992    "movdqu     %%xmm0," MEMACCESS2(16, 3) "   \n" 
     2993 
     2994    "movdqu     " MEMACCESS(0) ",%%xmm0        \n" 
     2995    "movdqu     " MEMACCESS(1) ",%%xmm1        \n" 
     2996    "movdqu     " MEMACCESS(2) ",%%xmm2        \n" 
     2997    "pshufb     %11, %%xmm0                    \n" 
     2998    "pshufb     %12, %%xmm1                    \n" 
     2999    "pshufb     %13, %%xmm2                    \n" 
     3000    "por        %%xmm1,%%xmm0                  \n" 
     3001    "por        %%xmm2,%%xmm0                  \n" 
     3002    "movdqu     %%xmm0," MEMACCESS2(32, 3) "   \n" 
     3003 
     3004    "lea        " MEMLEA(0x10,0) ",%0          \n" 
     3005    "lea        " MEMLEA(0x10,1) ",%1          \n" 
     3006    "lea        " MEMLEA(0x10,2) ",%2          \n" 
     3007    "lea        " MEMLEA(0x30,3) ",%3          \n" 
     3008    "sub        $0x10,%4                       \n" 
     3009    "jg         1b                             \n" 
     3010  : "+r"(src_r),                // %0 
     3011    "+r"(src_g),                // %1 
     3012    "+r"(src_b),                // %2 
     3013    "+r"(dst_rgb),              // %3 
     3014    "+r"(width)                 // %4 
     3015  : "m"(kShuffleMaskRToRGB0),   // %5 
     3016    "m"(kShuffleMaskGToRGB0),   // %6 
     3017    "m"(kShuffleMaskBToRGB0),   // %7 
     3018    "m"(kShuffleMaskRToRGB1),   // %8 
     3019    "m"(kShuffleMaskGToRGB1),   // %9 
     3020    "m"(kShuffleMaskBToRGB1),   // %10 
     3021    "m"(kShuffleMaskRToRGB2),   // %11 
     3022    "m"(kShuffleMaskGToRGB2),   // %12 
     3023    "m"(kShuffleMaskBToRGB2)    // %13 
     3024  : "memory", "cc", NACL_R14 
     3025    "xmm0", "xmm1", "xmm2" 
     3026  ); 
     3027} 
     3028#endif  // HAS_MERGERGBROW_SSSE3 
    27563029 
    27573030#ifdef HAS_COPYROW_SSE2 
     
    54545727static float kScaleBias = 1.9259299444e-34f; 
    54555728void HalfFloatRow_SSE2(const uint16* src, uint16* dst, float scale, int width) { 
     5729  scale *= kScaleBias; 
    54565730  asm volatile ( 
    54575731    "pshufd      $0x0,%3,%%xmm4                \n" 
     
    54805754    "+r"(dst),    // %1 
    54815755    "+r"(width)   // %2 
    5482   : "x"(scale * kScaleBias)   // %3 
     5756#if defined(__x86_64__) 
     5757  : "x"(scale)   // %3 
     5758#else 
     5759  : "m"(scale)   // %3 
     5760#endif 
    54835761  : "memory", "cc", 
    54845762    "xmm2", "xmm3", "xmm4", "xmm5" 
     
    54895767#ifdef HAS_HALFFLOATROW_AVX2 
    54905768void HalfFloatRow_AVX2(const uint16* src, uint16* dst, float scale, int width) { 
     5769  scale *= kScaleBias; 
    54915770  asm volatile ( 
    54925771    "vbroadcastss  %3, %%ymm4                  \n" 
     
    55165795    "+r"(dst),    // %1 
    55175796    "+r"(width)   // %2 
    5518   : "x"(scale * kScaleBias)   // %3 
     5797#if defined(__x86_64__) 
     5798  : "x"(scale)   // %3 
     5799#else 
     5800  : "m"(scale)   // %3 
     5801#endif 
    55195802  : "memory", "cc", 
    55205803    "xmm2", "xmm3", "xmm4", "xmm5" 
     
    55495832    "+r"(dst),   // %1 
    55505833    "+r"(width)  // %2 
     5834#if defined(__x86_64__) 
    55515835  : "x"(scale)   // %3 
     5836#else 
     5837  : "m"(scale)   // %3 
     5838#endif 
    55525839  : "memory", "cc", 
    55535840    "xmm2", "xmm3", "xmm4" 
  • pjproject/trunk/third_party/yuv/source/row_msa.cc

    r5633 r5699  
    29182918void ARGBSetRow_MSA(uint8* dst_argb, uint32 v32, int width) { 
    29192919  int x; 
    2920   v16u8 dst0 = (v16u8)__msa_fill_w(v32); 
     2920  v4i32 dst0 = __builtin_msa_fill_w(v32); 
    29212921 
    29222922  for (x = 0; x < width; x += 4) { 
     
    29702970} 
    29712971 
     2972void ARGBExtractAlphaRow_MSA(const uint8* src_argb, uint8* dst_a, int width) { 
     2973  int i; 
     2974  v16u8 src0, src1, src2, src3, vec0, vec1, dst0; 
     2975 
     2976  for (i = 0; i < width; i += 16) { 
     2977    src0 = (v16u8)__msa_ld_b((v16i8*)src_argb, 0); 
     2978    src1 = (v16u8)__msa_ld_b((v16i8*)src_argb, 16); 
     2979    src2 = (v16u8)__msa_ld_b((v16i8*)src_argb, 32); 
     2980    src3 = (v16u8)__msa_ld_b((v16i8*)src_argb, 48); 
     2981    vec0 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); 
     2982    vec1 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); 
     2983    dst0 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec0); 
     2984    ST_UB(dst0, dst_a); 
     2985    src_argb += 64; 
     2986    dst_a += 16; 
     2987  } 
     2988} 
     2989 
     2990void ARGBBlendRow_MSA(const uint8* src_argb0, 
     2991                      const uint8* src_argb1, 
     2992                      uint8* dst_argb, 
     2993                      int width) { 
     2994  int x; 
     2995  v16u8 src0, src1, src2, src3, dst0, dst1; 
     2996  v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; 
     2997  v8u16 vec8, vec9, vec10, vec11, vec12, vec13; 
     2998  v8u16 const_256 = (v8u16)__msa_ldi_h(256); 
     2999  v16u8 const_255 = (v16u8)__msa_ldi_b(255); 
     3000  v16u8 mask = {0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255}; 
     3001  v16i8 zero = {0}; 
     3002 
     3003  for (x = 0; x < width; x += 8) { 
     3004    src0 = (v16u8)__msa_ld_b((v16i8*)src_argb0, 0); 
     3005    src1 = (v16u8)__msa_ld_b((v16i8*)src_argb0, 16); 
     3006    src2 = (v16u8)__msa_ld_b((v16i8*)src_argb1, 0); 
     3007    src3 = (v16u8)__msa_ld_b((v16i8*)src_argb1, 16); 
     3008    vec0 = (v8u16)__msa_ilvr_b(zero, (v16i8)src0); 
     3009    vec1 = (v8u16)__msa_ilvl_b(zero, (v16i8)src0); 
     3010    vec2 = (v8u16)__msa_ilvr_b(zero, (v16i8)src1); 
     3011    vec3 = (v8u16)__msa_ilvl_b(zero, (v16i8)src1); 
     3012    vec4 = (v8u16)__msa_ilvr_b(zero, (v16i8)src2); 
     3013    vec5 = (v8u16)__msa_ilvl_b(zero, (v16i8)src2); 
     3014    vec6 = (v8u16)__msa_ilvr_b(zero, (v16i8)src3); 
     3015    vec7 = (v8u16)__msa_ilvl_b(zero, (v16i8)src3); 
     3016    vec8 = (v8u16)__msa_fill_h(vec0[3]); 
     3017    vec9 = (v8u16)__msa_fill_h(vec0[7]); 
     3018    vec10 = (v8u16)__msa_fill_h(vec1[3]); 
     3019    vec11 = (v8u16)__msa_fill_h(vec1[7]); 
     3020    vec8 = (v8u16)__msa_pckev_d((v2i64)vec9, (v2i64)vec8); 
     3021    vec9 = (v8u16)__msa_pckev_d((v2i64)vec11, (v2i64)vec10); 
     3022    vec10 = (v8u16)__msa_fill_h(vec2[3]); 
     3023    vec11 = (v8u16)__msa_fill_h(vec2[7]); 
     3024    vec12 = (v8u16)__msa_fill_h(vec3[3]); 
     3025    vec13 = (v8u16)__msa_fill_h(vec3[7]); 
     3026    vec10 = (v8u16)__msa_pckev_d((v2i64)vec11, (v2i64)vec10); 
     3027    vec11 = (v8u16)__msa_pckev_d((v2i64)vec13, (v2i64)vec12); 
     3028    vec8 = const_256 - vec8; 
     3029    vec9 = const_256 - vec9; 
     3030    vec10 = const_256 - vec10; 
     3031    vec11 = const_256 - vec11; 
     3032    vec8 *= vec4; 
     3033    vec9 *= vec5; 
     3034    vec10 *= vec6; 
     3035    vec11 *= vec7; 
     3036    vec8 = (v8u16)__msa_srai_h((v8i16)vec8, 8); 
     3037    vec9 = (v8u16)__msa_srai_h((v8i16)vec9, 8); 
     3038    vec10 = (v8u16)__msa_srai_h((v8i16)vec10, 8); 
     3039    vec11 = (v8u16)__msa_srai_h((v8i16)vec11, 8); 
     3040    vec0 += vec8; 
     3041    vec1 += vec9; 
     3042    vec2 += vec10; 
     3043    vec3 += vec11; 
     3044    dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); 
     3045    dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); 
     3046    dst0 = __msa_bmnz_v(dst0, const_255, mask); 
     3047    dst1 = __msa_bmnz_v(dst1, const_255, mask); 
     3048    ST_UB2(dst0, dst1, dst_argb, 16); 
     3049    src_argb0 += 32; 
     3050    src_argb1 += 32; 
     3051    dst_argb += 32; 
     3052  } 
     3053} 
     3054 
     3055void ARGBQuantizeRow_MSA(uint8* dst_argb, 
     3056                         int scale, 
     3057                         int interval_size, 
     3058                         int interval_offset, 
     3059                         int width) { 
     3060  int x; 
     3061  v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3; 
     3062  v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; 
     3063  v4i32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; 
     3064  v4i32 tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; 
     3065  v4i32 vec_scale = __msa_fill_w(scale); 
     3066  v16u8 vec_int_sz = (v16u8)__msa_fill_b(interval_size); 
     3067  v16u8 vec_int_ofst = (v16u8)__msa_fill_b(interval_offset); 
     3068  v16i8 mask = {0, 1, 2, 19, 4, 5, 6, 23, 8, 9, 10, 27, 12, 13, 14, 31}; 
     3069  v16i8 zero = {0}; 
     3070 
     3071  for (x = 0; x < width; x += 8) { 
     3072    src0 = (v16u8)__msa_ld_b((v16i8*)dst_argb, 0); 
     3073    src1 = (v16u8)__msa_ld_b((v16i8*)dst_argb, 16); 
     3074    src2 = (v16u8)__msa_ld_b((v16i8*)dst_argb, 32); 
     3075    src3 = (v16u8)__msa_ld_b((v16i8*)dst_argb, 48); 
     3076    vec0 = (v8i16)__msa_ilvr_b(zero, (v16i8)src0); 
     3077    vec1 = (v8i16)__msa_ilvl_b(zero, (v16i8)src0); 
     3078    vec2 = (v8i16)__msa_ilvr_b(zero, (v16i8)src1); 
     3079    vec3 = (v8i16)__msa_ilvl_b(zero, (v16i8)src1); 
     3080    vec4 = (v8i16)__msa_ilvr_b(zero, (v16i8)src2); 
     3081    vec5 = (v8i16)__msa_ilvl_b(zero, (v16i8)src2); 
     3082    vec6 = (v8i16)__msa_ilvr_b(zero, (v16i8)src3); 
     3083    vec7 = (v8i16)__msa_ilvl_b(zero, (v16i8)src3); 
     3084    tmp0 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec0); 
     3085    tmp1 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec0); 
     3086    tmp2 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec1); 
     3087    tmp3 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec1); 
     3088    tmp4 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec2); 
     3089    tmp5 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec2); 
     3090    tmp6 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec3); 
     3091    tmp7 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec3); 
     3092    tmp8 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec4); 
     3093    tmp9 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec4); 
     3094    tmp10 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec5); 
     3095    tmp11 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec5); 
     3096    tmp12 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec6); 
     3097    tmp13 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec6); 
     3098    tmp14 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec7); 
     3099    tmp15 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec7); 
     3100    tmp0 *= vec_scale; 
     3101    tmp1 *= vec_scale; 
     3102    tmp2 *= vec_scale; 
     3103    tmp3 *= vec_scale; 
     3104    tmp4 *= vec_scale; 
     3105    tmp5 *= vec_scale; 
     3106    tmp6 *= vec_scale; 
     3107    tmp7 *= vec_scale; 
     3108    tmp8 *= vec_scale; 
     3109    tmp9 *= vec_scale; 
     3110    tmp10 *= vec_scale; 
     3111    tmp11 *= vec_scale; 
     3112    tmp12 *= vec_scale; 
     3113    tmp13 *= vec_scale; 
     3114    tmp14 *= vec_scale; 
     3115    tmp15 *= vec_scale; 
     3116    tmp0 >>= 16; 
     3117    tmp1 >>= 16; 
     3118    tmp2 >>= 16; 
     3119    tmp3 >>= 16; 
     3120    tmp4 >>= 16; 
     3121    tmp5 >>= 16; 
     3122    tmp6 >>= 16; 
     3123    tmp7 >>= 16; 
     3124    tmp8 >>= 16; 
     3125    tmp9 >>= 16; 
     3126    tmp10 >>= 16; 
     3127    tmp11 >>= 16; 
     3128    tmp12 >>= 16; 
     3129    tmp13 >>= 16; 
     3130    tmp14 >>= 16; 
     3131    tmp15 >>= 16; 
     3132    vec0 = (v8i16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); 
     3133    vec1 = (v8i16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); 
     3134    vec2 = (v8i16)__msa_pckev_h((v8i16)tmp5, (v8i16)tmp4); 
     3135    vec3 = (v8i16)__msa_pckev_h((v8i16)tmp7, (v8i16)tmp6); 
     3136    vec4 = (v8i16)__msa_pckev_h((v8i16)tmp9, (v8i16)tmp8); 
     3137    vec5 = (v8i16)__msa_pckev_h((v8i16)tmp11, (v8i16)tmp10); 
     3138    vec6 = (v8i16)__msa_pckev_h((v8i16)tmp13, (v8i16)tmp12); 
     3139    vec7 = (v8i16)__msa_pckev_h((v8i16)tmp15, (v8i16)tmp14); 
     3140    dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); 
     3141    dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); 
     3142    dst2 = (v16u8)__msa_pckev_b((v16i8)vec5, (v16i8)vec4); 
     3143    dst3 = (v16u8)__msa_pckev_b((v16i8)vec7, (v16i8)vec6); 
     3144    dst0 *= vec_int_sz; 
     3145    dst1 *= vec_int_sz; 
     3146    dst2 *= vec_int_sz; 
     3147    dst3 *= vec_int_sz; 
     3148    dst0 += vec_int_ofst; 
     3149    dst1 += vec_int_ofst; 
     3150    dst2 += vec_int_ofst; 
     3151    dst3 += vec_int_ofst; 
     3152    dst0 = (v16u8)__msa_vshf_b(mask, (v16i8)src0, (v16i8)dst0); 
     3153    dst1 = (v16u8)__msa_vshf_b(mask, (v16i8)src1, (v16i8)dst1); 
     3154    dst2 = (v16u8)__msa_vshf_b(mask, (v16i8)src2, (v16i8)dst2); 
     3155    dst3 = (v16u8)__msa_vshf_b(mask, (v16i8)src3, (v16i8)dst3); 
     3156    ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); 
     3157    dst_argb += 64; 
     3158  } 
     3159} 
     3160 
     3161void ARGBColorMatrixRow_MSA(const uint8* src_argb, 
     3162                            uint8* dst_argb, 
     3163                            const int8* matrix_argb, 
     3164                            int width) { 
     3165  int32 x; 
     3166  v16i8 src0; 
     3167  v16u8 src1, src2, dst0, dst1; 
     3168  v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; 
     3169  v8i16 vec10, vec11, vec12, vec13, vec14, vec15, vec16, vec17; 
     3170  v4i32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; 
     3171  v4i32 tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; 
     3172  v16i8 zero = {0}; 
     3173  v8i16 max = __msa_ldi_h(255); 
     3174 
     3175  src0 = __msa_ld_b((v16i8*)matrix_argb, 0); 
     3176  vec0 = (v8i16)__msa_ilvr_b(zero, src0); 
     3177  vec1 = (v8i16)__msa_ilvl_b(zero, src0); 
     3178 
     3179  for (x = 0; x < width; x += 8) { 
     3180    src1 = (v16u8)__msa_ld_b((v16i8*)src_argb, 0); 
     3181    src2 = (v16u8)__msa_ld_b((v16i8*)src_argb, 16); 
     3182    vec2 = (v8i16)__msa_ilvr_b(zero, (v16i8)src1); 
     3183    vec3 = (v8i16)__msa_ilvl_b(zero, (v16i8)src1); 
     3184    vec4 = (v8i16)__msa_ilvr_b(zero, (v16i8)src2); 
     3185    vec5 = (v8i16)__msa_ilvl_b(zero, (v16i8)src2); 
     3186    vec6 = (v8i16)__msa_pckod_d((v2i64)vec2, (v2i64)vec2); 
     3187    vec7 = (v8i16)__msa_pckod_d((v2i64)vec3, (v2i64)vec3); 
     3188    vec8 = (v8i16)__msa_pckod_d((v2i64)vec4, (v2i64)vec4); 
     3189    vec9 = (v8i16)__msa_pckod_d((v2i64)vec5, (v2i64)vec5); 
     3190    vec2 = (v8i16)__msa_pckev_d((v2i64)vec2, (v2i64)vec2); 
     3191    vec3 = (v8i16)__msa_pckev_d((v2i64)vec3, (v2i64)vec3); 
     3192    vec4 = (v8i16)__msa_pckev_d((v2i64)vec4, (v2i64)vec4); 
     3193    vec5 = (v8i16)__msa_pckev_d((v2i64)vec5, (v2i64)vec5); 
     3194    vec10 = vec2 * vec0; 
     3195    vec11 = vec2 * vec1; 
     3196    vec12 = vec6 * vec0; 
     3197    vec13 = vec6 * vec1; 
     3198    tmp0 = __msa_hadd_s_w(vec10, vec10); 
     3199    tmp1 = __msa_hadd_s_w(vec11, vec11); 
     3200    tmp2 = __msa_hadd_s_w(vec12, vec12); 
     3201    tmp3 = __msa_hadd_s_w(vec13, vec13); 
     3202    vec14 = vec3 * vec0; 
     3203    vec15 = vec3 * vec1; 
     3204    vec16 = vec7 * vec0; 
     3205    vec17 = vec7 * vec1; 
     3206    tmp4 = __msa_hadd_s_w(vec14, vec14); 
     3207    tmp5 = __msa_hadd_s_w(vec15, vec15); 
     3208    tmp6 = __msa_hadd_s_w(vec16, vec16); 
     3209    tmp7 = __msa_hadd_s_w(vec17, vec17); 
     3210    vec10 = __msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); 
     3211    vec11 = __msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); 
     3212    vec12 = __msa_pckev_h((v8i16)tmp5, (v8i16)tmp4); 
     3213    vec13 = __msa_pckev_h((v8i16)tmp7, (v8i16)tmp6); 
     3214    tmp0 = __msa_hadd_s_w(vec10, vec10); 
     3215    tmp1 = __msa_hadd_s_w(vec11, vec11); 
     3216    tmp2 = __msa_hadd_s_w(vec12, vec12); 
     3217    tmp3 = __msa_hadd_s_w(vec13, vec13); 
     3218    tmp0 = __msa_srai_w(tmp0, 6); 
     3219    tmp1 = __msa_srai_w(tmp1, 6); 
     3220    tmp2 = __msa_srai_w(tmp2, 6); 
     3221    tmp3 = __msa_srai_w(tmp3, 6); 
     3222    vec2 = vec4 * vec0; 
     3223    vec6 = vec4 * vec1; 
     3224    vec3 = vec8 * vec0; 
     3225    vec7 = vec8 * vec1; 
     3226    tmp8 = __msa_hadd_s_w(vec2, vec2); 
     3227    tmp9 = __msa_hadd_s_w(vec6, vec6); 
     3228    tmp10 = __msa_hadd_s_w(vec3, vec3); 
     3229    tmp11 = __msa_hadd_s_w(vec7, vec7); 
     3230    vec4 = vec5 * vec0; 
     3231    vec8 = vec5 * vec1; 
     3232    vec5 = vec9 * vec0; 
     3233    vec9 = vec9 * vec1; 
     3234    tmp12 = __msa_hadd_s_w(vec4, vec4); 
     3235    tmp13 = __msa_hadd_s_w(vec8, vec8); 
     3236    tmp14 = __msa_hadd_s_w(vec5, vec5); 
     3237    tmp15 = __msa_hadd_s_w(vec9, vec9); 
     3238    vec14 = __msa_pckev_h((v8i16)tmp9, (v8i16)tmp8); 
     3239    vec15 = __msa_pckev_h((v8i16)tmp11, (v8i16)tmp10); 
     3240    vec16 = __msa_pckev_h((v8i16)tmp13, (v8i16)tmp12); 
     3241    vec17 = __msa_pckev_h((v8i16)tmp15, (v8i16)tmp14); 
     3242    tmp4 = __msa_hadd_s_w(vec14, vec14); 
     3243    tmp5 = __msa_hadd_s_w(vec15, vec15); 
     3244    tmp6 = __msa_hadd_s_w(vec16, vec16); 
     3245    tmp7 = __msa_hadd_s_w(vec17, vec17); 
     3246    tmp4 = __msa_srai_w(tmp4, 6); 
     3247    tmp5 = __msa_srai_w(tmp5, 6); 
     3248    tmp6 = __msa_srai_w(tmp6, 6); 
     3249    tmp7 = __msa_srai_w(tmp7, 6); 
     3250    vec10 = __msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); 
     3251    vec11 = __msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); 
     3252    vec12 = __msa_pckev_h((v8i16)tmp5, (v8i16)tmp4); 
     3253    vec13 = __msa_pckev_h((v8i16)tmp7, (v8i16)tmp6); 
     3254    vec10 = __msa_maxi_s_h(vec10, 0); 
     3255    vec11 = __msa_maxi_s_h(vec11, 0); 
     3256    vec12 = __msa_maxi_s_h(vec12, 0); 
     3257    vec13 = __msa_maxi_s_h(vec13, 0); 
     3258    vec10 = __msa_min_s_h(vec10, max); 
     3259    vec11 = __msa_min_s_h(vec11, max); 
     3260    vec12 = __msa_min_s_h(vec12, max); 
     3261    vec13 = __msa_min_s_h(vec13, max); 
     3262    dst0 = (v16u8)__msa_pckev_b((v16i8)vec11, (v16i8)vec10); 
     3263    dst1 = (v16u8)__msa_pckev_b((v16i8)vec13, (v16i8)vec12); 
     3264    ST_UB2(dst0, dst1, dst_argb, 16); 
     3265    src_argb += 32; 
     3266    dst_argb += 32; 
     3267  } 
     3268} 
     3269 
     3270void SplitUVRow_MSA(const uint8* src_uv, 
     3271                    uint8* dst_u, 
     3272                    uint8* dst_v, 
     3273                    int width) { 
     3274  int x; 
     3275  v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3; 
     3276 
     3277  for (x = 0; x < width; x += 32) { 
     3278    src0 = (v16u8)__msa_ld_b((v16i8*)src_uv, 0); 
     3279    src1 = (v16u8)__msa_ld_b((v16i8*)src_uv, 16); 
     3280    src2 = (v16u8)__msa_ld_b((v16i8*)src_uv, 32); 
     3281    src3 = (v16u8)__msa_ld_b((v16i8*)src_uv, 48); 
     3282    dst0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); 
     3283    dst1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); 
     3284    dst2 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); 
     3285    dst3 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); 
     3286    ST_UB2(dst0, dst1, dst_u, 16); 
     3287    ST_UB2(dst2, dst3, dst_v, 16); 
     3288    src_uv += 64; 
     3289    dst_u += 32; 
     3290    dst_v += 32; 
     3291  } 
     3292} 
     3293 
     3294void SetRow_MSA(uint8* dst, uint8 v8, int width) { 
     3295  int x; 
     3296  v16u8 dst0 = (v16u8)__msa_fill_b(v8); 
     3297 
     3298  for (x = 0; x < width; x += 16) { 
     3299    ST_UB(dst0, dst); 
     3300    dst += 16; 
     3301  } 
     3302} 
     3303 
     3304void MirrorUVRow_MSA(const uint8* src_uv, 
     3305                     uint8* dst_u, 
     3306                     uint8* dst_v, 
     3307                     int width) { 
     3308  int x; 
     3309  v16u8 src0, src1, src2, src3; 
     3310  v16u8 dst0, dst1, dst2, dst3; 
     3311  v16i8 mask0 = {30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0}; 
     3312  v16i8 mask1 = {31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1}; 
     3313 
     3314  src_uv += (2 * width); 
     3315 
     3316  for (x = 0; x < width; x += 32) { 
     3317    src_uv -= 64; 
     3318    src2 = (v16u8)__msa_ld_b((v16i8*)src_uv, 0); 
     3319    src3 = (v16u8)__msa_ld_b((v16i8*)src_uv, 16); 
     3320    src0 = (v16u8)__msa_ld_b((v16i8*)src_uv, 32); 
     3321    src1 = (v16u8)__msa_ld_b((v16i8*)src_uv, 48); 
     3322    dst0 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); 
     3323    dst1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2); 
     3324    dst2 = (v16u8)__msa_vshf_b(mask0, (v16i8)src1, (v16i8)src0); 
     3325    dst3 = (v16u8)__msa_vshf_b(mask0, (v16i8)src3, (v16i8)src2); 
     3326    ST_UB2(dst0, dst1, dst_v, 16); 
     3327    ST_UB2(dst2, dst3, dst_u, 16); 
     3328    dst_u += 32; 
     3329    dst_v += 32; 
     3330  } 
     3331} 
     3332 
     3333void SobelXRow_MSA(const uint8* src_y0, 
     3334                   const uint8* src_y1, 
     3335                   const uint8* src_y2, 
     3336                   uint8* dst_sobelx, 
     3337                   int32 width) { 
     3338  int x; 
     3339  v16u8 src0, src1, src2, src3, src4, src5, dst0; 
     3340  v8i16 vec0, vec1, vec2, vec3, vec4, vec5; 
     3341  v16i8 mask0 = {0, 2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6, 8, 7, 9}; 
     3342  v16i8 tmp = __msa_ldi_b(8); 
     3343  v16i8 mask1 = mask0 + tmp; 
     3344  v8i16 zero = {0}; 
     3345  v8i16 max = __msa_ldi_h(255); 
     3346 
     3347  for (x = 0; x < width; x += 16) { 
     3348    src0 = (v16u8)__msa_ld_b((v16i8*)src_y0, 0); 
     3349    src1 = (v16u8)__msa_ld_b((v16i8*)src_y0, 16); 
     3350    src2 = (v16u8)__msa_ld_b((v16i8*)src_y1, 0); 
     3351    src3 = (v16u8)__msa_ld_b((v16i8*)src_y1, 16); 
     3352    src4 = (v16u8)__msa_ld_b((v16i8*)src_y2, 0); 
     3353    src5 = (v16u8)__msa_ld_b((v16i8*)src_y2, 16); 
     3354    vec0 = (v8i16)__msa_vshf_b(mask0, (v16i8)src1, (v16i8)src0); 
     3355    vec1 = (v8i16)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); 
     3356    vec2 = (v8i16)__msa_vshf_b(mask0, (v16i8)src3, (v16i8)src2); 
     3357    vec3 = (v8i16)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2); 
     3358    vec4 = (v8i16)__msa_vshf_b(mask0, (v16i8)src5, (v16i8)src4); 
     3359    vec5 = (v8i16)__msa_vshf_b(mask1, (v16i8)src5, (v16i8)src4); 
     3360    vec0 = (v8i16)__msa_hsub_u_h((v16u8)vec0, (v16u8)vec0); 
     3361    vec1 = (v8i16)__msa_hsub_u_h((v16u8)vec1, (v16u8)vec1); 
     3362    vec2 = (v8i16)__msa_hsub_u_h((v16u8)vec2, (v16u8)vec2); 
     3363    vec3 = (v8i16)__msa_hsub_u_h((v16u8)vec3, (v16u8)vec3); 
     3364    vec4 = (v8i16)__msa_hsub_u_h((v16u8)vec4, (v16u8)vec4); 
     3365    vec5 = (v8i16)__msa_hsub_u_h((v16u8)vec5, (v16u8)vec5); 
     3366    vec0 += vec2; 
     3367    vec1 += vec3; 
     3368    vec4 += vec2; 
     3369    vec5 += vec3; 
     3370    vec0 += vec4; 
     3371    vec1 += vec5; 
     3372    vec0 = __msa_add_a_h(zero, vec0); 
     3373    vec1 = __msa_add_a_h(zero, vec1); 
     3374    vec0 = __msa_maxi_s_h(vec0, 0); 
     3375    vec1 = __msa_maxi_s_h(vec1, 0); 
     3376    vec0 = __msa_min_s_h(max, vec0); 
     3377    vec1 = __msa_min_s_h(max, vec1); 
     3378    dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); 
     3379    ST_UB(dst0, dst_sobelx); 
     3380    src_y0 += 16; 
     3381    src_y1 += 16; 
     3382    src_y2 += 16; 
     3383    dst_sobelx += 16; 
     3384  } 
     3385} 
     3386 
     3387void SobelYRow_MSA(const uint8* src_y0, 
     3388                   const uint8* src_y1, 
     3389                   uint8* dst_sobely, 
     3390                   int32 width) { 
     3391  int x; 
     3392  v16u8 src0, src1, dst0; 
     3393  v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6; 
     3394  v8i16 zero = {0}; 
     3395  v8i16 max = __msa_ldi_h(255); 
     3396 
     3397  for (x = 0; x < width; x += 16) { 
     3398    src0 = (v16u8)__msa_ld_b((v16i8*)src_y0, 0); 
     3399    src1 = (v16u8)__msa_ld_b((v16i8*)src_y1, 0); 
     3400    vec0 = (v8i16)__msa_ilvr_b((v16i8)zero, (v16i8)src0); 
     3401    vec1 = (v8i16)__msa_ilvl_b((v16i8)zero, (v16i8)src0); 
     3402    vec2 = (v8i16)__msa_ilvr_b((v16i8)zero, (v16i8)src1); 
     3403    vec3 = (v8i16)__msa_ilvl_b((v16i8)zero, (v16i8)src1); 
     3404    vec0 -= vec2; 
     3405    vec1 -= vec3; 
     3406    vec6[0] = src_y0[16] - src_y1[16]; 
     3407    vec6[1] = src_y0[17] - src_y1[17]; 
     3408    vec2 = (v8i16)__msa_sldi_b((v16i8)vec1, (v16i8)vec0, 2); 
     3409    vec3 = (v8i16)__msa_sldi_b((v16i8)vec6, (v16i8)vec1, 2); 
     3410    vec4 = (v8i16)__msa_sldi_b((v16i8)vec1, (v16i8)vec0, 4); 
     3411    vec5 = (v8i16)__msa_sldi_b((v16i8)vec6, (v16i8)vec1, 4); 
     3412    vec0 += vec2; 
     3413    vec1 += vec3; 
     3414    vec4 += vec2; 
     3415    vec5 += vec3; 
     3416    vec0 += vec4; 
     3417    vec1 += vec5; 
     3418    vec0 = __msa_add_a_h(zero, vec0); 
     3419    vec1 = __msa_add_a_h(zero, vec1); 
     3420    vec0 = __msa_maxi_s_h(vec0, 0); 
     3421    vec1 = __msa_maxi_s_h(vec1, 0); 
     3422    vec0 = __msa_min_s_h(max, vec0); 
     3423    vec1 = __msa_min_s_h(max, vec1); 
     3424    dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); 
     3425    ST_UB(dst0, dst_sobely); 
     3426    src_y0 += 16; 
     3427    src_y1 += 16; 
     3428    dst_sobely += 16; 
     3429  } 
     3430} 
     3431 
     3432void HalfFloatRow_MSA(const uint16* src, uint16* dst, float scale, int width) { 
     3433  int i; 
     3434  v8u16 src0, src1, src2, src3, dst0, dst1, dst2, dst3; 
     3435  v4u32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; 
     3436  v4f32 fvec0, fvec1, fvec2, fvec3, fvec4, fvec5, fvec6, fvec7; 
     3437  v4f32 mult_vec; 
     3438  v8i16 zero = {0}; 
     3439  mult_vec[0] = 1.9259299444e-34f * scale; 
     3440  mult_vec = (v4f32)__msa_splati_w((v4i32)mult_vec, 0); 
     3441 
     3442  for (i = 0; i < width; i += 32) { 
     3443    src0 = (v8u16)__msa_ld_h((v8i16*)src, 0); 
     3444    src1 = (v8u16)__msa_ld_h((v8i16*)src, 16); 
     3445    src2 = (v8u16)__msa_ld_h((v8i16*)src, 32); 
     3446    src3 = (v8u16)__msa_ld_h((v8i16*)src, 48); 
     3447    vec0 = (v4u32)__msa_ilvr_h(zero, (v8i16)src0); 
     3448    vec1 = (v4u32)__msa_ilvl_h(zero, (v8i16)src0); 
     3449    vec2 = (v4u32)__msa_ilvr_h(zero, (v8i16)src1); 
     3450    vec3 = (v4u32)__msa_ilvl_h(zero, (v8i16)src1); 
     3451    vec4 = (v4u32)__msa_ilvr_h(zero, (v8i16)src2); 
     3452    vec5 = (v4u32)__msa_ilvl_h(zero, (v8i16)src2); 
     3453    vec6 = (v4u32)__msa_ilvr_h(zero, (v8i16)src3); 
     3454    vec7 = (v4u32)__msa_ilvl_h(zero, (v8i16)src3); 
     3455    fvec0 = __msa_ffint_u_w(vec0); 
     3456    fvec1 = __msa_ffint_u_w(vec1); 
     3457    fvec2 = __msa_ffint_u_w(vec2); 
     3458    fvec3 = __msa_ffint_u_w(vec3); 
     3459    fvec4 = __msa_ffint_u_w(vec4); 
     3460    fvec5 = __msa_ffint_u_w(vec5); 
     3461    fvec6 = __msa_ffint_u_w(vec6); 
     3462    fvec7 = __msa_ffint_u_w(vec7); 
     3463    fvec0 *= mult_vec; 
     3464    fvec1 *= mult_vec; 
     3465    fvec2 *= mult_vec; 
     3466    fvec3 *= mult_vec; 
     3467    fvec4 *= mult_vec; 
     3468    fvec5 *= mult_vec; 
     3469    fvec6 *= mult_vec; 
     3470    fvec7 *= mult_vec; 
     3471    vec0 = ((v4u32)fvec0) >> 13; 
     3472    vec1 = ((v4u32)fvec1) >> 13; 
     3473    vec2 = ((v4u32)fvec2) >> 13; 
     3474    vec3 = ((v4u32)fvec3) >> 13; 
     3475    vec4 = ((v4u32)fvec4) >> 13; 
     3476    vec5 = ((v4u32)fvec5) >> 13; 
     3477    vec6 = ((v4u32)fvec6) >> 13; 
     3478    vec7 = ((v4u32)fvec7) >> 13; 
     3479    dst0 = (v8u16)__msa_pckev_h((v8i16)vec1, (v8i16)vec0); 
     3480    dst1 = (v8u16)__msa_pckev_h((v8i16)vec3, (v8i16)vec2); 
     3481    dst2 = (v8u16)__msa_pckev_h((v8i16)vec5, (v8i16)vec4); 
     3482    dst3 = (v8u16)__msa_pckev_h((v8i16)vec7, (v8i16)vec6); 
     3483    ST_UH2(dst0, dst1, dst, 8); 
     3484    ST_UH2(dst2, dst3, dst + 16, 8); 
     3485    src += 32; 
     3486    dst += 32; 
     3487  } 
     3488} 
     3489 
    29723490#ifdef __cplusplus 
    29733491}  // extern "C" 
  • pjproject/trunk/third_party/yuv/source/row_neon.cc

    r5633 r5699  
    116116      YUVTORGB_SETUP 
    117117      "vmov.u8    d23, #255                      \n" 
    118       "1:                                          \n" READYUV444 YUVTORGB 
     118      "1:                                        \n" READYUV444 YUVTORGB 
    119119      "subs       %4, %4, #8                     \n" 
    120120      "vst4.8     {d20, d21, d22, d23}, [%3]!    \n" 
     
    142142      YUVTORGB_SETUP 
    143143      "vmov.u8    d23, #255                      \n" 
    144       "1:                                          \n" READYUV422 YUVTORGB 
     144      "1:                                        \n" READYUV422 YUVTORGB 
    145145      "subs       %4, %4, #8                     \n" 
    146146      "vst4.8     {d20, d21, d22, d23}, [%3]!    \n" 
     
    168168  asm volatile( 
    169169      YUVTORGB_SETUP 
    170       "1:                                          \n" READYUV422 YUVTORGB 
     170      "1:                                        \n" READYUV422 YUVTORGB 
    171171      "subs       %5, %5, #8                     \n" 
    172172      "vld1.8     {d23}, [%3]!                   \n" 
     
    195195  asm volatile( 
    196196      YUVTORGB_SETUP 
    197       "1:                                          \n" READYUV422 YUVTORGB 
     197      "1:                                        \n" READYUV422 YUVTORGB 
    198198      "subs       %4, %4, #8                     \n" 
    199199      "vmov.u8    d19, #255                      \n"  // d19 modified by 
     
    222222  asm volatile( 
    223223      YUVTORGB_SETUP 
    224       "1:                                          \n" READYUV422 YUVTORGB 
     224      "1:                                        \n" READYUV422 YUVTORGB 
    225225      "subs       %4, %4, #8                     \n" 
    226226      "vst3.8     {d20, d21, d22}, [%3]!         \n" 
     
    254254  asm volatile( 
    255255      YUVTORGB_SETUP 
    256       "1:                                          \n" READYUV422 YUVTORGB 
     256      "1:                                        \n" READYUV422 YUVTORGB 
    257257      "subs       %4, %4, #8                     \n" ARGBTORGB565 
    258258      "vst1.8     {q0}, [%3]!                    \n"  // store 8 pixels RGB565. 
     
    288288  asm volatile( 
    289289      YUVTORGB_SETUP 
    290       "1:                                          \n" READYUV422 YUVTORGB 
     290      "1:                                        \n" READYUV422 YUVTORGB 
    291291      "subs       %4, %4, #8                     \n" 
    292292      "vmov.u8    d23, #255                      \n" ARGBTOARGB1555 
     
    326326      "vmov.u8    d4, #0x0f                      \n"  // bits to clear with 
    327327                                                      // vbic. 
    328       "1:                                          \n" READYUV422 YUVTORGB 
     328      "1:                                        \n" READYUV422 YUVTORGB 
    329329      "subs       %4, %4, #8                     \n" 
    330330      "vmov.u8    d23, #255                      \n" ARGBTOARGB4444 
     
    349349      YUVTORGB_SETUP 
    350350      "vmov.u8    d23, #255                      \n" 
    351       "1:                                          \n" READYUV400 YUVTORGB 
     351      "1:                                        \n" READYUV400 YUVTORGB 
    352352      "subs       %2, %2, #8                     \n" 
    353353      "vst4.8     {d20, d21, d22, d23}, [%1]!    \n" 
     
    367367  asm volatile( 
    368368      "vmov.u8    d23, #255                      \n" 
    369       "1:                                          \n" 
     369      "1:                                        \n" 
    370370      "vld1.8     {d20}, [%0]!                   \n" 
    371371      "vmov       d21, d20                       \n" 
     
    386386                        const struct YuvConstants* yuvconstants, 
    387387                        int width) { 
    388   asm volatile( 
    389       YUVTORGB_SETUP 
    390       "vmov.u8    d23, #255                      \n" 
    391       "1:                                          \n" READNV12 YUVTORGB 
    392       "subs       %3, %3, #8                     \n" 
    393       "vst4.8     {d20, d21, d22, d23}, [%2]!    \n" 
    394       "bgt        1b                             \n" 
    395       : "+r"(src_y),     // %0 
    396         "+r"(src_uv),    // %1 
    397         "+r"(dst_argb),  // %2 
    398         "+r"(width)      // %3 
    399       : [kUVToRB] "r"(&yuvconstants->kUVToRB), 
    400         [kUVToG] "r"(&yuvconstants->kUVToG), 
    401         [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), 
    402         [kYToRgb] "r"(&yuvconstants->kYToRgb) 
    403       : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", 
    404         "q12", "q13", "q14", "q15"); 
     388  asm volatile(YUVTORGB_SETUP 
     389               "vmov.u8    d23, #255                      \n" 
     390               "1:                                        \n" READNV12 YUVTORGB 
     391               "subs       %3, %3, #8                     \n" 
     392               "vst4.8     {d20, d21, d22, d23}, [%2]!    \n" 
     393               "bgt        1b                             \n" 
     394               : "+r"(src_y),     // %0 
     395                 "+r"(src_uv),    // %1 
     396                 "+r"(dst_argb),  // %2 
     397                 "+r"(width)      // %3 
     398               : [kUVToRB] "r"(&yuvconstants->kUVToRB), 
     399                 [kUVToG] "r"(&yuvconstants->kUVToG), 
     400                 [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), 
     401                 [kYToRgb] "r"(&yuvconstants->kYToRgb) 
     402               : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", 
     403                 "q10", "q11", "q12", "q13", "q14", "q15"); 
    405404} 
    406405 
     
    410409                        const struct YuvConstants* yuvconstants, 
    411410                        int width) { 
    412   asm volatile( 
    413       YUVTORGB_SETUP 
    414       "vmov.u8    d23, #255                      \n" 
    415       "1:                                          \n" READNV21 YUVTORGB 
    416       "subs       %3, %3, #8                     \n" 
    417       "vst4.8     {d20, d21, d22, d23}, [%2]!    \n" 
    418       "bgt        1b                             \n" 
    419       : "+r"(src_y),     // %0 
    420         "+r"(src_vu),    // %1 
    421         "+r"(dst_argb),  // %2 
    422         "+r"(width)      // %3 
    423       : [kUVToRB] "r"(&yuvconstants->kUVToRB), 
    424         [kUVToG] "r"(&yuvconstants->kUVToG), 
    425         [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), 
    426         [kYToRgb] "r"(&yuvconstants->kYToRgb) 
    427       : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", 
    428         "q12", "q13", "q14", "q15"); 
     411  asm volatile(YUVTORGB_SETUP 
     412               "vmov.u8    d23, #255                      \n" 
     413               "1:                                        \n" READNV21 YUVTORGB 
     414               "subs       %3, %3, #8                     \n" 
     415               "vst4.8     {d20, d21, d22, d23}, [%2]!    \n" 
     416               "bgt        1b                             \n" 
     417               : "+r"(src_y),     // %0 
     418                 "+r"(src_vu),    // %1 
     419                 "+r"(dst_argb),  // %2 
     420                 "+r"(width)      // %3 
     421               : [kUVToRB] "r"(&yuvconstants->kUVToRB), 
     422                 [kUVToG] "r"(&yuvconstants->kUVToG), 
     423                 [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), 
     424                 [kYToRgb] "r"(&yuvconstants->kYToRgb) 
     425               : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", 
     426                 "q10", "q11", "q12", "q13", "q14", "q15"); 
    429427} 
    430428 
     
    436434  asm volatile( 
    437435      YUVTORGB_SETUP 
    438       "1:                                          \n" READNV12 YUVTORGB 
     436      "1:                                        \n" READNV12 YUVTORGB 
    439437      "subs       %3, %3, #8                     \n" ARGBTORGB565 
    440438      "vst1.8     {q0}, [%2]!                    \n"  // store 8 pixels RGB565. 
     
    456454                        const struct YuvConstants* yuvconstants, 
    457455                        int width) { 
    458   asm volatile( 
    459       YUVTORGB_SETUP 
    460       "vmov.u8    d23, #255                      \n" 
    461       "1:                                          \n" READYUY2 YUVTORGB 
    462       "subs       %2, %2, #8                     \n" 
    463       "vst4.8     {d20, d21, d22, d23}, [%1]!    \n" 
    464       "bgt        1b                             \n" 
    465       : "+r"(src_yuy2),  // %0 
    466         "+r"(dst_argb),  // %1 
    467         "+r"(width)      // %2 
    468       : [kUVToRB] "r"(&yuvconstants->kUVToRB), 
    469         [kUVToG] "r"(&yuvconstants->kUVToG), 
    470         [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), 
    471         [kYToRgb] "r"(&yuvconstants->kYToRgb) 
    472       : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", 
    473         "q12", "q13", "q14", "q15"); 
     456  asm volatile(YUVTORGB_SETUP 
     457               "vmov.u8    d23, #255                      \n" 
     458               "1:                                        \n" READYUY2 YUVTORGB 
     459               "subs       %2, %2, #8                     \n" 
     460               "vst4.8     {d20, d21, d22, d23}, [%1]!    \n" 
     461               "bgt        1b                             \n" 
     462               : "+r"(src_yuy2),  // %0 
     463                 "+r"(dst_argb),  // %1 
     464                 "+r"(width)      // %2 
     465               : [kUVToRB] "r"(&yuvconstants->kUVToRB), 
     466                 [kUVToG] "r"(&yuvconstants->kUVToG), 
     467                 [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), 
     468                 [kYToRgb] "r"(&yuvconstants->kYToRgb) 
     469               : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", 
     470                 "q10", "q11", "q12", "q13", "q14", "q15"); 
    474471} 
    475472 
     
    478475                        const struct YuvConstants* yuvconstants, 
    479476                        int width) { 
    480   asm volatile( 
    481       YUVTORGB_SETUP 
    482       "vmov.u8    d23, #255                      \n" 
    483       "1:                                          \n" READUYVY YUVTORGB 
    484       "subs       %2, %2, #8                     \n" 
    485       "vst4.8     {d20, d21, d22, d23}, [%1]!    \n" 
    486       "bgt        1b                             \n" 
    487       : "+r"(src_uyvy),  // %0 
    488         "+r"(dst_argb),  // %1 
    489         "+r"(width)      // %2 
    490       : [kUVToRB] "r"(&yuvconstants->kUVToRB), 
    491         [kUVToG] "r"(&yuvconstants->kUVToG), 
    492         [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), 
    493         [kYToRgb] "r"(&yuvconstants->kYToRgb) 
    494       : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", 
    495         "q12", "q13", "q14", "q15"); 
     477  asm volatile(YUVTORGB_SETUP 
     478               "vmov.u8    d23, #255                      \n" 
     479               "1:                                        \n" READUYVY YUVTORGB 
     480               "subs       %2, %2, #8                     \n" 
     481               "vst4.8     {d20, d21, d22, d23}, [%1]!    \n" 
     482               "bgt        1b                             \n" 
     483               : "+r"(src_uyvy),  // %0 
     484                 "+r"(dst_argb),  // %1 
     485                 "+r"(width)      // %2 
     486               : [kUVToRB] "r"(&yuvconstants->kUVToRB), 
     487                 [kUVToG] "r"(&yuvconstants->kUVToG), 
     488                 [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), 
     489                 [kYToRgb] "r"(&yuvconstants->kYToRgb) 
     490               : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", 
     491                 "q10", "q11", "q12", "q13", "q14", "q15"); 
    496492} 
    497493 
     
    502498                     int width) { 
    503499  asm volatile( 
    504       "1:                                          \n" 
     500      "1:                                        \n" 
    505501      "vld2.8     {q0, q1}, [%0]!                \n"  // load 16 pairs of UV 
    506502      "subs       %3, %3, #16                    \n"  // 16 processed per loop 
     
    523519                     int width) { 
    524520  asm volatile( 
    525       "1:                                          \n" 
     521      "1:                                        \n" 
    526522      "vld1.8     {q0}, [%0]!                    \n"  // load U 
    527523      "vld1.8     {q1}, [%1]!                    \n"  // load V 
    528524      "subs       %3, %3, #16                    \n"  // 16 processed per loop 
    529       "vst2.u8    {q0, q1}, [%2]!                \n"  // store 16 pairs of UV 
     525      "vst2.8     {q0, q1}, [%2]!                \n"  // store 16 pairs of UV 
    530526      "bgt        1b                             \n" 
    531527      : "+r"(src_u),                // %0 
     
    538534} 
    539535 
     536// Reads 16 packed RGB and write to planar dst_r, dst_g, dst_b. 
     537void SplitRGBRow_NEON(const uint8* src_rgb, 
     538                      uint8* dst_r, 
     539                      uint8* dst_g, 
     540                      uint8* dst_b, 
     541                      int width) { 
     542  asm volatile( 
     543      "1:                                        \n" 
     544      "vld3.8     {d0, d2, d4}, [%0]!            \n"  // load 8 RGB 
     545      "vld3.8     {d1, d3, d5}, [%0]!            \n"  // next 8 RGB 
     546      "subs       %4, %4, #16                    \n"  // 16 processed per loop 
     547      "vst1.8     {q0}, [%1]!                    \n"  // store R 
     548      "vst1.8     {q1}, [%2]!                    \n"  // store G 
     549      "vst1.8     {q2}, [%3]!                    \n"  // store B 
     550      "bgt        1b                             \n" 
     551      : "+r"(src_rgb),                    // %0 
     552        "+r"(dst_r),                      // %1 
     553        "+r"(dst_g),                      // %2 
     554        "+r"(dst_b),                      // %3 
     555        "+r"(width)                       // %4 
     556      :                                   // Input registers 
     557      : "cc", "memory", "d0", "d1", "d2"  // Clobber List 
     558      ); 
     559} 
     560 
     561// Reads 16 planar R's, G's and B's and writes out 16 packed RGB at a time 
     562void MergeRGBRow_NEON(const uint8* src_r, 
     563                      const uint8* src_g, 
     564                      const uint8* src_b, 
     565                      uint8* dst_rgb, 
     566                      int width) { 
     567  asm volatile( 
     568      "1:                                        \n" 
     569      "vld1.8     {q0}, [%0]!                    \n"  // load R 
     570      "vld1.8     {q1}, [%1]!                    \n"  // load G 
     571      "vld1.8     {q2}, [%2]!                    \n"  // load B 
     572      "subs       %4, %4, #16                    \n"  // 16 processed per loop 
     573      "vst3.8     {d0, d2, d4}, [%3]!            \n"  // store 8 RGB 
     574      "vst3.8     {d1, d3, d5}, [%3]!            \n"  // next 8 RGB 
     575      "bgt        1b                             \n" 
     576      : "+r"(src_r),                      // %0 
     577        "+r"(src_g),                      // %1 
     578        "+r"(src_b),                      // %2 
     579        "+r"(dst_rgb),                    // %3 
     580        "+r"(width)                       // %4 
     581      :                                   // Input registers 
     582      : "cc", "memory", "q0", "q1", "q2"  // Clobber List 
     583      ); 
     584} 
     585 
    540586// Copy multiple of 32.  vld4.8  allow unaligned and is fastest on a15. 
    541587void CopyRow_NEON(const uint8* src, uint8* dst, int count) { 
    542588  asm volatile( 
    543       "1:                                          \n" 
     589      "1:                                        \n" 
    544590      "vld1.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 32 
    545591      "subs       %2, %2, #32                    \n"  // 32 processed per loop 
     
    558604  asm volatile( 
    559605      "vdup.8    q0, %2                          \n"  // duplicate 16 bytes 
    560       "1:                                          \n" 
     606      "1:                                        \n" 
    561607      "subs      %1, %1, #16                     \n"  // 16 bytes per loop 
    562608      "vst1.8    {q0}, [%0]!                     \n"  // store 
     
    572618  asm volatile( 
    573619      "vdup.u32  q0, %2                          \n"  // duplicate 4 ints 
    574       "1:                                          \n" 
     620      "1:                                        \n" 
    575621      "subs      %1, %1, #4                      \n"  // 4 pixels per loop 
    576622      "vst1.8    {q0}, [%0]!                     \n"  // store 
     
    589635      "sub        %0, #16                        \n" 
    590636 
    591       "1:                                          \n" 
     637      "1:                                        \n" 
    592638      "vld1.8     {q0}, [%0], r3                 \n"  // src -= 16 
    593639      "subs       %2, #16                        \n"  // 16 pixels per loop. 
     
    613659      "sub        %0, #16                        \n" 
    614660 
    615       "1:                                          \n" 
     661      "1:                                        \n" 
    616662      "vld2.8     {d0, d1}, [%0], r12            \n"  // src -= 16 
    617663      "subs       %3, #8                         \n"  // 8 pixels per loop. 
     
    635681      "sub        %0, #16                        \n" 
    636682 
    637       "1:                                          \n" 
     683      "1:                                        \n" 
    638684      "vld1.8     {q0}, [%0], r3                 \n"  // src -= 16 
    639685      "subs       %2, #4                         \n"  // 4 pixels per loop. 
     
    652698  asm volatile( 
    653699      "vmov.u8    d4, #255                       \n"  // Alpha 
    654       "1:                                          \n" 
     700      "1:                                        \n" 
    655701      "vld3.8     {d1, d2, d3}, [%0]!            \n"  // load 8 pixels of RGB24. 
    656702      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    668714  asm volatile( 
    669715      "vmov.u8    d4, #255                       \n"  // Alpha 
    670       "1:                                          \n" 
     716      "1:                                        \n" 
    671717      "vld3.8     {d1, d2, d3}, [%0]!            \n"  // load 8 pixels of RAW. 
    672718      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    684730void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) { 
    685731  asm volatile( 
    686       "1:                                          \n" 
     732      "1:                                        \n" 
    687733      "vld3.8     {d1, d2, d3}, [%0]!            \n"  // load 8 pixels of RAW. 
    688734      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    714760  asm volatile( 
    715761      "vmov.u8    d3, #255                       \n"  // Alpha 
    716       "1:                                          \n" 
     762      "1:                                        \n" 
    717763      "vld1.8     {q0}, [%0]!                    \n"  // load 8 RGB565 pixels. 
    718764      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    760806  asm volatile( 
    761807      "vmov.u8    d3, #255                       \n"  // Alpha 
    762       "1:                                          \n" 
     808      "1:                                        \n" 
    763809      "vld1.8     {q0}, [%0]!                    \n"  // load 8 ARGB1555 pixels. 
    764810      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    789835  asm volatile( 
    790836      "vmov.u8    d3, #255                       \n"  // Alpha 
    791       "1:                                          \n" 
     837      "1:                                        \n" 
    792838      "vld1.8     {q0}, [%0]!                    \n"  // load 8 ARGB4444 pixels. 
    793839      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    805851void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) { 
    806852  asm volatile( 
    807       "1:                                          \n" 
     853      "1:                                        \n" 
    808854      "vld4.8     {d1, d2, d3, d4}, [%0]!        \n"  // load 8 pixels of ARGB. 
    809855      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    821867void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) { 
    822868  asm volatile( 
    823       "1:                                          \n" 
     869      "1:                                        \n" 
    824870      "vld4.8     {d1, d2, d3, d4}, [%0]!        \n"  // load 8 pixels of ARGB. 
    825871      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    837883void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) { 
    838884  asm volatile( 
    839       "1:                                          \n" 
     885      "1:                                        \n" 
    840886      "vld2.8     {q0, q1}, [%0]!                \n"  // load 16 pixels of YUY2. 
    841887      "subs       %2, %2, #16                    \n"  // 16 processed per loop. 
     
    852898void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) { 
    853899  asm volatile( 
    854       "1:                                          \n" 
     900      "1:                                        \n" 
    855901      "vld2.8     {q0, q1}, [%0]!                \n"  // load 16 pixels of UYVY. 
    856902      "subs       %2, %2, #16                    \n"  // 16 processed per loop. 
     
    870916                         int width) { 
    871917  asm volatile( 
    872       "1:                                          \n" 
     918      "1:                                        \n" 
    873919      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 16 pixels of YUY2. 
    874920      "subs       %3, %3, #16                    \n"  // 16 pixels = 8 UVs. 
     
    890936                         int width) { 
    891937  asm volatile( 
    892       "1:                                          \n" 
     938      "1:                                        \n" 
    893939      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 16 pixels of UYVY. 
    894940      "subs       %3, %3, #16                    \n"  // 16 pixels = 8 UVs. 
     
    912958  asm volatile( 
    913959      "add        %1, %0, %1                     \n"  // stride + src_yuy2 
    914       "1:                                          \n" 
     960      "1:                                        \n" 
    915961      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 16 pixels of YUY2. 
    916962      "subs       %4, %4, #16                    \n"  // 16 pixels = 8 UVs. 
     
    939985  asm volatile( 
    940986      "add        %1, %0, %1                     \n"  // stride + src_uyvy 
    941       "1:                                          \n" 
     987      "1:                                        \n" 
    942988      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 16 pixels of UYVY. 
    943989      "subs       %4, %4, #16                    \n"  // 16 pixels = 8 UVs. 
     
    9661012  asm volatile( 
    9671013      "vld1.8     {q2}, [%3]                     \n"  // shuffler 
    968       "1:                                          \n" 
     1014      "1:                                        \n" 
    9691015      "vld1.8     {q0}, [%0]!                    \n"  // load 4 pixels. 
    9701016      "subs       %2, %2, #4                     \n"  // 4 processed per loop 
     
    9871033                        int width) { 
    9881034  asm volatile( 
    989       "1:                                          \n" 
     1035      "1:                                        \n" 
    9901036      "vld2.8     {d0, d2}, [%0]!                \n"  // load 16 Ys 
    9911037      "vld1.8     {d1}, [%1]!                    \n"  // load 8 Us 
     
    10091055                        int width) { 
    10101056  asm volatile( 
    1011       "1:                                          \n" 
     1057      "1:                                        \n" 
    10121058      "vld2.8     {d1, d3}, [%0]!                \n"  // load 16 Ys 
    10131059      "vld1.8     {d0}, [%1]!                    \n"  // load 8 Us 
     
    10271073void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) { 
    10281074  asm volatile( 
    1029       "1:                                          \n" 
     1075      "1:                                        \n" 
    10301076      "vld4.8     {d20, d21, d22, d23}, [%0]!    \n"  // load 8 pixels of ARGB. 
    10311077      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    10461092  asm volatile( 
    10471093      "vdup.32    d2, %2                         \n"  // dither4 
    1048       "1:                                          \n" 
     1094      "1:                                        \n" 
    10491095      "vld4.8     {d20, d21, d22, d23}, [%1]!    \n"  // load 8 pixels of ARGB. 
    10501096      "subs       %3, %3, #8                     \n"  // 8 processed per loop. 
    10511097      "vqadd.u8   d20, d20, d2                   \n" 
    10521098      "vqadd.u8   d21, d21, d2                   \n" 
    1053       "vqadd.u8   d22, d22, d2                   \n" ARGBTORGB565 
    1054       "vst1.8     {q0}, [%0]!                    \n"  // store 8 pixels RGB565. 
     1099      "vqadd.u8   d22, d22, d2                   \n"  // add for dither 
     1100      ARGBTORGB565 
     1101      "vst1.8     {q0}, [%0]!                    \n"  // store 8 RGB565. 
    10551102      "bgt        1b                             \n" 
    10561103      : "+r"(dst_rgb)   // %0 
     
    10651112                            int width) { 
    10661113  asm volatile( 
    1067       "1:                                          \n" 
     1114      "1:                                        \n" 
    10681115      "vld4.8     {d20, d21, d22, d23}, [%0]!    \n"  // load 8 pixels of ARGB. 
    10691116      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
    10701117      ARGBTOARGB1555 
    1071       "vst1.8     {q0}, [%1]!                    \n"  // store 8 pixels 
    1072                                                       // ARGB1555. 
     1118      "vst1.8     {q0}, [%1]!                    \n"  // store 8 ARGB1555. 
    10731119      "bgt        1b                             \n" 
    10741120      : "+r"(src_argb),      // %0 
     
    10851131      "vmov.u8    d4, #0x0f                      \n"  // bits to clear with 
    10861132                                                      // vbic. 
    1087       "1:                                          \n" 
     1133      "1:                                        \n" 
    10881134      "vld4.8     {d20, d21, d22, d23}, [%0]!    \n"  // load 8 pixels of ARGB. 
    10891135      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
    10901136      ARGBTOARGB4444 
    1091       "vst1.8     {q0}, [%1]!                    \n"  // store 8 pixels 
    1092                                                       // ARGB4444. 
     1137      "vst1.8     {q0}, [%1]!                    \n"  // store 8 ARGB4444. 
    10931138      "bgt        1b                             \n" 
    10941139      : "+r"(src_argb),      // %0 
     
    11051150      "vmov.u8    d26, #33                       \n"  // R * 0.2578 coefficient 
    11061151      "vmov.u8    d27, #16                       \n"  // Add 16 constant 
    1107       "1:                                          \n" 
     1152      "1:                                        \n" 
    11081153      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 ARGB pixels. 
    11091154      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    11241169void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) { 
    11251170  asm volatile( 
    1126       "1:                                          \n" 
     1171      "1:                                        \n" 
    11271172      "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ARGB pixels 
    11281173      "vld4.8     {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 ARGB pixels 
     
    11431188      "vmov.u8    d25, #75                       \n"  // G * 0.58700 coefficient 
    11441189      "vmov.u8    d26, #38                       \n"  // R * 0.29900 coefficient 
    1145       "1:                                          \n" 
     1190      "1:                                        \n" 
    11461191      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 ARGB pixels. 
    11471192      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    11721217      "vmov.u8    d28, #94                       \n"  // VG -0.7344 coefficient 
    11731218      "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1174       "1:                                          \n" 
     1219      "1:                                        \n" 
    11751220      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 ARGB pixels. 
    11761221      "subs       %3, %3, #8                     \n"  // 8 processed per loop. 
     
    12001245} 
    12011246 
     1247// clang-format off 
    12021248// 16x2 pixels -> 8x1.  width is number of argb pixels. e.g. 16. 
    12031249#define RGBTOUV(QB, QG, QR)                                                 \ 
    1204   "vmul.s16   q8, " #QB                                                     \ 
    1205   ", q10               \n" /* B                    */                       \ 
    1206   "vmls.s16   q8, " #QG                                                     \ 
    1207   ", q11               \n" /* G                    */                       \ 
    1208   "vmls.s16   q8, " #QR                                                     \ 
    1209   ", q12               \n"                       /* R                    */ \ 
     1250  "vmul.s16   q8, " #QB ", q10               \n" /* B                    */ \ 
     1251  "vmls.s16   q8, " #QG ", q11               \n" /* G                    */ \ 
     1252  "vmls.s16   q8, " #QR ", q12               \n" /* R                    */ \ 
    12101253  "vadd.u16   q8, q8, q15                    \n" /* +128 -> unsigned     */ \ 
    1211   "vmul.s16   q9, " #QR                                                     \ 
    1212   ", q10               \n" /* R                    */                       \ 
    1213   "vmls.s16   q9, " #QG                                                     \ 
    1214   ", q14               \n" /* G                    */                       \ 
    1215   "vmls.s16   q9, " #QB                                                     \ 
    1216   ", q13               \n"                       /* B                    */ \ 
     1254  "vmul.s16   q9, " #QR ", q10               \n" /* R                    */ \ 
     1255  "vmls.s16   q9, " #QG ", q14               \n" /* G                    */ \ 
     1256  "vmls.s16   q9, " #QB ", q13               \n" /* B                    */ \ 
    12171257  "vadd.u16   q9, q9, q15                    \n" /* +128 -> unsigned     */ \ 
    12181258  "vqshrn.u16  d0, q8, #8                    \n" /* 16 bit to 8 bit U    */ \ 
    12191259  "vqshrn.u16  d1, q9, #8                    \n" /* 16 bit to 8 bit V    */ 
     1260// clang-format on 
    12201261 
    12211262// TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr. 
     
    12331274    "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    12341275    "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1235   "1:                                          \n" 
     1276    "1:                                        \n" 
    12361277    "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ARGB pixels. 
    12371278    "vld4.8     {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 ARGB pixels. 
     
    12791320    "vmov.s16   q14, #107 / 2                  \n"  // VG -0.41869 coefficient 
    12801321    "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1281   "1:                                          \n" 
     1322    "1:                                        \n" 
    12821323    "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ARGB pixels. 
    12831324    "vld4.8     {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 ARGB pixels. 
     
    13241365    "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    13251366    "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1326   "1:                                          \n" 
     1367    "1:                                        \n" 
    13271368    "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 BGRA pixels. 
    13281369    "vld4.8     {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 BGRA pixels. 
     
    13691410    "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    13701411    "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1371   "1:                                          \n" 
     1412    "1:                                        \n" 
    13721413    "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ABGR pixels. 
    13731414    "vld4.8     {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 ABGR pixels. 
     
    14141455    "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    14151456    "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1416   "1:                                          \n" 
     1457    "1:                                        \n" 
    14171458    "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 RGBA pixels. 
    14181459    "vld4.8     {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 RGBA pixels. 
     
    14591500    "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    14601501    "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1461   "1:                                          \n" 
     1502    "1:                                        \n" 
    14621503    "vld3.8     {d0, d2, d4}, [%0]!            \n"  // load 8 RGB24 pixels. 
    14631504    "vld3.8     {d1, d3, d5}, [%0]!            \n"  // load next 8 RGB24 pixels. 
     
    15041545    "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    15051546    "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1506   "1:                                          \n" 
     1547    "1:                                        \n" 
    15071548    "vld3.8     {d0, d2, d4}, [%0]!            \n"  // load 8 RAW pixels. 
    15081549    "vld3.8     {d1, d3, d5}, [%0]!            \n"  // load next 8 RAW pixels. 
     
    15511592      "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    15521593      "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1553       "1:                                          \n" 
     1594      "1:                                        \n" 
    15541595      "vld1.8     {q0}, [%0]!                    \n"  // load 8 RGB565 pixels. 
    15551596      RGB565TOARGB 
     
    16171658      "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    16181659      "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1619       "1:                                          \n" 
     1660      "1:                                        \n" 
    16201661      "vld1.8     {q0}, [%0]!                    \n"  // load 8 ARGB1555 pixels. 
    16211662      RGB555TOARGB 
     
    16831724      "vmov.s16   q14, #94 / 2                   \n"  // VG -0.7344 coefficient 
    16841725      "vmov.u16   q15, #0x8080                   \n"  // 128.5 
    1685       "1:                                          \n" 
     1726      "1:                                        \n" 
    16861727      "vld1.8     {q0}, [%0]!                    \n"  // load 8 ARGB4444 pixels. 
    16871728      ARGB4444TOARGB 
     
    17401781      "vmov.u8    d26, #33                       \n"  // R * 0.2578 coefficient 
    17411782      "vmov.u8    d27, #16                       \n"  // Add 16 constant 
    1742       "1:                                          \n" 
     1783      "1:                                        \n" 
    17431784      "vld1.8     {q0}, [%0]!                    \n"  // load 8 RGB565 pixels. 
    17441785      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    17641805      "vmov.u8    d26, #33                       \n"  // R * 0.2578 coefficient 
    17651806      "vmov.u8    d27, #16                       \n"  // Add 16 constant 
    1766       "1:                                          \n" 
     1807      "1:                                        \n" 
    17671808      "vld1.8     {q0}, [%0]!                    \n"  // load 8 ARGB1555 pixels. 
    17681809      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    17881829      "vmov.u8    d26, #33                       \n"  // R * 0.2578 coefficient 
    17891830      "vmov.u8    d27, #16                       \n"  // Add 16 constant 
    1790       "1:                                          \n" 
     1831      "1:                                        \n" 
    17911832      "vld1.8     {q0}, [%0]!                    \n"  // load 8 ARGB4444 pixels. 
    17921833      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    18121853      "vmov.u8    d6, #13                        \n"  // B * 0.1016 coefficient 
    18131854      "vmov.u8    d7, #16                        \n"  // Add 16 constant 
    1814       "1:                                          \n" 
     1855      "1:                                        \n" 
    18151856      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 pixels of BGRA. 
    18161857      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    18351876      "vmov.u8    d6, #13                        \n"  // B * 0.1016 coefficient 
    18361877      "vmov.u8    d7, #16                        \n"  // Add 16 constant 
    1837       "1:                                          \n" 
     1878      "1:                                        \n" 
    18381879      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 pixels of ABGR. 
    18391880      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    18581899      "vmov.u8    d6, #33                        \n"  // R * 0.2578 coefficient 
    18591900      "vmov.u8    d7, #16                        \n"  // Add 16 constant 
    1860       "1:                                          \n" 
     1901      "1:                                        \n" 
    18611902      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 pixels of RGBA. 
    18621903      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    18811922      "vmov.u8    d6, #33                        \n"  // R * 0.2578 coefficient 
    18821923      "vmov.u8    d7, #16                        \n"  // Add 16 constant 
    1883       "1:                                          \n" 
     1924      "1:                                        \n" 
    18841925      "vld3.8     {d0, d1, d2}, [%0]!            \n"  // load 8 pixels of RGB24. 
    18851926      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    19041945      "vmov.u8    d6, #13                        \n"  // B * 0.1016 coefficient 
    19051946      "vmov.u8    d7, #16                        \n"  // Add 16 constant 
    1906       "1:                                          \n" 
     1947      "1:                                        \n" 
    19071948      "vld3.8     {d0, d1, d2}, [%0]!            \n"  // load 8 pixels of RAW. 
    19081949      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    19391980      "vdup.8     d4, %4                         \n" 
    19401981      // General purpose row blend. 
    1941       "1:                                          \n" 
     1982      "1:                                        \n" 
    19421983      "vld1.8     {q0}, [%1]!                    \n" 
    19431984      "vld1.8     {q1}, [%2]!                    \n" 
     
    19541995 
    19551996      // Blend 50 / 50. 
    1956       "50:                                         \n" 
     1997      "50:                                       \n" 
    19571998      "vld1.8     {q0}, [%1]!                    \n" 
    19581999      "vld1.8     {q1}, [%2]!                    \n" 
     
    19642005 
    19652006      // Blend 100 / 0 - Copy row unchanged. 
    1966       "100:                                        \n" 
     2007      "100:                                      \n" 
    19672008      "vld1.8     {q0}, [%1]!                    \n" 
    19682009      "subs       %3, %3, #16                    \n" 
     
    19702011      "bgt        100b                           \n" 
    19712012 
    1972       "99:                                         \n" 
     2013      "99:                                       \n" 
    19732014      : "+r"(dst_ptr),     // %0 
    19742015        "+r"(src_ptr),     // %1 
     
    19892030      "blt        89f                            \n" 
    19902031      // Blend 8 pixels. 
    1991       "8:                                          \n" 
     2032      "8:                                        \n" 
    19922033      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 pixels of ARGB0. 
    19932034      "vld4.8     {d4, d5, d6, d7}, [%1]!        \n"  // load 8 pixels of ARGB1. 
     
    20072048      "bge        8b                             \n" 
    20082049 
    2009       "89:                                         \n" 
     2050      "89:                                       \n" 
    20102051      "adds       %3, #8-1                       \n" 
    20112052      "blt        99f                            \n" 
    20122053 
    20132054      // Blend 1 pixels. 
    2014       "1:                                          \n" 
     2055      "1:                                        \n" 
    20152056      "vld4.8     {d0[0],d1[0],d2[0],d3[0]}, [%0]! \n"  // load 1 pixel ARGB0. 
    20162057      "vld4.8     {d4[0],d5[0],d6[0],d7[0]}, [%1]! \n"  // load 1 pixel ARGB1. 
     
    20442085  asm volatile( 
    20452086      // Attenuate 8 pixels. 
    2046       "1:                                          \n" 
     2087      "1:                                        \n" 
    20472088      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 pixels of ARGB. 
    20482089      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    20762117 
    20772118      // 8 pixel loop. 
    2078       "1:                                          \n" 
     2119      "1:                                        \n" 
    20792120      "vld4.8     {d0, d2, d4, d6}, [%0]         \n"  // load 8 pixels of ARGB. 
    20802121      "subs       %1, %1, #8                     \n"  // 8 processed per loop. 
     
    21172158 
    21182159      // 8 pixel loop. 
    2119       "1:                                          \n" 
     2160      "1:                                        \n" 
    21202161      "vld4.8     {d20, d22, d24, d26}, [%0]!    \n"  // load 8 pixels of ARGB. 
    21212162      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    21492190      "vmov.u8    d25, #75                       \n"  // G * 0.58700 coefficient 
    21502191      "vmov.u8    d26, #38                       \n"  // R * 0.29900 coefficient 
    2151       "1:                                          \n" 
     2192      "1:                                        \n" 
    21522193      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 ARGB pixels. 
    21532194      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    21822223      "vmov.u8    d29, #98                       \n"  // BG coefficient 
    21832224      "vmov.u8    d30, #50                       \n"  // BR coefficient 
    2184       "1:                                          \n" 
     2225      "1:                                        \n" 
    21852226      "vld4.8     {d0, d1, d2, d3}, [%0]         \n"  // load 8 ARGB pixels. 
    21862227      "subs       %1, %1, #8                     \n"  // 8 processed per loop. 
     
    22182259      "vmovl.s8   q1, d5                         \n"  // R,A coefficients s16. 
    22192260 
    2220       "1:                                          \n" 
     2261      "1:                                        \n" 
    22212262      "vld4.8     {d16, d18, d20, d22}, [%0]!    \n"  // load 8 ARGB pixels. 
    22222263      "subs       %2, %2, #8                     \n"  // 8 processed per loop. 
     
    22742315  asm volatile( 
    22752316      // 8 pixel loop. 
    2276       "1:                                          \n" 
     2317      "1:                                        \n" 
    22772318      "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ARGB pixels. 
    22782319      "vld4.8     {d1, d3, d5, d7}, [%1]!        \n"  // load 8 more ARGB 
    2279                                                       // pixels. 
    22802320      "subs       %3, %3, #8                     \n"  // 8 processed per loop. 
    22812321      "vmull.u8   q0, d0, d1                     \n"  // multiply B 
     
    22892329      "vst4.8     {d0, d1, d2, d3}, [%2]!        \n"  // store 8 ARGB pixels. 
    22902330      "bgt        1b                             \n" 
    2291  
    22922331      : "+r"(src_argb0),  // %0 
    22932332        "+r"(src_argb1),  // %1 
     
    23052344  asm volatile( 
    23062345      // 8 pixel loop. 
    2307       "1:                                          \n" 
     2346      "1:                                        \n" 
    23082347      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 ARGB pixels. 
    23092348      "vld4.8     {d4, d5, d6, d7}, [%1]!        \n"  // load 8 more ARGB 
    2310                                                       // pixels. 
    23112349      "subs       %3, %3, #8                     \n"  // 8 processed per loop. 
    23122350      "vqadd.u8   q0, q0, q2                     \n"  // add B, G 
     
    23142352      "vst4.8     {d0, d1, d2, d3}, [%2]!        \n"  // store 8 ARGB pixels. 
    23152353      "bgt        1b                             \n" 
    2316  
    23172354      : "+r"(src_argb0),  // %0 
    23182355        "+r"(src_argb1),  // %1 
     
    23302367  asm volatile( 
    23312368      // 8 pixel loop. 
    2332       "1:                                          \n" 
     2369      "1:                                        \n" 
    23332370      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // load 8 ARGB pixels. 
    23342371      "vld4.8     {d4, d5, d6, d7}, [%1]!        \n"  // load 8 more ARGB 
    2335                                                       // pixels. 
    23362372      "subs       %3, %3, #8                     \n"  // 8 processed per loop. 
    23372373      "vqsub.u8   q0, q0, q2                     \n"  // subtract B, G 
     
    23392375      "vst4.8     {d0, d1, d2, d3}, [%2]!        \n"  // store 8 ARGB pixels. 
    23402376      "bgt        1b                             \n" 
    2341  
    23422377      : "+r"(src_argb0),  // %0 
    23432378        "+r"(src_argb1),  // %1 
     
    23602395      "vmov.u8    d3, #255                       \n"  // alpha 
    23612396      // 8 pixel loop. 
    2362       "1:                                          \n" 
     2397      "1:                                        \n" 
    23632398      "vld1.8     {d0}, [%0]!                    \n"  // load 8 sobelx. 
    23642399      "vld1.8     {d1}, [%1]!                    \n"  // load 8 sobely. 
     
    23842419  asm volatile( 
    23852420      // 16 pixel loop. 
    2386       "1:                                          \n" 
     2421      "1:                                        \n" 
    23872422      "vld1.8     {q0}, [%0]!                    \n"  // load 16 sobelx. 
    23882423      "vld1.8     {q1}, [%1]!                    \n"  // load 16 sobely. 
     
    24112446      "vmov.u8    d3, #255                       \n"  // alpha 
    24122447      // 8 pixel loop. 
    2413       "1:                                          \n" 
     2448      "1:                                        \n" 
    24142449      "vld1.8     {d2}, [%0]!                    \n"  // load 8 sobelx. 
    24152450      "vld1.8     {d0}, [%1]!                    \n"  // load 8 sobely. 
     
    24362471                    int width) { 
    24372472  asm volatile( 
    2438       "1:                                          \n" 
     2473      "1:                                        \n" 
    24392474      "vld1.8     {d0}, [%0],%5                  \n"  // top 
    24402475      "vld1.8     {d1}, [%0],%6                  \n" 
     
    24742509                    int width) { 
    24752510  asm volatile( 
    2476       "1:                                          \n" 
     2511      "1:                                        \n" 
    24772512      "vld1.8     {d0}, [%0],%4                  \n"  // left 
    24782513      "vld1.8     {d1}, [%1],%4                  \n" 
     
    25062541      "vdup.32    q0, %3                         \n" 
    25072542 
    2508       "1:                                          \n" 
     2543      "1:                                        \n" 
    25092544      "vld1.8     {q1}, [%0]!                    \n"  // load 8 shorts 
    25102545      "subs       %2, %2, #8                     \n"  // 8 pixels per loop 
     
    25312566      "vdup.32    q0, %3                         \n" 
    25322567 
    2533       "1:                                          \n" 
     2568      "1:                                        \n" 
    25342569      "vld1.8     {q1}, [%0]!                    \n"  // load 8 shorts 
    25352570      "subs       %2, %2, #8                     \n"  // 8 pixels per loop 
  • pjproject/trunk/third_party/yuv/source/row_neon64.cc

    r5633 r5699  
    274274  asm volatile( 
    275275      YUVTORGB_SETUP 
    276       "1:                                          \n" READYUV422 YUVTORGB( 
     276      "1:                                        \n" READYUV422 YUVTORGB( 
    277277          v22, v21, 
    278278          v20) "subs       %w4, %w4, #8                   \n" ARGBTORGB565 
     
    311311      YUVTORGB_SETUP 
    312312      "movi       v23.8b, #255                   \n" 
    313       "1:                                          \n" READYUV422 YUVTORGB( 
     313      "1:                                        \n" READYUV422 YUVTORGB( 
    314314          v22, v21, 
    315315          v20) "subs       %w4, %w4, #8                   \n" ARGBTOARGB1555 
     
    396396  asm volatile( 
    397397      "movi       v23.8b, #255                   \n" 
    398       "1:                                          \n" 
     398      "1:                                        \n" 
    399399      "ld1        {v20.8b}, [%0], #8             \n" 
    400400      "orr        v21.8b, v20.8b, v20.8b         \n" 
     
    471471  asm volatile( 
    472472      YUVTORGB_SETUP 
    473       "1:                                          \n" READNV12 YUVTORGB( 
     473      "1:                                        \n" READNV12 YUVTORGB( 
    474474          v22, v21, 
    475475          v20) "subs       %w3, %w3, #8                   \n" ARGBTORGB565 
     
    545545                     int width) { 
    546546  asm volatile( 
    547       "1:                                          \n" 
     547      "1:                                        \n" 
    548548      "ld2        {v0.16b,v1.16b}, [%0], #32     \n"  // load 16 pairs of UV 
    549549      "subs       %w3, %w3, #16                  \n"  // 16 processed per loop 
     
    566566                     int width) { 
    567567  asm volatile( 
    568       "1:                                          \n" 
     568      "1:                                        \n" 
    569569      "ld1        {v0.16b}, [%0], #16            \n"  // load U 
    570570      "ld1        {v1.16b}, [%1], #16            \n"  // load V 
     
    581581} 
    582582 
    583 // Copy multiple of 32.  vld4.8  allow unaligned and is fastest on a15. 
     583// Reads 16 packed RGB and write to planar dst_r, dst_g, dst_b. 
     584void SplitRGBRow_NEON(const uint8* src_rgb, 
     585                      uint8* dst_r, 
     586                      uint8* dst_g, 
     587                      uint8* dst_b, 
     588                      int width) { 
     589  asm volatile( 
     590      "1:                                        \n" 
     591      "ld3        {v0.16b,v1.16b,v2.16b}, [%0], #48 \n"  // load 16 RGB 
     592      "subs       %w4, %w4, #16                  \n"  // 16 processed per loop 
     593      "st1        {v0.16b}, [%1], #16            \n"  // store R 
     594      "st1        {v1.16b}, [%2], #16            \n"  // store G 
     595      "st1        {v2.16b}, [%3], #16            \n"  // store B 
     596      "b.gt       1b                             \n" 
     597      : "+r"(src_rgb),                    // %0 
     598        "+r"(dst_r),                      // %1 
     599        "+r"(dst_g),                      // %2 
     600        "+r"(dst_b),                      // %3 
     601        "+r"(width)                       // %4 
     602      :                                   // Input registers 
     603      : "cc", "memory", "v0", "v1", "v2"  // Clobber List 
     604      ); 
     605} 
     606 
     607// Reads 16 planar R's, G's and B's and writes out 16 packed RGB at a time 
     608void MergeRGBRow_NEON(const uint8* src_r, 
     609                      const uint8* src_g, 
     610                      const uint8* src_b, 
     611                      uint8* dst_rgb, 
     612                      int width) { 
     613  asm volatile( 
     614      "1:                                        \n" 
     615      "ld1        {v0.16b}, [%0], #16            \n"  // load R 
     616      "ld1        {v1.16b}, [%1], #16            \n"  // load G 
     617      "ld1        {v2.16b}, [%2], #16            \n"  // load B 
     618      "subs       %w4, %w4, #16                  \n"  // 16 processed per loop 
     619      "st3        {v0.16b,v1.16b,v2.16b}, [%3], #48 \n"  // store 16 RGB 
     620      "b.gt       1b                             \n" 
     621      : "+r"(src_r),                      // %0 
     622        "+r"(src_g),                      // %1 
     623        "+r"(src_b),                      // %2 
     624        "+r"(dst_rgb),                    // %3 
     625        "+r"(width)                       // %4 
     626      :                                   // Input registers 
     627      : "cc", "memory", "v0", "v1", "v2"  // Clobber List 
     628      ); 
     629} 
     630 
     631// Copy multiple of 32. 
    584632void CopyRow_NEON(const uint8* src, uint8* dst, int count) { 
    585633  asm volatile( 
    586       "1:                                          \n" 
    587       "ld1        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32       \n"  // load 32 
     634      "1:                                        \n" 
     635      "ldp        q0, q1, [%0], #32              \n" 
    588636      "subs       %w2, %w2, #32                  \n"  // 32 processed per loop 
    589       "st1        {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32       \n"  // store 32 
    590       "b.gt       1b                             \n" 
    591       : "+r"(src),                              // %0 
    592         "+r"(dst),                              // %1 
    593         "+r"(count)                             // %2  // Output registers 
    594       :                                         // Input registers 
    595       : "cc", "memory", "v0", "v1", "v2", "v3"  // Clobber List 
     637      "stp        q0, q1, [%1], #32              \n" 
     638      "b.gt       1b                             \n" 
     639      : "+r"(src),                  // %0 
     640        "+r"(dst),                  // %1 
     641        "+r"(count)                 // %2  // Output registers 
     642      :                             // Input registers 
     643      : "cc", "memory", "v0", "v1"  // Clobber List 
    596644      ); 
    597645} 
     
    601649  asm volatile( 
    602650      "dup        v0.16b, %w2                    \n"  // duplicate 16 bytes 
    603       "1:                                          \n" 
     651      "1:                                        \n" 
    604652      "subs       %w1, %w1, #16                  \n"  // 16 bytes per loop 
    605653      "st1        {v0.16b}, [%0], #16            \n"  // store 
     
    614662  asm volatile( 
    615663      "dup        v0.4s, %w2                     \n"  // duplicate 4 ints 
    616       "1:                                          \n" 
     664      "1:                                        \n" 
    617665      "subs       %w1, %w1, #4                   \n"  // 4 ints per loop 
    618666      "st1        {v0.16b}, [%0], #16            \n"  // store 
     
    629677      "add        %0, %0, %w2, sxtw              \n" 
    630678      "sub        %0, %0, #16                    \n" 
    631       "1:                                          \n" 
     679      "1:                                        \n" 
    632680      "ld1        {v0.16b}, [%0], %3             \n"  // src -= 16 
    633681      "subs       %w2, %w2, #16                  \n"  // 16 pixels per loop. 
     
    651699      "add        %0, %0, %w3, sxtw #1           \n" 
    652700      "sub        %0, %0, #16                    \n" 
    653       "1:                                          \n" 
     701      "1:                                        \n" 
    654702      "ld2        {v0.8b, v1.8b}, [%0], %4       \n"  // src -= 16 
    655703      "subs       %w3, %w3, #8                   \n"  // 8 pixels per loop. 
     
    672720      "add        %0, %0, %w2, sxtw #2           \n" 
    673721      "sub        %0, %0, #16                    \n" 
    674       "1:                                          \n" 
     722      "1:                                        \n" 
    675723      "ld1        {v0.16b}, [%0], %3             \n"  // src -= 16 
    676724      "subs       %w2, %w2, #4                   \n"  // 4 pixels per loop. 
     
    689737  asm volatile( 
    690738      "movi       v4.8b, #255                    \n"  // Alpha 
    691       "1:                                          \n" 
     739      "1:                                        \n" 
    692740      "ld3        {v1.8b,v2.8b,v3.8b}, [%0], #24 \n"  // load 8 pixels of RGB24. 
    693741      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    694742      "st4        {v1.8b,v2.8b,v3.8b,v4.8b}, [%1], #32 \n"  // store 8 ARGB 
    695                                                             // pixels 
    696743      "b.gt       1b                             \n" 
    697744      : "+r"(src_rgb24),  // %0 
     
    706753  asm volatile( 
    707754      "movi       v5.8b, #255                    \n"  // Alpha 
    708       "1:                                          \n" 
     755      "1:                                        \n" 
    709756      "ld3        {v0.8b,v1.8b,v2.8b}, [%0], #24 \n"  // read r g b 
    710757      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    723770void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) { 
    724771  asm volatile( 
    725       "1:                                          \n" 
     772      "1:                                        \n" 
    726773      "ld3        {v0.8b,v1.8b,v2.8b}, [%0], #24 \n"  // read r g b 
    727774      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    754801  asm volatile( 
    755802      "movi       v3.8b, #255                    \n"  // Alpha 
    756       "1:                                          \n" 
     803      "1:                                        \n" 
    757804      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 RGB565 pixels. 
    758805      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    759806      RGB565TOARGB 
    760807      "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n"  // store 8 ARGB 
    761                                                             // pixels 
    762808      "b.gt       1b                             \n" 
    763809      : "+r"(src_rgb565),  // %0 
     
    811857  asm volatile( 
    812858      "movi       v3.8b, #255                    \n"  // Alpha 
    813       "1:                                          \n" 
     859      "1:                                        \n" 
    814860      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 ARGB1555 pixels. 
    815861      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    842888                            int width) { 
    843889  asm volatile( 
    844       "1:                                          \n" 
     890      "1:                                        \n" 
    845891      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 ARGB4444 pixels. 
    846892      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    859905void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) { 
    860906  asm volatile( 
    861       "1:                                          \n" 
     907      "1:                                        \n" 
    862908      "ld4        {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n"  // load 8 ARGB 
    863                                                             // pixels 
    864909      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    865910      "st3        {v1.8b,v2.8b,v3.8b}, [%1], #24 \n"  // store 8 pixels of 
     
    876921void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) { 
    877922  asm volatile( 
    878       "1:                                          \n" 
     923      "1:                                        \n" 
    879924      "ld4        {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n"  // load b g r a 
    880925      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    893938void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) { 
    894939  asm volatile( 
    895       "1:                                          \n" 
     940      "1:                                        \n" 
    896941      "ld2        {v0.16b,v1.16b}, [%0], #32     \n"  // load 16 pixels of YUY2. 
    897942      "subs       %w2, %w2, #16                  \n"  // 16 processed per loop. 
     
    908953void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) { 
    909954  asm volatile( 
    910       "1:                                          \n" 
     955      "1:                                        \n" 
    911956      "ld2        {v0.16b,v1.16b}, [%0], #32     \n"  // load 16 pixels of UYVY. 
    912957      "subs       %w2, %w2, #16                  \n"  // 16 processed per loop. 
     
    926971                         int width) { 
    927972  asm volatile( 
    928       "1:                                          \n" 
     973      "1:                                        \n" 
    929974      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 16 YUY2 
    930                                                             // pixels 
    931975      "subs       %w3, %w3, #16                  \n"  // 16 pixels = 8 UVs. 
    932976      "st1        {v1.8b}, [%1], #8              \n"  // store 8 U. 
     
    947991                         int width) { 
    948992  asm volatile( 
    949       "1:                                          \n" 
     993      "1:                                        \n" 
    950994      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 16 UYVY 
    951                                                             // pixels 
    952995      "subs       %w3, %w3, #16                  \n"  // 16 pixels = 8 UVs. 
    953996      "st1        {v0.8b}, [%1], #8              \n"  // store 8 U. 
     
    9701013  const uint8* src_yuy2b = src_yuy2 + stride_yuy2; 
    9711014  asm volatile( 
    972       "1:                                          \n" 
     1015      "1:                                        \n" 
    9731016      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 16 pixels 
    9741017      "subs       %w4, %w4, #16                  \n"  // 16 pixels = 8 UVs. 
     
    9971040  const uint8* src_uyvyb = src_uyvy + stride_uyvy; 
    9981041  asm volatile( 
    999       "1:                                          \n" 
     1042      "1:                                        \n" 
    10001043      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 16 pixels 
    10011044      "subs       %w4, %w4, #16                  \n"  // 16 pixels = 8 UVs. 
     
    10241067  asm volatile( 
    10251068      "ld1        {v2.16b}, [%3]                 \n"  // shuffler 
    1026       "1:                                          \n" 
     1069      "1:                                        \n" 
    10271070      "ld1        {v0.16b}, [%0], #16            \n"  // load 4 pixels. 
    10281071      "subs       %w2, %w2, #4                   \n"  // 4 processed per loop 
     
    10441087                        int width) { 
    10451088  asm volatile( 
    1046       "1:                                          \n" 
     1089      "1:                                        \n" 
    10471090      "ld2        {v0.8b, v1.8b}, [%0], #16      \n"  // load 16 Ys 
    10481091      "orr        v2.8b, v1.8b, v1.8b            \n" 
     
    10671110                        int width) { 
    10681111  asm volatile( 
    1069       "1:                                          \n" 
     1112      "1:                                        \n" 
    10701113      "ld2        {v1.8b,v2.8b}, [%0], #16       \n"  // load 16 Ys 
    10711114      "orr        v3.8b, v2.8b, v2.8b            \n" 
     
    10861129void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) { 
    10871130  asm volatile( 
    1088       "1:                                          \n" 
     1131      "1:                                        \n" 
    10891132      "ld4        {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n"  // load 8 pixels 
    10901133      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    11051148  asm volatile( 
    11061149      "dup        v1.4s, %w2                     \n"  // dither4 
    1107       "1:                                          \n" 
     1150      "1:                                        \n" 
    11081151      "ld4        {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n"  // load 8 pixels 
    11091152      "subs       %w3, %w3, #8                   \n"  // 8 processed per loop. 
     
    11241167                            int width) { 
    11251168  asm volatile( 
    1126       "1:                                          \n" 
     1169      "1:                                        \n" 
    11271170      "ld4        {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n"  // load 8 pixels 
    11281171      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    11441187      "movi       v4.16b, #0x0f                  \n"  // bits to clear with 
    11451188                                                      // vbic. 
    1146       "1:                                          \n" 
     1189      "1:                                        \n" 
    11471190      "ld4        {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n"  // load 8 pixels 
    11481191      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    11641207      "movi       v6.8b, #33                     \n"  // R * 0.2578 coefficient 
    11651208      "movi       v7.8b, #16                     \n"  // Add 16 constant 
    1166       "1:                                          \n" 
     1209      "1:                                        \n" 
    11671210      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB 
    1168                                                             // pixels. 
    11691211      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    11701212      "umull      v3.8h, v0.8b, v4.8b            \n"  // B 
     
    11841226void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) { 
    11851227  asm volatile( 
    1186       "1:                                          \n" 
     1228      "1:                                        \n" 
    11871229      "ld4        {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n"  // load row 16 
    11881230                                                                // pixels 
     
    12031245      "movi       v5.8b, #75                     \n"  // G * 0.58700 coefficient 
    12041246      "movi       v6.8b, #38                     \n"  // R * 0.29900 coefficient 
    1205       "1:                                          \n" 
     1247      "1:                                        \n" 
    12061248      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB 
    1207                                                             // pixels. 
    12081249      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    12091250      "umull      v3.8h, v0.8b, v4.8b            \n"  // B 
     
    12331274      "movi       v28.8b, #94                    \n"  // VG -0.7344 coefficient 
    12341275      "movi       v29.16b,#0x80                  \n"  // 128.5 
    1235       "1:                                          \n" 
     1276      "1:                                        \n" 
    12361277      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB 
    12371278                                                            // pixels. 
     
    12711312 
    12721313// 16x2 pixels -> 8x1.  width is number of argb pixels. e.g. 16. 
     1314// clang-format off 
    12731315#define RGBTOUV(QB, QG, QR)                                                 \ 
    1274   "mul        v3.8h, " #QB                                                  \ 
    1275   ",v20.8h          \n" /* B                    */                          \ 
    1276   "mul        v4.8h, " #QR                                                  \ 
    1277   ",v20.8h          \n" /* R                    */                          \ 
    1278   "mls        v3.8h, " #QG                                                  \ 
    1279   ",v21.8h          \n" /* G                    */                          \ 
    1280   "mls        v4.8h, " #QG                                                  \ 
    1281   ",v24.8h          \n" /* G                    */                          \ 
    1282   "mls        v3.8h, " #QR                                                  \ 
    1283   ",v22.8h          \n" /* R                    */                          \ 
    1284   "mls        v4.8h, " #QB                                                  \ 
    1285   ",v23.8h          \n"                          /* B                    */ \ 
     1316  "mul        v3.8h, " #QB ",v20.8h          \n" /* B                    */ \ 
     1317  "mul        v4.8h, " #QR ",v20.8h          \n" /* R                    */ \ 
     1318  "mls        v3.8h, " #QG ",v21.8h          \n" /* G                    */ \ 
     1319  "mls        v4.8h, " #QG ",v24.8h          \n" /* G                    */ \ 
     1320  "mls        v3.8h, " #QR ",v22.8h          \n" /* R                    */ \ 
     1321  "mls        v4.8h, " #QB ",v23.8h          \n" /* B                    */ \ 
    12861322  "add        v3.8h, v3.8h, v25.8h           \n" /* +128 -> unsigned     */ \ 
    12871323  "add        v4.8h, v4.8h, v25.8h           \n" /* +128 -> unsigned     */ \ 
    12881324  "uqshrn     v0.8b, v3.8h, #8               \n" /* 16 bit to 8 bit U    */ \ 
    12891325  "uqshrn     v1.8b, v4.8h, #8               \n" /* 16 bit to 8 bit V    */ 
     1326// clang-format on 
    12901327 
    12911328// TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr. 
     
    15791616      "movi       v25.8h, #9 , lsl #0            \n"  // VB coeff (-0.1406) / 2 
    15801617      "movi       v26.8h, #47, lsl #0            \n"  // VG coeff (-0.7344) / 2 
    1581       "movi       v27.16b, #0x80                 \n"  // 128.5 (0x8080 in 
    1582                                                       // 16-bit) 
    1583       "1:                                          \n" 
     1618      "movi       v27.16b, #0x80                 \n"  // 128.5 0x8080 in 16bit 
     1619      "1:                                        \n" 
    15841620      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 RGB565 pixels. 
    15851621      RGB565TOARGB 
     
    16461682  asm volatile( 
    16471683      RGBTOUV_SETUP_REG 
    1648       "1:                                          \n" 
     1684      "1:                                        \n" 
    16491685      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 ARGB1555 pixels. 
    16501686      RGB555TOARGB 
     
    17111747  asm volatile( 
    17121748      RGBTOUV_SETUP_REG 
    1713       "1:                                          \n" 
     1749      "1:                                        \n" 
    17141750      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 ARGB4444 pixels. 
    17151751      ARGB4444TOARGB 
     
    17751811      "movi       v26.8b, #33                    \n"  // R * 0.2578 coefficient 
    17761812      "movi       v27.8b, #16                    \n"  // Add 16 constant 
    1777       "1:                                          \n" 
     1813      "1:                                        \n" 
    17781814      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 RGB565 pixels. 
    17791815      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    18001836      "movi       v6.8b, #33                     \n"  // R * 0.2578 coefficient 
    18011837      "movi       v7.8b, #16                     \n"  // Add 16 constant 
    1802       "1:                                          \n" 
     1838      "1:                                        \n" 
    18031839      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 ARGB1555 pixels. 
    18041840      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    18241860      "movi       v26.8b, #33                    \n"  // R * 0.2578 coefficient 
    18251861      "movi       v27.8b, #16                    \n"  // Add 16 constant 
    1826       "1:                                          \n" 
     1862      "1:                                        \n" 
    18271863      "ld1        {v0.16b}, [%0], #16            \n"  // load 8 ARGB4444 pixels. 
    18281864      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    18481884      "movi       v6.8b, #13                     \n"  // B * 0.1016 coefficient 
    18491885      "movi       v7.8b, #16                     \n"  // Add 16 constant 
    1850       "1:                                          \n" 
     1886      "1:                                        \n" 
    18511887      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 pixels. 
    18521888      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    18711907      "movi       v6.8b, #13                     \n"  // B * 0.1016 coefficient 
    18721908      "movi       v7.8b, #16                     \n"  // Add 16 constant 
    1873       "1:                                          \n" 
     1909      "1:                                        \n" 
    18741910      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 pixels. 
    18751911      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    18941930      "movi       v6.8b, #33                     \n"  // R * 0.2578 coefficient 
    18951931      "movi       v7.8b, #16                     \n"  // Add 16 constant 
    1896       "1:                                          \n" 
     1932      "1:                                        \n" 
    18971933      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 pixels. 
    18981934      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    19171953      "movi       v6.8b, #33                     \n"  // R * 0.2578 coefficient 
    19181954      "movi       v7.8b, #16                     \n"  // Add 16 constant 
    1919       "1:                                          \n" 
     1955      "1:                                        \n" 
    19201956      "ld3        {v0.8b,v1.8b,v2.8b}, [%0], #24 \n"  // load 8 pixels. 
    19211957      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    19401976      "movi       v6.8b, #13                     \n"  // B * 0.1016 coefficient 
    19411977      "movi       v7.8b, #16                     \n"  // Add 16 constant 
    1942       "1:                                          \n" 
     1978      "1:                                        \n" 
    19431979      "ld3        {v0.8b,v1.8b,v2.8b}, [%0], #24 \n"  // load 8 pixels. 
    19441980      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
     
    19752011      "dup        v4.16b, %w5                    \n" 
    19762012      // General purpose row blend. 
    1977       "1:                                          \n" 
     2013      "1:                                        \n" 
    19782014      "ld1        {v0.16b}, [%1], #16            \n" 
    19792015      "ld1        {v1.16b}, [%2], #16            \n" 
     
    19902026 
    19912027      // Blend 50 / 50. 
    1992       "50:                                         \n" 
     2028      "50:                                       \n" 
    19932029      "ld1        {v0.16b}, [%1], #16            \n" 
    19942030      "ld1        {v1.16b}, [%2], #16            \n" 
     
    20002036 
    20012037      // Blend 100 / 0 - Copy row unchanged. 
    2002       "100:                                        \n" 
     2038      "100:                                      \n" 
    20032039      "ld1        {v0.16b}, [%1], #16            \n" 
    20042040      "subs       %w3, %w3, #16                  \n" 
     
    20062042      "b.gt       100b                           \n" 
    20072043 
    2008       "99:                                         \n" 
     2044      "99:                                       \n" 
    20092045      : "+r"(dst_ptr),      // %0 
    20102046        "+r"(src_ptr),      // %1 
     
    20262062      "b.lt       89f                            \n" 
    20272063      // Blend 8 pixels. 
    2028       "8:                                          \n" 
     2064      "8:                                        \n" 
    20292065      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB0 
    20302066                                                            // pixels 
     
    20492085      "b.ge       8b                             \n" 
    20502086 
    2051       "89:                                         \n" 
     2087      "89:                                       \n" 
    20522088      "adds       %w3, %w3, #8-1                 \n" 
    20532089      "b.lt       99f                            \n" 
    20542090 
    20552091      // Blend 1 pixels. 
    2056       "1:                                          \n" 
     2092      "1:                                        \n" 
    20572093      "ld4        {v0.b,v1.b,v2.b,v3.b}[0], [%0], #4 \n"  // load 1 pixel ARGB0. 
    20582094      "ld4        {v4.b,v5.b,v6.b,v7.b}[0], [%1], #4 \n"  // load 1 pixel ARGB1. 
     
    20742110      "b.ge       1b                             \n" 
    20752111 
    2076       "99:                                         \n" 
     2112      "99:                                       \n" 
    20772113 
    20782114      : "+r"(src_argb0),  // %0 
     
    20892125  asm volatile( 
    20902126      // Attenuate 8 pixels. 
    2091       "1:                                          \n" 
     2127      "1:                                        \n" 
    20922128      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB 
    2093                                                             // pixels 
    20942129      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    20952130      "umull      v4.8h, v0.8b, v3.8b            \n"  // b * a 
     
    21232158 
    21242159      // 8 pixel loop. 
    2125       "1:                                          \n" 
    2126       "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0]  \n"  // load 8 pixels of 
    2127                                                         // ARGB. 
     2160      "1:                                        \n" 
     2161      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0]  \n"  // load 8  ARGB. 
    21282162      "subs       %w1, %w1, #8                   \n"    // 8 processed per loop. 
    21292163      "uxtl       v0.8h, v0.8b                   \n"    // b (0 .. 255) 
     
    21432177      "uqxtn      v2.8b, v2.8h                   \n" 
    21442178      "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // store 8 ARGB 
    2145                                                             // pixels 
    21462179      "b.gt       1b                             \n" 
    21472180      : "+r"(dst_argb),       // %0 
     
    21662199 
    21672200      // 8 pixel loop. 
    2168       "1:                                          \n" 
     2201      "1:                                        \n" 
    21692202      "ld4        {v4.8b,v5.8b,v6.8b,v7.8b}, [%0], #32 \n"  // load 8 ARGB 
    2170                                                             // pixels. 
    21712203      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    21722204      "uxtl       v4.8h, v4.8b                   \n"  // b (0 .. 255) 
     
    21832215      "uqxtn      v7.8b, v7.8h                   \n" 
    21842216      "st4        {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n"  // store 8 ARGB 
    2185                                                             // pixels 
    21862217      "b.gt       1b                             \n" 
    21872218      : "+r"(src_argb),  // %0 
     
    22002231      "movi       v25.8b, #75                    \n"  // G * 0.58700 coefficient 
    22012232      "movi       v26.8b, #38                    \n"  // R * 0.29900 coefficient 
    2202       "1:                                          \n" 
     2233      "1:                                        \n" 
    22032234      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB 
    2204                                                             // pixels. 
    22052235      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    22062236      "umull      v4.8h, v0.8b, v24.8b           \n"  // B 
     
    22352265      "movi       v29.8b, #98                    \n"  // BG coefficient 
    22362266      "movi       v30.8b, #50                    \n"  // BR coefficient 
    2237       "1:                                          \n" 
     2267      "1:                                        \n" 
    22382268      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0] \n"  // load 8 ARGB pixels. 
    22392269      "subs       %w1, %w1, #8                   \n"   // 8 processed per loop. 
     
    22712301      "sxtl2      v1.8h, v2.16b                  \n"  // R,A coefficients s16. 
    22722302 
    2273       "1:                                          \n" 
    2274       "ld4        {v16.8b,v17.8b,v18.8b,v19.8b}, [%0], #32 \n"  // load 8 
    2275                                                                 // pixels. 
     2303      "1:                                        \n" 
     2304      "ld4        {v16.8b,v17.8b,v18.8b,v19.8b}, [%0], #32 \n"  // load 8 ARGB 
    22762305      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    22772306      "uxtl       v16.8h, v16.8b                 \n"  // b (0 .. 255) 16 bit 
     
    23112340      "sqshrun    v18.8b, v24.8h, #6             \n"  // 16 bit to 8 bit R 
    23122341      "sqshrun    v19.8b, v25.8h, #6             \n"  // 16 bit to 8 bit A 
    2313       "st4        {v16.8b,v17.8b,v18.8b,v19.8b}, [%1], #32 \n"  // store 8 
    2314                                                                 // pixels. 
     2342      "st4        {v16.8b,v17.8b,v18.8b,v19.8b}, [%1], #32 \n"  // store 8 ARGB 
    23152343      "b.gt       1b                             \n" 
    23162344      : "+r"(src_argb),   // %0 
     
    23302358  asm volatile( 
    23312359      // 8 pixel loop. 
    2332       "1:                                          \n" 
     2360      "1:                                        \n" 
    23332361      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB 
    2334                                                             // pixels. 
    23352362      "ld4        {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n"  // load 8 more 
    2336                                                             // pixels. 
    23372363      "subs       %w3, %w3, #8                   \n"  // 8 processed per loop. 
    23382364      "umull      v0.8h, v0.8b, v4.8b            \n"  // multiply B 
     
    23452371      "rshrn      v3.8b, v3.8h, #8               \n"  // 16 bit to 8 bit A 
    23462372      "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n"  // store 8 ARGB 
    2347                                                             // pixels 
    2348       "b.gt       1b                             \n" 
    2349  
     2373      "b.gt       1b                             \n" 
    23502374      : "+r"(src_argb0),  // %0 
    23512375        "+r"(src_argb1),  // %1 
     
    23632387  asm volatile( 
    23642388      // 8 pixel loop. 
    2365       "1:                                          \n" 
     2389      "1:                                        \n" 
    23662390      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB 
    2367                                                             // pixels. 
    23682391      "ld4        {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n"  // load 8 more 
    2369                                                             // pixels. 
    23702392      "subs       %w3, %w3, #8                   \n"  // 8 processed per loop. 
    23712393      "uqadd      v0.8b, v0.8b, v4.8b            \n" 
     
    23742396      "uqadd      v3.8b, v3.8b, v7.8b            \n" 
    23752397      "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n"  // store 8 ARGB 
    2376                                                             // pixels 
    2377       "b.gt       1b                             \n" 
    2378  
     2398      "b.gt       1b                             \n" 
    23792399      : "+r"(src_argb0),  // %0 
    23802400        "+r"(src_argb1),  // %1 
     
    23922412  asm volatile( 
    23932413      // 8 pixel loop. 
    2394       "1:                                          \n" 
     2414      "1:                                        \n" 
    23952415      "ld4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n"  // load 8 ARGB 
    2396                                                             // pixels. 
    23972416      "ld4        {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n"  // load 8 more 
    2398                                                             // pixels. 
    23992417      "subs       %w3, %w3, #8                   \n"  // 8 processed per loop. 
    24002418      "uqsub      v0.8b, v0.8b, v4.8b            \n" 
     
    24032421      "uqsub      v3.8b, v3.8b, v7.8b            \n" 
    24042422      "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n"  // store 8 ARGB 
    2405                                                             // pixels 
    2406       "b.gt       1b                             \n" 
    2407  
     2423      "b.gt       1b                             \n" 
    24082424      : "+r"(src_argb0),  // %0 
    24092425        "+r"(src_argb1),  // %1 
     
    24262442      "movi       v3.8b, #255                    \n"  // alpha 
    24272443      // 8 pixel loop. 
    2428       "1:                                          \n" 
     2444      "1:                                        \n" 
    24292445      "ld1        {v0.8b}, [%0], #8              \n"  // load 8 sobelx. 
    24302446      "ld1        {v1.8b}, [%1], #8              \n"  // load 8 sobely. 
     
    24342450      "orr        v2.8b, v0.8b, v0.8b            \n" 
    24352451      "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n"  // store 8 ARGB 
    2436                                                             // pixels 
    24372452      "b.gt       1b                             \n" 
    24382453      : "+r"(src_sobelx),  // %0 
     
    24512466  asm volatile( 
    24522467      // 16 pixel loop. 
    2453       "1:                                          \n" 
     2468      "1:                                        \n" 
    24542469      "ld1        {v0.16b}, [%0], #16            \n"  // load 16 sobelx. 
    24552470      "ld1        {v1.16b}, [%1], #16            \n"  // load 16 sobely. 
     
    24782493      "movi       v3.8b, #255                    \n"  // alpha 
    24792494      // 8 pixel loop. 
    2480       "1:                                          \n" 
     2495      "1:                                        \n" 
    24812496      "ld1        {v2.8b}, [%0], #8              \n"  // load 8 sobelx. 
    24822497      "ld1        {v0.8b}, [%1], #8              \n"  // load 8 sobely. 
     
    24842499      "uqadd      v1.8b, v0.8b, v2.8b            \n"  // add 
    24852500      "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n"  // store 8 ARGB 
    2486                                                             // pixels 
    24872501      "b.gt       1b                             \n" 
    24882502      : "+r"(src_sobelx),  // %0 
     
    25042518                    int width) { 
    25052519  asm volatile( 
    2506       "1:                                          \n" 
     2520      "1:                                        \n" 
    25072521      "ld1        {v0.8b}, [%0],%5               \n"  // top 
    25082522      "ld1        {v1.8b}, [%0],%6               \n" 
     
    25422556                    int width) { 
    25432557  asm volatile( 
    2544       "1:                                          \n" 
     2558      "1:                                        \n" 
    25452559      "ld1        {v0.8b}, [%0],%4               \n"  // left 
    25462560      "ld1        {v1.8b}, [%1],%4               \n" 
     
    25732587void HalfFloat1Row_NEON(const uint16* src, uint16* dst, float, int width) { 
    25742588  asm volatile( 
    2575       "1:                                          \n" 
     2589      "1:                                        \n" 
    25762590      "ld1        {v1.16b}, [%0], #16            \n"  // load 8 shorts 
    25772591      "subs       %w2, %w2, #8                   \n"  // 8 pixels per loop 
     
    25932607void HalfFloatRow_NEON(const uint16* src, uint16* dst, float scale, int width) { 
    25942608  asm volatile( 
    2595       "1:                                          \n" 
     2609      "1:                                        \n" 
    25962610      "ld1        {v1.16b}, [%0], #16            \n"  // load 8 shorts 
    25972611      "subs       %w2, %w2, #8                   \n"  // 8 pixels per loop 
     
    26132627} 
    26142628 
     2629float ScaleMaxSamples_NEON(const float* src, 
     2630                           float* dst, 
     2631                           float scale, 
     2632                           int width) { 
     2633  float fmax; 
     2634  asm volatile( 
     2635      "movi       v5.4s, #0                      \n"  // max 
     2636      "movi       v6.4s, #0                      \n" 
     2637 
     2638      "1:                                        \n" 
     2639      "ld1        {v1.4s, v2.4s}, [%0], #32      \n"  // load 8 samples 
     2640      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
     2641      "fmul       v3.4s, v1.4s, %4.s[0]          \n"  // scale 
     2642      "fmul       v4.4s, v2.4s, %4.s[0]          \n"  // scale 
     2643      "fmax       v5.4s, v5.4s, v1.4s            \n"  // max 
     2644      "fmax       v6.4s, v6.4s, v2.4s            \n" 
     2645      "st1        {v3.4s, v4.4s}, [%1], #32      \n"  // store 8 samples 
     2646      "b.gt       1b                             \n" 
     2647      "fmax       v5.4s, v5.4s, v6.4s            \n"  // max 
     2648      "fmaxv      %s3, v5.4s                     \n"  // signed max acculator 
     2649      : "+r"(src),                                    // %0 
     2650        "+r"(dst),                                    // %1 
     2651        "+r"(width),                                  // %2 
     2652        "=w"(fmax)                                    // %3 
     2653      : "w"(scale)                                    // %4 
     2654      : "cc", "memory", "v1", "v2", "v3", "v4", "v5", "v6"); 
     2655  return fmax; 
     2656} 
     2657 
     2658float ScaleSumSamples_NEON(const float* src, 
     2659                           float* dst, 
     2660                           float scale, 
     2661                           int width) { 
     2662  float fsum; 
     2663  asm volatile( 
     2664      "movi       v5.4s, #0                      \n"  // max 
     2665      "movi       v6.4s, #0                      \n"  // max 
     2666 
     2667      "1:                                        \n" 
     2668      "ld1        {v1.4s, v2.4s}, [%0], #32      \n"  // load 8 samples 
     2669      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
     2670      "fmul       v3.4s, v1.4s, %4.s[0]          \n"  // scale 
     2671      "fmul       v4.4s, v2.4s, %4.s[0]          \n" 
     2672      "fmla       v5.4s, v1.4s, v1.4s            \n"  // sum of squares 
     2673      "fmla       v6.4s, v2.4s, v2.4s            \n" 
     2674      "st1        {v3.4s, v4.4s}, [%1], #32      \n"  // store 8 samples 
     2675      "b.gt       1b                             \n" 
     2676      "faddp      v5.4s, v5.4s, v6.4s            \n" 
     2677      "faddp      v5.4s, v5.4s, v5.4s            \n" 
     2678      "faddp      %3.4s, v5.4s, v5.4s            \n"  // sum 
     2679      : "+r"(src),                                    // %0 
     2680        "+r"(dst),                                    // %1 
     2681        "+r"(width),                                  // %2 
     2682        "=w"(fsum)                                    // %3 
     2683      : "w"(scale)                                    // %4 
     2684      : "cc", "memory", "v1", "v2", "v3", "v4", "v5", "v6"); 
     2685  return fsum; 
     2686} 
     2687 
     2688void ScaleSamples_NEON(const float* src, float* dst, float scale, int width) { 
     2689  asm volatile( 
     2690      "1:                                        \n" 
     2691      "ld1        {v1.4s, v2.4s}, [%0], #32      \n"  // load 8 samples 
     2692      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
     2693      "fmul       v1.4s, v1.4s, %3.s[0]          \n"  // scale 
     2694      "fmul       v2.4s, v2.4s, %3.s[0]          \n"  // scale 
     2695      "st1        {v1.4s, v2.4s}, [%1], #32      \n"  // store 8 samples 
     2696      "b.gt       1b                             \n" 
     2697      : "+r"(src),   // %0 
     2698        "+r"(dst),   // %1 
     2699        "+r"(width)  // %2 
     2700      : "w"(scale)   // %3 
     2701      : "cc", "memory", "v1", "v2"); 
     2702} 
     2703 
     2704// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. 
     2705void GaussCol_NEON(const uint16* src0, 
     2706                   const uint16* src1, 
     2707                   const uint16* src2, 
     2708                   const uint16* src3, 
     2709                   const uint16* src4, 
     2710                   uint32* dst, 
     2711                   int width) { 
     2712  asm volatile( 
     2713      "movi       v6.8h, #4                      \n"  // constant 4 
     2714      "movi       v7.8h, #6                      \n"  // constant 6 
     2715 
     2716      "1:                                        \n" 
     2717      "ld1        {v1.8h}, [%0], #16             \n"  // load 8 samples, 5 rows 
     2718      "ld1        {v2.8h}, [%4], #16             \n" 
     2719      "uaddl      v0.4s, v1.4h, v2.4h            \n"  // * 1 
     2720      "uaddl2     v1.4s, v1.8h, v2.8h            \n"  // * 1 
     2721      "ld1        {v2.8h}, [%1], #16             \n" 
     2722      "umlal      v0.4s, v2.4h, v6.4h            \n"  // * 4 
     2723      "umlal2     v1.4s, v2.8h, v6.8h            \n"  // * 4 
     2724      "ld1        {v2.8h}, [%2], #16             \n" 
     2725      "umlal      v0.4s, v2.4h, v7.4h            \n"  // * 6 
     2726      "umlal2     v1.4s, v2.8h, v7.8h            \n"  // * 6 
     2727      "ld1        {v2.8h}, [%3], #16             \n" 
     2728      "umlal      v0.4s, v2.4h, v6.4h            \n"  // * 4 
     2729      "umlal2     v1.4s, v2.8h, v6.8h            \n"  // * 4 
     2730      "subs       %w6, %w6, #8                   \n"  // 8 processed per loop 
     2731      "st1        {v0.4s,v1.4s}, [%5], #32       \n"  // store 8 samples 
     2732      "b.gt       1b                             \n" 
     2733      : "+r"(src0),  // %0 
     2734        "+r"(src1),  // %1 
     2735        "+r"(src2),  // %2 
     2736        "+r"(src3),  // %3 
     2737        "+r"(src4),  // %4 
     2738        "+r"(dst),   // %5 
     2739        "+r"(width)  // %6 
     2740      : 
     2741      : "cc", "memory", "v0", "v1", "v2", "v6", "v7"); 
     2742} 
     2743 
     2744// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. 
     2745void GaussRow_NEON(const uint32* src, uint16* dst, int width) { 
     2746  const uint32* src1 = src + 1; 
     2747  const uint32* src2 = src + 2; 
     2748  const uint32* src3 = src + 3; 
     2749  asm volatile( 
     2750      "movi       v6.4s, #4                      \n"  // constant 4 
     2751      "movi       v7.4s, #6                      \n"  // constant 6 
     2752 
     2753      "1:                                        \n" 
     2754      "ld1        {v0.4s,v1.4s,v2.4s}, [%0], %6  \n"  // load 12 source samples 
     2755      "add        v0.4s, v0.4s, v1.4s            \n"  // * 1 
     2756      "add        v1.4s, v1.4s, v2.4s            \n"  // * 1 
     2757      "ld1        {v2.4s,v3.4s}, [%2], #32       \n" 
     2758      "mla        v0.4s, v2.4s, v7.4s            \n"  // * 6 
     2759      "mla        v1.4s, v3.4s, v7.4s            \n"  // * 6 
     2760      "ld1        {v2.4s,v3.4s}, [%1], #32       \n" 
     2761      "ld1        {v4.4s,v5.4s}, [%3], #32       \n" 
     2762      "add        v2.4s, v2.4s, v4.4s            \n"  // add rows for * 4 
     2763      "add        v3.4s, v3.4s, v5.4s            \n" 
     2764      "mla        v0.4s, v2.4s, v6.4s            \n"  // * 4 
     2765      "mla        v1.4s, v3.4s, v6.4s            \n"  // * 4 
     2766      "subs       %w5, %w5, #8                   \n"  // 8 processed per loop 
     2767      "uqrshrn    v0.4h, v0.4s, #8               \n"  // round and pack 
     2768      "uqrshrn2   v0.8h, v1.4s, #8               \n" 
     2769      "st1        {v0.8h}, [%4], #16             \n"  // store 8 samples 
     2770      "b.gt       1b                             \n" 
     2771      : "+r"(src),   // %0 
     2772        "+r"(src1),  // %1 
     2773        "+r"(src2),  // %2 
     2774        "+r"(src3),  // %3 
     2775        "+r"(dst),   // %4 
     2776        "+r"(width)  // %5 
     2777      : "r"(32LL)    // %6 
     2778      : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); 
     2779} 
     2780 
    26152781#endif  // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) 
    26162782 
  • pjproject/trunk/third_party/yuv/source/row_win.cc

    r5633 r5699  
    14111411    pavgb      xmm2, xmm4 
    14121412 
    1413     // step 2 - convert to U and V 
    1414     // from here down is very similar to Y code except 
    1415     // instead of 16 different pixels, its 8 pixels of U and 8 of V 
     1413        // step 2 - convert to U and V 
     1414        // from here down is very similar to Y code except 
     1415        // instead of 16 different pixels, its 8 pixels of U and 8 of V 
    14161416    movdqa     xmm1, xmm0 
    14171417    movdqa     xmm3, xmm2 
     
    14271427    paddb      xmm0, xmm5  // -> unsigned 
    14281428 
    1429     // step 3 - store 8 U and 8 V values 
     1429        // step 3 - store 8 U and 8 V values 
    14301430    movlps     qword ptr [edx], xmm0  // U 
    14311431    movhps     qword ptr [edx + edi], xmm0  // V 
     
    14831483    pavgb      xmm2, xmm4 
    14841484 
    1485     // step 2 - convert to U and V 
    1486     // from here down is very similar to Y code except 
    1487     // instead of 16 different pixels, its 8 pixels of U and 8 of V 
     1485        // step 2 - convert to U and V 
     1486        // from here down is very similar to Y code except 
     1487        // instead of 16 different pixels, its 8 pixels of U and 8 of V 
    14881488    movdqa     xmm1, xmm0 
    14891489    movdqa     xmm3, xmm2 
     
    15001500    packsswb   xmm0, xmm1 
    15011501 
    1502     // step 3 - store 8 U and 8 V values 
     1502        // step 3 - store 8 U and 8 V values 
    15031503    movlps     qword ptr [edx], xmm0  // U 
    15041504    movhps     qword ptr [edx + edi], xmm0  // V 
     
    15501550    vpavgb     ymm2, ymm2, ymm4  // mutated by vshufps 
    15511551 
    1552     // step 2 - convert to U and V 
    1553     // from here down is very similar to Y code except 
    1554     // instead of 32 different pixels, its 16 pixels of U and 16 of V 
     1552        // step 2 - convert to U and V 
     1553        // from here down is very similar to Y code except 
     1554        // instead of 32 different pixels, its 16 pixels of U and 16 of V 
    15551555    vpmaddubsw ymm1, ymm0, ymm7  // U 
    15561556    vpmaddubsw ymm3, ymm2, ymm7 
     
    15661566    vpaddb     ymm0, ymm0, ymm5  // -> unsigned 
    15671567 
    1568     // step 3 - store 16 U and 16 V values 
     1568        // step 3 - store 16 U and 16 V values 
    15691569    vextractf128 [edx], ymm0, 0  // U 
    15701570    vextractf128 [edx + edi], ymm0, 1  // V 
     
    16181618    vpavgb     ymm2, ymm2, ymm4  // mutated by vshufps 
    16191619 
    1620     // step 2 - convert to U and V 
    1621     // from here down is very similar to Y code except 
    1622     // instead of 32 different pixels, its 16 pixels of U and 16 of V 
     1620        // step 2 - convert to U and V 
     1621        // from here down is very similar to Y code except 
     1622        // instead of 32 different pixels, its 16 pixels of U and 16 of V 
    16231623    vpmaddubsw ymm1, ymm0, ymm7  // U 
    16241624    vpmaddubsw ymm3, ymm2, ymm7 
     
    16351635    vpshufb    ymm0, ymm0, ymmword ptr kShufARGBToUV_AVX  // for vshufps/vphaddw 
    16361636 
    1637     // step 3 - store 16 U and 16 V values 
     1637        // step 3 - store 16 U and 16 V values 
    16381638    vextractf128 [edx], ymm0, 0  // U 
    16391639    vextractf128 [edx + edi], ymm0, 1  // V 
     
    17511751    pavgb      xmm2, xmm4 
    17521752 
    1753     // step 2 - convert to U and V 
    1754     // from here down is very similar to Y code except 
    1755     // instead of 16 different pixels, its 8 pixels of U and 8 of V 
     1753        // step 2 - convert to U and V 
     1754        // from here down is very similar to Y code except 
     1755        // instead of 16 different pixels, its 8 pixels of U and 8 of V 
    17561756    movdqa     xmm1, xmm0 
    17571757    movdqa     xmm3, xmm2 
     
    17671767    paddb      xmm0, xmm5  // -> unsigned 
    17681768 
    1769     // step 3 - store 8 U and 8 V values 
     1769        // step 3 - store 8 U and 8 V values 
    17701770    movlps     qword ptr [edx], xmm0  // U 
    17711771    movhps     qword ptr [edx + edi], xmm0  // V 
     
    18231823    pavgb      xmm2, xmm4 
    18241824 
    1825     // step 2 - convert to U and V 
    1826     // from here down is very similar to Y code except 
    1827     // instead of 16 different pixels, its 8 pixels of U and 8 of V 
     1825        // step 2 - convert to U and V 
     1826        // from here down is very similar to Y code except 
     1827        // instead of 16 different pixels, its 8 pixels of U and 8 of V 
    18281828    movdqa     xmm1, xmm0 
    18291829    movdqa     xmm3, xmm2 
     
    18391839    paddb      xmm0, xmm5  // -> unsigned 
    18401840 
    1841     // step 3 - store 8 U and 8 V values 
     1841        // step 3 - store 8 U and 8 V values 
    18421842    movlps     qword ptr [edx], xmm0  // U 
    18431843    movhps     qword ptr [edx + edi], xmm0  // V 
     
    18951895    pavgb      xmm2, xmm4 
    18961896 
    1897     // step 2 - convert to U and V 
    1898     // from here down is very similar to Y code except 
    1899     // instead of 16 different pixels, its 8 pixels of U and 8 of V 
     1897        // step 2 - convert to U and V 
     1898        // from here down is very similar to Y code except 
     1899        // instead of 16 different pixels, its 8 pixels of U and 8 of V 
    19001900    movdqa     xmm1, xmm0 
    19011901    movdqa     xmm3, xmm2 
     
    19111911    paddb      xmm0, xmm5  // -> unsigned 
    19121912 
    1913     // step 3 - store 8 U and 8 V values 
     1913        // step 3 - store 8 U and 8 V values 
    19141914    movlps     qword ptr [edx], xmm0  // U 
    19151915    movhps     qword ptr [edx + edi], xmm0  // V 
     
    29282928    packuswb   xmm0, xmm0        // G 
    29292929 
    2930     // Step 2: Weave into ARGB 
     2930        // Step 2: Weave into ARGB 
    29312931    punpcklbw  xmm0, xmm0  // GG 
    29322932    movdqa     xmm1, xmm0 
     
    29762976    vpackuswb  ymm0, ymm0, ymm0        // G.  still mutated: 3120 
    29772977 
    2978     // TODO(fbarchard): Weave alpha with unpack. 
    2979     // Step 2: Weave into ARGB 
     2978        // TODO(fbarchard): Weave alpha with unpack. 
     2979        // Step 2: Weave into ARGB 
    29802980    vpunpcklbw ymm1, ymm0, ymm0  // GG - mutates 
    29812981    vpermq     ymm1, ymm1, 0xd8 
     
    40684068    sub        edi, esi 
    40694069 
    4070     // 8 pixel loop. 
     4070        // 8 pixel loop. 
    40714071  convertloop8: 
    40724072    movq       xmm0, qword ptr [esi]  // alpha 
     
    41244124    sub         edi, esi 
    41254125 
    4126     // 32 pixel loop. 
     4126        // 32 pixel loop. 
    41274127  convertloop32: 
    41284128    vmovdqu     ymm0, [esi]  // alpha 
     
    41844184    jl         convertloop4b  // less than 4 pixels? 
    41854185 
    4186     // 4 pixel loop. 
     4186        // 4 pixel loop. 
    41874187  convertloop4: 
    41884188    movdqu     xmm3, [eax]  // src argb 
     
    42134213    jl         convertloop1b 
    42144214 
    4215     // 1 pixel loop. 
     4215        // 1 pixel loop. 
    42164216  convertloop1: 
    42174217    movd       xmm3, [eax]  // src argb 
     
    52575257    packssdw   xmm5, xmm5  // 16 bit shorts 
    52585258 
    5259     // 4 pixel loop small blocks. 
     5259        // 4 pixel loop small blocks. 
    52605260  s4: 
    52615261        // top left 
     
    52995299    jmp        l4b 
    53005300 
    5301     // 4 pixel loop 
     5301            // 4 pixel loop 
    53025302  l4: 
    53035303        // top left 
     
    53515351    jl         l1b 
    53525352 
    5353     // 1 pixel loop 
     5353        // 1 pixel loop 
    53545354  l1: 
    53555355    movdqu     xmm0, [eax] 
     
    53935393    jne        l4b 
    53945394 
    5395     // 4 pixel loop 
     5395        // 4 pixel loop 
    53965396  l4: 
    53975397    movdqu     xmm2, [eax]  // 4 argb pixels 16 bytes. 
     
    54395439    jl         l1b 
    54405440 
    5441     // 1 pixel loop 
     5441        // 1 pixel loop 
    54425442  l1: 
    54435443    movd       xmm2, dword ptr [eax]  // 1 argb pixel 4 bytes. 
     
    54825482    jl         l4b 
    54835483 
    5484     // setup for 4 pixel loop 
     5484        // setup for 4 pixel loop 
    54855485    pshufd     xmm7, xmm7, 0x44  // dup dudv 
    54865486    pshufd     xmm5, xmm5, 0  // dup 4, stride 
     
    54945494    addps      xmm4, xmm4  // dudv *= 4 
    54955495 
    5496     // 4 pixel loop 
     5496        // 4 pixel loop 
    54975497  l4: 
    54985498    cvttps2dq  xmm0, xmm2  // x, y float to int first 2 
     
    55255525    jl         l1b 
    55265526 
    5527     // 1 pixel loop 
     5527        // 1 pixel loop 
    55285528  l1: 
    55295529    cvttps2dq  xmm0, xmm2  // x, y float to int 
     
    55995599    jmp        xloop99 
    56005600 
    5601     // Blend 50 / 50. 
     5601        // Blend 50 / 50. 
    56025602 xloop50: 
    56035603   vmovdqu    ymm0, [esi] 
     
    56095609   jmp        xloop99 
    56105610 
    5611     // Blend 100 / 0 - Copy row unchanged. 
     5611        // Blend 100 / 0 - Copy row unchanged. 
    56125612 xloop100: 
    56135613   rep movsb 
     
    56395639    mov        eax, [esp + 8 + 20]  // source_y_fraction (0..255) 
    56405640    sub        edi, esi 
    5641     // Dispatch to specialized filters if applicable. 
     5641        // Dispatch to specialized filters if applicable. 
    56425642    cmp        eax, 0 
    56435643    je         xloop100  // 0 /256.  Blend 100 / 0. 
     
    56795679    jmp        xloop99 
    56805680 
    5681     // Blend 50 / 50. 
     5681        // Blend 50 / 50. 
    56825682  xloop50: 
    56835683    movdqu     xmm0, [esi] 
     
    56905690    jmp        xloop99 
    56915691 
    5692     // Blend 100 / 0 - Copy row unchanged. 
     5692        // Blend 100 / 0 - Copy row unchanged. 
    56935693  xloop100: 
    56945694    movdqu     xmm0, [esi] 
     
    57855785    je         shuf_2103 
    57865786 
    5787     // TODO(fbarchard): Use one source pointer and 3 offsets. 
     5787        // TODO(fbarchard): Use one source pointer and 3 offsets. 
    57885788  shuf_any1: 
    57895789    movzx      ebx, byte ptr [esi] 
     
    59725972    pxor       xmm3, xmm3  // 0 constant for zero extending bytes to ints. 
    59735973 
    5974     // 2 pixel loop. 
     5974        // 2 pixel loop. 
    59755975 convertloop: 
    59765976        //    pmovzxbd  xmm0, dword ptr [eax]  // BGRA pixel 
     
    60736073    sub        edx, eax 
    60746074 
    6075     // 8 pixel loop. 
     6075        // 8 pixel loop. 
    60766076 convertloop: 
    60776077    movdqu      xmm2, xmmword ptr [eax]  // 8 shorts 
     
    61116111    sub        edx, eax 
    61126112 
    6113     // 16 pixel loop. 
     6113        // 16 pixel loop. 
    61146114 convertloop: 
    61156115    vmovdqu     ymm2, [eax]  // 16 shorts 
     
    61456145    sub        edx, eax 
    61466146 
    6147     // 16 pixel loop. 
     6147        // 16 pixel loop. 
    61486148 convertloop: 
    61496149    vpmovzxwd   ymm2, xmmword ptr [eax]  // 8 shorts -> 8 ints 
     
    62536253    pxor       xmm5, xmm5 
    62546254 
    6255     // 4 pixel loop. 
     6255        // 4 pixel loop. 
    62566256  convertloop: 
    62576257    movdqu     xmm0, xmmword ptr [eax]  // generate luma ptr 
  • pjproject/trunk/third_party/yuv/source/scale.cc

    r5633 r5699  
    372372  } 
    373373#endif 
     374#if defined(HAS_SCALEROWDOWN34_MSA) 
     375  if (TestCpuFlag(kCpuHasMSA)) { 
     376    if (!filtering) { 
     377      ScaleRowDown34_0 = ScaleRowDown34_Any_MSA; 
     378      ScaleRowDown34_1 = ScaleRowDown34_Any_MSA; 
     379    } else { 
     380      ScaleRowDown34_0 = ScaleRowDown34_0_Box_Any_MSA; 
     381      ScaleRowDown34_1 = ScaleRowDown34_1_Box_Any_MSA; 
     382    } 
     383    if (dst_width % 48 == 0) { 
     384      if (!filtering) { 
     385        ScaleRowDown34_0 = ScaleRowDown34_MSA; 
     386        ScaleRowDown34_1 = ScaleRowDown34_MSA; 
     387      } else { 
     388        ScaleRowDown34_0 = ScaleRowDown34_0_Box_MSA; 
     389        ScaleRowDown34_1 = ScaleRowDown34_1_Box_MSA; 
     390      } 
     391    } 
     392  } 
     393#endif 
    374394#if defined(HAS_SCALEROWDOWN34_SSSE3) 
    375395  if (TestCpuFlag(kCpuHasSSSE3)) { 
     
    803823                            int boxheight, 
    804824                            int x, 
    805                             int, 
     825                            int dx, 
    806826                            const uint16* src_ptr, 
    807827                            uint8* dst_ptr) { 
    808828  int scaleval = 65536 / boxheight; 
    809829  int i; 
     830  (void)dx; 
    810831  src_ptr += (x >> 16); 
    811832  for (i = 0; i < dst_width; ++i) { 
     
    10801101  } 
    10811102#endif 
     1103#if defined(HAS_SCALEFILTERCOLS_MSA) 
     1104  if (TestCpuFlag(kCpuHasMSA) && src_width < 32768) { 
     1105    ScaleFilterCols = ScaleFilterCols_Any_MSA; 
     1106    if (IS_ALIGNED(dst_width, 16)) { 
     1107      ScaleFilterCols = ScaleFilterCols_MSA; 
     1108    } 
     1109  } 
     1110#endif 
    10821111  if (y > max_y) { 
    10831112    y = max_y; 
     
    12781307  } 
    12791308#endif 
     1309#if defined(HAS_SCALEFILTERCOLS_MSA) 
     1310  if (filtering && TestCpuFlag(kCpuHasMSA) && src_width < 32768) { 
     1311    ScaleFilterCols = ScaleFilterCols_Any_MSA; 
     1312    if (IS_ALIGNED(dst_width, 16)) { 
     1313      ScaleFilterCols = ScaleFilterCols_MSA; 
     1314    } 
     1315  } 
     1316#endif 
    12801317  if (!filtering && src_width * 2 == dst_width && x < 0x8000) { 
    12811318    ScaleFilterCols = ScaleColsUp2_C; 
     
    16641701    return; 
    16651702  } 
    1666   if (dst_width == src_width) { 
     1703  if (dst_width == src_width && filtering != kFilterBox) { 
    16671704    int dy = FixedDiv(src_height, dst_height); 
    16681705    // Arbitrary scale vertically, but unscaled vertically. 
     
    16931730    } 
    16941731    if (4 * dst_width == src_width && 4 * dst_height == src_height && 
    1695         filtering != kFilterBilinear) { 
     1732        (filtering == kFilterBox || filtering == kFilterNone)) { 
    16961733      // optimized, 1/4 
    16971734      ScalePlaneDown4_16(src_width, src_height, dst_width, dst_height, 
  • pjproject/trunk/third_party/yuv/source/scale_any.cc

    r5633 r5699  
    3434CANY(ScaleFilterCols_Any_NEON, ScaleFilterCols_NEON, ScaleFilterCols_C, 1, 7) 
    3535#endif 
     36#ifdef HAS_SCALEFILTERCOLS_MSA 
     37CANY(ScaleFilterCols_Any_MSA, ScaleFilterCols_MSA, ScaleFilterCols_C, 1, 15) 
     38#endif 
    3639#ifdef HAS_SCALEARGBCOLS_NEON 
    3740CANY(ScaleARGBCols_Any_NEON, ScaleARGBCols_NEON, ScaleARGBCols_C, 4, 7) 
     41#endif 
     42#ifdef HAS_SCALEARGBCOLS_MSA 
     43CANY(ScaleARGBCols_Any_MSA, ScaleARGBCols_MSA, ScaleARGBCols_C, 4, 3) 
    3844#endif 
    3945#ifdef HAS_SCALEARGBFILTERCOLS_NEON 
     
    4349     4, 
    4450     3) 
     51#endif 
     52#ifdef HAS_SCALEARGBFILTERCOLS_MSA 
     53CANY(ScaleARGBFilterCols_Any_MSA, 
     54     ScaleARGBFilterCols_MSA, 
     55     ScaleARGBFilterCols_C, 
     56     4, 
     57     7) 
    4558#endif 
    4659#undef CANY 
     
    229242      23) 
    230243#endif 
     244#ifdef HAS_SCALEROWDOWN34_MSA 
     245SDANY(ScaleRowDown34_Any_MSA, 
     246      ScaleRowDown34_MSA, 
     247      ScaleRowDown34_C, 
     248      4 / 3, 
     249      1, 
     250      47) 
     251SDANY(ScaleRowDown34_0_Box_Any_MSA, 
     252      ScaleRowDown34_0_Box_MSA, 
     253      ScaleRowDown34_0_Box_C, 
     254      4 / 3, 
     255      1, 
     256      47) 
     257SDANY(ScaleRowDown34_1_Box_Any_MSA, 
     258      ScaleRowDown34_1_Box_MSA, 
     259      ScaleRowDown34_1_Box_C, 
     260      4 / 3, 
     261      1, 
     262      47) 
     263#endif 
    231264#ifdef HAS_SCALEROWDOWN38_SSSE3 
    232265SDANY(ScaleRowDown38_Any_SSSE3, 
  • pjproject/trunk/third_party/yuv/source/scale_argb.cc

    r5633 r5699  
    337337  } 
    338338#endif 
     339#if defined(HAS_SCALEARGBFILTERCOLS_MSA) 
     340  if (TestCpuFlag(kCpuHasMSA)) { 
     341    ScaleARGBFilterCols = ScaleARGBFilterCols_Any_MSA; 
     342    if (IS_ALIGNED(dst_width, 8)) { 
     343      ScaleARGBFilterCols = ScaleARGBFilterCols_MSA; 
     344    } 
     345  } 
     346#endif 
    339347  // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. 
    340348  // Allocate a row of ARGB. 
     
    443451  } 
    444452#endif 
     453#if defined(HAS_SCALEARGBFILTERCOLS_MSA) 
     454  if (filtering && TestCpuFlag(kCpuHasMSA)) { 
     455    ScaleARGBFilterCols = ScaleARGBFilterCols_Any_MSA; 
     456    if (IS_ALIGNED(dst_width, 8)) { 
     457      ScaleARGBFilterCols = ScaleARGBFilterCols_MSA; 
     458    } 
     459  } 
     460#endif 
    445461#if defined(HAS_SCALEARGBCOLS_SSE2) 
    446462  if (!filtering && TestCpuFlag(kCpuHasSSE2) && src_width < 32768) { 
     
    453469    if (IS_ALIGNED(dst_width, 8)) { 
    454470      ScaleARGBFilterCols = ScaleARGBCols_NEON; 
     471    } 
     472  } 
     473#endif 
     474#if defined(HAS_SCALEARGBCOLS_MSA) 
     475  if (!filtering && TestCpuFlag(kCpuHasMSA)) { 
     476    ScaleARGBFilterCols = ScaleARGBCols_Any_MSA; 
     477    if (IS_ALIGNED(dst_width, 4)) { 
     478      ScaleARGBFilterCols = ScaleARGBCols_MSA; 
    455479    } 
    456480  } 
     
    644668  } 
    645669#endif 
     670#if defined(HAS_SCALEARGBFILTERCOLS_MSA) 
     671  if (filtering && TestCpuFlag(kCpuHasMSA)) { 
     672    ScaleARGBFilterCols = ScaleARGBFilterCols_Any_MSA; 
     673    if (IS_ALIGNED(dst_width, 8)) { 
     674      ScaleARGBFilterCols = ScaleARGBFilterCols_MSA; 
     675    } 
     676  } 
     677#endif 
    646678#if defined(HAS_SCALEARGBCOLS_SSE2) 
    647679  if (!filtering && TestCpuFlag(kCpuHasSSE2) && src_width < 32768) { 
     
    654686    if (IS_ALIGNED(dst_width, 8)) { 
    655687      ScaleARGBFilterCols = ScaleARGBCols_NEON; 
     688    } 
     689  } 
     690#endif 
     691#if defined(HAS_SCALEARGBCOLS_MSA) 
     692  if (!filtering && TestCpuFlag(kCpuHasMSA)) { 
     693    ScaleARGBFilterCols = ScaleARGBCols_Any_MSA; 
     694    if (IS_ALIGNED(dst_width, 4)) { 
     695      ScaleARGBFilterCols = ScaleARGBCols_MSA; 
    656696    } 
    657697  } 
     
    777817    if (IS_ALIGNED(dst_width, 8)) { 
    778818      ScaleARGBCols = ScaleARGBCols_NEON; 
     819    } 
     820  } 
     821#endif 
     822#if defined(HAS_SCALEARGBCOLS_MSA) 
     823  if (TestCpuFlag(kCpuHasMSA)) { 
     824    ScaleARGBCols = ScaleARGBCols_Any_MSA; 
     825    if (IS_ALIGNED(dst_width, 4)) { 
     826      ScaleARGBCols = ScaleARGBCols_MSA; 
    779827    } 
    780828  } 
  • pjproject/trunk/third_party/yuv/source/scale_common.cc

    r5633 r5699  
    13071307#undef CENTERSTART 
    13081308 
     1309// Read 8x2 upsample with filtering and write 16x1. 
     1310// actually reads an extra pixel, so 9x2. 
     1311void ScaleRowUp2_16_C(const uint16* src_ptr, 
     1312                      ptrdiff_t src_stride, 
     1313                      uint16* dst, 
     1314                      int dst_width) { 
     1315  const uint16* src2 = src_ptr + src_stride; 
     1316 
     1317  int x; 
     1318  for (x = 0; x < dst_width - 1; x += 2) { 
     1319    uint16 p0 = src_ptr[0]; 
     1320    uint16 p1 = src_ptr[1]; 
     1321    uint16 p2 = src2[0]; 
     1322    uint16 p3 = src2[1]; 
     1323    dst[0] = (p0 * 9 + p1 * 3 + p2 * 3 + p3 + 8) >> 4; 
     1324    dst[1] = (p0 * 3 + p1 * 9 + p2 + p3 * 3 + 8) >> 4; 
     1325    ++src_ptr; 
     1326    ++src2; 
     1327    dst += 2; 
     1328  } 
     1329  if (dst_width & 1) { 
     1330    uint16 p0 = src_ptr[0]; 
     1331    uint16 p1 = src_ptr[1]; 
     1332    uint16 p2 = src2[0]; 
     1333    uint16 p3 = src2[1]; 
     1334    dst[0] = (p0 * 9 + p1 * 3 + p2 * 3 + p3 + 8) >> 4; 
     1335  } 
     1336} 
     1337 
    13091338#ifdef __cplusplus 
    13101339}  // extern "C" 
  • pjproject/trunk/third_party/yuv/source/scale_msa.cc

    r5633 r5699  
    2121extern "C" { 
    2222#endif 
     23 
     24#define LOAD_INDEXED_DATA(srcp, indx0, out0) \ 
     25  {                                          \ 
     26    out0[0] = srcp[indx0[0]];                \ 
     27    out0[1] = srcp[indx0[1]];                \ 
     28    out0[2] = srcp[indx0[2]];                \ 
     29    out0[3] = srcp[indx0[3]];                \ 
     30  } 
    2331 
    2432void ScaleARGBRowDown2_MSA(const uint8_t* src_argb, 
     
    546554} 
    547555 
     556void ScaleFilterCols_MSA(uint8* dst_ptr, 
     557                         const uint8* src_ptr, 
     558                         int dst_width, 
     559                         int x, 
     560                         int dx) { 
     561  int j; 
     562  v4i32 vec_x = __msa_fill_w(x); 
     563  v4i32 vec_dx = __msa_fill_w(dx); 
     564  v4i32 vec_const = {0, 1, 2, 3}; 
     565  v4i32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; 
     566  v4i32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; 
     567  v8u16 reg0, reg1; 
     568  v16u8 dst0; 
     569  v4i32 const_0xFFFF = __msa_fill_w(0xFFFF); 
     570  v4i32 const_0x40 = __msa_fill_w(0x40); 
     571 
     572  vec0 = vec_dx * vec_const; 
     573  vec1 = vec_dx * 4; 
     574  vec_x += vec0; 
     575 
     576  for (j = 0; j < dst_width - 1; j += 16) { 
     577    vec2 = vec_x >> 16; 
     578    vec6 = vec_x & const_0xFFFF; 
     579    vec_x += vec1; 
     580    vec3 = vec_x >> 16; 
     581    vec7 = vec_x & const_0xFFFF; 
     582    vec_x += vec1; 
     583    vec4 = vec_x >> 16; 
     584    vec8 = vec_x & const_0xFFFF; 
     585    vec_x += vec1; 
     586    vec5 = vec_x >> 16; 
     587    vec9 = vec_x & const_0xFFFF; 
     588    vec_x += vec1; 
     589    vec6 >>= 9; 
     590    vec7 >>= 9; 
     591    vec8 >>= 9; 
     592    vec9 >>= 9; 
     593    LOAD_INDEXED_DATA(src_ptr, vec2, tmp0); 
     594    LOAD_INDEXED_DATA(src_ptr, vec3, tmp1); 
     595    LOAD_INDEXED_DATA(src_ptr, vec4, tmp2); 
     596    LOAD_INDEXED_DATA(src_ptr, vec5, tmp3); 
     597    vec2 += 1; 
     598    vec3 += 1; 
     599    vec4 += 1; 
     600    vec5 += 1; 
     601    LOAD_INDEXED_DATA(src_ptr, vec2, tmp4); 
     602    LOAD_INDEXED_DATA(src_ptr, vec3, tmp5); 
     603    LOAD_INDEXED_DATA(src_ptr, vec4, tmp6); 
     604    LOAD_INDEXED_DATA(src_ptr, vec5, tmp7); 
     605    tmp4 -= tmp0; 
     606    tmp5 -= tmp1; 
     607    tmp6 -= tmp2; 
     608    tmp7 -= tmp3; 
     609    tmp4 *= vec6; 
     610    tmp5 *= vec7; 
     611    tmp6 *= vec8; 
     612    tmp7 *= vec9; 
     613    tmp4 += const_0x40; 
     614    tmp5 += const_0x40; 
     615    tmp6 += const_0x40; 
     616    tmp7 += const_0x40; 
     617    tmp4 >>= 7; 
     618    tmp5 >>= 7; 
     619    tmp6 >>= 7; 
     620    tmp7 >>= 7; 
     621    tmp0 += tmp4; 
     622    tmp1 += tmp5; 
     623    tmp2 += tmp6; 
     624    tmp3 += tmp7; 
     625    reg0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); 
     626    reg1 = (v8u16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); 
     627    dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); 
     628    __msa_st_b(dst0, dst_ptr, 0); 
     629    dst_ptr += 16; 
     630  } 
     631} 
     632 
     633void ScaleARGBCols_MSA(uint8* dst_argb, 
     634                       const uint8* src_argb, 
     635                       int dst_width, 
     636                       int x, 
     637                       int dx) { 
     638  const uint32* src = (const uint32*)(src_argb); 
     639  uint32* dst = (uint32*)(dst_argb); 
     640  int j; 
     641  v4i32 x_vec = __msa_fill_w(x); 
     642  v4i32 dx_vec = __msa_fill_w(dx); 
     643  v4i32 const_vec = {0, 1, 2, 3}; 
     644  v4i32 vec0, vec1, vec2; 
     645  v4i32 dst0; 
     646 
     647  vec0 = dx_vec * const_vec; 
     648  vec1 = dx_vec * 4; 
     649  x_vec += vec0; 
     650 
     651  for (j = 0; j < dst_width; j += 4) { 
     652    vec2 = x_vec >> 16; 
     653    x_vec += vec1; 
     654    LOAD_INDEXED_DATA(src, vec2, dst0); 
     655    __msa_st_w(dst0, dst, 0); 
     656    dst += 4; 
     657  } 
     658} 
     659 
     660void ScaleARGBFilterCols_MSA(uint8* dst_argb, 
     661                             const uint8* src_argb, 
     662                             int dst_width, 
     663                             int x, 
     664                             int dx) { 
     665  const uint32* src = (const uint32*)(src_argb); 
     666  int j; 
     667  v4u32 src0, src1, src2, src3; 
     668  v4u32 vec0, vec1, vec2, vec3; 
     669  v16u8 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; 
     670  v16u8 mult0, mult1, mult2, mult3; 
     671  v8u16 tmp0, tmp1, tmp2, tmp3; 
     672  v16u8 dst0, dst1; 
     673  v4u32 vec_x = (v4u32)__msa_fill_w(x); 
     674  v4u32 vec_dx = (v4u32)__msa_fill_w(dx); 
     675  v4u32 vec_const = {0, 1, 2, 3}; 
     676  v16u8 const_0x7f = (v16u8)__msa_fill_b(0x7f); 
     677 
     678  vec0 = vec_dx * vec_const; 
     679  vec1 = vec_dx * 4; 
     680  vec_x += vec0; 
     681 
     682  for (j = 0; j < dst_width - 1; j += 8) { 
     683    vec2 = vec_x >> 16; 
     684    reg0 = (v16u8)(vec_x >> 9); 
     685    vec_x += vec1; 
     686    vec3 = vec_x >> 16; 
     687    reg1 = (v16u8)(vec_x >> 9); 
     688    vec_x += vec1; 
     689    reg0 = reg0 & const_0x7f; 
     690    reg1 = reg1 & const_0x7f; 
     691    reg0 = (v16u8)__msa_shf_b((v16i8)reg0, 0); 
     692    reg1 = (v16u8)__msa_shf_b((v16i8)reg1, 0); 
     693    reg2 = reg0 ^ const_0x7f; 
     694    reg3 = reg1 ^ const_0x7f; 
     695    mult0 = (v16u8)__msa_ilvr_b((v16i8)reg0, (v16i8)reg2); 
     696    mult1 = (v16u8)__msa_ilvl_b((v16i8)reg0, (v16i8)reg2); 
     697    mult2 = (v16u8)__msa_ilvr_b((v16i8)reg1, (v16i8)reg3); 
     698    mult3 = (v16u8)__msa_ilvl_b((v16i8)reg1, (v16i8)reg3); 
     699    LOAD_INDEXED_DATA(src, vec2, src0); 
     700    LOAD_INDEXED_DATA(src, vec3, src1); 
     701    vec2 += 1; 
     702    vec3 += 1; 
     703    LOAD_INDEXED_DATA(src, vec2, src2); 
     704    LOAD_INDEXED_DATA(src, vec3, src3); 
     705    reg4 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src0); 
     706    reg5 = (v16u8)__msa_ilvl_b((v16i8)src2, (v16i8)src0); 
     707    reg6 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src1); 
     708    reg7 = (v16u8)__msa_ilvl_b((v16i8)src3, (v16i8)src1); 
     709    tmp0 = __msa_dotp_u_h(reg4, mult0); 
     710    tmp1 = __msa_dotp_u_h(reg5, mult1); 
     711    tmp2 = __msa_dotp_u_h(reg6, mult2); 
     712    tmp3 = __msa_dotp_u_h(reg7, mult3); 
     713    tmp0 >>= 7; 
     714    tmp1 >>= 7; 
     715    tmp2 >>= 7; 
     716    tmp3 >>= 7; 
     717    dst0 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); 
     718    dst1 = (v16u8)__msa_pckev_b((v16i8)tmp3, (v16i8)tmp2); 
     719    __msa_st_b(dst0, dst_argb, 0); 
     720    __msa_st_b(dst1, dst_argb, 16); 
     721    dst_argb += 32; 
     722  } 
     723} 
     724 
     725void ScaleRowDown34_MSA(const uint8* src_ptr, 
     726                        ptrdiff_t src_stride, 
     727                        uint8* dst, 
     728                        int dst_width) { 
     729  int x; 
     730  (void)src_stride; 
     731  v16u8 src0, src1, src2, src3; 
     732  v16u8 vec0, vec1, vec2; 
     733  v16i8 mask0 = {0, 1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20}; 
     734  v16i8 mask1 = {5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20, 21, 23, 24, 25}; 
     735  v16i8 mask2 = {11, 12, 13, 15, 16, 17, 19, 20, 
     736                 21, 23, 24, 25, 27, 28, 29, 31}; 
     737 
     738  assert((dst_width % 3 == 0) && (dst_width > 0)); 
     739 
     740  for (x = 0; x < dst_width; x += 48) { 
     741    src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0); 
     742    src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16); 
     743    src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32); 
     744    src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48); 
     745    vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src1, (v16i8)src0); 
     746    vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src2, (v16i8)src1); 
     747    vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src2); 
     748    __msa_st_b((v16i8)vec0, dst, 0); 
     749    __msa_st_b((v16i8)vec1, dst, 16); 
     750    __msa_st_b((v16i8)vec2, dst, 32); 
     751    src_ptr += 64; 
     752    dst += 48; 
     753  } 
     754} 
     755 
     756void ScaleRowDown34_0_Box_MSA(const uint8* src_ptr, 
     757                              ptrdiff_t src_stride, 
     758                              uint8* d, 
     759                              int dst_width) { 
     760  const uint8* s = src_ptr; 
     761  const uint8* t = src_ptr + src_stride; 
     762  int x; 
     763  v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1, dst2; 
     764  v16u8 vec0, vec1, vec2, vec3, vec4, vec5; 
     765  v16u8 vec6, vec7, vec8, vec9, vec10, vec11; 
     766  v8i16 reg0, reg1, reg2, reg3, reg4, reg5; 
     767  v8i16 reg6, reg7, reg8, reg9, reg10, reg11; 
     768  v16u8 const0 = {3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1}; 
     769  v16u8 const1 = {1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1}; 
     770  v16u8 const2 = {1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3}; 
     771  v16i8 mask0 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; 
     772  v16i8 mask1 = {10, 11, 12, 13, 13, 14, 14, 15, 
     773                 16, 17, 17, 18, 18, 19, 20, 21}; 
     774  v16i8 mask2 = {5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15}; 
     775  v8i16 shft0 = {2, 1, 2, 2, 1, 2, 2, 1}; 
     776  v8i16 shft1 = {2, 2, 1, 2, 2, 1, 2, 2}; 
     777  v8i16 shft2 = {1, 2, 2, 1, 2, 2, 1, 2}; 
     778 
     779  assert((dst_width % 3 == 0) && (dst_width > 0)); 
     780 
     781  for (x = 0; x < dst_width; x += 48) { 
     782    src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); 
     783    src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); 
     784    src2 = (v16u8)__msa_ld_b((v16i8*)s, 32); 
     785    src3 = (v16u8)__msa_ld_b((v16i8*)s, 48); 
     786    src4 = (v16u8)__msa_ld_b((v16i8*)t, 0); 
     787    src5 = (v16u8)__msa_ld_b((v16i8*)t, 16); 
     788    src6 = (v16u8)__msa_ld_b((v16i8*)t, 32); 
     789    src7 = (v16u8)__msa_ld_b((v16i8*)t, 48); 
     790    vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src0, (v16i8)src0); 
     791    vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); 
     792    vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src1, (v16i8)src1); 
     793    vec3 = (v16u8)__msa_vshf_b(mask0, (v16i8)src2, (v16i8)src2); 
     794    vec4 = (v16u8)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2); 
     795    vec5 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src3); 
     796    vec6 = (v16u8)__msa_vshf_b(mask0, (v16i8)src4, (v16i8)src4); 
     797    vec7 = (v16u8)__msa_vshf_b(mask1, (v16i8)src5, (v16i8)src4); 
     798    vec8 = (v16u8)__msa_vshf_b(mask2, (v16i8)src5, (v16i8)src5); 
     799    vec9 = (v16u8)__msa_vshf_b(mask0, (v16i8)src6, (v16i8)src6); 
     800    vec10 = (v16u8)__msa_vshf_b(mask1, (v16i8)src7, (v16i8)src6); 
     801    vec11 = (v16u8)__msa_vshf_b(mask2, (v16i8)src7, (v16i8)src7); 
     802    reg0 = (v8i16)__msa_dotp_u_h(vec0, const0); 
     803    reg1 = (v8i16)__msa_dotp_u_h(vec1, const1); 
     804    reg2 = (v8i16)__msa_dotp_u_h(vec2, const2); 
     805    reg3 = (v8i16)__msa_dotp_u_h(vec3, const0); 
     806    reg4 = (v8i16)__msa_dotp_u_h(vec4, const1); 
     807    reg5 = (v8i16)__msa_dotp_u_h(vec5, const2); 
     808    reg6 = (v8i16)__msa_dotp_u_h(vec6, const0); 
     809    reg7 = (v8i16)__msa_dotp_u_h(vec7, const1); 
     810    reg8 = (v8i16)__msa_dotp_u_h(vec8, const2); 
     811    reg9 = (v8i16)__msa_dotp_u_h(vec9, const0); 
     812    reg10 = (v8i16)__msa_dotp_u_h(vec10, const1); 
     813    reg11 = (v8i16)__msa_dotp_u_h(vec11, const2); 
     814    reg0 = __msa_srar_h(reg0, shft0); 
     815    reg1 = __msa_srar_h(reg1, shft1); 
     816    reg2 = __msa_srar_h(reg2, shft2); 
     817    reg3 = __msa_srar_h(reg3, shft0); 
     818    reg4 = __msa_srar_h(reg4, shft1); 
     819    reg5 = __msa_srar_h(reg5, shft2); 
     820    reg6 = __msa_srar_h(reg6, shft0); 
     821    reg7 = __msa_srar_h(reg7, shft1); 
     822    reg8 = __msa_srar_h(reg8, shft2); 
     823    reg9 = __msa_srar_h(reg9, shft0); 
     824    reg10 = __msa_srar_h(reg10, shft1); 
     825    reg11 = __msa_srar_h(reg11, shft2); 
     826    reg0 = reg0 * 3 + reg6; 
     827    reg1 = reg1 * 3 + reg7; 
     828    reg2 = reg2 * 3 + reg8; 
     829    reg3 = reg3 * 3 + reg9; 
     830    reg4 = reg4 * 3 + reg10; 
     831    reg5 = reg5 * 3 + reg11; 
     832    reg0 = __msa_srari_h(reg0, 2); 
     833    reg1 = __msa_srari_h(reg1, 2); 
     834    reg2 = __msa_srari_h(reg2, 2); 
     835    reg3 = __msa_srari_h(reg3, 2); 
     836    reg4 = __msa_srari_h(reg4, 2); 
     837    reg5 = __msa_srari_h(reg5, 2); 
     838    dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); 
     839    dst1 = (v16u8)__msa_pckev_b((v16i8)reg3, (v16i8)reg2); 
     840    dst2 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4); 
     841    __msa_st_b((v16i8)dst0, d, 0); 
     842    __msa_st_b((v16i8)dst1, d, 16); 
     843    __msa_st_b((v16i8)dst2, d, 32); 
     844    s += 64; 
     845    t += 64; 
     846    d += 48; 
     847  } 
     848} 
     849 
     850void ScaleRowDown34_1_Box_MSA(const uint8* src_ptr, 
     851                              ptrdiff_t src_stride, 
     852                              uint8* d, 
     853                              int dst_width) { 
     854  const uint8* s = src_ptr; 
     855  const uint8* t = src_ptr + src_stride; 
     856  int x; 
     857  v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1, dst2; 
     858  v16u8 vec0, vec1, vec2, vec3, vec4, vec5; 
     859  v16u8 vec6, vec7, vec8, vec9, vec10, vec11; 
     860  v8i16 reg0, reg1, reg2, reg3, reg4, reg5; 
     861  v8i16 reg6, reg7, reg8, reg9, reg10, reg11; 
     862  v16u8 const0 = {3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1}; 
     863  v16u8 const1 = {1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1}; 
     864  v16u8 const2 = {1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3}; 
     865  v16i8 mask0 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; 
     866  v16i8 mask1 = {10, 11, 12, 13, 13, 14, 14, 15, 
     867                 16, 17, 17, 18, 18, 19, 20, 21}; 
     868  v16i8 mask2 = {5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15}; 
     869  v8i16 shft0 = {2, 1, 2, 2, 1, 2, 2, 1}; 
     870  v8i16 shft1 = {2, 2, 1, 2, 2, 1, 2, 2}; 
     871  v8i16 shft2 = {1, 2, 2, 1, 2, 2, 1, 2}; 
     872 
     873  assert((dst_width % 3 == 0) && (dst_width > 0)); 
     874 
     875  for (x = 0; x < dst_width; x += 48) { 
     876    src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); 
     877    src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); 
     878    src2 = (v16u8)__msa_ld_b((v16i8*)s, 32); 
     879    src3 = (v16u8)__msa_ld_b((v16i8*)s, 48); 
     880    src4 = (v16u8)__msa_ld_b((v16i8*)t, 0); 
     881    src5 = (v16u8)__msa_ld_b((v16i8*)t, 16); 
     882    src6 = (v16u8)__msa_ld_b((v16i8*)t, 32); 
     883    src7 = (v16u8)__msa_ld_b((v16i8*)t, 48); 
     884    vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src0, (v16i8)src0); 
     885    vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); 
     886    vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src1, (v16i8)src1); 
     887    vec3 = (v16u8)__msa_vshf_b(mask0, (v16i8)src2, (v16i8)src2); 
     888    vec4 = (v16u8)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2); 
     889    vec5 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src3); 
     890    vec6 = (v16u8)__msa_vshf_b(mask0, (v16i8)src4, (v16i8)src4); 
     891    vec7 = (v16u8)__msa_vshf_b(mask1, (v16i8)src5, (v16i8)src4); 
     892    vec8 = (v16u8)__msa_vshf_b(mask2, (v16i8)src5, (v16i8)src5); 
     893    vec9 = (v16u8)__msa_vshf_b(mask0, (v16i8)src6, (v16i8)src6); 
     894    vec10 = (v16u8)__msa_vshf_b(mask1, (v16i8)src7, (v16i8)src6); 
     895    vec11 = (v16u8)__msa_vshf_b(mask2, (v16i8)src7, (v16i8)src7); 
     896    reg0 = (v8i16)__msa_dotp_u_h(vec0, const0); 
     897    reg1 = (v8i16)__msa_dotp_u_h(vec1, const1); 
     898    reg2 = (v8i16)__msa_dotp_u_h(vec2, const2); 
     899    reg3 = (v8i16)__msa_dotp_u_h(vec3, const0); 
     900    reg4 = (v8i16)__msa_dotp_u_h(vec4, const1); 
     901    reg5 = (v8i16)__msa_dotp_u_h(vec5, const2); 
     902    reg6 = (v8i16)__msa_dotp_u_h(vec6, const0); 
     903    reg7 = (v8i16)__msa_dotp_u_h(vec7, const1); 
     904    reg8 = (v8i16)__msa_dotp_u_h(vec8, const2); 
     905    reg9 = (v8i16)__msa_dotp_u_h(vec9, const0); 
     906    reg10 = (v8i16)__msa_dotp_u_h(vec10, const1); 
     907    reg11 = (v8i16)__msa_dotp_u_h(vec11, const2); 
     908    reg0 = __msa_srar_h(reg0, shft0); 
     909    reg1 = __msa_srar_h(reg1, shft1); 
     910    reg2 = __msa_srar_h(reg2, shft2); 
     911    reg3 = __msa_srar_h(reg3, shft0); 
     912    reg4 = __msa_srar_h(reg4, shft1); 
     913    reg5 = __msa_srar_h(reg5, shft2); 
     914    reg6 = __msa_srar_h(reg6, shft0); 
     915    reg7 = __msa_srar_h(reg7, shft1); 
     916    reg8 = __msa_srar_h(reg8, shft2); 
     917    reg9 = __msa_srar_h(reg9, shft0); 
     918    reg10 = __msa_srar_h(reg10, shft1); 
     919    reg11 = __msa_srar_h(reg11, shft2); 
     920    reg0 += reg6; 
     921    reg1 += reg7; 
     922    reg2 += reg8; 
     923    reg3 += reg9; 
     924    reg4 += reg10; 
     925    reg5 += reg11; 
     926    reg0 = __msa_srari_h(reg0, 1); 
     927    reg1 = __msa_srari_h(reg1, 1); 
     928    reg2 = __msa_srari_h(reg2, 1); 
     929    reg3 = __msa_srari_h(reg3, 1); 
     930    reg4 = __msa_srari_h(reg4, 1); 
     931    reg5 = __msa_srari_h(reg5, 1); 
     932    dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); 
     933    dst1 = (v16u8)__msa_pckev_b((v16i8)reg3, (v16i8)reg2); 
     934    dst2 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4); 
     935    __msa_st_b((v16i8)dst0, d, 0); 
     936    __msa_st_b((v16i8)dst1, d, 16); 
     937    __msa_st_b((v16i8)dst2, d, 32); 
     938    s += 64; 
     939    t += 64; 
     940    d += 48; 
     941  } 
     942} 
     943 
    548944#ifdef __cplusplus 
    549945}  // extern "C" 
  • pjproject/trunk/third_party/yuv/source/scale_neon.cc

    r5633 r5699  
    3030  (void)src_stride; 
    3131  asm volatile( 
    32       "1:                                          \n" 
     32      "1:                                        \n" 
    3333      // load even pixels into q0, odd into q1 
    3434      "vld2.8     {q0, q1}, [%0]!                \n" 
     
    5151  (void)src_stride; 
    5252  asm volatile( 
    53       "1:                                          \n" 
    54       "vld1.8     {q0, q1}, [%0]!                \n"  // load pixels and post 
    55                                                       // inc 
     53      "1:                                        \n" 
     54      "vld2.8     {q0, q1}, [%0]!                \n"  // load 32 pixels 
    5655      "subs       %2, %2, #16                    \n"  // 16 processed per loop 
    57       "vpaddl.u8  q0, q0                         \n"  // add adjacent 
    58       "vpaddl.u8  q1, q1                         \n" 
    59       "vrshrn.u16 d0, q0, #1                     \n"  // downshift, round and 
    60                                                       // pack 
    61       "vrshrn.u16 d1, q1, #1                     \n" 
     56      "vrhadd.u8  q0, q0, q1                     \n"  // rounding half add 
    6257      "vst1.8     {q0}, [%1]!                    \n" 
    6358      "bgt        1b                             \n" 
     
    7873      // change the stride to row 2 pointer 
    7974      "add        %1, %0                         \n" 
    80       "1:                                          \n" 
     75      "1:                                        \n" 
    8176      "vld1.8     {q0, q1}, [%0]!                \n"  // load row 1 and post inc 
    8277      "vld1.8     {q2, q3}, [%1]!                \n"  // load row 2 and post inc 
     
    107102  (void)src_stride; 
    108103  asm volatile( 
    109       "1:                                          \n" 
     104      "1:                                        \n" 
    110105      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // src line 0 
    111106      "subs       %2, %2, #8                     \n"  // 8 processed per loop 
     
    127122  const uint8* src_ptr3 = src_ptr + src_stride * 3; 
    128123  asm volatile( 
    129       "1:                                          \n" 
     124      "1:                                        \n" 
    130125      "vld1.8     {q0}, [%0]!                    \n"  // load up 16x4 
    131126      "vld1.8     {q1}, [%3]!                    \n" 
     
    161156  (void)src_stride; 
    162157  asm volatile( 
    163       "1:                                          \n" 
    164       "vld4.8     {d0, d1, d2, d3}, [%0]!      \n"  // src line 0 
    165       "subs       %2, %2, #24                  \n" 
    166       "vmov       d2, d3                       \n"  // order d0, d1, d2 
    167       "vst3.8     {d0, d1, d2}, [%1]!          \n" 
    168       "bgt        1b                           \n" 
     158      "1:                                        \n" 
     159      "vld4.8     {d0, d1, d2, d3}, [%0]!        \n"  // src line 0 
     160      "subs       %2, %2, #24                    \n" 
     161      "vmov       d2, d3                         \n"  // order d0, d1, d2 
     162      "vst3.8     {d0, d1, d2}, [%1]!            \n" 
     163      "bgt        1b                             \n" 
    169164      : "+r"(src_ptr),   // %0 
    170165        "+r"(dst_ptr),   // %1 
     
    181176      "vmov.u8    d24, #3                        \n" 
    182177      "add        %3, %0                         \n" 
    183       "1:                                          \n" 
     178      "1:                                        \n" 
    184179      "vld4.8       {d0, d1, d2, d3}, [%0]!      \n"  // src line 0 
    185180      "vld4.8       {d4, d5, d6, d7}, [%3]!      \n"  // src line 1 
     
    238233      "vmov.u8    d24, #3                        \n" 
    239234      "add        %3, %0                         \n" 
    240       "1:                                          \n" 
     235      "1:                                        \n" 
    241236      "vld4.8       {d0, d1, d2, d3}, [%0]!      \n"  // src line 0 
    242237      "vld4.8       {d4, d5, d6, d7}, [%3]!      \n"  // src line 1 
     
    286281  asm volatile( 
    287282      "vld1.8     {q3}, [%3]                     \n" 
    288       "1:                                          \n" 
     283      "1:                                        \n" 
    289284      "vld1.8     {d0, d1, d2, d3}, [%0]!        \n" 
    290285      "subs       %2, %2, #12                    \n" 
     
    313308      "vld1.8     {q15}, [%7]                    \n" 
    314309      "add        %3, %0                         \n" 
    315       "1:                                          \n" 
     310      "1:                                        \n" 
    316311 
    317312      // d0 = 00 40 01 41 02 42 03 43 
     
    422417      "vld1.8     {q14}, [%5]                    \n" 
    423418      "add        %3, %0                         \n" 
    424       "1:                                          \n" 
     419      "1:                                        \n" 
    425420 
    426421      // d0 = 00 40 01 41 02 42 03 43 
     
    514509  const uint8* src_tmp; 
    515510  asm volatile( 
    516       "1:                                          \n" 
     511      "1:                                        \n" 
    517512      "mov       %0, %1                          \n" 
    518513      "mov       r12, %5                         \n" 
    519514      "veor      q2, q2, q2                      \n" 
    520515      "veor      q3, q3, q3                      \n" 
    521       "2:                                          \n" 
     516      "2:                                        \n" 
    522517      // load 16 pixels into q0 
    523518      "vld1.8     {q0}, [%0], %3                 \n" 
     
    541536} 
    542537 
    543 // clang-format off 
    544538// TODO(Yang Zhang): Investigate less load instructions for 
    545539// the x/dx stepping 
    546 #define LOAD2_DATA8_LANE(n)                                    \ 
    547     "lsr        %5, %3, #16                    \n"             \ 
    548     "add        %6, %1, %5                     \n"             \ 
    549     "add        %3, %3, %4                     \n"             \ 
    550     "vld2.8     {d6["#n"], d7["#n"]}, [%6]     \n" 
    551 // clang-format on 
     540#define LOAD2_DATA8_LANE(n)                      \ 
     541  "lsr        %5, %3, #16                    \n" \ 
     542  "add        %6, %1, %5                     \n" \ 
     543  "add        %3, %3, %4                     \n" \ 
     544  "vld2.8     {d6[" #n "], d7[" #n "]}, [%6] \n" 
    552545 
    553546// The NEON version mimics this formula (from row_common.cc): 
     
    640633      "vdup.8       d4, %4                       \n" 
    641634      // General purpose row blend. 
    642       "1:                                          \n" 
     635      "1:                                        \n" 
    643636      "vld1.8       {q0}, [%1]!                  \n" 
    644637      "vld1.8       {q1}, [%2]!                  \n" 
     
    655648 
    656649      // Blend 25 / 75. 
    657       "25:                                         \n" 
     650      "25:                                       \n" 
    658651      "vld1.8       {q0}, [%1]!                  \n" 
    659652      "vld1.8       {q1}, [%2]!                  \n" 
     
    666659 
    667660      // Blend 50 / 50. 
    668       "50:                                         \n" 
     661      "50:                                       \n" 
    669662      "vld1.8       {q0}, [%1]!                  \n" 
    670663      "vld1.8       {q1}, [%2]!                  \n" 
     
    676669 
    677670      // Blend 75 / 25. 
    678       "75:                                         \n" 
     671      "75:                                       \n" 
    679672      "vld1.8       {q1}, [%1]!                  \n" 
    680673      "vld1.8       {q0}, [%2]!                  \n" 
     
    687680 
    688681      // Blend 100 / 0 - Copy row unchanged. 
    689       "100:                                        \n" 
     682      "100:                                      \n" 
    690683      "vld1.8       {q0}, [%1]!                  \n" 
    691684      "subs         %3, %3, #16                  \n" 
     
    693686      "bgt          100b                         \n" 
    694687 
    695       "99:                                         \n" 
     688      "99:                                       \n" 
    696689      "vst1.8       {d1[7]}, [%0]                \n" 
    697690      : "+r"(dst_ptr),           // %0 
     
    710703  (void)src_stride; 
    711704  asm volatile( 
    712       "1:                                          \n" 
    713       // load even pixels into q0, odd into q1 
    714       "vld2.32    {q0, q1}, [%0]!                \n" 
    715       "vld2.32    {q2, q3}, [%0]!                \n" 
     705      "1:                                        \n" 
     706      "vld4.32    {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ARGB pixels. 
     707      "vld4.32    {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 ARGB 
    716708      "subs       %2, %2, #8                     \n"  // 8 processed per loop 
    717       "vst1.8     {q1}, [%1]!                    \n"  // store odd pixels 
    718       "vst1.8     {q3}, [%1]!                    \n" 
     709      "vmov       q2, q1                         \n"  // load next 8 ARGB 
     710      "vst2.32    {q2, q3}, [%1]!                \n"  // store odd pixels 
    719711      "bgt        1b                             \n" 
    720712      : "+r"(src_ptr),   // %0 
     
    725717      ); 
    726718} 
     719 
     720//  46:  f964 018d   vld4.32  {d16,d18,d20,d22}, [r4]! 
     721//  4a:  3e04        subs  r6, #4 
     722//  4c:  f964 118d   vld4.32  {d17,d19,d21,d23}, [r4]! 
     723//  50:  ef64 21f4   vorr  q9, q10, q10 
     724//  54:  f942 038d   vst2.32  {d16-d19}, [r2]! 
     725//  58:  d1f5        bne.n  46 <ScaleARGBRowDown2_C+0x46> 
    727726 
    728727void ScaleARGBRowDown2Linear_NEON(const uint8* src_argb, 
     
    732731  (void)src_stride; 
    733732  asm volatile( 
    734       "1:                                          \n" 
    735       "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ARGB pixels. 
    736       "vld4.8     {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 ARGB 
    737                                                       // pixels. 
     733      "1:                                        \n" 
     734      "vld4.32    {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ARGB pixels. 
     735      "vld4.32    {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 ARGB 
    738736      "subs       %2, %2, #8                     \n"  // 8 processed per loop 
    739       "vpaddl.u8  q0, q0                         \n"  // B 16 bytes -> 8 shorts. 
    740       "vpaddl.u8  q1, q1                         \n"  // G 16 bytes -> 8 shorts. 
    741       "vpaddl.u8  q2, q2                         \n"  // R 16 bytes -> 8 shorts. 
    742       "vpaddl.u8  q3, q3                         \n"  // A 16 bytes -> 8 shorts. 
    743       "vrshrn.u16 d0, q0, #1                     \n"  // downshift, round and 
    744                                                       // pack 
    745       "vrshrn.u16 d1, q1, #1                     \n" 
    746       "vrshrn.u16 d2, q2, #1                     \n" 
    747       "vrshrn.u16 d3, q3, #1                     \n" 
    748       "vst4.8     {d0, d1, d2, d3}, [%1]!        \n" 
     737      "vrhadd.u8  q0, q0, q1                     \n"  // rounding half add 
     738      "vrhadd.u8  q1, q2, q3                     \n"  // rounding half add 
     739      "vst2.32    {q0, q1}, [%1]!                \n" 
    749740      "bgt       1b                              \n" 
    750741      : "+r"(src_argb),  // %0 
     
    763754      // change the stride to row 2 pointer 
    764755      "add        %1, %1, %0                     \n" 
    765       "1:                                          \n" 
     756      "1:                                        \n" 
    766757      "vld4.8     {d0, d2, d4, d6}, [%0]!        \n"  // load 8 ARGB pixels. 
    767758      "vld4.8     {d1, d3, d5, d7}, [%0]!        \n"  // load next 8 ARGB 
    768                                                       // pixels. 
    769759      "subs       %3, %3, #8                     \n"  // 8 processed per loop. 
    770760      "vpaddl.u8  q0, q0                         \n"  // B 16 bytes -> 8 shorts. 
     
    773763      "vpaddl.u8  q3, q3                         \n"  // A 16 bytes -> 8 shorts. 
    774764      "vld4.8     {d16, d18, d20, d22}, [%1]!    \n"  // load 8 more ARGB 
    775                                                       // pixels. 
    776765      "vld4.8     {d17, d19, d21, d23}, [%1]!    \n"  // load last 8 ARGB 
    777                                                       // pixels. 
    778766      "vpadal.u8  q0, q8                         \n"  // B 16 bytes -> 8 shorts. 
    779767      "vpadal.u8  q1, q9                         \n"  // G 16 bytes -> 8 shorts. 
    780768      "vpadal.u8  q2, q10                        \n"  // R 16 bytes -> 8 shorts. 
    781769      "vpadal.u8  q3, q11                        \n"  // A 16 bytes -> 8 shorts. 
    782       "vrshrn.u16 d0, q0, #2                     \n"  // downshift, round and 
    783                                                       // pack 
     770      "vrshrn.u16 d0, q0, #2                     \n"  // round and pack to bytes 
    784771      "vrshrn.u16 d1, q1, #2                     \n" 
    785772      "vrshrn.u16 d2, q2, #2                     \n" 
     
    805792  asm volatile( 
    806793      "mov        r12, %3, lsl #2                \n" 
    807       "1:                                          \n" 
     794      "1:                                        \n" 
    808795      "vld1.32    {d0[0]}, [%0], r12             \n" 
    809796      "vld1.32    {d0[1]}, [%0], r12             \n" 
     
    830817      "mov        r12, %4, lsl #2                \n" 
    831818      "add        %1, %1, %0                     \n" 
    832       "1:                                          \n" 
    833       "vld1.8     {d0}, [%0], r12                \n"  // Read 4 2x2 blocks -> 
    834                                                       // 2x1 
     819      "1:                                        \n" 
     820      "vld1.8     {d0}, [%0], r12                \n"  // 4 2x2 blocks -> 2x1 
    835821      "vld1.8     {d1}, [%1], r12                \n" 
    836822      "vld1.8     {d2}, [%0], r12                \n" 
     
    861847} 
    862848 
    863 // clang-format off 
    864849// TODO(Yang Zhang): Investigate less load instructions for 
    865850// the x/dx stepping 
    866 #define LOAD1_DATA32_LANE(dn, n)                            \ 
    867   "lsr        %5, %3, #16                    \n"            \ 
    868   "add        %6, %1, %5, lsl #2             \n"            \ 
    869   "add        %3, %3, %4                     \n"            \ 
     851#define LOAD1_DATA32_LANE(dn, n)                 \ 
     852  "lsr        %5, %3, #16                    \n" \ 
     853  "add        %6, %1, %5, lsl #2             \n" \ 
     854  "add        %3, %3, %4                     \n" \ 
    870855  "vld1.32    {" #dn "[" #n "]}, [%6]        \n" 
    871 // clang-format on 
    872856 
    873857void ScaleARGBCols_NEON(uint8* dst_argb, 
     
    879863  const uint8* src_tmp = src_argb; 
    880864  asm volatile( 
    881       "1:                                          \n" LOAD1_DATA32_LANE( 
    882           d0, 0) LOAD1_DATA32_LANE(d0, 1) LOAD1_DATA32_LANE(d1, 0) 
    883           LOAD1_DATA32_LANE(d1, 1) LOAD1_DATA32_LANE(d2, 0) LOAD1_DATA32_LANE( 
    884               d2, 1) LOAD1_DATA32_LANE(d3, 0) LOAD1_DATA32_LANE(d3, 1) 
    885  
    886               "vst1.32     {q0, q1}, [%0]!               \n"  // store pixels 
    887               "subs       %2, %2, #8                     \n"  // 8 processed per 
    888                                                               // loop 
    889               "bgt        1b                             \n" 
     865      "1:                                        \n" 
     866      // clang-format off 
     867      LOAD1_DATA32_LANE(d0, 0) 
     868      LOAD1_DATA32_LANE(d0, 1) 
     869      LOAD1_DATA32_LANE(d1, 0) 
     870      LOAD1_DATA32_LANE(d1, 1) 
     871      LOAD1_DATA32_LANE(d2, 0) 
     872      LOAD1_DATA32_LANE(d2, 1) 
     873      LOAD1_DATA32_LANE(d3, 0) 
     874      LOAD1_DATA32_LANE(d3, 1) 
     875      // clang-format on 
     876      "vst1.32     {q0, q1}, [%0]!               \n"  // store pixels 
     877      "subs       %2, %2, #8                     \n"  // 8 processed per loop 
     878      "bgt        1b                             \n" 
    890879      : "+r"(dst_argb),   // %0 
    891880        "+r"(src_argb),   // %1 
     
    901890#undef LOAD1_DATA32_LANE 
    902891 
    903 // clang-format off 
    904892// TODO(Yang Zhang): Investigate less load instructions for 
    905893// the x/dx stepping 
    906 #define LOAD2_DATA32_LANE(dn1, dn2, n)                             \ 
    907   "lsr        %5, %3, #16                           \n"            \ 
    908   "add        %6, %1, %5, lsl #2                    \n"            \ 
    909   "add        %3, %3, %4                            \n"            \ 
    910   "vld2.32    {" #dn1 "[" #n "], " #dn2 "[" #n "]}, [%6]    \n" 
    911 // clang-format on 
     894#define LOAD2_DATA32_LANE(dn1, dn2, n)                       \ 
     895  "lsr        %5, %3, #16                                \n" \ 
     896  "add        %6, %1, %5, lsl #2                         \n" \ 
     897  "add        %3, %3, %4                                 \n" \ 
     898  "vld2.32    {" #dn1 "[" #n "], " #dn2 "[" #n "]}, [%6] \n" 
    912899 
    913900void ScaleARGBFilterCols_NEON(uint8* dst_argb, 
  • pjproject/trunk/third_party/yuv/source/scale_neon64.cc

    r5633 r5699  
    2727                        int dst_width) { 
    2828  (void)src_stride; 
    29   asm volatile ( 
    30   "1:                                          \n" 
    31     // load even pixels into v0, odd into v1 
    32     "ld2        {v0.16b,v1.16b}, [%0], #32     \n" 
    33     "subs       %w2, %w2, #16                  \n"  // 16 processed per loop 
    34     "st1        {v1.16b}, [%1], #16            \n"  // store odd pixels 
    35     "b.gt       1b                             \n" 
    36   : "+r"(src_ptr),          // %0 
    37     "+r"(dst),              // %1 
    38     "+r"(dst_width)         // %2 
    39   : 
    40   : "v0", "v1"              // Clobber List 
    41   ); 
     29  asm volatile( 
     30      "1:                                        \n" 
     31      // load even pixels into v0, odd into v1 
     32      "ld2        {v0.16b,v1.16b}, [%0], #32     \n" 
     33      "subs       %w2, %w2, #16                  \n"  // 16 processed per loop 
     34      "st1        {v1.16b}, [%1], #16            \n"  // store odd pixels 
     35      "b.gt       1b                             \n" 
     36      : "+r"(src_ptr),   // %0 
     37        "+r"(dst),       // %1 
     38        "+r"(dst_width)  // %2 
     39      : 
     40      : "v0", "v1"  // Clobber List 
     41      ); 
    4242} 
    4343 
     
    4848                              int dst_width) { 
    4949  (void)src_stride; 
    50   asm volatile ( 
    51   "1:                                          \n" 
    52     "ld1        {v0.16b,v1.16b}, [%0], #32     \n"  // load pixels and post inc 
    53     "subs       %w2, %w2, #16                  \n"  // 16 processed per loop 
    54     "uaddlp     v0.8h, v0.16b                  \n"  // add adjacent 
    55     "uaddlp     v1.8h, v1.16b                  \n" 
    56     "rshrn      v0.8b, v0.8h, #1               \n"  // downshift, round and pack 
    57     "rshrn2     v0.16b, v1.8h, #1              \n" 
    58     "st1        {v0.16b}, [%1], #16            \n" 
    59     "b.gt       1b                             \n" 
    60   : "+r"(src_ptr),          // %0 
    61     "+r"(dst),              // %1 
    62     "+r"(dst_width)         // %2 
    63   : 
    64   : "v0", "v1"     // Clobber List 
    65   ); 
     50  asm volatile( 
     51      "1:                                        \n" 
     52      // load even pixels into v0, odd into v1 
     53      "ld2        {v0.16b,v1.16b}, [%0], #32     \n" 
     54      "subs       %w2, %w2, #16                  \n"  // 16 processed per loop 
     55      "urhadd     v0.16b, v0.16b, v1.16b         \n"  // rounding half add 
     56      "st1        {v0.16b}, [%1], #16            \n" 
     57      "b.gt       1b                             \n" 
     58      : "+r"(src_ptr),   // %0 
     59        "+r"(dst),       // %1 
     60        "+r"(dst_width)  // %2 
     61      : 
     62      : "v0", "v1"  // Clobber List 
     63      ); 
    6664} 
    6765 
     
    7169                           uint8* dst, 
    7270                           int dst_width) { 
    73   asm volatile ( 
    74     // change the stride to row 2 pointer 
    75     "add        %1, %1, %0                     \n" 
    76   "1:                                          \n" 
    77     "ld1        {v0.16b, v1.16b}, [%0], #32    \n"  // load row 1 and post inc 
    78     "ld1        {v2.16b, v3.16b}, [%1], #32    \n"  // load row 2 and post inc 
    79     "subs       %w3, %w3, #16                  \n"  // 16 processed per loop 
    80     "uaddlp     v0.8h, v0.16b                  \n"  // row 1 add adjacent 
    81     "uaddlp     v1.8h, v1.16b                  \n" 
    82     "uadalp     v0.8h, v2.16b                  \n"  // row 2 add adjacent + row1 
    83     "uadalp     v1.8h, v3.16b                  \n" 
    84     "rshrn      v0.8b, v0.8h, #2               \n"  // downshift, round and pack 
    85     "rshrn2     v0.16b, v1.8h, #2              \n" 
    86     "st1        {v0.16b}, [%2], #16            \n" 
    87     "b.gt       1b                             \n" 
    88   : "+r"(src_ptr),          // %0 
    89     "+r"(src_stride),       // %1 
    90     "+r"(dst),              // %2 
    91     "+r"(dst_width)         // %3 
    92   : 
    93   : "v0", "v1", "v2", "v3"     // Clobber List 
    94   ); 
     71  asm volatile( 
     72      // change the stride to row 2 pointer 
     73      "add        %1, %1, %0                     \n" 
     74      "1:                                        \n" 
     75      "ld1        {v0.16b, v1.16b}, [%0], #32    \n"  // load row 1 and post inc 
     76      "ld1        {v2.16b, v3.16b}, [%1], #32    \n"  // load row 2 and post inc 
     77      "subs       %w3, %w3, #16                  \n"  // 16 processed per loop 
     78      "uaddlp     v0.8h, v0.16b                  \n"  // row 1 add adjacent 
     79      "uaddlp     v1.8h, v1.16b                  \n" 
     80      "uadalp     v0.8h, v2.16b                  \n"  // += row 2 add adjacent 
     81      "uadalp     v1.8h, v3.16b                  \n" 
     82      "rshrn      v0.8b, v0.8h, #2               \n"  // round and pack 
     83      "rshrn2     v0.16b, v1.8h, #2              \n" 
     84      "st1        {v0.16b}, [%2], #16            \n" 
     85      "b.gt       1b                             \n" 
     86      : "+r"(src_ptr),     // %0 
     87        "+r"(src_stride),  // %1 
     88        "+r"(dst),         // %2 
     89        "+r"(dst_width)    // %3 
     90      : 
     91      : "v0", "v1", "v2", "v3"  // Clobber List 
     92      ); 
    9593} 
    9694 
     
    10098                        int dst_width) { 
    10199  (void)src_stride; 
    102   asm volatile ( 
    103   "1:                                          \n" 
    104     "ld4     {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32          \n"  // src line 0 
    105     "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
    106     "st1     {v2.8b}, [%1], #8                 \n" 
    107     "b.gt       1b                             \n" 
    108   : "+r"(src_ptr),          // %0 
    109     "+r"(dst_ptr),          // %1 
    110     "+r"(dst_width)         // %2 
    111   : 
    112   : "v0", "v1", "v2", "v3", "memory", "cc" 
    113   ); 
     100  asm volatile( 
     101      "1:                                        \n" 
     102      "ld4     {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32  \n"  // src line 0 
     103      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
     104      "st1     {v2.8b}, [%1], #8                 \n" 
     105      "b.gt       1b                             \n" 
     106      : "+r"(src_ptr),   // %0 
     107        "+r"(dst_ptr),   // %1 
     108        "+r"(dst_width)  // %2 
     109      : 
     110      : "v0", "v1", "v2", "v3", "memory", "cc"); 
    114111} 
    115112 
     
    121118  const uint8* src_ptr2 = src_ptr + src_stride * 2; 
    122119  const uint8* src_ptr3 = src_ptr + src_stride * 3; 
    123   asm volatile ( 
    124   "1:                                          \n" 
    125     "ld1     {v0.16b}, [%0], #16               \n"   // load up 16x4 
    126     "ld1     {v1.16b}, [%2], #16               \n" 
    127     "ld1     {v2.16b}, [%3], #16               \n" 
    128     "ld1     {v3.16b}, [%4], #16               \n" 
    129     "subs    %w5, %w5, #4                      \n" 
    130     "uaddlp  v0.8h, v0.16b                     \n" 
    131     "uadalp  v0.8h, v1.16b                     \n" 
    132     "uadalp  v0.8h, v2.16b                     \n" 
    133     "uadalp  v0.8h, v3.16b                     \n" 
    134     "addp    v0.8h, v0.8h, v0.8h               \n" 
    135     "rshrn   v0.8b, v0.8h, #4                  \n"   // divide by 16 w/rounding 
    136     "st1    {v0.s}[0], [%1], #4                \n" 
    137     "b.gt       1b                             \n" 
    138   : "+r"(src_ptr),   // %0 
    139     "+r"(dst_ptr),   // %1 
    140     "+r"(src_ptr1),  // %2 
    141     "+r"(src_ptr2),  // %3 
    142     "+r"(src_ptr3),  // %4 
    143     "+r"(dst_width)  // %5 
    144   : 
    145   : "v0", "v1", "v2", "v3", "memory", "cc" 
    146   ); 
     120  asm volatile( 
     121      "1:                                        \n" 
     122      "ld1     {v0.16b}, [%0], #16               \n"  // load up 16x4 
     123      "ld1     {v1.16b}, [%2], #16               \n" 
     124      "ld1     {v2.16b}, [%3], #16               \n" 
     125      "ld1     {v3.16b}, [%4], #16               \n" 
     126      "subs    %w5, %w5, #4                      \n" 
     127      "uaddlp  v0.8h, v0.16b                     \n" 
     128      "uadalp  v0.8h, v1.16b                     \n" 
     129      "uadalp  v0.8h, v2.16b                     \n" 
     130      "uadalp  v0.8h, v3.16b                     \n" 
     131      "addp    v0.8h, v0.8h, v0.8h               \n" 
     132      "rshrn   v0.8b, v0.8h, #4                  \n"  // divide by 16 w/rounding 
     133      "st1    {v0.s}[0], [%1], #4                \n" 
     134      "b.gt       1b                             \n" 
     135      : "+r"(src_ptr),   // %0 
     136        "+r"(dst_ptr),   // %1 
     137        "+r"(src_ptr1),  // %2 
     138        "+r"(src_ptr2),  // %3 
     139        "+r"(src_ptr3),  // %4 
     140        "+r"(dst_width)  // %5 
     141      : 
     142      : "v0", "v1", "v2", "v3", "memory", "cc"); 
    147143} 
    148144 
     
    155151                         int dst_width) { 
    156152  (void)src_stride; 
    157   asm volatile ( 
    158   "1:                                                  \n" 
    159     "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n"  // src line 0 
    160     "subs      %w2, %w2, #24                           \n" 
    161     "orr       v2.16b, v3.16b, v3.16b                  \n"  // order v0, v1, v2 
    162     "st3       {v0.8b,v1.8b,v2.8b}, [%1], #24          \n" 
    163     "b.gt      1b                                      \n" 
    164   : "+r"(src_ptr),          // %0 
    165     "+r"(dst_ptr),          // %1 
    166     "+r"(dst_width)         // %2 
    167   : 
    168   : "v0", "v1", "v2", "v3", "memory", "cc" 
    169   ); 
     153  asm volatile( 
     154      "1:                                                \n" 
     155      "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n"  // src line 0 
     156      "subs      %w2, %w2, #24                           \n" 
     157      "orr       v2.16b, v3.16b, v3.16b                  \n"  // order v0,v1,v2 
     158      "st3       {v0.8b,v1.8b,v2.8b}, [%1], #24          \n" 
     159      "b.gt      1b                                      \n" 
     160      : "+r"(src_ptr),   // %0 
     161        "+r"(dst_ptr),   // %1 
     162        "+r"(dst_width)  // %2 
     163      : 
     164      : "v0", "v1", "v2", "v3", "memory", "cc"); 
    170165} 
    171166 
     
    174169                               uint8* dst_ptr, 
    175170                               int dst_width) { 
    176   asm volatile ( 
    177     "movi      v20.8b, #3                              \n" 
    178     "add       %3, %3, %0                              \n" 
    179   "1:                                                  \n" 
    180     "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n"  // src line 0 
    181     "ld4       {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32    \n"  // src line 1 
    182     "subs         %w2, %w2, #24                        \n" 
    183  
    184     // filter src line 0 with src line 1 
    185     // expand chars to shorts to allow for room 
    186     // when adding lines together 
    187     "ushll     v16.8h, v4.8b, #0                       \n" 
    188     "ushll     v17.8h, v5.8b, #0                       \n" 
    189     "ushll     v18.8h, v6.8b, #0                       \n" 
    190     "ushll     v19.8h, v7.8b, #0                       \n" 
    191  
    192     // 3 * line_0 + line_1 
    193     "umlal     v16.8h, v0.8b, v20.8b                   \n" 
    194     "umlal     v17.8h, v1.8b, v20.8b                   \n" 
    195     "umlal     v18.8h, v2.8b, v20.8b                   \n" 
    196     "umlal     v19.8h, v3.8b, v20.8b                   \n" 
    197  
    198     // (3 * line_0 + line_1) >> 2 
    199     "uqrshrn   v0.8b, v16.8h, #2                       \n" 
    200     "uqrshrn   v1.8b, v17.8h, #2                       \n" 
    201     "uqrshrn   v2.8b, v18.8h, #2                       \n" 
    202     "uqrshrn   v3.8b, v19.8h, #2                       \n" 
    203  
    204     // a0 = (src[0] * 3 + s[1] * 1) >> 2 
    205     "ushll     v16.8h, v1.8b, #0                       \n" 
    206     "umlal     v16.8h, v0.8b, v20.8b                   \n" 
    207     "uqrshrn   v0.8b, v16.8h, #2                       \n" 
    208  
    209     // a1 = (src[1] * 1 + s[2] * 1) >> 1 
    210     "urhadd    v1.8b, v1.8b, v2.8b                     \n" 
    211  
    212     // a2 = (src[2] * 1 + s[3] * 3) >> 2 
    213     "ushll     v16.8h, v2.8b, #0                       \n" 
    214     "umlal     v16.8h, v3.8b, v20.8b                   \n" 
    215     "uqrshrn   v2.8b, v16.8h, #2                       \n" 
    216  
    217     "st3       {v0.8b,v1.8b,v2.8b}, [%1], #24          \n" 
    218  
    219     "b.gt      1b                                      \n" 
    220   : "+r"(src_ptr),          // %0 
    221     "+r"(dst_ptr),          // %1 
    222     "+r"(dst_width),        // %2 
    223     "+r"(src_stride)        // %3 
    224   : 
    225   : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", "v19", 
    226     "v20", "memory", "cc" 
    227   ); 
     171  asm volatile( 
     172      "movi      v20.8b, #3                              \n" 
     173      "add       %3, %3, %0                              \n" 
     174      "1:                                                \n" 
     175      "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n"  // src line 0 
     176      "ld4       {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32    \n"  // src line 1 
     177      "subs         %w2, %w2, #24                        \n" 
     178 
     179      // filter src line 0 with src line 1 
     180      // expand chars to shorts to allow for room 
     181      // when adding lines together 
     182      "ushll     v16.8h, v4.8b, #0                       \n" 
     183      "ushll     v17.8h, v5.8b, #0                       \n" 
     184      "ushll     v18.8h, v6.8b, #0                       \n" 
     185      "ushll     v19.8h, v7.8b, #0                       \n" 
     186 
     187      // 3 * line_0 + line_1 
     188      "umlal     v16.8h, v0.8b, v20.8b                   \n" 
     189      "umlal     v17.8h, v1.8b, v20.8b                   \n" 
     190      "umlal     v18.8h, v2.8b, v20.8b                   \n" 
     191      "umlal     v19.8h, v3.8b, v20.8b                   \n" 
     192 
     193      // (3 * line_0 + line_1) >> 2 
     194      "uqrshrn   v0.8b, v16.8h, #2                       \n" 
     195      "uqrshrn   v1.8b, v17.8h, #2                       \n" 
     196      "uqrshrn   v2.8b, v18.8h, #2                       \n" 
     197      "uqrshrn   v3.8b, v19.8h, #2                       \n" 
     198 
     199      // a0 = (src[0] * 3 + s[1] * 1) >> 2 
     200      "ushll     v16.8h, v1.8b, #0                       \n" 
     201      "umlal     v16.8h, v0.8b, v20.8b                   \n" 
     202      "uqrshrn   v0.8b, v16.8h, #2                       \n" 
     203 
     204      // a1 = (src[1] * 1 + s[2] * 1) >> 1 
     205      "urhadd    v1.8b, v1.8b, v2.8b                     \n" 
     206 
     207      // a2 = (src[2] * 1 + s[3] * 3) >> 2 
     208      "ushll     v16.8h, v2.8b, #0                       \n" 
     209      "umlal     v16.8h, v3.8b, v20.8b                   \n" 
     210      "uqrshrn   v2.8b, v16.8h, #2                       \n" 
     211 
     212      "st3       {v0.8b,v1.8b,v2.8b}, [%1], #24          \n" 
     213 
     214      "b.gt      1b                                      \n" 
     215      : "+r"(src_ptr),    // %0 
     216        "+r"(dst_ptr),    // %1 
     217        "+r"(dst_width),  // %2 
     218        "+r"(src_stride)  // %3 
     219      : 
     220      : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", 
     221        "v19", "v20", "memory", "cc"); 
    228222} 
    229223 
     
    232226                               uint8* dst_ptr, 
    233227                               int dst_width) { 
    234   asm volatile ( 
    235     "movi      v20.8b, #3                              \n" 
    236     "add       %3, %3, %0                              \n" 
    237   "1:                                                  \n" 
    238     "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n"  // src line 0 
    239     "ld4       {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32    \n"  // src line 1 
    240     "subs         %w2, %w2, #24                        \n" 
    241     // average src line 0 with src line 1 
    242     "urhadd    v0.8b, v0.8b, v4.8b                     \n" 
    243     "urhadd    v1.8b, v1.8b, v5.8b                     \n" 
    244     "urhadd    v2.8b, v2.8b, v6.8b                     \n" 
    245     "urhadd    v3.8b, v3.8b, v7.8b                     \n" 
    246  
    247     // a0 = (src[0] * 3 + s[1] * 1) >> 2 
    248     "ushll     v4.8h, v1.8b, #0                        \n" 
    249     "umlal     v4.8h, v0.8b, v20.8b                    \n" 
    250     "uqrshrn   v0.8b, v4.8h, #2                        \n" 
    251  
    252     // a1 = (src[1] * 1 + s[2] * 1) >> 1 
    253     "urhadd    v1.8b, v1.8b, v2.8b                     \n" 
    254  
    255     // a2 = (src[2] * 1 + s[3] * 3) >> 2 
    256     "ushll     v4.8h, v2.8b, #0                        \n" 
    257     "umlal     v4.8h, v3.8b, v20.8b                    \n" 
    258     "uqrshrn   v2.8b, v4.8h, #2                        \n" 
    259  
    260     "st3       {v0.8b,v1.8b,v2.8b}, [%1], #24          \n" 
    261     "b.gt      1b                                      \n" 
    262   : "+r"(src_ptr),          // %0 
    263     "+r"(dst_ptr),          // %1 
    264     "+r"(dst_width),        // %2 
    265     "+r"(src_stride)        // %3 
    266   : 
    267   : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", "memory", "cc" 
    268   ); 
     228  asm volatile( 
     229      "movi      v20.8b, #3                              \n" 
     230      "add       %3, %3, %0                              \n" 
     231      "1:                                                \n" 
     232      "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n"  // src line 0 
     233      "ld4       {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32    \n"  // src line 1 
     234      "subs         %w2, %w2, #24                        \n" 
     235      // average src line 0 with src line 1 
     236      "urhadd    v0.8b, v0.8b, v4.8b                     \n" 
     237      "urhadd    v1.8b, v1.8b, v5.8b                     \n" 
     238      "urhadd    v2.8b, v2.8b, v6.8b                     \n" 
     239      "urhadd    v3.8b, v3.8b, v7.8b                     \n" 
     240 
     241      // a0 = (src[0] * 3 + s[1] * 1) >> 2 
     242      "ushll     v4.8h, v1.8b, #0                        \n" 
     243      "umlal     v4.8h, v0.8b, v20.8b                    \n" 
     244      "uqrshrn   v0.8b, v4.8h, #2                        \n" 
     245 
     246      // a1 = (src[1] * 1 + s[2] * 1) >> 1 
     247      "urhadd    v1.8b, v1.8b, v2.8b                     \n" 
     248 
     249      // a2 = (src[2] * 1 + s[3] * 3) >> 2 
     250      "ushll     v4.8h, v2.8b, #0                        \n" 
     251      "umlal     v4.8h, v3.8b, v20.8b                    \n" 
     252      "uqrshrn   v2.8b, v4.8h, #2                        \n" 
     253 
     254      "st3       {v0.8b,v1.8b,v2.8b}, [%1], #24          \n" 
     255      "b.gt      1b                                      \n" 
     256      : "+r"(src_ptr),    // %0 
     257        "+r"(dst_ptr),    // %1 
     258        "+r"(dst_width),  // %2 
     259        "+r"(src_stride)  // %3 
     260      : 
     261      : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", "memory", "cc"); 
    269262} 
    270263 
     
    283276                         int dst_width) { 
    284277  (void)src_stride; 
    285   asm volatile ( 
    286     "ld1       {v3.16b}, [%3]                          \n" 
    287   "1:                                                  \n" 
    288     "ld1       {v0.16b,v1.16b}, [%0], #32              \n" 
    289     "subs      %w2, %w2, #12                           \n" 
    290     "tbl       v2.16b, {v0.16b,v1.16b}, v3.16b         \n" 
    291     "st1       {v2.8b}, [%1], #8                       \n" 
    292     "st1       {v2.s}[2], [%1], #4                     \n" 
    293     "b.gt      1b                                      \n" 
    294   : "+r"(src_ptr),          // %0 
    295     "+r"(dst_ptr),          // %1 
    296     "+r"(dst_width)         // %2 
    297   : "r"(&kShuf38)           // %3 
    298   : "v0", "v1", "v2", "v3", "memory", "cc" 
    299   ); 
     278  asm volatile( 
     279      "ld1       {v3.16b}, [%3]                          \n" 
     280      "1:                                                \n" 
     281      "ld1       {v0.16b,v1.16b}, [%0], #32              \n" 
     282      "subs      %w2, %w2, #12                           \n" 
     283      "tbl       v2.16b, {v0.16b,v1.16b}, v3.16b         \n" 
     284      "st1       {v2.8b}, [%1], #8                       \n" 
     285      "st1       {v2.s}[2], [%1], #4                     \n" 
     286      "b.gt      1b                                      \n" 
     287      : "+r"(src_ptr),   // %0 
     288        "+r"(dst_ptr),   // %1 
     289        "+r"(dst_width)  // %2 
     290      : "r"(&kShuf38)    // %3 
     291      : "v0", "v1", "v2", "v3", "memory", "cc"); 
    300292} 
    301293 
     
    308300  ptrdiff_t tmp_src_stride = src_stride; 
    309301 
    310   asm volatile ( 
    311     "ld1       {v29.8h}, [%5]                          \n" 
    312     "ld1       {v30.16b}, [%6]                         \n" 
    313     "ld1       {v31.8h}, [%7]                          \n" 
    314     "add       %2, %2, %0                              \n" 
    315   "1:                                                  \n" 
    316  
    317     // 00 40 01 41 02 42 03 43 
    318     // 10 50 11 51 12 52 13 53 
    319     // 20 60 21 61 22 62 23 63 
    320     // 30 70 31 71 32 72 33 73 
    321     "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32      \n" 
    322     "ld4       {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32      \n" 
    323     "ld4       {v16.8b,v17.8b,v18.8b,v19.8b}, [%3], #32  \n" 
    324     "subs      %w4, %w4, #12                           \n" 
    325  
    326     // Shuffle the input data around to get align the data 
    327     //  so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 
    328     // 00 10 01 11 02 12 03 13 
    329     // 40 50 41 51 42 52 43 53 
    330     "trn1      v20.8b, v0.8b, v1.8b                    \n" 
    331     "trn2      v21.8b, v0.8b, v1.8b                    \n" 
    332     "trn1      v22.8b, v4.8b, v5.8b                    \n" 
    333     "trn2      v23.8b, v4.8b, v5.8b                    \n" 
    334     "trn1      v24.8b, v16.8b, v17.8b                  \n" 
    335     "trn2      v25.8b, v16.8b, v17.8b                  \n" 
    336  
    337     // 20 30 21 31 22 32 23 33 
    338     // 60 70 61 71 62 72 63 73 
    339     "trn1      v0.8b, v2.8b, v3.8b                     \n" 
    340     "trn2      v1.8b, v2.8b, v3.8b                     \n" 
    341     "trn1      v4.8b, v6.8b, v7.8b                     \n" 
    342     "trn2      v5.8b, v6.8b, v7.8b                     \n" 
    343     "trn1      v16.8b, v18.8b, v19.8b                  \n" 
    344     "trn2      v17.8b, v18.8b, v19.8b                  \n" 
    345  
    346     // 00+10 01+11 02+12 03+13 
    347     // 40+50 41+51 42+52 43+53 
    348     "uaddlp    v20.4h, v20.8b                          \n" 
    349     "uaddlp    v21.4h, v21.8b                          \n" 
    350     "uaddlp    v22.4h, v22.8b                          \n" 
    351     "uaddlp    v23.4h, v23.8b                          \n" 
    352     "uaddlp    v24.4h, v24.8b                          \n" 
    353     "uaddlp    v25.4h, v25.8b                          \n" 
    354  
    355     // 60+70 61+71 62+72 63+73 
    356     "uaddlp    v1.4h, v1.8b                            \n" 
    357     "uaddlp    v5.4h, v5.8b                            \n" 
    358     "uaddlp    v17.4h, v17.8b                          \n" 
    359  
    360     // combine source lines 
    361     "add       v20.4h, v20.4h, v22.4h                  \n" 
    362     "add       v21.4h, v21.4h, v23.4h                  \n" 
    363     "add       v20.4h, v20.4h, v24.4h                  \n" 
    364     "add       v21.4h, v21.4h, v25.4h                  \n" 
    365     "add       v2.4h, v1.4h, v5.4h                     \n" 
    366     "add       v2.4h, v2.4h, v17.4h                    \n" 
    367  
    368     // dst_ptr[3] = (s[6 + st * 0] + s[7 + st * 0] 
    369     //             + s[6 + st * 1] + s[7 + st * 1] 
    370     //             + s[6 + st * 2] + s[7 + st * 2]) / 6 
    371     "sqrdmulh  v2.8h, v2.8h, v29.8h                    \n" 
    372     "xtn       v2.8b,  v2.8h                           \n" 
    373  
    374     // Shuffle 2,3 reg around so that 2 can be added to the 
    375     //  0,1 reg and 3 can be added to the 4,5 reg. This 
    376     //  requires expanding from u8 to u16 as the 0,1 and 4,5 
    377     //  registers are already expanded. Then do transposes 
    378     //  to get aligned. 
    379     // xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 
    380     "ushll     v16.8h, v16.8b, #0                      \n" 
    381     "uaddl     v0.8h, v0.8b, v4.8b                     \n" 
    382  
    383     // combine source lines 
    384     "add       v0.8h, v0.8h, v16.8h                    \n" 
    385  
    386     // xx 20 xx 21 xx 22 xx 23 
    387     // xx 30 xx 31 xx 32 xx 33 
    388     "trn1      v1.8h, v0.8h, v0.8h                     \n" 
    389     "trn2      v4.8h, v0.8h, v0.8h                     \n" 
    390     "xtn       v0.4h, v1.4s                            \n" 
    391     "xtn       v4.4h, v4.4s                            \n" 
    392  
    393     // 0+1+2, 3+4+5 
    394     "add       v20.8h, v20.8h, v0.8h                   \n" 
    395     "add       v21.8h, v21.8h, v4.8h                   \n" 
    396  
    397     // Need to divide, but can't downshift as the the value 
    398     //  isn't a power of 2. So multiply by 65536 / n 
    399     //  and take the upper 16 bits. 
    400     "sqrdmulh  v0.8h, v20.8h, v31.8h                   \n" 
    401     "sqrdmulh  v1.8h, v21.8h, v31.8h                   \n" 
    402  
    403     // Align for table lookup, vtbl requires registers to 
    404     //  be adjacent 
    405     "tbl       v3.16b, {v0.16b, v1.16b, v2.16b}, v30.16b \n" 
    406  
    407     "st1       {v3.8b}, [%1], #8                       \n" 
    408     "st1       {v3.s}[2], [%1], #4                     \n" 
    409     "b.gt      1b                                      \n" 
    410   : "+r"(src_ptr),          // %0 
    411     "+r"(dst_ptr),          // %1 
    412     "+r"(tmp_src_stride),   // %2 
    413     "+r"(src_ptr1),         // %3 
    414     "+r"(dst_width)         // %4 
    415   : "r"(&kMult38_Div6),     // %5 
    416     "r"(&kShuf38_2),        // %6 
    417     "r"(&kMult38_Div9)      // %7 
    418   : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", 
    419     "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v29", 
    420     "v30", "v31", "memory", "cc" 
    421   ); 
     302  asm volatile( 
     303      "ld1       {v29.8h}, [%5]                          \n" 
     304      "ld1       {v30.16b}, [%6]                         \n" 
     305      "ld1       {v31.8h}, [%7]                          \n" 
     306      "add       %2, %2, %0                              \n" 
     307      "1:                                                \n" 
     308 
     309      // 00 40 01 41 02 42 03 43 
     310      // 10 50 11 51 12 52 13 53 
     311      // 20 60 21 61 22 62 23 63 
     312      // 30 70 31 71 32 72 33 73 
     313      "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n" 
     314      "ld4       {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32    \n" 
     315      "ld4       {v16.8b,v17.8b,v18.8b,v19.8b}, [%3], #32  \n" 
     316      "subs      %w4, %w4, #12                           \n" 
     317 
     318      // Shuffle the input data around to get align the data 
     319      //  so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 
     320      // 00 10 01 11 02 12 03 13 
     321      // 40 50 41 51 42 52 43 53 
     322      "trn1      v20.8b, v0.8b, v1.8b                    \n" 
     323      "trn2      v21.8b, v0.8b, v1.8b                    \n" 
     324      "trn1      v22.8b, v4.8b, v5.8b                    \n" 
     325      "trn2      v23.8b, v4.8b, v5.8b                    \n" 
     326      "trn1      v24.8b, v16.8b, v17.8b                  \n" 
     327      "trn2      v25.8b, v16.8b, v17.8b                  \n" 
     328 
     329      // 20 30 21 31 22 32 23 33 
     330      // 60 70 61 71 62 72 63 73 
     331      "trn1      v0.8b, v2.8b, v3.8b                     \n" 
     332      "trn2      v1.8b, v2.8b, v3.8b                     \n" 
     333      "trn1      v4.8b, v6.8b, v7.8b                     \n" 
     334      "trn2      v5.8b, v6.8b, v7.8b                     \n" 
     335      "trn1      v16.8b, v18.8b, v19.8b                  \n" 
     336      "trn2      v17.8b, v18.8b, v19.8b                  \n" 
     337 
     338      // 00+10 01+11 02+12 03+13 
     339      // 40+50 41+51 42+52 43+53 
     340      "uaddlp    v20.4h, v20.8b                          \n" 
     341      "uaddlp    v21.4h, v21.8b                          \n" 
     342      "uaddlp    v22.4h, v22.8b                          \n" 
     343      "uaddlp    v23.4h, v23.8b                          \n" 
     344      "uaddlp    v24.4h, v24.8b                          \n" 
     345      "uaddlp    v25.4h, v25.8b                          \n" 
     346 
     347      // 60+70 61+71 62+72 63+73 
     348      "uaddlp    v1.4h, v1.8b                            \n" 
     349      "uaddlp    v5.4h, v5.8b                            \n" 
     350      "uaddlp    v17.4h, v17.8b                          \n" 
     351 
     352      // combine source lines 
     353      "add       v20.4h, v20.4h, v22.4h                  \n" 
     354      "add       v21.4h, v21.4h, v23.4h                  \n" 
     355      "add       v20.4h, v20.4h, v24.4h                  \n" 
     356      "add       v21.4h, v21.4h, v25.4h                  \n" 
     357      "add       v2.4h, v1.4h, v5.4h                     \n" 
     358      "add       v2.4h, v2.4h, v17.4h                    \n" 
     359 
     360      // dst_ptr[3] = (s[6 + st * 0] + s[7 + st * 0] 
     361      //             + s[6 + st * 1] + s[7 + st * 1] 
     362      //             + s[6 + st * 2] + s[7 + st * 2]) / 6 
     363      "sqrdmulh  v2.8h, v2.8h, v29.8h                    \n" 
     364      "xtn       v2.8b,  v2.8h                           \n" 
     365 
     366      // Shuffle 2,3 reg around so that 2 can be added to the 
     367      //  0,1 reg and 3 can be added to the 4,5 reg. This 
     368      //  requires expanding from u8 to u16 as the 0,1 and 4,5 
     369      //  registers are already expanded. Then do transposes 
     370      //  to get aligned. 
     371      // xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 
     372      "ushll     v16.8h, v16.8b, #0                      \n" 
     373      "uaddl     v0.8h, v0.8b, v4.8b                     \n" 
     374 
     375      // combine source lines 
     376      "add       v0.8h, v0.8h, v16.8h                    \n" 
     377 
     378      // xx 20 xx 21 xx 22 xx 23 
     379      // xx 30 xx 31 xx 32 xx 33 
     380      "trn1      v1.8h, v0.8h, v0.8h                     \n" 
     381      "trn2      v4.8h, v0.8h, v0.8h                     \n" 
     382      "xtn       v0.4h, v1.4s                            \n" 
     383      "xtn       v4.4h, v4.4s                            \n" 
     384 
     385      // 0+1+2, 3+4+5 
     386      "add       v20.8h, v20.8h, v0.8h                   \n" 
     387      "add       v21.8h, v21.8h, v4.8h                   \n" 
     388 
     389      // Need to divide, but can't downshift as the the value 
     390      //  isn't a power of 2. So multiply by 65536 / n 
     391      //  and take the upper 16 bits. 
     392      "sqrdmulh  v0.8h, v20.8h, v31.8h                   \n" 
     393      "sqrdmulh  v1.8h, v21.8h, v31.8h                   \n" 
     394 
     395      // Align for table lookup, vtbl requires registers to be adjacent 
     396      "tbl       v3.16b, {v0.16b, v1.16b, v2.16b}, v30.16b \n" 
     397 
     398      "st1       {v3.8b}, [%1], #8                       \n" 
     399      "st1       {v3.s}[2], [%1], #4                     \n" 
     400      "b.gt      1b                                      \n" 
     401      : "+r"(src_ptr),         // %0 
     402        "+r"(dst_ptr),         // %1 
     403        "+r"(tmp_src_stride),  // %2 
     404        "+r"(src_ptr1),        // %3 
     405        "+r"(dst_width)        // %4 
     406      : "r"(&kMult38_Div6),    // %5 
     407        "r"(&kShuf38_2),       // %6 
     408        "r"(&kMult38_Div9)     // %7 
     409      : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", 
     410        "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v29", "v30", "v31", 
     411        "memory", "cc"); 
    422412} 
    423413 
     
    429419  // TODO(fbarchard): use src_stride directly for clang 3.5+. 
    430420  ptrdiff_t tmp_src_stride = src_stride; 
    431   asm volatile ( 
    432     "ld1       {v30.8h}, [%4]                          \n" 
    433     "ld1       {v31.16b}, [%5]                         \n" 
    434     "add       %2, %2, %0                              \n" 
    435   "1:                                                  \n" 
    436  
    437     // 00 40 01 41 02 42 03 43 
    438     // 10 50 11 51 12 52 13 53 
    439     // 20 60 21 61 22 62 23 63 
    440     // 30 70 31 71 32 72 33 73 
    441     "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n" 
    442     "ld4       {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32    \n" 
    443     "subs      %w3, %w3, #12                           \n" 
    444  
    445     // Shuffle the input data around to get align the data 
    446     //  so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 
    447     // 00 10 01 11 02 12 03 13 
    448     // 40 50 41 51 42 52 43 53 
    449     "trn1      v16.8b, v0.8b, v1.8b                    \n" 
    450     "trn2      v17.8b, v0.8b, v1.8b                    \n" 
    451     "trn1      v18.8b, v4.8b, v5.8b                    \n" 
    452     "trn2      v19.8b, v4.8b, v5.8b                    \n" 
    453  
    454     // 20 30 21 31 22 32 23 33 
    455     // 60 70 61 71 62 72 63 73 
    456     "trn1      v0.8b, v2.8b, v3.8b                     \n" 
    457     "trn2      v1.8b, v2.8b, v3.8b                     \n" 
    458     "trn1      v4.8b, v6.8b, v7.8b                     \n" 
    459     "trn2      v5.8b, v6.8b, v7.8b                     \n" 
    460  
    461     // 00+10 01+11 02+12 03+13 
    462     // 40+50 41+51 42+52 43+53 
    463     "uaddlp    v16.4h, v16.8b                          \n" 
    464     "uaddlp    v17.4h, v17.8b                          \n" 
    465     "uaddlp    v18.4h, v18.8b                          \n" 
    466     "uaddlp    v19.4h, v19.8b                          \n" 
    467  
    468     // 60+70 61+71 62+72 63+73 
    469     "uaddlp    v1.4h, v1.8b                            \n" 
    470     "uaddlp    v5.4h, v5.8b                            \n" 
    471  
    472     // combine source lines 
    473     "add       v16.4h, v16.4h, v18.4h                  \n" 
    474     "add       v17.4h, v17.4h, v19.4h                  \n" 
    475     "add       v2.4h, v1.4h, v5.4h                     \n" 
    476  
    477     // dst_ptr[3] = (s[6] + s[7] + s[6+st] + s[7+st]) / 4 
    478     "uqrshrn   v2.8b, v2.8h, #2                        \n" 
    479  
    480     // Shuffle 2,3 reg around so that 2 can be added to the 
    481     //  0,1 reg and 3 can be added to the 4,5 reg. This 
    482     //  requires expanding from u8 to u16 as the 0,1 and 4,5 
    483     //  registers are already expanded. Then do transposes 
    484     //  to get aligned. 
    485     // xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 
    486  
    487     // combine source lines 
    488     "uaddl     v0.8h, v0.8b, v4.8b                     \n" 
    489  
    490     // xx 20 xx 21 xx 22 xx 23 
    491     // xx 30 xx 31 xx 32 xx 33 
    492     "trn1      v1.8h, v0.8h, v0.8h                     \n" 
    493     "trn2      v4.8h, v0.8h, v0.8h                     \n" 
    494     "xtn       v0.4h, v1.4s                            \n" 
    495     "xtn       v4.4h, v4.4s                            \n" 
    496  
    497     // 0+1+2, 3+4+5 
    498     "add       v16.8h, v16.8h, v0.8h                   \n" 
    499     "add       v17.8h, v17.8h, v4.8h                   \n" 
    500  
    501     // Need to divide, but can't downshift as the the value 
    502     //  isn't a power of 2. So multiply by 65536 / n 
    503     //  and take the upper 16 bits. 
    504     "sqrdmulh  v0.8h, v16.8h, v30.8h                   \n" 
    505     "sqrdmulh  v1.8h, v17.8h, v30.8h                   \n" 
    506  
    507     // Align for table lookup, vtbl requires registers to 
    508     //  be adjacent 
    509  
    510     "tbl       v3.16b, {v0.16b, v1.16b, v2.16b}, v31.16b \n" 
    511  
    512     "st1       {v3.8b}, [%1], #8                       \n" 
    513     "st1       {v3.s}[2], [%1], #4                     \n" 
    514     "b.gt      1b                                      \n" 
    515   : "+r"(src_ptr),         // %0 
    516     "+r"(dst_ptr),         // %1 
    517     "+r"(tmp_src_stride),  // %2 
    518     "+r"(dst_width)        // %3 
    519   : "r"(&kMult38_Div6),    // %4 
    520     "r"(&kShuf38_2)        // %5 
    521   : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", 
    522     "v18", "v19", "v30", "v31", "memory", "cc" 
    523   ); 
     421  asm volatile( 
     422      "ld1       {v30.8h}, [%4]                          \n" 
     423      "ld1       {v31.16b}, [%5]                         \n" 
     424      "add       %2, %2, %0                              \n" 
     425      "1:                                                \n" 
     426 
     427      // 00 40 01 41 02 42 03 43 
     428      // 10 50 11 51 12 52 13 53 
     429      // 20 60 21 61 22 62 23 63 
     430      // 30 70 31 71 32 72 33 73 
     431      "ld4       {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32    \n" 
     432      "ld4       {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32    \n" 
     433      "subs      %w3, %w3, #12                           \n" 
     434 
     435      // Shuffle the input data around to get align the data 
     436      //  so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 
     437      // 00 10 01 11 02 12 03 13 
     438      // 40 50 41 51 42 52 43 53 
     439      "trn1      v16.8b, v0.8b, v1.8b                    \n" 
     440      "trn2      v17.8b, v0.8b, v1.8b                    \n" 
     441      "trn1      v18.8b, v4.8b, v5.8b                    \n" 
     442      "trn2      v19.8b, v4.8b, v5.8b                    \n" 
     443 
     444      // 20 30 21 31 22 32 23 33 
     445      // 60 70 61 71 62 72 63 73 
     446      "trn1      v0.8b, v2.8b, v3.8b                     \n" 
     447      "trn2      v1.8b, v2.8b, v3.8b                     \n" 
     448      "trn1      v4.8b, v6.8b, v7.8b                     \n" 
     449      "trn2      v5.8b, v6.8b, v7.8b                     \n" 
     450 
     451      // 00+10 01+11 02+12 03+13 
     452      // 40+50 41+51 42+52 43+53 
     453      "uaddlp    v16.4h, v16.8b                          \n" 
     454      "uaddlp    v17.4h, v17.8b                          \n" 
     455      "uaddlp    v18.4h, v18.8b                          \n" 
     456      "uaddlp    v19.4h, v19.8b                          \n" 
     457 
     458      // 60+70 61+71 62+72 63+73 
     459      "uaddlp    v1.4h, v1.8b                            \n" 
     460      "uaddlp    v5.4h, v5.8b                            \n" 
     461 
     462      // combine source lines 
     463      "add       v16.4h, v16.4h, v18.4h                  \n" 
     464      "add       v17.4h, v17.4h, v19.4h                  \n" 
     465      "add       v2.4h, v1.4h, v5.4h                     \n" 
     466 
     467      // dst_ptr[3] = (s[6] + s[7] + s[6+st] + s[7+st]) / 4 
     468      "uqrshrn   v2.8b, v2.8h, #2                        \n" 
     469 
     470      // Shuffle 2,3 reg around so that 2 can be added to the 
     471      //  0,1 reg and 3 can be added to the 4,5 reg. This 
     472      //  requires expanding from u8 to u16 as the 0,1 and 4,5 
     473      //  registers are already expanded. Then do transposes 
     474      //  to get aligned. 
     475      // xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 
     476 
     477      // combine source lines 
     478      "uaddl     v0.8h, v0.8b, v4.8b                     \n" 
     479 
     480      // xx 20 xx 21 xx 22 xx 23 
     481      // xx 30 xx 31 xx 32 xx 33 
     482      "trn1      v1.8h, v0.8h, v0.8h                     \n" 
     483      "trn2      v4.8h, v0.8h, v0.8h                     \n" 
     484      "xtn       v0.4h, v1.4s                            \n" 
     485      "xtn       v4.4h, v4.4s                            \n" 
     486 
     487      // 0+1+2, 3+4+5 
     488      "add       v16.8h, v16.8h, v0.8h                   \n" 
     489      "add       v17.8h, v17.8h, v4.8h                   \n" 
     490 
     491      // Need to divide, but can't downshift as the the value 
     492      //  isn't a power of 2. So multiply by 65536 / n 
     493      //  and take the upper 16 bits. 
     494      "sqrdmulh  v0.8h, v16.8h, v30.8h                   \n" 
     495      "sqrdmulh  v1.8h, v17.8h, v30.8h                   \n" 
     496 
     497      // Align for table lookup, vtbl requires registers to 
     498      //  be adjacent 
     499 
     500      "tbl       v3.16b, {v0.16b, v1.16b, v2.16b}, v31.16b \n" 
     501 
     502      "st1       {v3.8b}, [%1], #8                       \n" 
     503      "st1       {v3.s}[2], [%1], #4                     \n" 
     504      "b.gt      1b                                      \n" 
     505      : "+r"(src_ptr),         // %0 
     506        "+r"(dst_ptr),         // %1 
     507        "+r"(tmp_src_stride),  // %2 
     508        "+r"(dst_width)        // %3 
     509      : "r"(&kMult38_Div6),    // %4 
     510        "r"(&kShuf38_2)        // %5 
     511      : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", 
     512        "v19", "v30", "v31", "memory", "cc"); 
    524513} 
    525514 
     
    530519                       int src_height) { 
    531520  const uint8* src_tmp; 
    532   asm volatile ( 
    533   "1:                                          \n" 
    534     "mov       %0, %1                          \n" 
    535     "mov       w12, %w5                        \n" 
    536     "eor       v2.16b, v2.16b, v2.16b          \n" 
    537     "eor       v3.16b, v3.16b, v3.16b          \n" 
    538   "2:                                          \n" 
    539     // load 16 pixels into q0 
    540     "ld1       {v0.16b}, [%0], %3              \n" 
    541     "uaddw2    v3.8h, v3.8h, v0.16b            \n" 
    542     "uaddw     v2.8h, v2.8h, v0.8b             \n" 
    543     "subs      w12, w12, #1                    \n" 
    544     "b.gt      2b                              \n" 
    545     "st1      {v2.8h, v3.8h}, [%2], #32        \n"  // store pixels 
    546     "add      %1, %1, #16                      \n" 
    547     "subs     %w4, %w4, #16                    \n"  // 16 processed per loop 
    548     "b.gt     1b                               \n" 
    549   : "=&r"(src_tmp),    // %0 
    550     "+r"(src_ptr),     // %1 
    551     "+r"(dst_ptr),     // %2 
    552     "+r"(src_stride),  // %3 
    553     "+r"(src_width),   // %4 
    554     "+r"(src_height)   // %5 
    555   : 
    556   : "memory", "cc", "w12", "v0", "v1", "v2", "v3"  // Clobber List 
    557   ); 
    558 } 
    559  
    560 // clang-format off 
     521  asm volatile( 
     522      "1:                                        \n" 
     523      "mov       %0, %1                          \n" 
     524      "mov       w12, %w5                        \n" 
     525      "eor       v2.16b, v2.16b, v2.16b          \n" 
     526      "eor       v3.16b, v3.16b, v3.16b          \n" 
     527      "2:                                        \n" 
     528      // load 16 pixels into q0 
     529      "ld1       {v0.16b}, [%0], %3              \n" 
     530      "uaddw2    v3.8h, v3.8h, v0.16b            \n" 
     531      "uaddw     v2.8h, v2.8h, v0.8b             \n" 
     532      "subs      w12, w12, #1                    \n" 
     533      "b.gt      2b                              \n" 
     534      "st1      {v2.8h, v3.8h}, [%2], #32        \n"  // store pixels 
     535      "add      %1, %1, #16                      \n" 
     536      "subs     %w4, %w4, #16                    \n"  // 16 processed per loop 
     537      "b.gt     1b                               \n" 
     538      : "=&r"(src_tmp),    // %0 
     539        "+r"(src_ptr),     // %1 
     540        "+r"(dst_ptr),     // %2 
     541        "+r"(src_stride),  // %3 
     542        "+r"(src_width),   // %4 
     543        "+r"(src_height)   // %5 
     544      : 
     545      : "memory", "cc", "w12", "v0", "v1", "v2", "v3"  // Clobber List 
     546      ); 
     547} 
     548 
    561549// TODO(Yang Zhang): Investigate less load instructions for 
    562550// the x/dx stepping 
    563 #define LOAD2_DATA8_LANE(n)                                 \ 
    564   "lsr        %5, %3, #16                    \n"            \ 
    565   "add        %6, %1, %5                     \n"            \ 
    566   "add        %3, %3, %4                     \n"            \ 
     551#define LOAD2_DATA8_LANE(n)                      \ 
     552  "lsr        %5, %3, #16                    \n" \ 
     553  "add        %6, %1, %5                     \n" \ 
     554  "add        %3, %3, %4                     \n" \ 
    567555  "ld2        {v4.b, v5.b}[" #n "], [%6]     \n" 
    568 // clang-format on 
    569556 
    570557// The NEON version mimics this formula (from row_common.cc): 
     
    580567  int* tmp = dx_offset; 
    581568  const uint8* src_tmp = src_ptr; 
    582   int64 x64 = (int64)x; 
    583   int64 dx64 = (int64)dx; 
     569  int64 x64 = (int64)x;    // NOLINT 
     570  int64 dx64 = (int64)dx;  // NOLINT 
    584571  asm volatile ( 
    585572    "dup        v0.4s, %w3                     \n"  // x 
     
    645632                          int source_y_fraction) { 
    646633  int y_fraction = 256 - source_y_fraction; 
    647   asm volatile ( 
    648     "cmp          %w4, #0                      \n" 
    649     "b.eq         100f                         \n" 
    650     "add          %2, %2, %1                   \n" 
    651     "cmp          %w4, #64                     \n" 
    652     "b.eq         75f                          \n" 
    653     "cmp          %w4, #128                    \n" 
    654     "b.eq         50f                          \n" 
    655     "cmp          %w4, #192                    \n" 
    656     "b.eq         25f                          \n" 
    657  
    658     "dup          v5.8b, %w4                   \n" 
    659     "dup          v4.8b, %w5                   \n" 
    660     // General purpose row blend. 
    661   "1:                                          \n" 
    662     "ld1          {v0.16b}, [%1], #16          \n" 
    663     "ld1          {v1.16b}, [%2], #16          \n" 
    664     "subs         %w3, %w3, #16                \n" 
    665     "umull        v6.8h, v0.8b, v4.8b          \n" 
    666     "umull2       v7.8h, v0.16b, v4.16b        \n" 
    667     "umlal        v6.8h, v1.8b, v5.8b          \n" 
    668     "umlal2       v7.8h, v1.16b, v5.16b        \n" 
    669     "rshrn        v0.8b, v6.8h, #8             \n" 
    670     "rshrn2       v0.16b, v7.8h, #8            \n" 
    671     "st1          {v0.16b}, [%0], #16          \n" 
    672     "b.gt         1b                           \n" 
    673     "b            99f                          \n" 
    674  
    675     // Blend 25 / 75. 
    676   "25:                                         \n" 
    677     "ld1          {v0.16b}, [%1], #16          \n" 
    678     "ld1          {v1.16b}, [%2], #16          \n" 
    679     "subs         %w3, %w3, #16                \n" 
    680     "urhadd       v0.16b, v0.16b, v1.16b       \n" 
    681     "urhadd       v0.16b, v0.16b, v1.16b       \n" 
    682     "st1          {v0.16b}, [%0], #16          \n" 
    683     "b.gt         25b                          \n" 
    684     "b            99f                          \n" 
    685  
    686     // Blend 50 / 50. 
    687   "50:                                         \n" 
    688     "ld1          {v0.16b}, [%1], #16          \n" 
    689     "ld1          {v1.16b}, [%2], #16          \n" 
    690     "subs         %w3, %w3, #16                \n" 
    691     "urhadd       v0.16b, v0.16b, v1.16b       \n" 
    692     "st1          {v0.16b}, [%0], #16          \n" 
    693     "b.gt         50b                          \n" 
    694     "b            99f                          \n" 
    695  
    696     // Blend 75 / 25. 
    697   "75:                                         \n" 
    698     "ld1          {v1.16b}, [%1], #16          \n" 
    699     "ld1          {v0.16b}, [%2], #16          \n" 
    700     "subs         %w3, %w3, #16                \n" 
    701     "urhadd       v0.16b, v0.16b, v1.16b       \n" 
    702     "urhadd       v0.16b, v0.16b, v1.16b       \n" 
    703     "st1          {v0.16b}, [%0], #16          \n" 
    704     "b.gt         75b                          \n" 
    705     "b            99f                          \n" 
    706  
    707     // Blend 100 / 0 - Copy row unchanged. 
    708   "100:                                        \n" 
    709     "ld1          {v0.16b}, [%1], #16          \n" 
    710     "subs         %w3, %w3, #16                \n" 
    711     "st1          {v0.16b}, [%0], #16          \n" 
    712     "b.gt         100b                         \n" 
    713  
    714   "99:                                         \n" 
    715     "st1          {v0.b}[15], [%0]             \n" 
    716   : "+r"(dst_ptr),          // %0 
    717     "+r"(src_ptr),          // %1 
    718     "+r"(src_stride),       // %2 
    719     "+r"(dst_width),        // %3 
    720     "+r"(source_y_fraction),// %4 
    721     "+r"(y_fraction)        // %5 
    722   : 
    723   : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "memory", "cc" 
    724   ); 
     634  asm volatile( 
     635      "cmp          %w4, #0                      \n" 
     636      "b.eq         100f                         \n" 
     637      "add          %2, %2, %1                   \n" 
     638      "cmp          %w4, #64                     \n" 
     639      "b.eq         75f                          \n" 
     640      "cmp          %w4, #128                    \n" 
     641      "b.eq         50f                          \n" 
     642      "cmp          %w4, #192                    \n" 
     643      "b.eq         25f                          \n" 
     644 
     645      "dup          v5.8b, %w4                   \n" 
     646      "dup          v4.8b, %w5                   \n" 
     647      // General purpose row blend. 
     648      "1:                                        \n" 
     649      "ld1          {v0.16b}, [%1], #16          \n" 
     650      "ld1          {v1.16b}, [%2], #16          \n" 
     651      "subs         %w3, %w3, #16                \n" 
     652      "umull        v6.8h, v0.8b, v4.8b          \n" 
     653      "umull2       v7.8h, v0.16b, v4.16b        \n" 
     654      "umlal        v6.8h, v1.8b, v5.8b          \n" 
     655      "umlal2       v7.8h, v1.16b, v5.16b        \n" 
     656      "rshrn        v0.8b, v6.8h, #8             \n" 
     657      "rshrn2       v0.16b, v7.8h, #8            \n" 
     658      "st1          {v0.16b}, [%0], #16          \n" 
     659      "b.gt         1b                           \n" 
     660      "b            99f                          \n" 
     661 
     662      // Blend 25 / 75. 
     663      "25:                                       \n" 
     664      "ld1          {v0.16b}, [%1], #16          \n" 
     665      "ld1          {v1.16b}, [%2], #16          \n" 
     666      "subs         %w3, %w3, #16                \n" 
     667      "urhadd       v0.16b, v0.16b, v1.16b       \n" 
     668      "urhadd       v0.16b, v0.16b, v1.16b       \n" 
     669      "st1          {v0.16b}, [%0], #16          \n" 
     670      "b.gt         25b                          \n" 
     671      "b            99f                          \n" 
     672 
     673      // Blend 50 / 50. 
     674      "50:                                       \n" 
     675      "ld1          {v0.16b}, [%1], #16          \n" 
     676      "ld1          {v1.16b}, [%2], #16          \n" 
     677      "subs         %w3, %w3, #16                \n" 
     678      "urhadd       v0.16b, v0.16b, v1.16b       \n" 
     679      "st1          {v0.16b}, [%0], #16          \n" 
     680      "b.gt         50b                          \n" 
     681      "b            99f                          \n" 
     682 
     683      // Blend 75 / 25. 
     684      "75:                                       \n" 
     685      "ld1          {v1.16b}, [%1], #16          \n" 
     686      "ld1          {v0.16b}, [%2], #16          \n" 
     687      "subs         %w3, %w3, #16                \n" 
     688      "urhadd       v0.16b, v0.16b, v1.16b       \n" 
     689      "urhadd       v0.16b, v0.16b, v1.16b       \n" 
     690      "st1          {v0.16b}, [%0], #16          \n" 
     691      "b.gt         75b                          \n" 
     692      "b            99f                          \n" 
     693 
     694      // Blend 100 / 0 - Copy row unchanged. 
     695      "100:                                      \n" 
     696      "ld1          {v0.16b}, [%1], #16          \n" 
     697      "subs         %w3, %w3, #16                \n" 
     698      "st1          {v0.16b}, [%0], #16          \n" 
     699      "b.gt         100b                         \n" 
     700 
     701      "99:                                       \n" 
     702      "st1          {v0.b}[15], [%0]             \n" 
     703      : "+r"(dst_ptr),            // %0 
     704        "+r"(src_ptr),            // %1 
     705        "+r"(src_stride),         // %2 
     706        "+r"(dst_width),          // %3 
     707        "+r"(source_y_fraction),  // %4 
     708        "+r"(y_fraction)          // %5 
     709      : 
     710      : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "memory", "cc"); 
    725711} 
    726712 
     
    730716                            int dst_width) { 
    731717  (void)src_stride; 
    732   asm volatile ( 
    733   "1:                                          \n" 
    734     // load even pixels into q0, odd into q1 
    735     "ld2        {v0.4s, v1.4s}, [%0], #32      \n" 
    736     "ld2        {v2.4s, v3.4s}, [%0], #32      \n" 
    737     "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
    738     "st1        {v1.16b}, [%1], #16            \n"  // store odd pixels 
    739     "st1        {v3.16b}, [%1], #16            \n" 
    740     "b.gt       1b                             \n" 
    741   : "+r" (src_ptr),          // %0 
    742     "+r" (dst),              // %1 
    743     "+r" (dst_width)         // %2 
    744   : 
    745   : "memory", "cc", "v0", "v1", "v2", "v3"  // Clobber List 
    746   ); 
     718  asm volatile( 
     719      "1:                                        \n" 
     720      // load 16 ARGB pixels with even pixels into q0/q2, odd into q1/q3 
     721      "ld4        {v0.4s,v1.4s,v2.4s,v3.4s}, [%0], #64 \n" 
     722      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
     723      "mov        v2.16b, v3.16b                 \n" 
     724      "st2        {v1.4s,v2.4s}, [%1], #32       \n"  // store 8 odd pixels 
     725      "b.gt       1b                             \n" 
     726      : "+r"(src_ptr),   // %0 
     727        "+r"(dst),       // %1 
     728        "+r"(dst_width)  // %2 
     729      : 
     730      : "memory", "cc", "v0", "v1", "v2", "v3"  // Clobber List 
     731      ); 
    747732} 
    748733 
     
    752737                                  int dst_width) { 
    753738  (void)src_stride; 
    754   asm volatile ( 
    755   "1:                                          \n" 
    756     // load 8 ARGB pixels. 
    757     "ld4        {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64   \n" 
    758     "subs       %w2, %w2, #8                   \n"  // 8 processed per loop. 
    759     "uaddlp     v0.8h, v0.16b                  \n"  // B 16 bytes -> 8 shorts. 
    760     "uaddlp     v1.8h, v1.16b                  \n"  // G 16 bytes -> 8 shorts. 
    761     "uaddlp     v2.8h, v2.16b                  \n"  // R 16 bytes -> 8 shorts. 
    762     "uaddlp     v3.8h, v3.16b                  \n"  // A 16 bytes -> 8 shorts. 
    763     "rshrn      v0.8b, v0.8h, #1               \n"  // downshift, round and pack 
    764     "rshrn      v1.8b, v1.8h, #1               \n" 
    765     "rshrn      v2.8b, v2.8h, #1               \n" 
    766     "rshrn      v3.8b, v3.8h, #1               \n" 
    767     "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32     \n" 
    768     "b.gt       1b                             \n" 
    769   : "+r"(src_argb),         // %0 
    770     "+r"(dst_argb),         // %1 
    771     "+r"(dst_width)         // %2 
    772   : 
    773   : "memory", "cc", "v0", "v1", "v2", "v3"    // Clobber List 
    774   ); 
     739  asm volatile( 
     740      "1:                                        \n" 
     741      // load 16 ARGB pixels with even pixels into q0/q2, odd into q1/q3 
     742      "ld4        {v0.4s,v1.4s,v2.4s,v3.4s}, [%0], #64 \n" 
     743      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
     744 
     745      "urhadd     v0.16b, v0.16b, v1.16b         \n"  // rounding half add 
     746      "urhadd     v1.16b, v2.16b, v3.16b         \n" 
     747      "st2        {v0.4s,v1.4s}, [%1], #32       \n"  // store 8 pixels 
     748      "b.gt       1b                             \n" 
     749      : "+r"(src_argb),  // %0 
     750        "+r"(dst_argb),  // %1 
     751        "+r"(dst_width)  // %2 
     752      : 
     753      : "memory", "cc", "v0", "v1", "v2", "v3"  // Clobber List 
     754      ); 
    775755} 
    776756 
     
    779759                               uint8* dst, 
    780760                               int dst_width) { 
    781   asm volatile ( 
    782     // change the stride to row 2 pointer 
    783     "add        %1, %1, %0                     \n" 
    784   "1:                                          \n" 
    785     "ld4        {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64   \n"  // load 8 ARGB pixels. 
    786     "subs       %w3, %w3, #8                   \n"  // 8 processed per loop. 
    787     "uaddlp     v0.8h, v0.16b                  \n"  // B 16 bytes -> 8 shorts. 
    788     "uaddlp     v1.8h, v1.16b                  \n"  // G 16 bytes -> 8 shorts. 
    789     "uaddlp     v2.8h, v2.16b                  \n"  // R 16 bytes -> 8 shorts. 
    790     "uaddlp     v3.8h, v3.16b                  \n"  // A 16 bytes -> 8 shorts. 
    791     "ld4        {v16.16b,v17.16b,v18.16b,v19.16b}, [%1], #64 \n"  // load 8 more ARGB pixels. 
    792     "uadalp     v0.8h, v16.16b                 \n"  // B 16 bytes -> 8 shorts. 
    793     "uadalp     v1.8h, v17.16b                 \n"  // G 16 bytes -> 8 shorts. 
    794     "uadalp     v2.8h, v18.16b                 \n"  // R 16 bytes -> 8 shorts. 
    795     "uadalp     v3.8h, v19.16b                 \n"  // A 16 bytes -> 8 shorts. 
    796     "rshrn      v0.8b, v0.8h, #2               \n"  // downshift, round and pack 
    797     "rshrn      v1.8b, v1.8h, #2               \n" 
    798     "rshrn      v2.8b, v2.8h, #2               \n" 
    799     "rshrn      v3.8b, v3.8h, #2               \n" 
    800     "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32     \n" 
    801     "b.gt       1b                             \n" 
    802   : "+r" (src_ptr),          // %0 
    803     "+r" (src_stride),       // %1 
    804     "+r" (dst),              // %2 
    805     "+r" (dst_width)         // %3 
    806   : 
    807   : "memory", "cc", "v0", "v1", "v2", "v3", "v16", "v17", "v18", "v19" 
    808   ); 
     761  asm volatile( 
     762      // change the stride to row 2 pointer 
     763      "add        %1, %1, %0                     \n" 
     764      "1:                                        \n" 
     765      "ld4        {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n"  // load 8 ARGB 
     766      "subs       %w3, %w3, #8                   \n"  // 8 processed per loop. 
     767      "uaddlp     v0.8h, v0.16b                  \n"  // B 16 bytes -> 8 shorts. 
     768      "uaddlp     v1.8h, v1.16b                  \n"  // G 16 bytes -> 8 shorts. 
     769      "uaddlp     v2.8h, v2.16b                  \n"  // R 16 bytes -> 8 shorts. 
     770      "uaddlp     v3.8h, v3.16b                  \n"  // A 16 bytes -> 8 shorts. 
     771      "ld4        {v16.16b,v17.16b,v18.16b,v19.16b}, [%1], #64 \n"  // load 8 
     772      "uadalp     v0.8h, v16.16b                 \n"  // B 16 bytes -> 8 shorts. 
     773      "uadalp     v1.8h, v17.16b                 \n"  // G 16 bytes -> 8 shorts. 
     774      "uadalp     v2.8h, v18.16b                 \n"  // R 16 bytes -> 8 shorts. 
     775      "uadalp     v3.8h, v19.16b                 \n"  // A 16 bytes -> 8 shorts. 
     776      "rshrn      v0.8b, v0.8h, #2               \n"  // round and pack 
     777      "rshrn      v1.8b, v1.8h, #2               \n" 
     778      "rshrn      v2.8b, v2.8h, #2               \n" 
     779      "rshrn      v3.8b, v3.8h, #2               \n" 
     780      "st4        {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32     \n" 
     781      "b.gt       1b                             \n" 
     782      : "+r"(src_ptr),     // %0 
     783        "+r"(src_stride),  // %1 
     784        "+r"(dst),         // %2 
     785        "+r"(dst_width)    // %3 
     786      : 
     787      : "memory", "cc", "v0", "v1", "v2", "v3", "v16", "v17", "v18", "v19"); 
    809788} 
    810789 
     
    817796                               int dst_width) { 
    818797  (void)src_stride; 
    819   asm volatile ( 
    820   "1:                                          \n" 
    821     "ld1        {v0.s}[0], [%0], %3            \n" 
    822     "ld1        {v0.s}[1], [%0], %3            \n" 
    823     "ld1        {v0.s}[2], [%0], %3            \n" 
    824     "ld1        {v0.s}[3], [%0], %3            \n" 
    825     "subs       %w2, %w2, #4                   \n"  // 4 pixels per loop. 
    826     "st1        {v0.16b}, [%1], #16            \n" 
    827     "b.gt       1b                             \n" 
    828   : "+r"(src_argb),    // %0 
    829     "+r"(dst_argb),    // %1 
    830     "+r"(dst_width)    // %2 
    831   : "r"((int64)(src_stepx * 4)) // %3 
    832   : "memory", "cc", "v0" 
    833   ); 
     798  asm volatile( 
     799      "1:                                        \n" 
     800      "ld1        {v0.s}[0], [%0], %3            \n" 
     801      "ld1        {v0.s}[1], [%0], %3            \n" 
     802      "ld1        {v0.s}[2], [%0], %3            \n" 
     803      "ld1        {v0.s}[3], [%0], %3            \n" 
     804      "subs       %w2, %w2, #4                   \n"  // 4 pixels per loop. 
     805      "st1        {v0.16b}, [%1], #16            \n" 
     806      "b.gt       1b                             \n" 
     807      : "+r"(src_argb),              // %0 
     808        "+r"(dst_argb),              // %1 
     809        "+r"(dst_width)              // %2 
     810      : "r"((int64)(src_stepx * 4))  // %3 
     811      : "memory", "cc", "v0"); 
    834812} 
    835813 
     
    843821                                  uint8* dst_argb, 
    844822                                  int dst_width) { 
    845   asm volatile ( 
    846     "add        %1, %1, %0                     \n" 
    847   "1:                                          \n" 
    848     "ld1        {v0.8b}, [%0], %4              \n"  // Read 4 2x2 blocks -> 2x1 
    849     "ld1        {v1.8b}, [%1], %4              \n" 
    850     "ld1        {v2.8b}, [%0], %4              \n" 
    851     "ld1        {v3.8b}, [%1], %4              \n" 
    852     "ld1        {v4.8b}, [%0], %4              \n" 
    853     "ld1        {v5.8b}, [%1], %4              \n" 
    854     "ld1        {v6.8b}, [%0], %4              \n" 
    855     "ld1        {v7.8b}, [%1], %4              \n" 
    856     "uaddl      v0.8h, v0.8b, v1.8b            \n" 
    857     "uaddl      v2.8h, v2.8b, v3.8b            \n" 
    858     "uaddl      v4.8h, v4.8b, v5.8b            \n" 
    859     "uaddl      v6.8h, v6.8b, v7.8b            \n" 
    860     "mov        v16.d[1], v0.d[1]              \n"  // ab_cd -> ac_bd 
    861     "mov        v0.d[1], v2.d[0]               \n" 
    862     "mov        v2.d[0], v16.d[1]              \n" 
    863     "mov        v16.d[1], v4.d[1]              \n"  // ef_gh -> eg_fh 
    864     "mov        v4.d[1], v6.d[0]               \n" 
    865     "mov        v6.d[0], v16.d[1]              \n" 
    866     "add        v0.8h, v0.8h, v2.8h            \n"  // (a+b)_(c+d) 
    867     "add        v4.8h, v4.8h, v6.8h            \n"  // (e+f)_(g+h) 
    868     "rshrn      v0.8b, v0.8h, #2               \n"  // first 2 pixels. 
    869     "rshrn2     v0.16b, v4.8h, #2              \n"  // next 2 pixels. 
    870     "subs       %w3, %w3, #4                   \n"  // 4 pixels per loop. 
    871     "st1     {v0.16b}, [%2], #16               \n" 
    872     "b.gt       1b                             \n" 
    873   : "+r"(src_argb),    // %0 
    874     "+r"(src_stride),  // %1 
    875     "+r"(dst_argb),    // %2 
    876     "+r"(dst_width)    // %3 
    877   : "r"((int64)(src_stepx * 4)) // %4 
    878   : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16" 
    879   ); 
    880 } 
    881  
    882 // clang-format off 
     823  asm volatile( 
     824      "add        %1, %1, %0                     \n" 
     825      "1:                                        \n" 
     826      "ld1        {v0.8b}, [%0], %4              \n"  // Read 4 2x2 -> 2x1 
     827      "ld1        {v1.8b}, [%1], %4              \n" 
     828      "ld1        {v2.8b}, [%0], %4              \n" 
     829      "ld1        {v3.8b}, [%1], %4              \n" 
     830      "ld1        {v4.8b}, [%0], %4              \n" 
     831      "ld1        {v5.8b}, [%1], %4              \n" 
     832      "ld1        {v6.8b}, [%0], %4              \n" 
     833      "ld1        {v7.8b}, [%1], %4              \n" 
     834      "uaddl      v0.8h, v0.8b, v1.8b            \n" 
     835      "uaddl      v2.8h, v2.8b, v3.8b            \n" 
     836      "uaddl      v4.8h, v4.8b, v5.8b            \n" 
     837      "uaddl      v6.8h, v6.8b, v7.8b            \n" 
     838      "mov        v16.d[1], v0.d[1]              \n"  // ab_cd -> ac_bd 
     839      "mov        v0.d[1], v2.d[0]               \n" 
     840      "mov        v2.d[0], v16.d[1]              \n" 
     841      "mov        v16.d[1], v4.d[1]              \n"  // ef_gh -> eg_fh 
     842      "mov        v4.d[1], v6.d[0]               \n" 
     843      "mov        v6.d[0], v16.d[1]              \n" 
     844      "add        v0.8h, v0.8h, v2.8h            \n"  // (a+b)_(c+d) 
     845      "add        v4.8h, v4.8h, v6.8h            \n"  // (e+f)_(g+h) 
     846      "rshrn      v0.8b, v0.8h, #2               \n"  // first 2 pixels. 
     847      "rshrn2     v0.16b, v4.8h, #2              \n"  // next 2 pixels. 
     848      "subs       %w3, %w3, #4                   \n"  // 4 pixels per loop. 
     849      "st1     {v0.16b}, [%2], #16               \n" 
     850      "b.gt       1b                             \n" 
     851      : "+r"(src_argb),              // %0 
     852        "+r"(src_stride),            // %1 
     853        "+r"(dst_argb),              // %2 
     854        "+r"(dst_width)              // %3 
     855      : "r"((int64)(src_stepx * 4))  // %4 
     856      : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); 
     857} 
     858 
    883859// TODO(Yang Zhang): Investigate less load instructions for 
    884860// the x/dx stepping 
    885 #define LOAD1_DATA32_LANE(vn, n)                            \ 
    886   "lsr        %5, %3, #16                    \n"            \ 
    887   "add        %6, %1, %5, lsl #2             \n"            \ 
    888   "add        %3, %3, %4                     \n"            \ 
     861#define LOAD1_DATA32_LANE(vn, n)                 \ 
     862  "lsr        %5, %3, #16                    \n" \ 
     863  "add        %6, %1, %5, lsl #2             \n" \ 
     864  "add        %3, %3, %4                     \n" \ 
    889865  "ld1        {" #vn ".s}[" #n "], [%6]      \n" 
    890 // clang-format on 
    891866 
    892867void ScaleARGBCols_NEON(uint8* dst_argb, 
     
    896871                        int dx) { 
    897872  const uint8* src_tmp = src_argb; 
    898   int64 x64 = (int64)x; 
    899   int64 dx64 = (int64)dx; 
     873  int64 x64 = (int64)x;    // NOLINT 
     874  int64 dx64 = (int64)dx;  // NOLINT 
    900875  int64 tmp64; 
    901   asm volatile ( 
    902   "1:                                          \n" 
    903     LOAD1_DATA32_LANE(v0, 0) 
    904     LOAD1_DATA32_LANE(v0, 1) 
    905     LOAD1_DATA32_LANE(v0, 2) 
    906     LOAD1_DATA32_LANE(v0, 3) 
    907     LOAD1_DATA32_LANE(v1, 0) 
    908     LOAD1_DATA32_LANE(v1, 1) 
    909     LOAD1_DATA32_LANE(v1, 2) 
    910     LOAD1_DATA32_LANE(v1, 3) 
    911  
    912     "st1        {v0.4s, v1.4s}, [%0], #32      \n"  // store pixels 
    913     "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
    914     "b.gt       1b                             \n" 
    915   : "+r"(dst_argb),     // %0 
    916     "+r"(src_argb),     // %1 
    917     "+r"(dst_width),    // %2 
    918     "+r"(x64),          // %3 
    919     "+r"(dx64),         // %4 
    920     "=&r"(tmp64),       // %5 
    921     "+r"(src_tmp)       // %6 
    922   : 
    923   : "memory", "cc", "v0", "v1" 
    924   ); 
     876  asm volatile( 
     877      "1:                                        \n" 
     878      // clang-format off 
     879      LOAD1_DATA32_LANE(v0, 0) 
     880      LOAD1_DATA32_LANE(v0, 1) 
     881      LOAD1_DATA32_LANE(v0, 2) 
     882      LOAD1_DATA32_LANE(v0, 3) 
     883      LOAD1_DATA32_LANE(v1, 0) 
     884      LOAD1_DATA32_LANE(v1, 1) 
     885      LOAD1_DATA32_LANE(v1, 2) 
     886      LOAD1_DATA32_LANE(v1, 3) 
     887      // clang-format on 
     888      "st1        {v0.4s, v1.4s}, [%0], #32      \n"  // store pixels 
     889      "subs       %w2, %w2, #8                   \n"  // 8 processed per loop 
     890      "b.gt       1b                             \n" 
     891      : "+r"(dst_argb),   // %0 
     892        "+r"(src_argb),   // %1 
     893        "+r"(dst_width),  // %2 
     894        "+r"(x64),        // %3 
     895        "+r"(dx64),       // %4 
     896        "=&r"(tmp64),     // %5 
     897        "+r"(src_tmp)     // %6 
     898      : 
     899      : "memory", "cc", "v0", "v1"); 
    925900} 
    926901 
    927902#undef LOAD1_DATA32_LANE 
    928903 
    929 // clang-format off 
    930904// TODO(Yang Zhang): Investigate less load instructions for 
    931905// the x/dx stepping 
    932 #define LOAD2_DATA32_LANE(vn1, vn2, n)                             \ 
    933   "lsr        %5, %3, #16                           \n"            \ 
    934   "add        %6, %1, %5, lsl #2                    \n"            \ 
    935   "add        %3, %3, %4                            \n"            \ 
     906#define LOAD2_DATA32_LANE(vn1, vn2, n)                  \ 
     907  "lsr        %5, %3, #16                           \n" \ 
     908  "add        %6, %1, %5, lsl #2                    \n" \ 
     909  "add        %3, %3, %4                            \n" \ 
    936910  "ld2        {" #vn1 ".s, " #vn2 ".s}[" #n "], [%6]  \n" 
    937 // clang-format on 
    938911 
    939912void ScaleARGBFilterCols_NEON(uint8* dst_argb, 
     
    945918  int* tmp = dx_offset; 
    946919  const uint8* src_tmp = src_argb; 
    947   int64 x64 = (int64)x; 
    948   int64 dx64 = (int64)dx; 
     920  int64 x64 = (int64)x;    // NOLINT 
     921  int64 dx64 = (int64)dx;  // NOLINT 
    949922  asm volatile ( 
    950923    "dup        v0.4s, %w3                     \n"  // x 
     
    1002975#undef LOAD2_DATA32_LANE 
    1003976 
     977// Read 16x2 average down and write 8x1. 
     978void ScaleRowDown2Box_16_NEON(const uint16* src_ptr, 
     979                              ptrdiff_t src_stride, 
     980                              uint16* dst, 
     981                              int dst_width) { 
     982  asm volatile( 
     983      // change the stride to row 2 pointer 
     984      "add        %1, %0, %1, lsl #1             \n"  // ptr + stide * 2 
     985      "1:                                        \n" 
     986      "ld1        {v0.8h, v1.8h}, [%0], #32      \n"  // load row 1 and post inc 
     987      "ld1        {v2.8h, v3.8h}, [%1], #32      \n"  // load row 2 and post inc 
     988      "subs       %w3, %w3, #8                   \n"  // 8 processed per loop 
     989      "uaddlp     v0.4s, v0.8h                   \n"  // row 1 add adjacent 
     990      "uaddlp     v1.4s, v1.8h                   \n" 
     991      "uadalp     v0.4s, v2.8h                   \n"  // +row 2 add adjacent 
     992      "uadalp     v1.4s, v3.8h                   \n" 
     993      "rshrn      v0.4h, v0.4s, #2               \n"  // round and pack 
     994      "rshrn2     v0.8h, v1.4s, #2               \n" 
     995      "st1        {v0.8h}, [%2], #16             \n" 
     996      "b.gt       1b                             \n" 
     997      : "+r"(src_ptr),     // %0 
     998        "+r"(src_stride),  // %1 
     999        "+r"(dst),         // %2 
     1000        "+r"(dst_width)    // %3 
     1001      : 
     1002      : "v0", "v1", "v2", "v3"  // Clobber List 
     1003      ); 
     1004} 
     1005 
     1006// Read 8x2 upsample with filtering and write 16x1. 
     1007// Actually reads an extra pixel, so 9x2. 
     1008void ScaleRowUp2_16_NEON(const uint16* src_ptr, 
     1009                         ptrdiff_t src_stride, 
     1010                         uint16* dst, 
     1011                         int dst_width) { 
     1012  asm volatile( 
     1013      "add        %1, %0, %1, lsl #1             \n"  // ptr + stide * 2 
     1014      "movi       v0.8h, #9                      \n"  // constants 
     1015      "movi       v1.4s, #3                      \n" 
     1016 
     1017      "1:                                        \n" 
     1018      "ld1        {v3.8h}, [%0], %4              \n"  // TL read first 8 
     1019      "ld1        {v4.8h}, [%0], %5              \n"  // TR read 8 offset by 1 
     1020      "ld1        {v5.8h}, [%1], %4              \n"  // BL read 8 from next row 
     1021      "ld1        {v6.8h}, [%1], %5              \n"  // BR offset by 1 
     1022      "subs       %w3, %w3, #16                  \n"  // 16 dst pixels per loop 
     1023      "umull      v16.4s, v3.4h, v0.4h           \n" 
     1024      "umull2     v7.4s, v3.8h, v0.8h            \n" 
     1025      "umull      v18.4s, v4.4h, v0.4h           \n" 
     1026      "umull2     v17.4s, v4.8h, v0.8h           \n" 
     1027      "uaddw      v16.4s, v16.4s, v6.4h          \n" 
     1028      "uaddl2     v19.4s, v6.8h, v3.8h           \n" 
     1029      "uaddl      v3.4s, v6.4h, v3.4h            \n" 
     1030      "uaddw2     v6.4s, v7.4s, v6.8h            \n" 
     1031      "uaddl2     v7.4s, v5.8h, v4.8h            \n" 
     1032      "uaddl      v4.4s, v5.4h, v4.4h            \n" 
     1033      "uaddw      v18.4s, v18.4s, v5.4h          \n" 
     1034      "mla        v16.4s, v4.4s, v1.4s           \n" 
     1035      "mla        v18.4s, v3.4s, v1.4s           \n" 
     1036      "mla        v6.4s, v7.4s, v1.4s            \n" 
     1037      "uaddw2     v4.4s, v17.4s, v5.8h           \n" 
     1038      "uqrshrn    v16.4h,  v16.4s, #4            \n" 
     1039      "mla        v4.4s, v19.4s, v1.4s           \n" 
     1040      "uqrshrn2   v16.8h, v6.4s, #4              \n" 
     1041      "uqrshrn    v17.4h, v18.4s, #4             \n" 
     1042      "uqrshrn2   v17.8h, v4.4s, #4              \n" 
     1043      "st2        {v16.8h-v17.8h}, [%2], #32     \n" 
     1044      "b.gt       1b                             \n" 
     1045      : "+r"(src_ptr),     // %0 
     1046        "+r"(src_stride),  // %1 
     1047        "+r"(dst),         // %2 
     1048        "+r"(dst_width)    // %3 
     1049      : "r"(2LL),          // %4 
     1050        "r"(14LL)          // %5 
     1051      : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", 
     1052        "v19"  // Clobber List 
     1053      ); 
     1054} 
     1055 
    10041056#endif  // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) 
    10051057 
  • pjproject/trunk/third_party/yuv/source/scale_win.cc

    r5633 r5699  
    1818 
    1919// This module is for 32 bit Visual C x86 and clangcl 
    20 #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) 
     20#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) 
    2121 
    2222// Offsets for source bytes 0 to 9 
     
    817817    pxor       xmm5, xmm5 
    818818 
    819     // sum rows 
     819        // sum rows 
    820820  xloop: 
    821821    movdqu     xmm3, [eax]  // read 16 bytes 
     
    848848    vpxor       ymm5, ymm5, ymm5 
    849849 
    850     // sum rows 
     850        // sum rows 
    851851  xloop: 
    852852    vmovdqu     ymm3, [eax]  // read 32 bytes 
     
    940940    jl         xloop99 
    941941 
    942         // 1 pixel remainder 
     942            // 1 pixel remainder 
    943943    movzx      ebx, word ptr [esi + eax]  // 2 source x0 pixels 
    944944    movd       xmm0, ebx 
     
    11951195    jl         xloop49 
    11961196 
    1197     // 4 Pixel loop. 
     1197        // 4 Pixel loop. 
    11981198 xloop4: 
    11991199    movd       xmm0, [esi + eax * 4]  // 1 source x0 pixels 
     
    12191219    je         xloop29 
    12201220 
    1221     // 2 Pixels. 
     1221        // 2 Pixels. 
    12221222    movd       xmm0, [esi + eax * 4]  // 1 source x0 pixels 
    12231223    movd       xmm1, [esi + edx * 4]  // 1 source x1 pixels 
     
    12321232    je         xloop99 
    12331233 
    1234     // 1 Pixels. 
     1234        // 1 Pixels. 
    12351235    movd       xmm0, [esi + eax * 4]  // 1 source x2 pixels 
    12361236    movd       dword ptr [edi], xmm0 
     
    13101310    jl         xloop99 
    13111311 
    1312         // 1 pixel remainder 
     1312            // 1 pixel remainder 
    13131313    psrlw      xmm2, 9  // 7 bit fractions. 
    13141314    movq       xmm0, qword ptr [esi + eax * 4]  // 2 source x0 pixels 
Note: See TracChangeset for help on using the changeset viewer.