Commit 8e50e619 authored by fbarchard@google.com's avatar fbarchard@google.com

ARGBScale_NEON

BUG=none
TEST=./libyuv_unittest --gtest_filter=*ARGBScale*
Review URL: https://webrtc-codereview.appspot.com/964016

git-svn-id: http://libyuv.googlecode.com/svn/trunk@494 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 4a86a836
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 493 Version: 494
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -11,6 +11,6 @@ ...@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 493 #define LIBYUV_VERSION 494
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
...@@ -36,6 +36,14 @@ void ScaleARGBRowDownEven_NEON(const uint8* src_argb, int src_stride, ...@@ -36,6 +36,14 @@ void ScaleARGBRowDownEven_NEON(const uint8* src_argb, int src_stride,
void ScaleARGBRowDownEvenInt_NEON(const uint8* src_argb, int src_stride, void ScaleARGBRowDownEvenInt_NEON(const uint8* src_argb, int src_stride,
int src_stepx, int src_stepx,
uint8* dst_argb, int dst_width); uint8* dst_argb, int dst_width);
#define HAS_SCALEARGBROWDOWN2_NEON
void ScaleARGBRowDown2_NEON(const uint8* src_ptr, ptrdiff_t /* src_stride */,
uint8* dst, int dst_width);
void ScaleARGBRowDown2Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width);
#endif #endif
/** /**
...@@ -876,13 +884,18 @@ static void ScaleARGBDown2(int /* src_width */, int /* src_height */, ...@@ -876,13 +884,18 @@ static void ScaleARGBDown2(int /* src_width */, int /* src_height */,
uint8* dst_argb, int dst_width) = uint8* dst_argb, int dst_width) =
filtering ? ScaleARGBRowDown2Int_C : ScaleARGBRowDown2_C; filtering ? ScaleARGBRowDown2Int_C : ScaleARGBRowDown2_C;
#if defined(HAS_SCALEARGBROWDOWN2_SSE2) #if defined(HAS_SCALEARGBROWDOWN2_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 4) &&
IS_ALIGNED(dst_width, 4) &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) && IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) &&
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) {
ScaleARGBRowDown2 = filtering ? ScaleARGBRowDown2Int_SSE2 : ScaleARGBRowDown2 = filtering ? ScaleARGBRowDown2Int_SSE2 :
ScaleARGBRowDown2_SSE2; ScaleARGBRowDown2_SSE2;
} }
#elif defined(HAS_SCALEARGBROWDOWN2_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(dst_width, 8) &&
IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4)) {
ScaleARGBRowDown2 = filtering ? ScaleARGBRowDown2Int_NEON :
ScaleARGBRowDown2_NEON;
}
#endif #endif
// TODO(fbarchard): Loop through source height to allow odd height. // TODO(fbarchard): Loop through source height to allow odd height.
......
...@@ -18,6 +18,61 @@ extern "C" { ...@@ -18,6 +18,61 @@ extern "C" {
// This module is for GCC Neon // This module is for GCC Neon
#if !defined(YUV_DISABLE_ASM) && defined(__ARM_NEON__) #if !defined(YUV_DISABLE_ASM) && defined(__ARM_NEON__)
void ScaleARGBRowDown2_NEON(const uint8* src_ptr, ptrdiff_t /* src_stride */,
uint8* dst, int dst_width) {
asm volatile (
"1: \n"
// load even pixels into q0, odd into q1
"vld2.u32 {q0, q1}, [%0]! \n"
"vld2.u32 {q2, q3}, [%0]! \n"
"subs %2, %2, #8 \n" // 8 processed per loop
"vst1.u8 {q0}, [%1]! \n" // store even pixels
"vst1.u8 {q2}, [%1]! \n"
"bgt 1b \n"
: "+r"(src_ptr), // %0
"+r"(dst), // %1
"+r"(dst_width) // %2
:
: "memory", "cc", "q0", "q1", "q2", "q3" // Clobber List
);
}
void ScaleARGBRowDown2Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
uint8* dst, int dst_width) {
asm volatile (
// change the stride to row 2 pointer
"add %1, %0 \n"
"1: \n"
"vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels.
"vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels.
"subs %3, %3, #8 \n" // 8 processed per loop.
"vpaddl.u8 q0, q0 \n" // B 16 bytes -> 8 shorts.
"vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts.
"vpaddl.u8 q2, q2 \n" // R 16 bytes -> 8 shorts.
"vpaddl.u8 q3, q3 \n" // A 16 bytes -> 8 shorts.
"vld4.8 {d16, d18, d20, d22}, [%1]! \n" // load 8 more ARGB pixels.
"vld4.8 {d17, d19, d21, d23}, [%1]! \n" // load last 8 ARGB pixels.
"vpadal.u8 q0, q8 \n" // B 16 bytes -> 8 shorts.
"vpadal.u8 q1, q9 \n" // G 16 bytes -> 8 shorts.
"vpadal.u8 q2, q10 \n" // R 16 bytes -> 8 shorts.
"vpadal.u8 q3, q11 \n" // A 16 bytes -> 8 shorts.
"vrshrn.u16 d0, q0, #2 \n" // downshift, round and pack
"vrshrn.u16 d1, q1, #2 \n"
"vrshrn.u16 d2, q2, #2 \n"
"vrshrn.u16 d3, q3, #2 \n"
"vst4.u8 {d0, d1, d2, d3}, [%2]! \n"
"bgt 1b \n"
: "+r"(src_ptr), // %0
"+r"(src_stride), // %1
"+r"(dst), // %2
"+r"(dst_width) // %3
:
: "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"
);
}
// Reads 4 pixels at a time. // Reads 4 pixels at a time.
// Alignment requirement: src_argb 4 byte aligned. // Alignment requirement: src_argb 4 byte aligned.
void ScaleARGBRowDownEven_NEON(const uint8* src_argb, ptrdiff_t, void ScaleARGBRowDownEven_NEON(const uint8* src_argb, ptrdiff_t,
......
...@@ -32,14 +32,14 @@ void ScaleRowDown2_NEON(const uint8* src_ptr, ptrdiff_t /* src_stride */, ...@@ -32,14 +32,14 @@ void ScaleRowDown2_NEON(const uint8* src_ptr, ptrdiff_t /* src_stride */,
"1: \n" "1: \n"
// load even pixels into q0, odd into q1 // load even pixels into q0, odd into q1
"vld2.u8 {q0,q1}, [%0]! \n" "vld2.u8 {q0,q1}, [%0]! \n"
"vst1.u8 {q0}, [%1]! \n" // store even pixels
"subs %2, %2, #16 \n" // 16 processed per loop "subs %2, %2, #16 \n" // 16 processed per loop
"vst1.u8 {q0}, [%1]! \n" // store even pixels
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst), // %1 "+r"(dst), // %1
"+r"(dst_width) // %2 "+r"(dst_width) // %2
: :
: "q0", "q1" // Clobber List : "q0", "q1" // Clobber List
); );
} }
...@@ -51,6 +51,7 @@ void ScaleRowDown2Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride, ...@@ -51,6 +51,7 @@ void ScaleRowDown2Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
"1: \n" "1: \n"
"vld1.u8 {q0,q1}, [%0]! \n" // load row 1 and post inc "vld1.u8 {q0,q1}, [%0]! \n" // load row 1 and post inc
"vld1.u8 {q2,q3}, [%1]! \n" // load row 2 and post inc "vld1.u8 {q2,q3}, [%1]! \n" // load row 2 and post inc
"subs %3, %3, #16 \n" // 16 processed per loop
"vpaddl.u8 q0, q0 \n" // row 1 add adjacent "vpaddl.u8 q0, q0 \n" // row 1 add adjacent
"vpaddl.u8 q1, q1 \n" "vpaddl.u8 q1, q1 \n"
"vpadal.u8 q0, q2 \n" // row 2 add adjacent + row1 "vpadal.u8 q0, q2 \n" // row 2 add adjacent + row1
...@@ -58,15 +59,14 @@ void ScaleRowDown2Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride, ...@@ -58,15 +59,14 @@ void ScaleRowDown2Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
"vrshrn.u16 d0, q0, #2 \n" // downshift, round and pack "vrshrn.u16 d0, q0, #2 \n" // downshift, round and pack
"vrshrn.u16 d1, q1, #2 \n" "vrshrn.u16 d1, q1, #2 \n"
"vst1.u8 {q0}, [%2]! \n" "vst1.u8 {q0}, [%2]! \n"
"subs %3, %3, #16 \n" // 16 processed per loop
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(src_stride), // %1 "+r"(src_stride), // %1
"+r"(dst), // %2 "+r"(dst), // %2
"+r"(dst_width) // %3 "+r"(dst_width) // %3
: :
: "q0", "q1", "q2", "q3" // Clobber List : "q0", "q1", "q2", "q3" // Clobber List
); );
} }
void ScaleRowDown4_NEON(const uint8* src_ptr, ptrdiff_t /* src_stride */, void ScaleRowDown4_NEON(const uint8* src_ptr, ptrdiff_t /* src_stride */,
...@@ -74,16 +74,16 @@ void ScaleRowDown4_NEON(const uint8* src_ptr, ptrdiff_t /* src_stride */, ...@@ -74,16 +74,16 @@ void ScaleRowDown4_NEON(const uint8* src_ptr, ptrdiff_t /* src_stride */,
asm volatile ( asm volatile (
"1: \n" "1: \n"
"vld2.u8 {d0, d1}, [%0]! \n" "vld2.u8 {d0, d1}, [%0]! \n"
"subs %2, #4 \n"
"vtrn.u8 d1, d0 \n" "vtrn.u8 d1, d0 \n"
"vshrn.u16 d0, q0, #8 \n" "vshrn.u16 d0, q0, #8 \n"
"vst1.u32 {d0[1]}, [%1]! \n" "vst1.u32 {d0[1]}, [%1]! \n"
"subs %2, #4 \n"
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1 "+r"(dst_ptr), // %1
"+r"(dst_width) // %2 "+r"(dst_width) // %2
: :
: "q0", "q1", "memory", "cc" : "q0", "q1", "memory", "cc"
); );
} }
...@@ -98,6 +98,7 @@ void ScaleRowDown4Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride, ...@@ -98,6 +98,7 @@ void ScaleRowDown4Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
"vld1.u8 {q1}, [r4]! \n" "vld1.u8 {q1}, [r4]! \n"
"vld1.u8 {q2}, [r5]! \n" "vld1.u8 {q2}, [r5]! \n"
"vld1.u8 {q3}, [%3]! \n" "vld1.u8 {q3}, [%3]! \n"
"subs %2, #4 \n"
"vpaddl.u8 q0, q0 \n" "vpaddl.u8 q0, q0 \n"
"vpadal.u8 q0, q1 \n" "vpadal.u8 q0, q1 \n"
"vpadal.u8 q0, q2 \n" "vpadal.u8 q0, q2 \n"
...@@ -106,13 +107,12 @@ void ScaleRowDown4Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride, ...@@ -106,13 +107,12 @@ void ScaleRowDown4Int_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
"vrshrn.u32 d0, q0, #4 \n" // divide by 16 w/rounding "vrshrn.u32 d0, q0, #4 \n" // divide by 16 w/rounding
"vmovn.u16 d0, q0 \n" "vmovn.u16 d0, q0 \n"
"vst1.u32 {d0[0]}, [%1]! \n" "vst1.u32 {d0[0]}, [%1]! \n"
"subs %2, #4 \n"
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1 "+r"(dst_ptr), // %1
"+r"(dst_width) // %2 "+r"(dst_width) // %2
: "r"(src_stride) // %3 : "r"(src_stride) // %3
: "r4", "r5", "q0", "q1", "q2", "q3", "memory", "cc" : "r4", "r5", "q0", "q1", "q2", "q3", "memory", "cc"
); );
} }
...@@ -125,15 +125,15 @@ void ScaleRowDown34_NEON(const uint8* src_ptr, ...@@ -125,15 +125,15 @@ void ScaleRowDown34_NEON(const uint8* src_ptr,
asm volatile ( asm volatile (
"1: \n" "1: \n"
"vld4.u8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 "vld4.u8 {d0, d1, d2, d3}, [%0]! \n" // src line 0
"subs %2, #24 \n"
"vmov d2, d3 \n" // order d0, d1, d2 "vmov d2, d3 \n" // order d0, d1, d2
"vst3.u8 {d0, d1, d2}, [%1]! \n" "vst3.u8 {d0, d1, d2}, [%1]! \n"
"subs %2, #24 \n"
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1 "+r"(dst_ptr), // %1
"+r"(dst_width) // %2 "+r"(dst_width) // %2
: :
: "d0", "d1", "d2", "d3", "memory", "cc" : "d0", "d1", "d2", "d3", "memory", "cc"
); );
} }
...@@ -146,6 +146,7 @@ void ScaleRowDown34_0_Int_NEON(const uint8* src_ptr, ...@@ -146,6 +146,7 @@ void ScaleRowDown34_0_Int_NEON(const uint8* src_ptr,
"1: \n" "1: \n"
"vld4.u8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 "vld4.u8 {d0, d1, d2, d3}, [%0]! \n" // src line 0
"vld4.u8 {d4, d5, d6, d7}, [%3]! \n" // src line 1 "vld4.u8 {d4, d5, d6, d7}, [%3]! \n" // src line 1
"subs %2, #24 \n"
// filter src line 0 with src line 1 // filter src line 0 with src line 1
// expand chars to shorts to allow for room // expand chars to shorts to allow for room
...@@ -182,14 +183,13 @@ void ScaleRowDown34_0_Int_NEON(const uint8* src_ptr, ...@@ -182,14 +183,13 @@ void ScaleRowDown34_0_Int_NEON(const uint8* src_ptr,
"vst3.u8 {d0, d1, d2}, [%1]! \n" "vst3.u8 {d0, d1, d2}, [%1]! \n"
"subs %2, #24 \n"
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1 "+r"(dst_ptr), // %1
"+r"(dst_width), // %2 "+r"(dst_width), // %2
"+r"(src_stride) // %3 "+r"(src_stride) // %3
: :
: "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "d24", "memory", "cc" : "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "d24", "memory", "cc"
); );
} }
...@@ -202,7 +202,7 @@ void ScaleRowDown34_1_Int_NEON(const uint8* src_ptr, ...@@ -202,7 +202,7 @@ void ScaleRowDown34_1_Int_NEON(const uint8* src_ptr,
"1: \n" "1: \n"
"vld4.u8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 "vld4.u8 {d0, d1, d2, d3}, [%0]! \n" // src line 0
"vld4.u8 {d4, d5, d6, d7}, [%3]! \n" // src line 1 "vld4.u8 {d4, d5, d6, d7}, [%3]! \n" // src line 1
"subs %2, #24 \n"
// average src line 0 with src line 1 // average src line 0 with src line 1
"vrhadd.u8 q0, q0, q2 \n" "vrhadd.u8 q0, q0, q2 \n"
"vrhadd.u8 q1, q1, q3 \n" "vrhadd.u8 q1, q1, q3 \n"
...@@ -221,15 +221,13 @@ void ScaleRowDown34_1_Int_NEON(const uint8* src_ptr, ...@@ -221,15 +221,13 @@ void ScaleRowDown34_1_Int_NEON(const uint8* src_ptr,
"vqrshrn.u16 d2, q3, #2 \n" "vqrshrn.u16 d2, q3, #2 \n"
"vst3.u8 {d0, d1, d2}, [%1]! \n" "vst3.u8 {d0, d1, d2}, [%1]! \n"
"subs %2, #24 \n"
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1 "+r"(dst_ptr), // %1
"+r"(dst_width), // %2 "+r"(dst_width), // %2
"+r"(src_stride) // %3 "+r"(src_stride) // %3
: :
: "r4", "q0", "q1", "q2", "q3", "d24", "memory", "cc" : "r4", "q0", "q1", "q2", "q3", "d24", "memory", "cc"
); );
} }
...@@ -253,17 +251,17 @@ void ScaleRowDown38_NEON(const uint8* src_ptr, ...@@ -253,17 +251,17 @@ void ScaleRowDown38_NEON(const uint8* src_ptr,
"vld1.u8 {q3}, [%3] \n" "vld1.u8 {q3}, [%3] \n"
"1: \n" "1: \n"
"vld1.u8 {d0, d1, d2, d3}, [%0]! \n" "vld1.u8 {d0, d1, d2, d3}, [%0]! \n"
"subs %2, #12 \n"
"vtbl.u8 d4, {d0, d1, d2, d3}, d6 \n" "vtbl.u8 d4, {d0, d1, d2, d3}, d6 \n"
"vtbl.u8 d5, {d0, d1, d2, d3}, d7 \n" "vtbl.u8 d5, {d0, d1, d2, d3}, d7 \n"
"vst1.u8 {d4}, [%1]! \n" "vst1.u8 {d4}, [%1]! \n"
"vst1.u32 {d5[0]}, [%1]! \n" "vst1.u32 {d5[0]}, [%1]! \n"
"subs %2, #12 \n"
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1 "+r"(dst_ptr), // %1
"+r"(dst_width) // %2 "+r"(dst_width) // %2
: "r"(&kShuf38) // %3 : "r"(&kShuf38) // %3
: "d0", "d1", "d2", "d3", "d4", "d5", "memory", "cc" : "d0", "d1", "d2", "d3", "d4", "d5", "memory", "cc"
); );
} }
...@@ -286,6 +284,7 @@ void OMITFP ScaleRowDown38_3_Int_NEON(const uint8* src_ptr, ...@@ -286,6 +284,7 @@ void OMITFP ScaleRowDown38_3_Int_NEON(const uint8* src_ptr,
"vld4.u8 {d0, d1, d2, d3}, [%0]! \n" "vld4.u8 {d0, d1, d2, d3}, [%0]! \n"
"vld4.u8 {d4, d5, d6, d7}, [%3]! \n" "vld4.u8 {d4, d5, d6, d7}, [%3]! \n"
"vld4.u8 {d16, d17, d18, d19}, [r4]! \n" "vld4.u8 {d16, d17, d18, d19}, [r4]! \n"
"subs %2, #12 \n"
// Shuffle the input data around to get align the data // Shuffle the input data around to get align the data
// so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7
...@@ -363,17 +362,16 @@ void OMITFP ScaleRowDown38_3_Int_NEON(const uint8* src_ptr, ...@@ -363,17 +362,16 @@ void OMITFP ScaleRowDown38_3_Int_NEON(const uint8* src_ptr,
"vst1.u8 {d3}, [%1]! \n" "vst1.u8 {d3}, [%1]! \n"
"vst1.u32 {d4[0]}, [%1]! \n" "vst1.u32 {d4[0]}, [%1]! \n"
"subs %2, #12 \n"
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1 "+r"(dst_ptr), // %1
"+r"(dst_width), // %2 "+r"(dst_width), // %2
"+r"(src_stride) // %3 "+r"(src_stride) // %3
: "r"(&kMult38_Div6), // %4 : "r"(&kMult38_Div6), // %4
"r"(&kShuf38_2), // %5 "r"(&kShuf38_2), // %5
"r"(&kMult38_Div9) // %6 "r"(&kMult38_Div9) // %6
: "r4", "q0", "q1", "q2", "q3", "q8", "q9", : "r4", "q0", "q1", "q2", "q3", "q8", "q9",
"q13", "q14", "q15", "memory", "cc" "q13", "q14", "q15", "memory", "cc"
); );
} }
...@@ -393,6 +391,7 @@ void ScaleRowDown38_2_Int_NEON(const uint8* src_ptr, ...@@ -393,6 +391,7 @@ void ScaleRowDown38_2_Int_NEON(const uint8* src_ptr,
// d3 = 30 70 31 71 32 72 33 73 // d3 = 30 70 31 71 32 72 33 73
"vld4.u8 {d0, d1, d2, d3}, [%0]! \n" "vld4.u8 {d0, d1, d2, d3}, [%0]! \n"
"vld4.u8 {d4, d5, d6, d7}, [%3]! \n" "vld4.u8 {d4, d5, d6, d7}, [%3]! \n"
"subs %2, #12 \n"
// Shuffle the input data around to get align the data // Shuffle the input data around to get align the data
// so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7
...@@ -459,15 +458,14 @@ void ScaleRowDown38_2_Int_NEON(const uint8* src_ptr, ...@@ -459,15 +458,14 @@ void ScaleRowDown38_2_Int_NEON(const uint8* src_ptr,
"vst1.u8 {d3}, [%1]! \n" "vst1.u8 {d3}, [%1]! \n"
"vst1.u32 {d4[0]}, [%1]! \n" "vst1.u32 {d4[0]}, [%1]! \n"
"subs %2, #12 \n"
"bgt 1b \n" "bgt 1b \n"
: "+r"(src_ptr), // %0 : "+r"(src_ptr), // %0
"+r"(dst_ptr), // %1 "+r"(dst_ptr), // %1
"+r"(dst_width), // %2 "+r"(dst_width), // %2
"+r"(src_stride) // %3 "+r"(src_stride) // %3
: "r"(&kMult38_Div6), // %4 : "r"(&kMult38_Div6), // %4
"r"(&kShuf38_2) // %5 "r"(&kShuf38_2) // %5
: "q0", "q1", "q2", "q3", "q13", "q14", "memory", "cc" : "q0", "q1", "q2", "q3", "q13", "q14", "memory", "cc"
); );
} }
...@@ -545,13 +543,13 @@ void ScaleFilterRows_NEON(uint8* dst_ptr, ...@@ -545,13 +543,13 @@ void ScaleFilterRows_NEON(uint8* dst_ptr,
"99: \n" "99: \n"
"vst1.u8 {d1[7]}, [%0] \n" "vst1.u8 {d1[7]}, [%0] \n"
: "+r"(dst_ptr), // %0 : "+r"(dst_ptr), // %0
"+r"(src_ptr), // %1 "+r"(src_ptr), // %1
"+r"(src_stride), // %2 "+r"(src_stride), // %2
"+r"(dst_width), // %3 "+r"(dst_width), // %3
"+r"(source_y_fraction) // %4 "+r"(source_y_fraction) // %4
: :
: "q0", "q1", "d4", "d5", "q13", "q14", "memory", "cc" : "q0", "q1", "d4", "d5", "q13", "q14", "memory", "cc"
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment