Commit 78c58ab8 authored by Frank Barchard's avatar Frank Barchard

Add MSA optimized ARGB4444ToI420 and ARGB4444ToARGB functions

R=fbarchard@google.com
BUG=libyuv:634

Performance gains : (Auto-vectorized C vs MSA SIMD)

ARGB4444ToYRow_MSA        : ~3.0x
ARGB4444ToUVRow_MSA       : ~1.8x
ARGB4444ToARGBRow_MSA     : ~3.4x

ARGB4444ToYRow_Any_MSA    : ~2.8x
ARGB4444ToUVRow_Any_MSA   : ~1.7x
ARGB4444ToARGBRow_Any_MSA : ~3.2x

Review URL: https://codereview.chromium.org/2421843002 .
parent e16e3a62
......@@ -374,6 +374,9 @@ extern "C" {
#define HAS_YUY2TOUV422ROW_MSA
#define HAS_YUY2TOUVROW_MSA
#define HAS_YUY2TOYROW_MSA
#define HAS_ARGB4444TOARGBROW_MSA
#define HAS_ARGBTOYROW_MSA
#define HAS_ARGBTOUVROW_MSA
#endif
......@@ -657,10 +660,13 @@ void RGB24ToYRow_SSSE3(const uint8* src_rgb24, uint8* dst_y, int width);
void RAWToYRow_SSSE3(const uint8* src_raw, uint8* dst_y, int width);
void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width);
void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width);
void ARGBToYRow_MSA(const uint8* src_argb, uint8* dst_y, int width);
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width);
void ARGBToUVRow_NEON(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVRow_MSA(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVJRow_NEON(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void BGRAToUVRow_NEON(const uint8* src_bgra, int src_stride_bgra,
......@@ -716,6 +722,7 @@ void ARGB1555ToYRow_Any_NEON(const uint8* src_argb1555, uint8* dst_y,
int width);
void ARGB4444ToYRow_Any_NEON(const uint8* src_argb4444, uint8* dst_y,
int width);
void ARGBToYRow_Any_MSA(const uint8* src_argb, uint8* dst_y, int width);
void ARGBToUVRow_AVX2(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
......@@ -749,6 +756,8 @@ void ARGBToUV444Row_Any_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width);
void ARGBToUVRow_Any_NEON(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVRow_Any_MSA(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void ARGBToUVJRow_Any_NEON(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width);
void BGRAToUVRow_Any_NEON(const uint8* src_bgra, int src_stride_bgra,
......@@ -954,6 +963,8 @@ void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, uint8* dst_argb,
int width);
void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, uint8* dst_argb,
int width);
void ARGB4444ToARGBRow_MSA(const uint8* src_argb4444, uint8* dst_argb,
int width);
void RGB24ToARGBRow_C(const uint8* src_rgb24, uint8* dst_argb, int width);
void RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int width);
void RAWToRGB24Row_C(const uint8* src_raw, uint8* dst_rgb24, int width);
......@@ -988,6 +999,8 @@ void ARGB1555ToARGBRow_Any_NEON(const uint8* src_argb1555, uint8* dst_argb,
int width);
void ARGB4444ToARGBRow_Any_NEON(const uint8* src_argb4444, uint8* dst_argb,
int width);
void ARGB4444ToARGBRow_Any_MSA(const uint8* src_argb4444, uint8* dst_argb,
int width);
void ARGBToRGB24Row_SSSE3(const uint8* src_argb, uint8* dst_rgb, int width);
void ARGBToRAWRow_SSSE3(const uint8* src_argb, uint8* dst_rgb, int width);
......
......@@ -532,6 +532,22 @@ int ARGBToI420(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
}
}
#endif
#if defined(HAS_ARGBTOUVROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToUVRow = ARGBToUVRow_Any_MSA;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_MSA;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width);
......@@ -1283,6 +1299,14 @@ int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444,
}
}
#endif
#if defined(HAS_ARGB4444TOARGBROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGB4444ToARGBRow = ARGB4444ToARGBRow_MSA;
}
}
#endif
#if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
......@@ -1302,6 +1326,18 @@ int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444,
ARGBToYRow = ARGBToYRow_AVX2;
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToUVRow = ARGBToUVRow_Any_MSA;
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_MSA;
}
}
}
#endif
{
// Allocate 2 rows of ARGB.
......
......@@ -1075,6 +1075,14 @@ int ARGB4444ToARGB(const uint8* src_argb4444, int src_stride_argb4444,
}
}
#endif
#if defined(HAS_ARGB4444TOARGBROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGB4444ToARGBRow = ARGB4444ToARGBRow_MSA;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGB4444ToARGBRow(src_argb4444, dst_argb, width);
......
......@@ -89,6 +89,14 @@ int ARGBToI444(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToUV444Row(src_argb, dst_u, dst_v, width);
......@@ -169,6 +177,22 @@ int ARGBToI422(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
}
}
#endif
#if defined(HAS_ARGBTOUVROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToUVRow = ARGBToUVRow_Any_MSA;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_MSA;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
......@@ -241,6 +265,22 @@ int ARGBToNV12(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
}
}
#endif
#if defined(HAS_ARGBTOUVROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToUVRow = ARGBToUVRow_Any_MSA;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_MSA;
}
}
#endif
#if defined(HAS_MERGEUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
MergeUVRow_ = MergeUVRow_Any_SSE2;
......@@ -350,6 +390,22 @@ int ARGBToNV21(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
}
}
#endif
#if defined(HAS_ARGBTOUVROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToUVRow = ARGBToUVRow_Any_MSA;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_MSA;
}
}
#endif
#if defined(HAS_MERGEUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
MergeUVRow_ = MergeUVRow_Any_SSE2;
......@@ -464,6 +520,22 @@ int ARGBToYUY2(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
}
}
#endif
#if defined(HAS_ARGBTOUVROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToUVRow = ARGBToUVRow_Any_MSA;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_MSA;
}
}
#endif
#if defined(HAS_I422TOYUY2ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
I422ToYUY2Row = I422ToYUY2Row_Any_SSE2;
......@@ -574,6 +646,22 @@ int ARGBToUYVY(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
}
}
#endif
#if defined(HAS_ARGBTOUVROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToUVRow = ARGBToUVRow_Any_MSA;
if (IS_ALIGNED(width, 32)) {
ARGBToUVRow = ARGBToUVRow_MSA;
}
}
#endif
#if defined(HAS_I422TOUYVYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
I422ToUYVYRow = I422ToUYVYRow_Any_SSE2;
......@@ -665,6 +753,14 @@ int ARGBToI400(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBTOYROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBToYRow = ARGBToYRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBToYRow = ARGBToYRow_MSA;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToYRow(src_argb, dst_y, width);
......
......@@ -402,6 +402,9 @@ ANY11(ARGBToYJRow_Any_SSSE3, ARGBToYJRow_SSSE3, 0, 4, 1, 15)
#ifdef HAS_ARGBTOYROW_NEON
ANY11(ARGBToYRow_Any_NEON, ARGBToYRow_NEON, 0, 4, 1, 7)
#endif
#ifdef HAS_ARGBTOYROW_MSA
ANY11(ARGBToYRow_Any_MSA, ARGBToYRow_MSA, 0, 4, 1, 15)
#endif
#ifdef HAS_ARGBTOYJROW_NEON
ANY11(ARGBToYJRow_Any_NEON, ARGBToYJRow_NEON, 0, 4, 1, 7)
#endif
......@@ -456,6 +459,9 @@ ANY11(ARGB1555ToARGBRow_Any_NEON, ARGB1555ToARGBRow_NEON, 0, 2, 4, 7)
#ifdef HAS_ARGB4444TOARGBROW_NEON
ANY11(ARGB4444ToARGBRow_Any_NEON, ARGB4444ToARGBRow_NEON, 0, 2, 4, 7)
#endif
#ifdef HAS_ARGB4444TOARGBROW_MSA
ANY11(ARGB4444ToARGBRow_Any_MSA, ARGB4444ToARGBRow_MSA, 0, 2, 4, 15)
#endif
#ifdef HAS_ARGBATTENUATEROW_SSSE3
ANY11(ARGBAttenuateRow_Any_SSSE3, ARGBAttenuateRow_SSSE3, 0, 4, 4, 3)
#endif
......@@ -807,6 +813,9 @@ ANY12S(UYVYToUVRow_Any_SSE2, UYVYToUVRow_SSE2, 1, 4, 15)
#ifdef HAS_ARGBTOUVROW_NEON
ANY12S(ARGBToUVRow_Any_NEON, ARGBToUVRow_NEON, 0, 4, 15)
#endif
#ifdef HAS_ARGBTOUVROW_MSA
ANY12S(ARGBToUVRow_Any_MSA, ARGBToUVRow_MSA, 0, 4, 31)
#endif
#ifdef HAS_ARGBTOUVJROW_NEON
ANY12S(ARGBToUVJRow_Any_NEON, ARGBToUVJRow_NEON, 0, 4, 15)
#endif
......
......@@ -221,6 +221,195 @@ void UYVYToUV422Row_MSA(const uint8* src_uyvy, uint8* dst_u, uint8* dst_v,
}
}
void ARGBToYRow_MSA(const uint8* src_argb0, uint8* dst_y, int width) {
int x;
v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, dst0;
v8u16 reg0, reg1, reg2, reg3, reg4, reg5;
v16i8 zero = { 0 };
v8u16 const_0x19 = (v8u16) __msa_ldi_h(0x19);
v8u16 const_0x81 = (v8u16) __msa_ldi_h(0x81);
v8u16 const_0x42 = (v8u16) __msa_ldi_h(0x42);
v8u16 const_0x1080 = (v8u16) __msa_fill_h(0x1080);
for (x = 0; x < width; x += 16) {
src0 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 0);
src1 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 16);
src2 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 32);
src3 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 48);
vec0 = (v16u8) __msa_pckev_b((v16i8) src1, (v16i8) src0);
vec1 = (v16u8) __msa_pckev_b((v16i8) src3, (v16i8) src2);
vec2 = (v16u8) __msa_pckod_b((v16i8) src1, (v16i8) src0);
vec3 = (v16u8) __msa_pckod_b((v16i8) src3, (v16i8) src2);
reg0 = (v8u16) __msa_ilvev_b(zero, (v16i8) vec0);
reg1 = (v8u16) __msa_ilvev_b(zero, (v16i8) vec1);
reg2 = (v8u16) __msa_ilvev_b(zero, (v16i8) vec2);
reg3 = (v8u16) __msa_ilvev_b(zero, (v16i8) vec3);
reg4 = (v8u16) __msa_ilvod_b(zero, (v16i8) vec0);
reg5 = (v8u16) __msa_ilvod_b(zero, (v16i8) vec1);
reg0 *= const_0x19;
reg1 *= const_0x19;
reg2 *= const_0x81;
reg3 *= const_0x81;
reg4 *= const_0x42;
reg5 *= const_0x42;
reg0 += reg2;
reg1 += reg3;
reg0 += reg4;
reg1 += reg5;
reg0 += const_0x1080;
reg1 += const_0x1080;
reg0 = (v8u16) __msa_srai_h((v8i16) reg0, 8);
reg1 = (v8u16) __msa_srai_h((v8i16) reg1, 8);
dst0 = (v16u8) __msa_pckev_b((v16i8) reg1, (v16i8) reg0);
ST_UB(dst0, dst_y);
src_argb0 += 64;
dst_y += 16;
}
}
void ARGBToUVRow_MSA(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) {
int x;
const uint8* src_argb0_next = src_argb0 + src_stride_argb;
v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9;
v8u16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9;
v16u8 dst0, dst1;
v8u16 const_0x70 = (v8u16) __msa_ldi_h(0x70);
v8u16 const_0x4A = (v8u16) __msa_ldi_h(0x4A);
v8u16 const_0x26 = (v8u16) __msa_ldi_h(0x26);
v8u16 const_0x5E = (v8u16) __msa_ldi_h(0x5E);
v8u16 const_0x12 = (v8u16) __msa_ldi_h(0x12);
v8u16 const_0x8080 = (v8u16) __msa_fill_h(0x8080);
for (x = 0; x < width; x += 32) {
src0 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 0);
src1 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 16);
src2 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 32);
src3 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 48);
src4 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 64);
src5 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 80);
src6 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 96);
src7 = (v16u8) __msa_ld_b((v16u8*) src_argb0, 112);
vec0 = (v16u8) __msa_pckev_b((v16i8) src1, (v16i8) src0);
vec1 = (v16u8) __msa_pckev_b((v16i8) src3, (v16i8) src2);
vec2 = (v16u8) __msa_pckev_b((v16i8) src5, (v16i8) src4);
vec3 = (v16u8) __msa_pckev_b((v16i8) src7, (v16i8) src6);
vec4 = (v16u8) __msa_pckod_b((v16i8) src1, (v16i8) src0);
vec5 = (v16u8) __msa_pckod_b((v16i8) src3, (v16i8) src2);
vec6 = (v16u8) __msa_pckod_b((v16i8) src5, (v16i8) src4);
vec7 = (v16u8) __msa_pckod_b((v16i8) src7, (v16i8) src6);
vec8 = (v16u8) __msa_pckev_b((v16i8) vec1, (v16i8) vec0);
vec9 = (v16u8) __msa_pckev_b((v16i8) vec3, (v16i8) vec2);
vec4 = (v16u8) __msa_pckev_b((v16i8) vec5, (v16i8) vec4);
vec5 = (v16u8) __msa_pckev_b((v16i8) vec7, (v16i8) vec6);
vec0 = (v16u8) __msa_pckod_b((v16i8) vec1, (v16i8) vec0);
vec1 = (v16u8) __msa_pckod_b((v16i8) vec3, (v16i8) vec2);
reg0 = __msa_hadd_u_h(vec8, vec8);
reg1 = __msa_hadd_u_h(vec9, vec9);
reg2 = __msa_hadd_u_h(vec4, vec4);
reg3 = __msa_hadd_u_h(vec5, vec5);
reg4 = __msa_hadd_u_h(vec0, vec0);
reg5 = __msa_hadd_u_h(vec1, vec1);
src0 = (v16u8) __msa_ld_b((v16u8*) src_argb0_next, 0);
src1 = (v16u8) __msa_ld_b((v16u8*) src_argb0_next, 16);
src2 = (v16u8) __msa_ld_b((v16u8*) src_argb0_next, 32);
src3 = (v16u8) __msa_ld_b((v16u8*) src_argb0_next, 48);
src4 = (v16u8) __msa_ld_b((v16u8*) src_argb0_next, 64);
src5 = (v16u8) __msa_ld_b((v16u8*) src_argb0_next, 80);
src6 = (v16u8) __msa_ld_b((v16u8*) src_argb0_next, 96);
src7 = (v16u8) __msa_ld_b((v16u8*) src_argb0_next, 112);
vec0 = (v16u8) __msa_pckev_b((v16i8) src1, (v16i8) src0);
vec1 = (v16u8) __msa_pckev_b((v16i8) src3, (v16i8) src2);
vec2 = (v16u8) __msa_pckev_b((v16i8) src5, (v16i8) src4);
vec3 = (v16u8) __msa_pckev_b((v16i8) src7, (v16i8) src6);
vec4 = (v16u8) __msa_pckod_b((v16i8) src1, (v16i8) src0);
vec5 = (v16u8) __msa_pckod_b((v16i8) src3, (v16i8) src2);
vec6 = (v16u8) __msa_pckod_b((v16i8) src5, (v16i8) src4);
vec7 = (v16u8) __msa_pckod_b((v16i8) src7, (v16i8) src6);
vec8 = (v16u8) __msa_pckev_b((v16i8) vec1, (v16i8) vec0);
vec9 = (v16u8) __msa_pckev_b((v16i8) vec3, (v16i8) vec2);
vec4 = (v16u8) __msa_pckev_b((v16i8) vec5, (v16i8) vec4);
vec5 = (v16u8) __msa_pckev_b((v16i8) vec7, (v16i8) vec6);
vec0 = (v16u8) __msa_pckod_b((v16i8) vec1, (v16i8) vec0);
vec1 = (v16u8) __msa_pckod_b((v16i8) vec3, (v16i8) vec2);
reg0 += __msa_hadd_u_h(vec8, vec8);
reg1 += __msa_hadd_u_h(vec9, vec9);
reg2 += __msa_hadd_u_h(vec4, vec4);
reg3 += __msa_hadd_u_h(vec5, vec5);
reg4 += __msa_hadd_u_h(vec0, vec0);
reg5 += __msa_hadd_u_h(vec1, vec1);
reg0 = (v8u16) __msa_srai_h((v8i16) reg0, 2);
reg1 = (v8u16) __msa_srai_h((v8i16) reg1, 2);
reg2 = (v8u16) __msa_srai_h((v8i16) reg2, 2);
reg3 = (v8u16) __msa_srai_h((v8i16) reg3, 2);
reg4 = (v8u16) __msa_srai_h((v8i16) reg4, 2);
reg5 = (v8u16) __msa_srai_h((v8i16) reg5, 2);
reg6 = reg0 * const_0x70;
reg7 = reg1 * const_0x70;
reg8 = reg2 * const_0x4A;
reg9 = reg3 * const_0x4A;
reg6 += const_0x8080;
reg7 += const_0x8080;
reg8 += reg4 * const_0x26;
reg9 += reg5 * const_0x26;
reg0 *= const_0x12;
reg1 *= const_0x12;
reg2 *= const_0x5E;
reg3 *= const_0x5E;
reg4 *= const_0x70;
reg5 *= const_0x70;
reg2 += reg0;
reg3 += reg1;
reg4 += const_0x8080;
reg5 += const_0x8080;
reg6 -= reg8;
reg7 -= reg9;
reg4 -= reg2;
reg5 -= reg3;
reg6 = (v8u16) __msa_srai_h((v8i16) reg6, 8);
reg7 = (v8u16) __msa_srai_h((v8i16) reg7, 8);
reg4 = (v8u16) __msa_srai_h((v8i16) reg4, 8);
reg5 = (v8u16) __msa_srai_h((v8i16) reg5, 8);
dst0 = (v16u8) __msa_pckev_b((v16i8) reg7, (v16i8) reg6);
dst1 = (v16u8) __msa_pckev_b((v16i8) reg5, (v16i8) reg4);
ST_UB(dst0, dst_u);
ST_UB(dst1, dst_v);
src_argb0 += 128;
src_argb0_next += 128;
dst_u += 16;
dst_v += 16;
}
}
void ARGB4444ToARGBRow_MSA(const uint8* src_argb4444, uint8* dst_argb,
int width) {
int x;
v16u8 src0, src1;
v8u16 vec0, vec1, vec2, vec3;
v16u8 dst0, dst1, dst2, dst3;
for (x = 0; x < width; x += 16) {
src0 = (v16u8) __msa_ld_b((v16u8*) src_argb4444, 0);
src1 = (v16u8) __msa_ld_b((v16u8*) src_argb4444, 16);
vec0 = (v8u16) __msa_andi_b(src0, 0x0F);
vec1 = (v8u16) __msa_andi_b(src1, 0x0F);
vec2 = (v8u16) __msa_andi_b(src0, 0xF0);
vec3 = (v8u16) __msa_andi_b(src1, 0xF0);
vec0 |= (v8u16) __msa_slli_b((v16i8) vec0, 4);
vec1 |= (v8u16) __msa_slli_b((v16i8) vec1, 4);
vec2 |= (v8u16) __msa_srli_b((v16i8) vec2, 4);
vec3 |= (v8u16) __msa_srli_b((v16i8) vec3, 4);
dst0 = (v16u8) __msa_ilvr_b((v16i8) vec2, (v16i8) vec0);
dst1 = (v16u8) __msa_ilvl_b((v16i8) vec2, (v16i8) vec0);
dst2 = (v16u8) __msa_ilvr_b((v16i8) vec3, (v16i8) vec1);
dst3 = (v16u8) __msa_ilvl_b((v16i8) vec3, (v16i8) vec1);
ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16);
src_argb4444 += 32;
dst_argb += 64;
}
}
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
......
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