mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-11-09 14:49:57 +08:00
[libyuv] Consolidate LoongArch LSX and LASX inline asm into *_la.cc
Merge 64-bit LoongArch LSX and LASX inline assembly implementations from rotate_lsx.cc, rotate_lasx.cc, row_lsx.cc, row_lasx.cc, and scale_lsx.cc into compare_la.cc, rotate_la.cc, row_la.cc, and scale_la.cc, and remove the obsolete loongson_intrinsics.h header. Because all LSX and LASX kernels use inline assembly rather than compiler intrinsics, separate libyuv_lsx/libyuv_lasx build targets and -mlsx/-mlasx compiler flags are no longer required. Guard HAS_*_LSX and HAS_*_LASX macros with defined(__loongarch_lp64) so runtime CPU dispatch enables LASX and LSX without requiring global -mlasx/-mlsx flags, and wrap every function and helper in *_la.cc with its corresponding #ifdef HAS_* guard. Also fix bugs found during LoongArch verification: - Replace illegal vldi/xvldi -1 immediate encodings (si13 = 0x1fff, which raises SIGILL at runtime) in ARGBDetectRow_LSX and ARGBDetectRow_LASX with vseqi.b/xvseqi.b -1. - Set simd_size to 16 for LSX and 32 for LASX in ComputeHammingDistance and ComputeSumSquareError. - Remove orphaned dead BGRAToUVRow, ABGRToUVRow, RGBAToUVRow, and XRGBToUVHelper functions in row_la.cc. - Remove dead alpha shifts in ARGB1555ToYRow/UVRow_LSX/LASX and hoist channel masks out of the loop in RGB565ToUVRow/ARGB1555ToUVRow. Compare SIMD ISA per *_C: ------------------------------------------------------------------------ C Function LSX LASX ------------------------------------------------------------------------ ARGBDetectRow_C LSX LASX HammingDistance_C LSX LASX HashDjb2_C LSX LASX Ssim4x4Row_C LSX LASX SsimWindowRow_C LSX LASX SumSquareError_C LSX LASX ------------------------------------------------------------------------ Compare: 6 (100%) 6 (100%) 6 (100%) ------------------------------------------------------------------------ Convert SIMD ISA per *_C: ------------------------------------------------------------------------ C Function LSX LASX ------------------------------------------------------------------------ AB64ToARGBRow_C - - ABGRToAR30Row_C - - AR30ToAB30Row_C - - AR30ToABGRRow_C - - AR30ToARGBRow_C - - AR64ShuffleRow_C LSX LASX AR64ToAB64Row_C LSX LASX AR64ToARGBRow_C - - ARGB1555ToARGBRow_C LSX LASX ARGB1555ToUVMatrixRow_C - - ARGB1555ToUVRow_C LSX LASX ARGB1555ToYMatrixRow_C - - ARGB1555ToYRow_C LSX LASX ARGB4444ToARGBRow_C LSX LASX ARGB4444ToUVMatrixRow_C - - ARGB4444ToUVRow_C - - ARGB4444ToYMatrixRow_C - - ARGB4444ToYRow_C - - ARGBAddRow_C LSX LASX ARGBAffineRow_C - - ARGBAlphaBlendRow_C LSX LASX ARGBAttenuateRow_C LSX LASX ARGBBlendRow_C LSX LASX ARGBColorMatrixRow_C LSX LASX ARGBColorTableRow_C - - ARGBCopyAlphaRow_C - - ARGBCopyYToAlphaRow_C - - ARGBExtractAlphaRow_C LSX LASX ARGBGrayRow_C LSX LASX ARGBLumaColorTableRow_C - - ARGBMirrorRow_C LSX LASX ARGBMultiplyRow_C LSX LASX ARGBOrRow_C LSX LASX ARGBPolynomialRow_C - - ARGBQuantizeRow_C LSX LASX ARGBSepiaRow_C LSX LASX ARGBSetRow_C LSX LASX ARGBShadeRow_C LSX LASX ARGBShuffleRow_C LSX LASX ARGBSubtractRow_C LSX LASX ARGBToAB64Row_C - - ARGBToABGRRow_C LSX LASX ARGBToAR30Row_C - - ARGBToAR64Row_C - - ARGBToARGB1555Row_C LSX LASX ARGBToARGB4444Row_C LSX LASX ARGBToBGRARow_C LSX LASX ARGBToRAWRow_C LSX LASX ARGBToRGB24Row_C LSX LASX ARGBToRGB565DitherRow_C LSX LASX ARGBToRGB565Row_C LSX LASX ARGBToRGBARow_C LSX LASX ARGBToUV444MatrixRow_C - - ARGBToUVMatrixRow_C - - ARGBToYMatrixRow_C LSX LASX ARGBUnattenuateRow_C - - AYUVToUVRow_C - - AYUVToVURow_C - - AYUVToYRow_C - - BlendPlaneRow_C - - ByteToFloatRow_C - - ComputeCumulativeSumRow_C - - Convert16To8Row_C - - Convert8To16Row_C - - Convert8To8Row_C - - CopyRow_16_C - - CopyRow_C LSX LASX CumulativeSumToAverageRow_C - - DetileRow_16_C - - DetileRow_C - - DetileSplitUVRow_C - - DetileToYUY2_C - - DivideRow_16_C - - GaussCol_C - - GaussCol_F32_C - - GaussRow_C - - GaussRow_F32_C - - HalfFloatRow_C LSX LASX HalfMergeUVRow_C - - HalfRow_16To8_C - - HalfRow_16_C - - HalfRow_C - - HalfWidthRow_16To8_C - - HalfWidthRow_16To8_Odd_C - - I210AlphaToARGBRow_C - - I210ToAR30Row_C - - I210ToARGBRow_C - - I212ToAR30Row_C - - I212ToARGBRow_C - - I400ToARGBRow_C LSX LASX I410AlphaToARGBRow_C - - I410ToAR30Row_C - - I410ToARGBRow_C - - I422AlphaToARGBRow_C LSX LASX I422ToAR30Row_C - - I422ToARGB1555Row_C LSX LASX I422ToARGB4444Row_C LSX LASX I422ToARGBRow_C LSX LASX I422ToRGB24Row_C LSX LASX I422ToRGB565Row_C LSX LASX I422ToRGBARow_C LSX LASX I422ToUYVYRow_C LSX LASX I422ToYUY2Row_C LSX LASX I444AlphaToARGBRow_C - - I444ToARGBRow_C LSX LASX I444ToRGB24Row_C - - InterpolateRow_16_C - - InterpolateRow_C LSX LASX J400ToARGBRow_C LSX LASX MergeAR64Row_C - - MergeARGB16To8Row_C - - MergeARGBRow_C - - MergeRGBRow_C - - MergeUVRow_16_C - - MergeUVRow_C LSX LASX MergeXR30Row_C - - MergeXR64Row_C - - MergeXRGB16To8Row_C - - MergeXRGBRow_C - - MirrorRow_16_C LSX LASX MirrorRow_C LSX LASX MirrorSplitUVRow_C LSX LASX MirrorUVRow_C LSX LASX MultiplyRow_16_C - - NV12ToARGBRow_C LSX LASX NV12ToRGB24Row_C - - NV12ToRGB565Row_C LSX LASX NV21ToARGBRow_C LSX LASX NV21ToRGB24Row_C - - NV21ToYUV24Row_C - - P210ToAR30Row_C - - P210ToARGBRow_C - - P410ToAR30Row_C - - P410ToARGBRow_C - - RAWToARGBRow_C LSX LASX RAWToRGB24Row_C LSX LASX RAWToRGBARow_C - - RGB24MirrorRow_C - - RGB24ToARGBRow_C LSX LASX RGB565ToARGBRow_C LSX LASX RGB565ToUVMatrixRow_C - - RGB565ToUVRow_C LSX LASX RGB565ToYMatrixRow_C - - RGB565ToYRow_C LSX LASX RGBAToARGBRow_C LSX LASX RGBColorTableRow_C - - RGBToUV444MatrixRow_C - - RGBToUVMatrixRow_C - - RGBToYMatrixRow_C LSX LASX ScaleMaxSamples_C - - ScaleSamples_C - - ScaleSumSamples_C - - SetRow_C LSX LASX SobelRow_C LSX LASX SobelToPlaneRow_C LSX LASX SobelXRow_C - - SobelXYRow_C LSX LASX SobelYRow_C - - SplitARGBRow_C - - SplitRGBRow_C - - SplitUVRow_16_C - - SplitUVRow_C LSX LASX SplitXRGBRow_C - - SwapUVRow_C - - UYVYToARGBRow_C LSX LASX UYVYToUV422Row_C LSX LASX UYVYToUVRow_C LSX LASX UYVYToYRow_C LSX LASX UnpackMT2T_C - - YUY2ToARGBRow_C LSX LASX YUY2ToNVUVRow_C - - YUY2ToUV422Row_C LSX LASX YUY2ToUVRow_C LSX LASX YUY2ToYRow_C LSX LASX ------------------------------------------------------------------------ Convert: 174 (100%) 76 (44%) 76 (44%) ------------------------------------------------------------------------ Rotate SIMD ISA per *_C: ------------------------------------------------------------------------ C Function LSX LASX ------------------------------------------------------------------------ TransposeUVWx16_C - LASX TransposeUVWx8_C LSX - TransposeWx16_C - LASX TransposeWx4_32_C LSX LASX TransposeWx8_16_C LSX LASX TransposeWx8_C LSX - TransposeWxH_32_C - - ------------------------------------------------------------------------ Rotate: 7 (100%) 4 (57%) 4 (57%) ------------------------------------------------------------------------ Scale SIMD ISA per *_C: ------------------------------------------------------------------------ C Function LSX LASX ------------------------------------------------------------------------ FixedDiv1_C - - FixedDiv_C - - ScaleARGBCols64_C - - ScaleARGBColsUp2_C - - ScaleARGBCols_C LSX - ScaleARGBFilterCols64_C - - ScaleARGBFilterCols_C LSX - ScaleARGBRowDown2Box_C LSX - ScaleARGBRowDown2Linear_C LSX - ScaleARGBRowDown2_C LSX - ScaleARGBRowDownEvenBox_C LSX - ScaleARGBRowDownEven_C LSX - ScaleAddCols0_C - - ScaleAddCols1_16_C - - ScaleAddCols1_C - - ScaleAddCols2_16_C - - ScaleAddCols2_C - - ScaleAddRow_16_C - - ScaleAddRow_C LSX - ScaleColsUp2_16_C - - ScaleColsUp2_C - - ScaleCols_16_C - - ScaleCols_C - - ScaleFilterCols64_16_C - - ScaleFilterCols64_C - - ScaleFilterCols_16_C - - ScaleFilterCols_C LSX - ScaleRowDown2Box_16_C - - ScaleRowDown2Box_C LSX - ScaleRowDown2Box_Odd_C - - ScaleRowDown2Linear_16_C - - ScaleRowDown2Linear_C LSX - ScaleRowDown2_16_C - - ScaleRowDown2_C LSX - ScaleRowDown34_0_Box_16_C - - ScaleRowDown34_0_Box_C LSX - ScaleRowDown34_16_C - - ScaleRowDown34_1_Box_16_C - - ScaleRowDown34_1_Box_C LSX - ScaleRowDown34_C LSX - ScaleRowDown38_16_C - - ScaleRowDown38_2_Box_16_C - - ScaleRowDown38_2_Box_C LSX - ScaleRowDown38_3_Box_16_C - - ScaleRowDown38_3_Box_C LSX - ScaleRowDown38_C LSX - ScaleRowDown4Box_16_C - - ScaleRowDown4Box_C LSX - ScaleRowDown4_16_C - - ScaleRowDown4_C LSX - ScaleRowUp2_Bilinear_16_Any_C - - ScaleRowUp2_Bilinear_16_C - - ScaleRowUp2_Bilinear_Any_C - - ScaleRowUp2_Bilinear_C - - ScaleRowUp2_Linear_16_Any_C - - ScaleRowUp2_Linear_16_C - - ScaleRowUp2_Linear_Any_C - - ScaleRowUp2_Linear_C - - ScaleUVAddCols1_16_C - - ScaleUVAddCols1_C - - ScaleUVAddCols2_16_C - - ScaleUVAddCols2_C - - ScaleUVAddCols3_16_C - - ScaleUVAddCols3_C LSX - ScaleUVCols64_16_C - - ScaleUVCols64_C - - ScaleUVColsUp2_16_C - - ScaleUVColsUp2_C - - ScaleUVCols_16_C - - ScaleUVCols_C - - ScaleUVFilterCols64_16_C - - ScaleUVFilterCols64_C - - ScaleUVFilterCols_16_C - - ScaleUVFilterCols_C - - ScaleUVRowDown2Box_16_C - - ScaleUVRowDown2Box_C - - ScaleUVRowDown2Linear_16_C - - ScaleUVRowDown2Linear_C - - ScaleUVRowDown2_16_C - - ScaleUVRowDown2_C - - ScaleUVRowDownEvenBox_16_C - - ScaleUVRowDownEvenBox_C - - ScaleUVRowDownEven_16_C - - ScaleUVRowDownEven_C - - ScaleUVRowUp2_Bilinear_16_Any_C - - ScaleUVRowUp2_Bilinear_16_C - - ScaleUVRowUp2_Bilinear_Any_C - - ScaleUVRowUp2_Bilinear_C - - ScaleUVRowUp2_Linear_16_Any_C - - ScaleUVRowUp2_Linear_16_C - - ScaleUVRowUp2_Linear_Any_C - - ScaleUVRowUp2_Linear_C - - ------------------------------------------------------------------------ Scale: 92 (100%) 21 (23%) 0 (0%) ------------------------------------------------------------------------ Test: qemu-loongarch64 -cpu la464 ./libyuv_unittest Bug: none Change-Id: I7990bc8c2524dc9434441b5379cf839012e73d5f Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8701144 Reviewed-by: richard winterton <rrwinterton@gmail.com> Commit-Queue: Frank Barchard <fbarchard@google.com>
This commit is contained in:
parent
d088b8f2bd
commit
c6700f48dd
@ -35,6 +35,7 @@ cc_library {
|
||||
"source/compare_common.cc",
|
||||
"source/compare_gcc.cc",
|
||||
"source/compare_hvx.cc",
|
||||
"source/compare_la.cc",
|
||||
"source/compare_neon.cc",
|
||||
"source/compare_neon64.cc",
|
||||
"source/convert.cc",
|
||||
@ -54,6 +55,7 @@ cc_library {
|
||||
"source/rotate_common.cc",
|
||||
"source/rotate_gcc.cc",
|
||||
"source/rotate_hvx.cc",
|
||||
"source/rotate_la.cc",
|
||||
"source/rotate_neon.cc",
|
||||
"source/rotate_neon64.cc",
|
||||
"source/rotate_rvv.cc",
|
||||
@ -63,6 +65,7 @@ cc_library {
|
||||
"source/row_common.cc",
|
||||
"source/row_gcc.cc",
|
||||
"source/row_hvx.cc",
|
||||
"source/row_la.cc",
|
||||
"source/row_neon.cc",
|
||||
"source/row_neon64.cc",
|
||||
"source/row_rvv.cc",
|
||||
@ -74,6 +77,7 @@ cc_library {
|
||||
"source/scale_common.cc",
|
||||
"source/scale_gcc.cc",
|
||||
"source/scale_hvx.cc",
|
||||
"source/scale_la.cc",
|
||||
"source/scale_neon.cc",
|
||||
"source/scale_neon64.cc",
|
||||
"source/scale_rgb.cc",
|
||||
|
||||
@ -13,6 +13,7 @@ LOCAL_SRC_FILES := \
|
||||
source/compare_common.cc \
|
||||
source/compare_gcc.cc \
|
||||
source/compare_hvx.cc \
|
||||
source/compare_la.cc \
|
||||
source/compare_neon.cc \
|
||||
source/compare_neon64.cc \
|
||||
source/compare_win.cc \
|
||||
@ -30,6 +31,7 @@ LOCAL_SRC_FILES := \
|
||||
source/rotate_common.cc \
|
||||
source/rotate_gcc.cc \
|
||||
source/rotate_hvx.cc \
|
||||
source/rotate_la.cc \
|
||||
source/rotate_neon.cc \
|
||||
source/rotate_neon64.cc \
|
||||
source/rotate_rvv.cc \
|
||||
@ -38,6 +40,7 @@ LOCAL_SRC_FILES := \
|
||||
source/row_common.cc \
|
||||
source/row_gcc.cc \
|
||||
source/row_hvx.cc \
|
||||
source/row_la.cc \
|
||||
source/row_neon.cc \
|
||||
source/row_neon64.cc \
|
||||
source/row_rvv.cc \
|
||||
@ -48,6 +51,7 @@ LOCAL_SRC_FILES := \
|
||||
source/scale_common.cc \
|
||||
source/scale_gcc.cc \
|
||||
source/scale_hvx.cc \
|
||||
source/scale_la.cc \
|
||||
source/scale_neon.cc \
|
||||
source/scale_neon64.cc \
|
||||
source/scale_rgb.cc \
|
||||
|
||||
52
BUILD.gn
52
BUILD.gn
@ -98,14 +98,6 @@ group("libyuv") {
|
||||
deps += [ ":libyuv_rvv" ]
|
||||
}
|
||||
|
||||
if (libyuv_use_lsx) {
|
||||
deps += [ ":libyuv_lsx" ]
|
||||
}
|
||||
|
||||
if (libyuv_use_lasx) {
|
||||
deps += [ ":libyuv_lasx" ]
|
||||
}
|
||||
|
||||
if (!is_ios && !libyuv_disable_jpeg) {
|
||||
# Make sure that clients of libyuv link with libjpeg. This can't go in
|
||||
# libyuv_internal because in Windows x64 builds that will generate a clang
|
||||
@ -129,7 +121,6 @@ static_library("libyuv_internal") {
|
||||
"include/libyuv/convert_from_argb.h",
|
||||
"include/libyuv/cpu_id.h",
|
||||
"include/libyuv/cpu_support.h",
|
||||
"include/libyuv/loongson_intrinsics.h",
|
||||
"include/libyuv/mjpeg_decoder.h",
|
||||
"include/libyuv/planar_functions.h",
|
||||
"include/libyuv/rotate.h",
|
||||
@ -150,6 +141,7 @@ static_library("libyuv_internal") {
|
||||
"source/compare_common.cc",
|
||||
"source/compare_gcc.cc",
|
||||
"source/compare_hvx.cc",
|
||||
"source/compare_la.cc",
|
||||
"source/compare_wasm.cc",
|
||||
"source/compare_win.cc",
|
||||
"source/convert.cc",
|
||||
@ -169,12 +161,14 @@ static_library("libyuv_internal") {
|
||||
"source/rotate_common.cc",
|
||||
"source/rotate_gcc.cc",
|
||||
"source/rotate_hvx.cc",
|
||||
"source/rotate_la.cc",
|
||||
"source/rotate_wasm.cc",
|
||||
"source/rotate_win.cc",
|
||||
"source/row_any.cc",
|
||||
"source/row_common.cc",
|
||||
"source/row_gcc.cc",
|
||||
"source/row_hvx.cc",
|
||||
"source/row_la.cc",
|
||||
"source/row_wasm.cc",
|
||||
"source/row_win.cc",
|
||||
"source/scale.cc",
|
||||
@ -183,6 +177,7 @@ static_library("libyuv_internal") {
|
||||
"source/scale_common.cc",
|
||||
"source/scale_gcc.cc",
|
||||
"source/scale_hvx.cc",
|
||||
"source/scale_la.cc",
|
||||
"source/scale_rgb.cc",
|
||||
"source/scale_uv.cc",
|
||||
"source/scale_wasm.cc",
|
||||
@ -328,45 +323,6 @@ if (libyuv_use_rvv && !libyuv_disable_rvv) {
|
||||
}
|
||||
}
|
||||
|
||||
if (libyuv_use_lsx) {
|
||||
static_library("libyuv_lsx") {
|
||||
sources = [
|
||||
# LSX Source Files
|
||||
"source/rotate_lsx.cc",
|
||||
"source/row_lsx.cc",
|
||||
"source/scale_lsx.cc",
|
||||
]
|
||||
|
||||
cflags_cc = [
|
||||
"-mlsx",
|
||||
"-Wno-c++11-narrowing",
|
||||
]
|
||||
|
||||
deps = [ ":libyuv_internal" ]
|
||||
|
||||
public_configs = [ ":libyuv_config" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (libyuv_use_lasx) {
|
||||
static_library("libyuv_lasx") {
|
||||
sources = [
|
||||
# LASX Source Files
|
||||
"source/rotate_lasx.cc",
|
||||
"source/row_lasx.cc",
|
||||
]
|
||||
|
||||
cflags_cc = [
|
||||
"-mlasx",
|
||||
"-Wno-c++11-narrowing",
|
||||
]
|
||||
|
||||
deps = [ ":libyuv_internal" ]
|
||||
|
||||
public_configs = [ ":libyuv_config" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (libyuv_include_tests) {
|
||||
config("libyuv_unittest_warnings_config") {
|
||||
if (!is_win) {
|
||||
|
||||
@ -25,6 +25,7 @@ set ( ly_common_source_files
|
||||
${ly_src_dir}/compare_common.cc
|
||||
${ly_src_dir}/compare_gcc.cc
|
||||
${ly_src_dir}/compare_hvx.cc
|
||||
${ly_src_dir}/compare_la.cc
|
||||
${ly_src_dir}/compare_wasm.cc
|
||||
${ly_src_dir}/compare_win.cc
|
||||
${ly_src_dir}/convert.cc
|
||||
@ -44,6 +45,7 @@ set ( ly_common_source_files
|
||||
${ly_src_dir}/rotate_common.cc
|
||||
${ly_src_dir}/rotate_gcc.cc
|
||||
${ly_src_dir}/rotate_hvx.cc
|
||||
${ly_src_dir}/rotate_la.cc
|
||||
${ly_src_dir}/rotate_rvv.cc
|
||||
${ly_src_dir}/rotate_wasm.cc
|
||||
${ly_src_dir}/rotate_win.cc
|
||||
@ -51,6 +53,7 @@ set ( ly_common_source_files
|
||||
${ly_src_dir}/row_common.cc
|
||||
${ly_src_dir}/row_gcc.cc
|
||||
${ly_src_dir}/row_hvx.cc
|
||||
${ly_src_dir}/row_la.cc
|
||||
${ly_src_dir}/row_rvv.cc
|
||||
${ly_src_dir}/row_wasm.cc
|
||||
${ly_src_dir}/row_win.cc
|
||||
@ -60,6 +63,7 @@ set ( ly_common_source_files
|
||||
${ly_src_dir}/scale_common.cc
|
||||
${ly_src_dir}/scale_gcc.cc
|
||||
${ly_src_dir}/scale_hvx.cc
|
||||
${ly_src_dir}/scale_la.cc
|
||||
${ly_src_dir}/scale_rgb.cc
|
||||
${ly_src_dir}/scale_rvv.cc
|
||||
${ly_src_dir}/scale_uv.cc
|
||||
@ -198,7 +202,6 @@ endif()
|
||||
|
||||
if(LOONGARCH64)
|
||||
include(CheckCXXSourceCompiles)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-narrowing")
|
||||
check_cxx_source_compiles("
|
||||
int main(int argc, char **argv) {
|
||||
__asm__ volatile (
|
||||
@ -213,23 +216,11 @@ if(LOONGARCH64)
|
||||
);
|
||||
return 0; }" SUPPORTS_LASX)
|
||||
|
||||
if(SUPPORTS_LSX)
|
||||
# These kernels use only LSX (128-bit) instructions and must not be
|
||||
# compiled with -mlasx, which would let the compiler emit 256-bit LASX
|
||||
# code (e.g. for stack-array copies) and crash on LSX-only CPUs.
|
||||
add_library(${ly_lib_name}_lsx OBJECT
|
||||
${ly_src_dir}/rotate_lsx.cc
|
||||
${ly_src_dir}/row_lsx.cc
|
||||
${ly_src_dir}/scale_lsx.cc)
|
||||
target_compile_options(${ly_lib_name}_lsx PRIVATE -mlsx)
|
||||
list(APPEND ly_lib_parts $<TARGET_OBJECTS:${ly_lib_name}_lsx>)
|
||||
if(NOT SUPPORTS_LSX)
|
||||
add_definitions(-DLIBYUV_DISABLE_LSX)
|
||||
endif()
|
||||
if(SUPPORTS_LASX)
|
||||
add_library(${ly_lib_name}_lasx OBJECT
|
||||
${ly_src_dir}/rotate_lasx.cc
|
||||
${ly_src_dir}/row_lasx.cc)
|
||||
target_compile_options(${ly_lib_name}_lasx PRIVATE -mlasx)
|
||||
list(APPEND ly_lib_parts $<TARGET_OBJECTS:${ly_lib_name}_lasx>)
|
||||
if(NOT SUPPORTS_LASX)
|
||||
add_definitions(-DLIBYUV_DISABLE_LASX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@ -43,7 +43,8 @@ and compiler compatibility.
|
||||
for SiFive X280.
|
||||
* **row_hvx.cc**: Qualcomm Hexagon Vector Extensions (HVX). Implemented using
|
||||
intrinsics.
|
||||
* **row_lsx.cc / row_lasx.cc**: Loongarch MIPS-like extensions.
|
||||
* **row_la.cc**: 64-bit LoongArch LSX and LASX extensions (written in inline
|
||||
assembly).
|
||||
|
||||
### Utility and Fallbacks
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: https://chromium.googlesource.com/libyuv/libyuv/
|
||||
Version: 1977
|
||||
Version: 1978
|
||||
Revision: DEPS
|
||||
License: BSD-3-Clause
|
||||
License File: LICENSE
|
||||
|
||||
@ -132,7 +132,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// The following are available for LoongArch LSX:
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_lp64)
|
||||
#define HAS_HAMMINGDISTANCE_LSX
|
||||
#define HAS_SUMSQUAREERROR_LSX
|
||||
#define HAS_HASHDJB2_LSX
|
||||
@ -142,7 +142,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// The following are available for LoongArch LASX:
|
||||
#if !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_asx)
|
||||
#if !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_lp64)
|
||||
#define HAS_HAMMINGDISTANCE_LASX
|
||||
#define HAS_SUMSQUAREERROR_LASX
|
||||
#define HAS_HASHDJB2_LASX
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The LibYuv Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_LIBYUV_LOONGSON_INTRINSICS_H_
|
||||
#define INCLUDE_LIBYUV_LOONGSON_INTRINSICS_H_
|
||||
|
||||
#endif // INCLUDE_LIBYUV_LOONGSON_INTRINSICS_H_
|
||||
@ -113,14 +113,14 @@ extern "C" {
|
||||
#define HAS_TRANSPOSEWXH_32_SME
|
||||
#endif
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_lp64)
|
||||
#define HAS_TRANSPOSEWX8_LSX
|
||||
#define HAS_TRANSPOSEUVWX8_LSX
|
||||
#define HAS_TRANSPOSEWX8_16_LSX
|
||||
#define HAS_TRANSPOSEWX4_32_LSX
|
||||
#endif
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_asx)
|
||||
#if !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_lp64)
|
||||
#define HAS_TRANSPOSEWX16_LASX
|
||||
#define HAS_TRANSPOSEUVWX16_LASX
|
||||
#define HAS_TRANSPOSEWX16_16_LASX
|
||||
|
||||
@ -1027,7 +1027,7 @@ extern "C" {
|
||||
#define HAS_SCALESUMSAMPLES_NEON
|
||||
#endif
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_lp64)
|
||||
#define HAS_ARGB1555TOARGBROW_LSX
|
||||
#define HAS_ARGB1555TOUVROW_LSX
|
||||
#define HAS_ARGB1555TOYROW_LSX
|
||||
@ -1039,38 +1039,41 @@ extern "C" {
|
||||
#define HAS_ARGBCOLORMATRIXROW_LSX
|
||||
#define HAS_ARGBEXTRACTALPHAROW_LSX
|
||||
#define HAS_ARGBGRAYROW_LSX
|
||||
#define HAS_ARGBMIRRORROW_LSX
|
||||
#define HAS_ARGBMULTIPLYROW_LSX
|
||||
#define HAS_ARGBORROW_LSX
|
||||
#define HAS_ARGBQUANTIZEROW_LSX
|
||||
#define HAS_ARGBSEPIAROW_LSX
|
||||
#define HAS_ARGBSETROW_LSX
|
||||
#define HAS_ARGBSHADEROW_LSX
|
||||
#define HAS_ARGBSHUFFLEROW_LSX
|
||||
#define HAS_ARGBSUBTRACTROW_LSX
|
||||
#define HAS_ARGBQUANTIZEROW_LSX
|
||||
#define HAS_ARGBSETROW_LSX
|
||||
#define HAS_ARGBTOARGB1555ROW_LSX
|
||||
#define HAS_ARGBTOARGB4444ROW_LSX
|
||||
#define HAS_ARGBTORAWROW_LSX
|
||||
#define HAS_ARGBTORGB24ROW_LSX
|
||||
#define HAS_ARGBTORGB565ROW_LSX
|
||||
#define HAS_ARGBTORGB565DITHERROW_LSX
|
||||
#define HAS_ARGBMIRRORROW_LSX
|
||||
#define HAS_ARGBMULTIPLYROW_LSX
|
||||
#define HAS_ARGBTORGB565ROW_LSX
|
||||
#define HAS_ARGBTOYMATRIXROW_LSX
|
||||
#define HAS_COPYROW_LSX
|
||||
#define HAS_HALFFLOATROW_LSX
|
||||
#define HAS_I400TOARGBROW_LSX
|
||||
#define HAS_I444TOARGBROW_LSX
|
||||
#define HAS_INTERPOLATEROW_LSX
|
||||
#define HAS_I422ALPHATOARGBROW_LSX
|
||||
#define HAS_I422TOARGB1555ROW_LSX
|
||||
#define HAS_I422TOARGB4444ROW_LSX
|
||||
#define HAS_I422TOARGBROW_LSX
|
||||
#define HAS_I422TORGB24ROW_LSX
|
||||
#define HAS_I422TORGB565ROW_LSX
|
||||
#define HAS_I422TORGBAROW_LSX
|
||||
#define HAS_I422TOUYVYROW_LSX
|
||||
#define HAS_I422TOYUY2ROW_LSX
|
||||
#define HAS_I444TOARGBROW_LSX
|
||||
#define HAS_INTERPOLATEROW_LSX
|
||||
#define HAS_J400TOARGBROW_LSX
|
||||
#define HAS_MERGEUVROW_LSX
|
||||
#define HAS_MIRRORROW_LSX
|
||||
#define HAS_MIRRORUVROW_LSX
|
||||
#define HAS_MIRRORSPLITUVROW_LSX
|
||||
#define HAS_MIRRORUVROW_LSX
|
||||
#define HAS_NV12TOARGBROW_LSX
|
||||
#define HAS_NV12TORGB565ROW_LSX
|
||||
#define HAS_NV21TOARGBROW_LSX
|
||||
@ -1082,6 +1085,7 @@ extern "C" {
|
||||
#define HAS_RGB565TOARGBROW_LSX
|
||||
#define HAS_RGB565TOUVROW_LSX
|
||||
#define HAS_RGB565TOYROW_LSX
|
||||
#define HAS_RGBTOYMATRIXROW_LSX
|
||||
#define HAS_SETROW_LSX
|
||||
#define HAS_SOBELROW_LSX
|
||||
#define HAS_SOBELTOPLANEROW_LSX
|
||||
@ -1092,19 +1096,12 @@ extern "C" {
|
||||
#define HAS_UYVYTOUVROW_LSX
|
||||
#define HAS_UYVYTOYROW_LSX
|
||||
#define HAS_YUY2TOARGBROW_LSX
|
||||
#define HAS_YUY2TOUVROW_LSX
|
||||
#define HAS_YUY2TOUV422ROW_LSX
|
||||
#define HAS_YUY2TOUVROW_LSX
|
||||
#define HAS_YUY2TOYROW_LSX
|
||||
#define HAS_ARGBTOYMATRIXROW_LSX
|
||||
#define HAS_COPYROW_LSX
|
||||
#define HAS_RGBTOYMATRIXROW_LSX
|
||||
#endif
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
#define HAS_I422TOARGBROW_LSX
|
||||
#endif
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_asx)
|
||||
#if !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_lp64)
|
||||
#define HAS_ARGB1555TOARGBROW_LASX
|
||||
#define HAS_ARGB1555TOUVROW_LASX
|
||||
#define HAS_ARGB1555TOYROW_LASX
|
||||
|
||||
@ -151,7 +151,7 @@ extern "C" {
|
||||
#define HAS_SCALEUVROWDOWN2_SME
|
||||
#endif
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_lp64)
|
||||
#define HAS_SCALEARGBROWDOWN2_LSX
|
||||
#define HAS_SCALEARGBROWDOWNEVEN_LSX
|
||||
#define HAS_SCALEROWDOWN2_LSX
|
||||
|
||||
@ -11,6 +11,6 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 1977
|
||||
#define LIBYUV_VERSION 1978
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
import("//build/config/arm.gni")
|
||||
import("//build/config/loongarch64.gni")
|
||||
import("//build/config/mips.gni")
|
||||
import("//build_overrides/build.gni")
|
||||
|
||||
@ -28,7 +27,7 @@ declare_args() {
|
||||
(current_cpu == "mips64el" || current_cpu == "mipsel") && mips_use_msa
|
||||
libyuv_use_mmi =
|
||||
(current_cpu == "mips64el" || current_cpu == "mipsel") && mips_use_mmi
|
||||
libyuv_use_lsx = current_cpu == "loong64" && loongarch64_use_lsx
|
||||
libyuv_use_lasx = current_cpu == "loong64" && loongarch64_use_lasx
|
||||
libyuv_use_lsx = current_cpu == "loong64"
|
||||
libyuv_use_lasx = current_cpu == "loong64"
|
||||
libyuv_use_rvv = current_cpu == "riscv64" || current_cpu == "riscv32"
|
||||
}
|
||||
|
||||
10
libyuv.gypi
10
libyuv.gypi
@ -20,7 +20,6 @@
|
||||
'include/libyuv/convert_from_argb.h',
|
||||
'include/libyuv/cpu_id.h',
|
||||
'include/libyuv/cpu_support.h',
|
||||
'include/libyuv/loongson_intrinsics.h',
|
||||
'include/libyuv/mjpeg_decoder.h',
|
||||
'include/libyuv/planar_functions.h',
|
||||
'include/libyuv/rotate.h',
|
||||
@ -41,6 +40,7 @@
|
||||
'source/compare_common.cc',
|
||||
'source/compare_gcc.cc',
|
||||
'source/compare_hvx.cc',
|
||||
'source/compare_la.cc',
|
||||
'source/compare_neon.cc',
|
||||
'source/compare_neon64.cc',
|
||||
'source/compare_win.cc',
|
||||
@ -61,8 +61,7 @@
|
||||
'source/rotate_common.cc',
|
||||
'source/rotate_gcc.cc',
|
||||
'source/rotate_hvx.cc',
|
||||
'source/rotate_lasx.cc',
|
||||
'source/rotate_lsx.cc',
|
||||
'source/rotate_la.cc',
|
||||
'source/rotate_neon.cc',
|
||||
'source/rotate_neon64.cc',
|
||||
'source/rotate_rvv.cc',
|
||||
@ -71,8 +70,7 @@
|
||||
'source/row_common.cc',
|
||||
'source/row_gcc.cc',
|
||||
'source/row_hvx.cc',
|
||||
'source/row_lasx.cc',
|
||||
'source/row_lsx.cc',
|
||||
'source/row_la.cc',
|
||||
'source/row_neon.cc',
|
||||
'source/row_neon64.cc',
|
||||
'source/row_rvv.cc',
|
||||
@ -83,7 +81,7 @@
|
||||
'source/scale_common.cc',
|
||||
'source/scale_gcc.cc',
|
||||
'source/scale_hvx.cc',
|
||||
'source/scale_lsx.cc',
|
||||
'source/scale_la.cc',
|
||||
'source/scale_neon.cc',
|
||||
'source/scale_neon64.cc',
|
||||
'source/scale_rgb.cc',
|
||||
|
||||
9
linux.mk
9
linux.mk
@ -14,6 +14,7 @@ LOCAL_OBJ_FILES := \
|
||||
source/compare_common.o \
|
||||
source/compare_gcc.o \
|
||||
source/compare_hvx.o \
|
||||
source/compare_la.o \
|
||||
source/compare_neon.o \
|
||||
source/compare_neon64.o \
|
||||
source/compare_win.o \
|
||||
@ -34,8 +35,7 @@ LOCAL_OBJ_FILES := \
|
||||
source/rotate_common.o \
|
||||
source/rotate_gcc.o \
|
||||
source/rotate_hvx.o \
|
||||
source/rotate_lasx.o \
|
||||
source/rotate_lsx.o \
|
||||
source/rotate_la.o \
|
||||
source/rotate_neon.o \
|
||||
source/rotate_neon64.o \
|
||||
source/rotate_rvv.o \
|
||||
@ -46,8 +46,7 @@ LOCAL_OBJ_FILES := \
|
||||
source/row_common.o \
|
||||
source/row_gcc.o \
|
||||
source/row_hvx.o \
|
||||
source/row_lasx.o \
|
||||
source/row_lsx.o \
|
||||
source/row_la.o \
|
||||
source/row_neon.o \
|
||||
source/row_neon64.o \
|
||||
source/row_rvv.o \
|
||||
@ -60,7 +59,7 @@ LOCAL_OBJ_FILES := \
|
||||
source/scale_common.o \
|
||||
source/scale_gcc.o \
|
||||
source/scale_hvx.o \
|
||||
source/scale_lsx.o \
|
||||
source/scale_la.o \
|
||||
source/scale_neon.o \
|
||||
source/scale_neon64.o \
|
||||
source/scale_rgb.o \
|
||||
|
||||
@ -238,11 +238,13 @@ uint64_t ComputeHammingDistance(const uint8_t* src_a,
|
||||
#if defined(HAS_HAMMINGDISTANCE_LSX)
|
||||
if (TestCpuFlag(kCpuHasLSX)) {
|
||||
HammingDistance = HammingDistance_LSX;
|
||||
simd_size = 16;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_HAMMINGDISTANCE_LASX)
|
||||
if (TestCpuFlag(kCpuHasLASX)) {
|
||||
HammingDistance = HammingDistance_LASX;
|
||||
simd_size = 32;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_HAMMINGDISTANCE_WASMSIMD)
|
||||
@ -346,11 +348,13 @@ uint64_t ComputeSumSquareError(const uint8_t* src_a,
|
||||
#if defined(HAS_SUMSQUAREERROR_LSX)
|
||||
if (TestCpuFlag(kCpuHasLSX)) {
|
||||
SumSquareError = SumSquareError_LSX;
|
||||
simd_size = 16;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_SUMSQUAREERROR_LASX)
|
||||
if (TestCpuFlag(kCpuHasLASX)) {
|
||||
SumSquareError = SumSquareError_LASX;
|
||||
simd_size = 32;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_SUMSQUAREERROR_WASMSIMD)
|
||||
|
||||
652
source/compare_la.cc
Normal file
652
source/compare_la.cc
Normal file
@ -0,0 +1,652 @@
|
||||
/*
|
||||
* Copyright 2022 The LibYuv Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "libyuv/compare_row.h"
|
||||
#include "libyuv/row.h"
|
||||
#include "libyuv/video_common.h"
|
||||
|
||||
// Note: every register written by an inline asm block (vector, general
|
||||
// purpose, mask/predicate, "cc" for flags and "memory" for stores) must be
|
||||
// listed in its clobber list, even when the ABI treats it as caller-saved.
|
||||
// With LTO/LTCG the compiler may keep values live in any register across the
|
||||
// asm statement, and other OS ABIs (e.g. Windows) differ in which registers
|
||||
// are callee-saved. List "memory" first, then "cc", then registers.
|
||||
|
||||
#if (!defined(LIBYUV_DISABLE_LSX) || !defined(LIBYUV_DISABLE_LASX)) && \
|
||||
defined(__loongarch_lp64)
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace libyuv {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(HAS_HASHDJB2_LSX) || defined(HAS_HASHDJB2_LASX)
|
||||
static const ulvec32 kDjb2Multiplicands[] = {
|
||||
{0x0c3525e1, 0xa3476dc1, 0x3b4039a1, 0x4f5f0981, 0x30f35d61, 0x855cb541,
|
||||
0x040a9121, 0x747c7101},
|
||||
{0xec41d4e1, 0x4cfa3cc1, 0x025528a1, 0x00121881, 0x00008c61, 0x00000441,
|
||||
0x00000021, 0x00000001},
|
||||
};
|
||||
#endif // defined(HAS_HASHDJB2_LSX) || defined(HAS_HASHDJB2_LASX)
|
||||
|
||||
#ifdef HAS_HAMMINGDISTANCE_LSX
|
||||
uint32_t HammingDistance_LSX(const uint8_t* src_a,
|
||||
const uint8_t* src_b,
|
||||
int count) {
|
||||
uint32_t diff;
|
||||
asm volatile(
|
||||
"vxor.v $vr4, $vr4, $vr4\n\t"
|
||||
"1:\n\t"
|
||||
"vld $vr0, %[sa], 0\n\t"
|
||||
"vld $vr1, %[sb], 0\n\t"
|
||||
"vxor.v $vr0, $vr0, $vr1\n\t"
|
||||
"vpcnt.b $vr0, $vr0\n\t"
|
||||
"vhaddw.hu.bu $vr0, $vr0, $vr0\n\t"
|
||||
"vhaddw.wu.hu $vr0, $vr0, $vr0\n\t"
|
||||
"vadd.w $vr4, $vr4, $vr0\n\t"
|
||||
"addi.d %[sa], %[sa], 16\n\t"
|
||||
"addi.d %[sb], %[sb], 16\n\t"
|
||||
"addi.d %[cnt], %[cnt], -16\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
"vhaddw.du.wu $vr4, $vr4, $vr4\n\t"
|
||||
"vhaddw.qu.du $vr4, $vr4, $vr4\n\t"
|
||||
"vpickve2gr.wu %[diff], $vr4, 0\n\t"
|
||||
: [sa] "+r"(src_a), [sb] "+r"(src_b), [cnt] "+r"(count), [diff] "=r"(diff)
|
||||
:
|
||||
: "memory", "$vr0", "$vr1", "$vr4");
|
||||
return diff;
|
||||
}
|
||||
#endif // HAS_HAMMINGDISTANCE_LSX
|
||||
|
||||
#ifdef HAS_SUMSQUAREERROR_LSX
|
||||
uint32_t SumSquareError_LSX(const uint8_t* src_a,
|
||||
const uint8_t* src_b,
|
||||
int count) {
|
||||
uint32_t sse;
|
||||
asm volatile(
|
||||
"vxor.v $vr4, $vr4, $vr4\n\t"
|
||||
"1:\n\t"
|
||||
"vld $vr0, %[sa], 0\n\t"
|
||||
"vld $vr1, %[sb], 0\n\t"
|
||||
"vabsd.bu $vr0, $vr0, $vr1\n\t"
|
||||
"vmulwev.h.bu $vr2, $vr0, $vr0\n\t"
|
||||
"vmulwod.h.bu $vr3, $vr0, $vr0\n\t"
|
||||
"vhaddw.wu.hu $vr2, $vr2, $vr2\n\t"
|
||||
"vhaddw.wu.hu $vr3, $vr3, $vr3\n\t"
|
||||
"vadd.w $vr4, $vr4, $vr2\n\t"
|
||||
"vadd.w $vr4, $vr4, $vr3\n\t"
|
||||
"addi.d %[sa], %[sa], 16\n\t"
|
||||
"addi.d %[sb], %[sb], 16\n\t"
|
||||
"addi.d %[cnt], %[cnt], -16\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
"vhaddw.du.wu $vr4, $vr4, $vr4\n\t"
|
||||
"vhaddw.qu.du $vr4, $vr4, $vr4\n\t"
|
||||
"vpickve2gr.wu %[sse], $vr4, 0\n\t"
|
||||
: [sa] "+r"(src_a), [sb] "+r"(src_b), [cnt] "+r"(count), [sse] "=r"(sse)
|
||||
:
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4");
|
||||
return sse;
|
||||
}
|
||||
#endif // HAS_SUMSQUAREERROR_LSX
|
||||
|
||||
#ifdef HAS_HASHDJB2_LSX
|
||||
uint32_t HashDjb2_LSX(const uint8_t* src, int count, uint32_t seed) {
|
||||
uint32_t hash = seed;
|
||||
uint32_t tmp;
|
||||
uint32_t c16 = 0x92d9e201u;
|
||||
asm volatile(
|
||||
"vld $vr4, %[muls], 0\n\t"
|
||||
"vld $vr5, %[muls], 16\n\t"
|
||||
"vld $vr6, %[muls], 32\n\t"
|
||||
"vld $vr7, %[muls], 48\n\t"
|
||||
"1:\n\t"
|
||||
"vld $vr0, %[src], 0\n\t"
|
||||
"vsllwil.hu.bu $vr1, $vr0, 0\n\t"
|
||||
"vexth.hu.bu $vr2, $vr0\n\t"
|
||||
"vsllwil.wu.hu $vr0, $vr1, 0\n\t"
|
||||
"vexth.wu.hu $vr1, $vr1\n\t"
|
||||
"vsllwil.wu.hu $vr3, $vr2, 0\n\t"
|
||||
"vexth.wu.hu $vr2, $vr2\n\t"
|
||||
"vmul.w $vr0, $vr0, $vr4\n\t"
|
||||
"vmadd.w $vr0, $vr1, $vr5\n\t"
|
||||
"vmadd.w $vr0, $vr3, $vr6\n\t"
|
||||
"vmadd.w $vr0, $vr2, $vr7\n\t"
|
||||
"vhaddw.du.wu $vr0, $vr0, $vr0\n\t"
|
||||
"vhaddw.qu.du $vr0, $vr0, $vr0\n\t"
|
||||
"vpickve2gr.wu %[tmp], $vr0, 0\n\t"
|
||||
"mul.w %[hash], %[hash], %[c16]\n\t"
|
||||
"add.w %[hash], %[hash], %[tmp]\n\t"
|
||||
"addi.d %[src], %[src], 16\n\t"
|
||||
"addi.d %[cnt], %[cnt], -16\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
: [src] "+r"(src), [cnt] "+r"(count), [hash] "+r"(hash), [tmp] "=&r"(tmp)
|
||||
: [muls] "r"(kDjb2Multiplicands), [c16] "r"(c16)
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
return hash;
|
||||
}
|
||||
#endif // HAS_HASHDJB2_LSX
|
||||
|
||||
#ifdef HAS_SSIM4X4ROW_LSX
|
||||
void Ssim4x4Row_LSX(const uint8_t* src_a,
|
||||
int stride_a,
|
||||
const uint8_t* src_b,
|
||||
int stride_b,
|
||||
uint32_t* dst,
|
||||
int width) {
|
||||
const uint8_t* pa;
|
||||
const uint8_t* pb;
|
||||
int r;
|
||||
asm volatile(
|
||||
"1:\n\t"
|
||||
"move %[pa], %[sa]\n\t"
|
||||
"move %[pb], %[sb]\n\t"
|
||||
"li.d %[r], 4\n\t"
|
||||
"vxor.v $vr8, $vr8, $vr8\n\t"
|
||||
"vxor.v $vr9, $vr9, $vr9\n\t"
|
||||
"vxor.v $vr10, $vr10, $vr10\n\t"
|
||||
"vxor.v $vr11, $vr11, $vr11\n\t"
|
||||
"2:\n\t"
|
||||
"vld $vr0, %[pa], 0\n\t"
|
||||
"vld $vr1, %[pb], 0\n\t"
|
||||
"add.d %[pa], %[pa], %[sta]\n\t"
|
||||
"add.d %[pb], %[pb], %[stb]\n\t"
|
||||
"vhaddw.hu.bu $vr2, $vr0, $vr0\n\t"
|
||||
"vhaddw.hu.bu $vr3, $vr1, $vr1\n\t"
|
||||
"vadd.h $vr8, $vr8, $vr2\n\t"
|
||||
"vadd.h $vr9, $vr9, $vr3\n\t"
|
||||
"vmulwev.h.bu $vr2, $vr0, $vr1\n\t"
|
||||
"vmulwod.h.bu $vr3, $vr0, $vr1\n\t"
|
||||
"vhaddw.wu.hu $vr2, $vr2, $vr2\n\t"
|
||||
"vhaddw.wu.hu $vr3, $vr3, $vr3\n\t"
|
||||
"vadd.w $vr11, $vr11, $vr2\n\t"
|
||||
"vadd.w $vr11, $vr11, $vr3\n\t"
|
||||
"vmulwev.h.bu $vr2, $vr0, $vr0\n\t"
|
||||
"vmulwod.h.bu $vr3, $vr0, $vr0\n\t"
|
||||
"vmulwev.h.bu $vr4, $vr1, $vr1\n\t"
|
||||
"vmulwod.h.bu $vr5, $vr1, $vr1\n\t"
|
||||
"vhaddw.wu.hu $vr2, $vr2, $vr2\n\t"
|
||||
"vhaddw.wu.hu $vr3, $vr3, $vr3\n\t"
|
||||
"vhaddw.wu.hu $vr4, $vr4, $vr4\n\t"
|
||||
"vhaddw.wu.hu $vr5, $vr5, $vr5\n\t"
|
||||
"vadd.w $vr2, $vr2, $vr3\n\t"
|
||||
"vadd.w $vr4, $vr4, $vr5\n\t"
|
||||
"vadd.w $vr10, $vr10, $vr2\n\t"
|
||||
"vadd.w $vr10, $vr10, $vr4\n\t"
|
||||
"addi.d %[r], %[r], -1\n\t"
|
||||
"bnez %[r], 2b\n\t"
|
||||
"vhaddw.wu.hu $vr8, $vr8, $vr8\n\t"
|
||||
"vhaddw.wu.hu $vr9, $vr9, $vr9\n\t"
|
||||
"vilvl.w $vr0, $vr9, $vr8\n\t"
|
||||
"vilvh.w $vr1, $vr9, $vr8\n\t"
|
||||
"vilvl.w $vr2, $vr11, $vr10\n\t"
|
||||
"vilvh.w $vr3, $vr11, $vr10\n\t"
|
||||
"vilvl.d $vr4, $vr2, $vr0\n\t"
|
||||
"vilvh.d $vr5, $vr2, $vr0\n\t"
|
||||
"vilvl.d $vr6, $vr3, $vr1\n\t"
|
||||
"vilvh.d $vr7, $vr3, $vr1\n\t"
|
||||
"vst $vr4, %[dst], 0\n\t"
|
||||
"vst $vr5, %[dst], 16\n\t"
|
||||
"vst $vr6, %[dst], 32\n\t"
|
||||
"vst $vr7, %[dst], 48\n\t"
|
||||
"addi.d %[sa], %[sa], 16\n\t"
|
||||
"addi.d %[sb], %[sb], 16\n\t"
|
||||
"addi.d %[dst], %[dst], 64\n\t"
|
||||
"addi.d %[cnt], %[cnt], -16\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
: [sa] "+r"(src_a), [sb] "+r"(src_b), [dst] "+r"(dst), [cnt] "+r"(width),
|
||||
[pa] "=&r"(pa), [pb] "=&r"(pb), [r] "=&r"(r)
|
||||
: [sta] "r"((ptrdiff_t)stride_a), [stb] "r"((ptrdiff_t)stride_b)
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11");
|
||||
}
|
||||
#endif // HAS_SSIM4X4ROW_LSX
|
||||
|
||||
#ifdef HAS_SSIMWINDOWROW_LSX
|
||||
float SsimWindowRow_LSX(const uint32_t* row0,
|
||||
const uint32_t* row1,
|
||||
int num_windows) {
|
||||
const uint32_t* row0_next = row0 + 4;
|
||||
const uint32_t* row1_next = row1 + 4;
|
||||
float total;
|
||||
uint32_t c1 = 26634;
|
||||
uint32_t c2 = 239708;
|
||||
uint32_t c0 = 0;
|
||||
asm volatile(
|
||||
"vreplgr2vr.w $vr6, %[c0]\n\t"
|
||||
"vreplgr2vr.w $vr4, %[c1]\n\t"
|
||||
"vreplgr2vr.w $vr5, %[c2]\n\t"
|
||||
"1:\n\t"
|
||||
"vld $vr0, %[r0], 0\n\t"
|
||||
"vld $vr1, %[r0n], 0\n\t"
|
||||
"vld $vr2, %[r1], 0\n\t"
|
||||
"vld $vr3, %[r1n], 0\n\t"
|
||||
"vadd.w $vr0, $vr0, $vr1\n\t"
|
||||
"vadd.w $vr2, $vr2, $vr3\n\t"
|
||||
"vadd.w $vr0, $vr0, $vr2\n\t"
|
||||
"vshuf4i.w $vr1, $vr0, 0x00\n\t"
|
||||
"vshuf4i.w $vr2, $vr0, 0x55\n\t"
|
||||
"vshuf4i.w $vr3, $vr0, 0xaa\n\t"
|
||||
"vshuf4i.w $vr0, $vr0, 0xff\n\t"
|
||||
"vmul.w $vr7, $vr1, $vr2\n\t"
|
||||
"vslli.w $vr7, $vr7, 1\n\t"
|
||||
"vmul.w $vr1, $vr1, $vr1\n\t"
|
||||
"vmadd.w $vr1, $vr2, $vr2\n\t"
|
||||
"vslli.w $vr0, $vr0, 7\n\t"
|
||||
"vsub.w $vr0, $vr0, $vr7\n\t"
|
||||
"vadd.w $vr7, $vr7, $vr4\n\t"
|
||||
"vadd.w $vr0, $vr0, $vr5\n\t"
|
||||
"vslli.w $vr3, $vr3, 6\n\t"
|
||||
"vsub.w $vr3, $vr3, $vr1\n\t"
|
||||
"vadd.w $vr1, $vr1, $vr4\n\t"
|
||||
"vadd.w $vr3, $vr3, $vr5\n\t"
|
||||
"vffint.s.w $vr7, $vr7\n\t"
|
||||
"vffint.s.w $vr0, $vr0\n\t"
|
||||
"vffint.s.w $vr1, $vr1\n\t"
|
||||
"vffint.s.w $vr3, $vr3\n\t"
|
||||
"vfmul.s $vr7, $vr7, $vr0\n\t"
|
||||
"vfmul.s $vr1, $vr1, $vr3\n\t"
|
||||
"vfdiv.s $vr7, $vr7, $vr1\n\t"
|
||||
"vfadd.s $vr6, $vr6, $vr7\n\t"
|
||||
"addi.d %[r0], %[r0], 16\n\t"
|
||||
"addi.d %[r0n], %[r0n], 16\n\t"
|
||||
"addi.d %[r1], %[r1], 16\n\t"
|
||||
"addi.d %[r1n], %[r1n], 16\n\t"
|
||||
"addi.d %[cnt], %[cnt], -1\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
"vstelm.w $vr6, %[tot], 0, 0\n\t"
|
||||
: [r0] "+r"(row0), [r0n] "+r"(row0_next), [r1] "+r"(row1),
|
||||
[r1n] "+r"(row1_next), [cnt] "+r"(num_windows)
|
||||
: [c0] "r"(c0), [c1] "r"(c1), [c2] "r"(c2), [tot] "r"(&total)
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
return total;
|
||||
}
|
||||
#endif // HAS_SSIMWINDOWROW_LSX
|
||||
|
||||
#ifdef HAS_ARGBDETECTROW_LSX
|
||||
uint32_t ARGBDetectRow_LSX(const uint8_t* argb, int width) {
|
||||
uint32_t diff = 0;
|
||||
uint32_t rgb_mask = 0x00ffff00u;
|
||||
asm volatile(
|
||||
"vreplgr2vr.w $vr2, %[rgb_mask]\n\t"
|
||||
"addi.d %[w], %[w], -4\n\t"
|
||||
"bltz %[w], 2f\n\t"
|
||||
"1:\n\t"
|
||||
"vld $vr0, %[argb], 0\n\t"
|
||||
"addi.d %[argb], %[argb], 16\n\t"
|
||||
"vor.v $vr0, $vr0, $vr2\n\t"
|
||||
"vseqi.b $vr0, $vr0, -1\n\t"
|
||||
"vmskltz.b $vr0, $vr0\n\t"
|
||||
"vpickve2gr.hu %[diff], $vr0, 0\n\t"
|
||||
"nor %[diff], %[diff], $zero\n\t"
|
||||
"bstrpick.w %[diff], %[diff], 15, 0\n\t"
|
||||
"bnez %[diff], 4f\n\t"
|
||||
"addi.d %[w], %[w], -4\n\t"
|
||||
"bgez %[w], 1b\n\t"
|
||||
"2:\n\t"
|
||||
"addi.d %[w], %[w], 4\n\t"
|
||||
"beqz %[w], 4f\n\t"
|
||||
"3:\n\t"
|
||||
"vldrepl.w $vr0, %[argb], 0\n\t"
|
||||
"addi.d %[argb], %[argb], 4\n\t"
|
||||
"vor.v $vr0, $vr0, $vr2\n\t"
|
||||
"vseqi.b $vr0, $vr0, -1\n\t"
|
||||
"vmskltz.b $vr0, $vr0\n\t"
|
||||
"vpickve2gr.hu %[diff], $vr0, 0\n\t"
|
||||
"nor %[diff], %[diff], $zero\n\t"
|
||||
"bstrpick.w %[diff], %[diff], 15, 0\n\t"
|
||||
"bnez %[diff], 4f\n\t"
|
||||
"addi.d %[w], %[w], -1\n\t"
|
||||
"bnez %[w], 3b\n\t"
|
||||
"4:\n\t"
|
||||
: [argb] "+r"(argb), [w] "+r"(width), [diff] "+r"(diff)
|
||||
: [rgb_mask] "r"(rgb_mask)
|
||||
: "memory", "$vr0", "$vr2");
|
||||
if (diff) {
|
||||
return (__builtin_ctz(diff) & 3) == 0 ? FOURCC_BGRA : FOURCC_ARGB;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // HAS_ARGBDETECTROW_LSX
|
||||
|
||||
#ifdef HAS_HAMMINGDISTANCE_LASX
|
||||
uint32_t HammingDistance_LASX(const uint8_t* src_a,
|
||||
const uint8_t* src_b,
|
||||
int count) {
|
||||
uint32_t diff;
|
||||
asm volatile(
|
||||
"xvxor.v $xr4, $xr4, $xr4\n\t"
|
||||
"1:\n\t"
|
||||
"xvld $xr0, %[sa], 0\n\t"
|
||||
"xvld $xr1, %[sb], 0\n\t"
|
||||
"xvxor.v $xr0, $xr0, $xr1\n\t"
|
||||
"xvpcnt.b $xr0, $xr0\n\t"
|
||||
"xvhaddw.hu.bu $xr0, $xr0, $xr0\n\t"
|
||||
"xvhaddw.wu.hu $xr0, $xr0, $xr0\n\t"
|
||||
"xvadd.w $xr4, $xr4, $xr0\n\t"
|
||||
"addi.d %[sa], %[sa], 32\n\t"
|
||||
"addi.d %[sb], %[sb], 32\n\t"
|
||||
"addi.d %[cnt], %[cnt], -32\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
"xvhaddw.du.wu $xr4, $xr4, $xr4\n\t"
|
||||
"xvhaddw.qu.du $xr4, $xr4, $xr4\n\t"
|
||||
"xvpermi.q $xr0, $xr4, 0x01\n\t"
|
||||
"vadd.w $vr4, $vr4, $vr0\n\t"
|
||||
"vpickve2gr.wu %[diff], $vr4, 0\n\t"
|
||||
: [sa] "+r"(src_a), [sb] "+r"(src_b), [cnt] "+r"(count), [diff] "=r"(diff)
|
||||
:
|
||||
: "memory", "$xr0", "$xr1", "$xr4");
|
||||
return diff;
|
||||
}
|
||||
#endif // HAS_HAMMINGDISTANCE_LASX
|
||||
|
||||
#ifdef HAS_SUMSQUAREERROR_LASX
|
||||
uint32_t SumSquareError_LASX(const uint8_t* src_a,
|
||||
const uint8_t* src_b,
|
||||
int count) {
|
||||
uint32_t sse;
|
||||
asm volatile(
|
||||
"xvxor.v $xr4, $xr4, $xr4\n\t"
|
||||
"1:\n\t"
|
||||
"xvld $xr0, %[sa], 0\n\t"
|
||||
"xvld $xr1, %[sb], 0\n\t"
|
||||
"xvabsd.bu $xr0, $xr0, $xr1\n\t"
|
||||
"xvmulwev.h.bu $xr2, $xr0, $xr0\n\t"
|
||||
"xvmulwod.h.bu $xr3, $xr0, $xr0\n\t"
|
||||
"xvhaddw.wu.hu $xr2, $xr2, $xr2\n\t"
|
||||
"xvhaddw.wu.hu $xr3, $xr3, $xr3\n\t"
|
||||
"xvadd.w $xr4, $xr4, $xr2\n\t"
|
||||
"xvadd.w $xr4, $xr4, $xr3\n\t"
|
||||
"addi.d %[sa], %[sa], 32\n\t"
|
||||
"addi.d %[sb], %[sb], 32\n\t"
|
||||
"addi.d %[cnt], %[cnt], -32\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
"xvhaddw.du.wu $xr4, $xr4, $xr4\n\t"
|
||||
"xvhaddw.qu.du $xr4, $xr4, $xr4\n\t"
|
||||
"xvpermi.q $xr0, $xr4, 0x01\n\t"
|
||||
"vadd.w $vr4, $vr4, $vr0\n\t"
|
||||
"vpickve2gr.wu %[sse], $vr4, 0\n\t"
|
||||
: [sa] "+r"(src_a), [sb] "+r"(src_b), [cnt] "+r"(count), [sse] "=r"(sse)
|
||||
:
|
||||
: "memory", "$xr0", "$xr1", "$xr2", "$xr3", "$xr4");
|
||||
return sse;
|
||||
}
|
||||
#endif // HAS_SUMSQUAREERROR_LASX
|
||||
|
||||
#ifdef HAS_HASHDJB2_LASX
|
||||
uint32_t HashDjb2_LASX(const uint8_t* src, int count, uint32_t seed) {
|
||||
uint32_t hash = seed;
|
||||
uint32_t tmp;
|
||||
uint32_t c16 = 0x92d9e201u;
|
||||
asm volatile(
|
||||
"xvld $xr4, %[muls], 0\n\t"
|
||||
"xvld $xr5, %[muls], 32\n\t"
|
||||
"1:\n\t"
|
||||
"vld $vr0, %[src], 0\n\t"
|
||||
"vbsrl.v $vr1, $vr0, 8\n\t"
|
||||
"vext2xv.wu.bu $xr0, $xr0\n\t"
|
||||
"vext2xv.wu.bu $xr1, $xr1\n\t"
|
||||
"xvmul.w $xr0, $xr0, $xr4\n\t"
|
||||
"xvmadd.w $xr0, $xr1, $xr5\n\t"
|
||||
"xvhaddw.du.wu $xr0, $xr0, $xr0\n\t"
|
||||
"xvhaddw.qu.du $xr0, $xr0, $xr0\n\t"
|
||||
"xvpermi.q $xr1, $xr0, 0x01\n\t"
|
||||
"vadd.w $vr0, $vr0, $vr1\n\t"
|
||||
"vpickve2gr.wu %[tmp], $vr0, 0\n\t"
|
||||
"mul.w %[hash], %[hash], %[c16]\n\t"
|
||||
"add.w %[hash], %[hash], %[tmp]\n\t"
|
||||
"addi.d %[src], %[src], 16\n\t"
|
||||
"addi.d %[cnt], %[cnt], -16\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
: [src] "+r"(src), [cnt] "+r"(count), [hash] "+r"(hash), [tmp] "=&r"(tmp)
|
||||
: [muls] "r"(kDjb2Multiplicands), [c16] "r"(c16)
|
||||
: "memory", "$xr0", "$xr1", "$xr4", "$xr5");
|
||||
return hash;
|
||||
}
|
||||
#endif // HAS_HASHDJB2_LASX
|
||||
|
||||
#ifdef HAS_SSIM4X4ROW_LASX
|
||||
void Ssim4x4Row_LASX(const uint8_t* src_a,
|
||||
int stride_a,
|
||||
const uint8_t* src_b,
|
||||
int stride_b,
|
||||
uint32_t* dst,
|
||||
int width) {
|
||||
const uint8_t* pa;
|
||||
const uint8_t* pb;
|
||||
int r;
|
||||
asm volatile(
|
||||
"1:\n\t"
|
||||
"move %[pa], %[sa]\n\t"
|
||||
"move %[pb], %[sb]\n\t"
|
||||
"li.d %[r], 4\n\t"
|
||||
"xvxor.v $xr8, $xr8, $xr8\n\t"
|
||||
"xvxor.v $xr9, $xr9, $xr9\n\t"
|
||||
"xvxor.v $xr10, $xr10, $xr10\n\t"
|
||||
"xvxor.v $xr11, $xr11, $xr11\n\t"
|
||||
"2:\n\t"
|
||||
"xvld $xr0, %[pa], 0\n\t"
|
||||
"xvld $xr1, %[pb], 0\n\t"
|
||||
"add.d %[pa], %[pa], %[sta]\n\t"
|
||||
"add.d %[pb], %[pb], %[stb]\n\t"
|
||||
"xvhaddw.hu.bu $xr2, $xr0, $xr0\n\t"
|
||||
"xvhaddw.hu.bu $xr3, $xr1, $xr1\n\t"
|
||||
"xvadd.h $xr8, $xr8, $xr2\n\t"
|
||||
"xvadd.h $xr9, $xr9, $xr3\n\t"
|
||||
"xvmulwev.h.bu $xr2, $xr0, $xr1\n\t"
|
||||
"xvmulwod.h.bu $xr3, $xr0, $xr1\n\t"
|
||||
"xvhaddw.wu.hu $xr2, $xr2, $xr2\n\t"
|
||||
"xvhaddw.wu.hu $xr3, $xr3, $xr3\n\t"
|
||||
"xvadd.w $xr11, $xr11, $xr2\n\t"
|
||||
"xvadd.w $xr11, $xr11, $xr3\n\t"
|
||||
"xvmulwev.h.bu $xr2, $xr0, $xr0\n\t"
|
||||
"xvmulwod.h.bu $xr3, $xr0, $xr0\n\t"
|
||||
"xvmulwev.h.bu $xr4, $xr1, $xr1\n\t"
|
||||
"xvmulwod.h.bu $xr5, $xr1, $xr1\n\t"
|
||||
"xvhaddw.wu.hu $xr2, $xr2, $xr2\n\t"
|
||||
"xvhaddw.wu.hu $xr3, $xr3, $xr3\n\t"
|
||||
"xvhaddw.wu.hu $xr4, $xr4, $xr4\n\t"
|
||||
"xvhaddw.wu.hu $xr5, $xr5, $xr5\n\t"
|
||||
"xvadd.w $xr2, $xr2, $xr3\n\t"
|
||||
"xvadd.w $xr4, $xr4, $xr5\n\t"
|
||||
"xvadd.w $xr10, $xr10, $xr2\n\t"
|
||||
"xvadd.w $xr10, $xr10, $xr4\n\t"
|
||||
"addi.d %[r], %[r], -1\n\t"
|
||||
"bnez %[r], 2b\n\t"
|
||||
"xvhaddw.wu.hu $xr8, $xr8, $xr8\n\t"
|
||||
"xvhaddw.wu.hu $xr9, $xr9, $xr9\n\t"
|
||||
"xvilvl.w $xr0, $xr9, $xr8\n\t"
|
||||
"xvilvh.w $xr1, $xr9, $xr8\n\t"
|
||||
"xvilvl.w $xr2, $xr11, $xr10\n\t"
|
||||
"xvilvh.w $xr3, $xr11, $xr10\n\t"
|
||||
"xvilvl.d $xr4, $xr2, $xr0\n\t"
|
||||
"xvilvh.d $xr5, $xr2, $xr0\n\t"
|
||||
"xvilvl.d $xr6, $xr3, $xr1\n\t"
|
||||
"xvilvh.d $xr7, $xr3, $xr1\n\t"
|
||||
"xvor.v $xr0, $xr5, $xr5\n\t"
|
||||
"xvpermi.q $xr0, $xr4, 0x20\n\t"
|
||||
"xvpermi.q $xr5, $xr4, 0x31\n\t"
|
||||
"xvor.v $xr1, $xr7, $xr7\n\t"
|
||||
"xvpermi.q $xr1, $xr6, 0x20\n\t"
|
||||
"xvpermi.q $xr7, $xr6, 0x31\n\t"
|
||||
"xvst $xr0, %[dst], 0\n\t"
|
||||
"xvst $xr1, %[dst], 32\n\t"
|
||||
"xvst $xr5, %[dst], 64\n\t"
|
||||
"xvst $xr7, %[dst], 96\n\t"
|
||||
"addi.d %[sa], %[sa], 32\n\t"
|
||||
"addi.d %[sb], %[sb], 32\n\t"
|
||||
"addi.d %[dst], %[dst], 128\n\t"
|
||||
"addi.d %[cnt], %[cnt], -32\n\t"
|
||||
"bnez %[cnt], 1b\n\t"
|
||||
: [sa] "+r"(src_a), [sb] "+r"(src_b), [dst] "+r"(dst), [cnt] "+r"(width),
|
||||
[pa] "=&r"(pa), [pb] "=&r"(pb), [r] "=&r"(r)
|
||||
: [sta] "r"((ptrdiff_t)stride_a), [stb] "r"((ptrdiff_t)stride_b)
|
||||
: "memory", "$xr0", "$xr1", "$xr2", "$xr3", "$xr4", "$xr5", "$xr6",
|
||||
"$xr7", "$xr8", "$xr9", "$xr10", "$xr11");
|
||||
}
|
||||
#endif // HAS_SSIM4X4ROW_LASX
|
||||
|
||||
#ifdef HAS_SSIMWINDOWROW_LASX
|
||||
float SsimWindowRow_LASX(const uint32_t* row0,
|
||||
const uint32_t* row1,
|
||||
int num_windows) {
|
||||
const uint32_t* row0_next = row0 + 4;
|
||||
const uint32_t* row1_next = row1 + 4;
|
||||
float total;
|
||||
uint32_t c1 = 26634;
|
||||
uint32_t c2 = 239708;
|
||||
uint32_t c0 = 0;
|
||||
asm volatile(
|
||||
"xvreplgr2vr.w $xr6, %[c0]\n\t"
|
||||
"xvreplgr2vr.w $xr4, %[c1]\n\t"
|
||||
"xvreplgr2vr.w $xr5, %[c2]\n\t"
|
||||
"addi.d %[cnt], %[cnt], -2\n\t"
|
||||
"bltz %[cnt], 2f\n\t"
|
||||
"1:\n\t"
|
||||
"xvld $xr0, %[r0], 0\n\t"
|
||||
"xvld $xr1, %[r0n], 0\n\t"
|
||||
"xvld $xr2, %[r1], 0\n\t"
|
||||
"xvld $xr3, %[r1n], 0\n\t"
|
||||
"xvadd.w $xr0, $xr0, $xr1\n\t"
|
||||
"xvadd.w $xr2, $xr2, $xr3\n\t"
|
||||
"xvadd.w $xr0, $xr0, $xr2\n\t"
|
||||
"xvshuf4i.w $xr1, $xr0, 0x00\n\t"
|
||||
"xvshuf4i.w $xr2, $xr0, 0x55\n\t"
|
||||
"xvshuf4i.w $xr3, $xr0, 0xaa\n\t"
|
||||
"xvshuf4i.w $xr0, $xr0, 0xff\n\t"
|
||||
"xvmul.w $xr7, $xr1, $xr2\n\t"
|
||||
"xvslli.w $xr7, $xr7, 1\n\t"
|
||||
"xvmul.w $xr1, $xr1, $xr1\n\t"
|
||||
"xvmadd.w $xr1, $xr2, $xr2\n\t"
|
||||
"xvslli.w $xr0, $xr0, 7\n\t"
|
||||
"xvsub.w $xr0, $xr0, $xr7\n\t"
|
||||
"xvadd.w $xr7, $xr7, $xr4\n\t"
|
||||
"xvadd.w $xr0, $xr0, $xr5\n\t"
|
||||
"xvslli.w $xr3, $xr3, 6\n\t"
|
||||
"xvsub.w $xr3, $xr3, $xr1\n\t"
|
||||
"xvadd.w $xr1, $xr1, $xr4\n\t"
|
||||
"xvadd.w $xr3, $xr3, $xr5\n\t"
|
||||
"xvffint.s.w $xr7, $xr7\n\t"
|
||||
"xvffint.s.w $xr0, $xr0\n\t"
|
||||
"xvffint.s.w $xr1, $xr1\n\t"
|
||||
"xvffint.s.w $xr3, $xr3\n\t"
|
||||
"xvfmul.s $xr7, $xr7, $xr0\n\t"
|
||||
"xvfmul.s $xr1, $xr1, $xr3\n\t"
|
||||
"xvfdiv.s $xr7, $xr7, $xr1\n\t"
|
||||
"xvfadd.s $xr6, $xr6, $xr7\n\t"
|
||||
"addi.d %[r0], %[r0], 32\n\t"
|
||||
"addi.d %[r0n], %[r0n], 32\n\t"
|
||||
"addi.d %[r1], %[r1], 32\n\t"
|
||||
"addi.d %[r1n], %[r1n], 32\n\t"
|
||||
"addi.d %[cnt], %[cnt], -2\n\t"
|
||||
"bgez %[cnt], 1b\n\t"
|
||||
"xvpermi.q $xr0, $xr6, 0x01\n\t"
|
||||
"vfadd.s $vr6, $vr6, $vr0\n\t"
|
||||
"2:\n\t"
|
||||
"addi.d %[cnt], %[cnt], 2\n\t"
|
||||
"beqz %[cnt], 3f\n\t"
|
||||
"vld $vr0, %[r0], 0\n\t"
|
||||
"vld $vr1, %[r0n], 0\n\t"
|
||||
"vld $vr2, %[r1], 0\n\t"
|
||||
"vld $vr3, %[r1n], 0\n\t"
|
||||
"vadd.w $vr0, $vr0, $vr1\n\t"
|
||||
"vadd.w $vr2, $vr2, $vr3\n\t"
|
||||
"vadd.w $vr0, $vr0, $vr2\n\t"
|
||||
"vshuf4i.w $vr1, $vr0, 0x00\n\t"
|
||||
"vshuf4i.w $vr2, $vr0, 0x55\n\t"
|
||||
"vshuf4i.w $vr3, $vr0, 0xaa\n\t"
|
||||
"vshuf4i.w $vr0, $vr0, 0xff\n\t"
|
||||
"vmul.w $vr7, $vr1, $vr2\n\t"
|
||||
"vslli.w $vr7, $vr7, 1\n\t"
|
||||
"vmul.w $vr1, $vr1, $vr1\n\t"
|
||||
"vmadd.w $vr1, $vr2, $vr2\n\t"
|
||||
"vslli.w $vr0, $vr0, 7\n\t"
|
||||
"vsub.w $vr0, $vr0, $vr7\n\t"
|
||||
"vadd.w $vr7, $vr7, $vr4\n\t"
|
||||
"vadd.w $vr0, $vr0, $vr5\n\t"
|
||||
"vslli.w $vr3, $vr3, 6\n\t"
|
||||
"vsub.w $vr3, $vr3, $vr1\n\t"
|
||||
"vadd.w $vr1, $vr1, $vr4\n\t"
|
||||
"vadd.w $vr3, $vr3, $vr5\n\t"
|
||||
"vffint.s.w $vr7, $vr7\n\t"
|
||||
"vffint.s.w $vr0, $vr0\n\t"
|
||||
"vffint.s.w $vr1, $vr1\n\t"
|
||||
"vffint.s.w $vr3, $vr3\n\t"
|
||||
"vfmul.s $vr7, $vr7, $vr0\n\t"
|
||||
"vfmul.s $vr1, $vr1, $vr3\n\t"
|
||||
"vfdiv.s $vr7, $vr7, $vr1\n\t"
|
||||
"vfadd.s $vr6, $vr6, $vr7\n\t"
|
||||
"3:\n\t"
|
||||
"vstelm.w $vr6, %[tot], 0, 0\n\t"
|
||||
: [r0] "+r"(row0), [r0n] "+r"(row0_next), [r1] "+r"(row1),
|
||||
[r1n] "+r"(row1_next), [cnt] "+r"(num_windows)
|
||||
: [c0] "r"(c0), [c1] "r"(c1), [c2] "r"(c2), [tot] "r"(&total)
|
||||
: "memory", "$xr0", "$xr1", "$xr2", "$xr3", "$xr4", "$xr5", "$xr6",
|
||||
"$xr7");
|
||||
return total;
|
||||
}
|
||||
#endif // HAS_SSIMWINDOWROW_LASX
|
||||
|
||||
#ifdef HAS_ARGBDETECTROW_LASX
|
||||
uint32_t ARGBDetectRow_LASX(const uint8_t* argb, int width) {
|
||||
uint32_t diff = 0;
|
||||
uint32_t tmp;
|
||||
uint32_t rgb_mask = 0x00ffff00u;
|
||||
asm volatile(
|
||||
"xvreplgr2vr.w $xr2, %[rgb_mask]\n\t"
|
||||
"addi.d %[w], %[w], -8\n\t"
|
||||
"bltz %[w], 2f\n\t"
|
||||
"1:\n\t"
|
||||
"xvld $xr0, %[argb], 0\n\t"
|
||||
"addi.d %[argb], %[argb], 32\n\t"
|
||||
"xvor.v $xr0, $xr0, $xr2\n\t"
|
||||
"xvseqi.b $xr0, $xr0, -1\n\t"
|
||||
"xvmskltz.b $xr0, $xr0\n\t"
|
||||
"xvpickve2gr.wu %[diff], $xr0, 0\n\t"
|
||||
"xvpickve2gr.wu %[tmp], $xr0, 4\n\t"
|
||||
"bstrins.w %[diff], %[tmp], 31, 16\n\t"
|
||||
"nor %[diff], %[diff], $zero\n\t"
|
||||
"bnez %[diff], 4f\n\t"
|
||||
"addi.d %[w], %[w], -8\n\t"
|
||||
"bgez %[w], 1b\n\t"
|
||||
"2:\n\t"
|
||||
"addi.d %[w], %[w], 8\n\t"
|
||||
"beqz %[w], 4f\n\t"
|
||||
"3:\n\t"
|
||||
"vldrepl.w $vr0, %[argb], 0\n\t"
|
||||
"addi.d %[argb], %[argb], 4\n\t"
|
||||
"vor.v $vr0, $vr0, $vr2\n\t"
|
||||
"vseqi.b $vr0, $vr0, -1\n\t"
|
||||
"vmskltz.b $vr0, $vr0\n\t"
|
||||
"vpickve2gr.hu %[diff], $vr0, 0\n\t"
|
||||
"nor %[diff], %[diff], $zero\n\t"
|
||||
"bstrpick.w %[diff], %[diff], 15, 0\n\t"
|
||||
"bnez %[diff], 4f\n\t"
|
||||
"addi.d %[w], %[w], -1\n\t"
|
||||
"bnez %[w], 3b\n\t"
|
||||
"4:\n\t"
|
||||
: [argb] "+r"(argb), [w] "+r"(width), [diff] "+r"(diff), [tmp] "=&r"(tmp)
|
||||
: [rgb_mask] "r"(rgb_mask)
|
||||
: "memory", "$xr0", "$xr2");
|
||||
if (diff) {
|
||||
return (__builtin_ctz(diff) & 3) == 0 ? FOURCC_BGRA : FOURCC_ARGB;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // HAS_ARGBDETECTROW_LASX
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
#endif
|
||||
|
||||
#endif // (!defined(LIBYUV_DISABLE_LSX) || !defined(LIBYUV_DISABLE_LASX)) &&
|
||||
// defined(__loongarch_lp64)
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2026 The LibYuv Project Authors. All rights reserved.
|
||||
* Copyright 2022 The LibYuv Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -9,14 +9,383 @@
|
||||
*/
|
||||
|
||||
#include "libyuv/rotate_row.h"
|
||||
#include "libyuv/row.h"
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_asx)
|
||||
#if (!defined(LIBYUV_DISABLE_LSX) || !defined(LIBYUV_DISABLE_LASX)) && \
|
||||
defined(__loongarch_lp64)
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace libyuv {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAS_TRANSPOSEWX8_LSX
|
||||
void TransposeWx8_LSX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst,
|
||||
int dst_stride,
|
||||
int width) {
|
||||
const ptrdiff_t s = src_stride;
|
||||
const ptrdiff_t d = dst_stride;
|
||||
const uint8_t* t;
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 4 \n"
|
||||
"beqz %[w], 2f \n"
|
||||
"1: \n"
|
||||
"move %[t], %[src] \n"
|
||||
"vld $vr0, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr1, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr2, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr3, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr4, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr5, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr6, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr7, %[t], 0 \n"
|
||||
"addi.d %[src], %[src], 16 \n"
|
||||
|
||||
"vilvl.b $vr8, $vr1, $vr0 \n"
|
||||
"vilvh.b $vr9, $vr1, $vr0 \n"
|
||||
"vilvl.b $vr10, $vr3, $vr2 \n"
|
||||
"vilvh.b $vr11, $vr3, $vr2 \n"
|
||||
"vilvl.b $vr12, $vr5, $vr4 \n"
|
||||
"vilvh.b $vr13, $vr5, $vr4 \n"
|
||||
"vilvl.b $vr14, $vr7, $vr6 \n"
|
||||
"vilvh.b $vr15, $vr7, $vr6 \n"
|
||||
|
||||
"vilvl.h $vr0, $vr10, $vr8 \n"
|
||||
"vilvh.h $vr1, $vr10, $vr8 \n"
|
||||
"vilvl.h $vr2, $vr11, $vr9 \n"
|
||||
"vilvh.h $vr3, $vr11, $vr9 \n"
|
||||
"vilvl.h $vr4, $vr14, $vr12 \n"
|
||||
"vilvh.h $vr5, $vr14, $vr12 \n"
|
||||
"vilvl.h $vr6, $vr15, $vr13 \n"
|
||||
"vilvh.h $vr7, $vr15, $vr13 \n"
|
||||
|
||||
"vilvl.w $vr8, $vr4, $vr0 \n"
|
||||
"vilvh.w $vr9, $vr4, $vr0 \n"
|
||||
"vilvl.w $vr10, $vr5, $vr1 \n"
|
||||
"vilvh.w $vr11, $vr5, $vr1 \n"
|
||||
"vilvl.w $vr12, $vr6, $vr2 \n"
|
||||
"vilvh.w $vr13, $vr6, $vr2 \n"
|
||||
"vilvl.w $vr14, $vr7, $vr3 \n"
|
||||
"vilvh.w $vr15, $vr7, $vr3 \n"
|
||||
|
||||
"vstelm.d $vr8, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr8, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr9, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr9, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr10, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr10, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr11, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr11, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr12, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr12, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr13, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr13, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr14, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr14, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr15, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr15, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"addi.w %[w], %[w], -1 \n"
|
||||
"bnez %[w], 1b \n"
|
||||
"2: \n"
|
||||
: [src] "+r"(src), // %[src]
|
||||
[dst] "+r"(dst), // %[dst]
|
||||
[w] "+r"(width), // %[w]
|
||||
[t] "=&r"(t) // %[t]
|
||||
: [s] "r"(s), // %[s]
|
||||
[d] "r"(d) // %[d]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14",
|
||||
"$vr15");
|
||||
}
|
||||
#endif // HAS_TRANSPOSEWX8_LSX
|
||||
|
||||
#ifdef HAS_TRANSPOSEUVWX8_LSX
|
||||
void TransposeUVWx8_LSX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
uint8_t* dst_b,
|
||||
int dst_stride_b,
|
||||
int width) {
|
||||
const ptrdiff_t s = src_stride;
|
||||
const ptrdiff_t da = dst_stride_a;
|
||||
const ptrdiff_t db = dst_stride_b;
|
||||
const uint8_t* t;
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 3 \n"
|
||||
"beqz %[w], 2f \n"
|
||||
"1: \n"
|
||||
"move %[t], %[src] \n"
|
||||
"vld $vr0, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr1, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr2, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr3, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr4, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr5, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr6, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr7, %[t], 0 \n"
|
||||
"addi.d %[src], %[src], 16 \n"
|
||||
|
||||
"vilvl.b $vr8, $vr1, $vr0 \n"
|
||||
"vilvh.b $vr9, $vr1, $vr0 \n"
|
||||
"vilvl.b $vr10, $vr3, $vr2 \n"
|
||||
"vilvh.b $vr11, $vr3, $vr2 \n"
|
||||
"vilvl.b $vr12, $vr5, $vr4 \n"
|
||||
"vilvh.b $vr13, $vr5, $vr4 \n"
|
||||
"vilvl.b $vr14, $vr7, $vr6 \n"
|
||||
"vilvh.b $vr15, $vr7, $vr6 \n"
|
||||
|
||||
"vilvl.h $vr0, $vr10, $vr8 \n"
|
||||
"vilvh.h $vr1, $vr10, $vr8 \n"
|
||||
"vilvl.h $vr2, $vr11, $vr9 \n"
|
||||
"vilvh.h $vr3, $vr11, $vr9 \n"
|
||||
"vilvl.h $vr4, $vr14, $vr12 \n"
|
||||
"vilvh.h $vr5, $vr14, $vr12 \n"
|
||||
"vilvl.h $vr6, $vr15, $vr13 \n"
|
||||
"vilvh.h $vr7, $vr15, $vr13 \n"
|
||||
|
||||
"vilvl.w $vr8, $vr4, $vr0 \n"
|
||||
"vilvh.w $vr9, $vr4, $vr0 \n"
|
||||
"vilvl.w $vr10, $vr5, $vr1 \n"
|
||||
"vilvh.w $vr11, $vr5, $vr1 \n"
|
||||
"vilvl.w $vr12, $vr6, $vr2 \n"
|
||||
"vilvh.w $vr13, $vr6, $vr2 \n"
|
||||
"vilvl.w $vr14, $vr7, $vr3 \n"
|
||||
"vilvh.w $vr15, $vr7, $vr3 \n"
|
||||
|
||||
"vstelm.d $vr8, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr8, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr9, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr9, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr10, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr10, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr11, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr11, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr12, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr12, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr13, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr13, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr14, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr14, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr15, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr15, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"addi.w %[w], %[w], -1 \n"
|
||||
"bnez %[w], 1b \n"
|
||||
"2: \n"
|
||||
: [src] "+r"(src), // %[src]
|
||||
[dst_a] "+r"(dst_a), // %[dst_a]
|
||||
[dst_b] "+r"(dst_b), // %[dst_b]
|
||||
[w] "+r"(width), // %[w]
|
||||
[t] "=&r"(t) // %[t]
|
||||
: [s] "r"(s), // %[s]
|
||||
[da] "r"(da), // %[da]
|
||||
[db] "r"(db) // %[db]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14",
|
||||
"$vr15");
|
||||
}
|
||||
#endif // HAS_TRANSPOSEUVWX8_LSX
|
||||
|
||||
#ifdef HAS_TRANSPOSEWX4_32_LSX
|
||||
void TransposeWx4_32_LSX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst,
|
||||
int dst_stride,
|
||||
int width) {
|
||||
const ptrdiff_t s = src_stride;
|
||||
const ptrdiff_t s2 = s * 2;
|
||||
const ptrdiff_t s3 = s + s2;
|
||||
const ptrdiff_t s4 = s * 4;
|
||||
uint8_t* dst0 = dst;
|
||||
uint8_t* dst1 = dst0 + dst_stride;
|
||||
uint8_t* dst2 = dst1 + dst_stride;
|
||||
uint8_t* dst3 = dst2 + dst_stride;
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 2 \n"
|
||||
"beqz %[w], 2f \n"
|
||||
"1: \n"
|
||||
"vld $vr0, %[src], 0 \n"
|
||||
"vldx $vr1, %[src], %[s] \n"
|
||||
"vldx $vr2, %[src], %[s2] \n"
|
||||
"vldx $vr3, %[src], %[s3] \n"
|
||||
"add.d %[src], %[src], %[s4] \n"
|
||||
|
||||
"vilvl.w $vr4, $vr1, $vr0 \n"
|
||||
"vilvh.w $vr5, $vr1, $vr0 \n"
|
||||
"vilvl.w $vr6, $vr3, $vr2 \n"
|
||||
"vilvh.w $vr7, $vr3, $vr2 \n"
|
||||
|
||||
"vilvl.d $vr0, $vr6, $vr4 \n"
|
||||
"vilvh.d $vr1, $vr6, $vr4 \n"
|
||||
"vilvl.d $vr2, $vr7, $vr5 \n"
|
||||
"vilvh.d $vr3, $vr7, $vr5 \n"
|
||||
|
||||
"vst $vr0, %[dst0], 0 \n"
|
||||
"vst $vr1, %[dst1], 0 \n"
|
||||
"vst $vr2, %[dst2], 0 \n"
|
||||
"vst $vr3, %[dst3], 0 \n"
|
||||
"addi.d %[dst0], %[dst0], 16 \n"
|
||||
"addi.d %[dst1], %[dst1], 16 \n"
|
||||
"addi.d %[dst2], %[dst2], 16 \n"
|
||||
"addi.d %[dst3], %[dst3], 16 \n"
|
||||
"addi.w %[w], %[w], -1 \n"
|
||||
"bnez %[w], 1b \n"
|
||||
"2: \n"
|
||||
: [src] "+r"(src), // %[src]
|
||||
[dst0] "+r"(dst0), // %[dst0]
|
||||
[dst1] "+r"(dst1), // %[dst1]
|
||||
[dst2] "+r"(dst2), // %[dst2]
|
||||
[dst3] "+r"(dst3), // %[dst3]
|
||||
[w] "+r"(width) // %[w]
|
||||
: [s] "r"(s), // %[s]
|
||||
[s2] "r"(s2), // %[s2]
|
||||
[s3] "r"(s3), // %[s3]
|
||||
[s4] "r"(s4) // %[s4]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
}
|
||||
#endif // HAS_TRANSPOSEWX4_32_LSX
|
||||
|
||||
#ifdef HAS_TRANSPOSEWX8_16_LSX
|
||||
void TransposeWx8_16_LSX(const uint16_t* src,
|
||||
int src_stride,
|
||||
uint16_t* dst,
|
||||
int dst_stride,
|
||||
int width) {
|
||||
const ptrdiff_t s = (ptrdiff_t)src_stride * 2;
|
||||
const ptrdiff_t d = (ptrdiff_t)dst_stride * 2;
|
||||
const uint8_t* src_b = (const uint8_t*)src;
|
||||
uint8_t* dst_b = (uint8_t*)dst;
|
||||
const uint8_t* t;
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 3 \n"
|
||||
"beqz %[w], 2f \n"
|
||||
"1: \n"
|
||||
"move %[t], %[src] \n"
|
||||
"vld $vr0, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr1, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr2, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr3, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr4, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr5, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr6, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr7, %[t], 0 \n"
|
||||
"addi.d %[src], %[src], 16 \n"
|
||||
|
||||
"vilvl.h $vr8, $vr1, $vr0 \n"
|
||||
"vilvh.h $vr9, $vr1, $vr0 \n"
|
||||
"vilvl.h $vr10, $vr3, $vr2 \n"
|
||||
"vilvh.h $vr11, $vr3, $vr2 \n"
|
||||
"vilvl.h $vr12, $vr5, $vr4 \n"
|
||||
"vilvh.h $vr13, $vr5, $vr4 \n"
|
||||
"vilvl.h $vr14, $vr7, $vr6 \n"
|
||||
"vilvh.h $vr15, $vr7, $vr6 \n"
|
||||
|
||||
"vilvl.w $vr0, $vr10, $vr8 \n"
|
||||
"vilvh.w $vr1, $vr10, $vr8 \n"
|
||||
"vilvl.w $vr2, $vr11, $vr9 \n"
|
||||
"vilvh.w $vr3, $vr11, $vr9 \n"
|
||||
"vilvl.w $vr4, $vr14, $vr12 \n"
|
||||
"vilvh.w $vr5, $vr14, $vr12 \n"
|
||||
"vilvl.w $vr6, $vr15, $vr13 \n"
|
||||
"vilvh.w $vr7, $vr15, $vr13 \n"
|
||||
|
||||
"vilvl.d $vr8, $vr4, $vr0 \n"
|
||||
"vilvh.d $vr9, $vr4, $vr0 \n"
|
||||
"vilvl.d $vr10, $vr5, $vr1 \n"
|
||||
"vilvh.d $vr11, $vr5, $vr1 \n"
|
||||
"vilvl.d $vr12, $vr6, $vr2 \n"
|
||||
"vilvh.d $vr13, $vr6, $vr2 \n"
|
||||
"vilvl.d $vr14, $vr7, $vr3 \n"
|
||||
"vilvh.d $vr15, $vr7, $vr3 \n"
|
||||
|
||||
"vst $vr8, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr9, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr10, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr11, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr12, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr13, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr14, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr15, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"addi.w %[w], %[w], -1 \n"
|
||||
"bnez %[w], 1b \n"
|
||||
"2: \n"
|
||||
: [src] "+r"(src_b), // %[src]
|
||||
[dst] "+r"(dst_b), // %[dst]
|
||||
[w] "+r"(width), // %[w]
|
||||
[t] "=&r"(t) // %[t]
|
||||
: [s] "r"(s), // %[s]
|
||||
[d] "r"(d) // %[d]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14",
|
||||
"$vr15");
|
||||
}
|
||||
#endif // HAS_TRANSPOSEWX8_16_LSX
|
||||
|
||||
#ifdef HAS_TRANSPOSEWX16_LASX
|
||||
void TransposeWx16_LASX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst,
|
||||
@ -161,7 +530,9 @@ void TransposeWx16_LASX(const uint8_t* src,
|
||||
"$xr7", "$xr8", "$xr9", "$xr10", "$xr11", "$xr12", "$xr13", "$xr14",
|
||||
"$xr15");
|
||||
}
|
||||
#endif // HAS_TRANSPOSEWX16_LASX
|
||||
|
||||
#ifdef HAS_TRANSPOSEUVWX16_LASX
|
||||
void TransposeUVWx16_LASX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
@ -311,7 +682,9 @@ void TransposeUVWx16_LASX(const uint8_t* src,
|
||||
"$xr7", "$xr8", "$xr9", "$xr10", "$xr11", "$xr12", "$xr13", "$xr14",
|
||||
"$xr15");
|
||||
}
|
||||
#endif // HAS_TRANSPOSEUVWX16_LASX
|
||||
|
||||
#ifdef HAS_TRANSPOSEWX4_32_LASX
|
||||
void TransposeWx4_32_LASX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst,
|
||||
@ -382,7 +755,9 @@ void TransposeWx4_32_LASX(const uint8_t* src,
|
||||
: "memory", "$xr0", "$xr1", "$xr2", "$xr3", "$xr4", "$xr5", "$xr6",
|
||||
"$xr7");
|
||||
}
|
||||
#endif // HAS_TRANSPOSEWX4_32_LASX
|
||||
|
||||
#ifdef HAS_TRANSPOSEWX16_16_LASX
|
||||
void TransposeWx16_16_LASX(const uint16_t* src,
|
||||
int src_stride,
|
||||
uint16_t* dst,
|
||||
@ -497,10 +872,12 @@ void TransposeWx16_16_LASX(const uint16_t* src,
|
||||
"$xr7", "$xr8", "$xr9", "$xr10", "$xr11", "$xr12", "$xr13", "$xr14",
|
||||
"$xr15");
|
||||
}
|
||||
#endif // HAS_TRANSPOSEWX16_16_LASX
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
#endif
|
||||
|
||||
#endif // !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_asx)
|
||||
#endif // (!defined(LIBYUV_DISABLE_LSX) || !defined(LIBYUV_DISABLE_LASX)) &&
|
||||
// defined(__loongarch_lp64)
|
||||
@ -1,383 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The LibYuv Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "libyuv/rotate_row.h"
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace libyuv {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void TransposeWx8_LSX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst,
|
||||
int dst_stride,
|
||||
int width) {
|
||||
const ptrdiff_t s = src_stride;
|
||||
const ptrdiff_t d = dst_stride;
|
||||
const uint8_t* t;
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 4 \n"
|
||||
"beqz %[w], 2f \n"
|
||||
"1: \n"
|
||||
"move %[t], %[src] \n"
|
||||
"vld $vr0, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr1, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr2, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr3, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr4, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr5, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr6, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr7, %[t], 0 \n"
|
||||
"addi.d %[src], %[src], 16 \n"
|
||||
|
||||
"vilvl.b $vr8, $vr1, $vr0 \n"
|
||||
"vilvh.b $vr9, $vr1, $vr0 \n"
|
||||
"vilvl.b $vr10, $vr3, $vr2 \n"
|
||||
"vilvh.b $vr11, $vr3, $vr2 \n"
|
||||
"vilvl.b $vr12, $vr5, $vr4 \n"
|
||||
"vilvh.b $vr13, $vr5, $vr4 \n"
|
||||
"vilvl.b $vr14, $vr7, $vr6 \n"
|
||||
"vilvh.b $vr15, $vr7, $vr6 \n"
|
||||
|
||||
"vilvl.h $vr0, $vr10, $vr8 \n"
|
||||
"vilvh.h $vr1, $vr10, $vr8 \n"
|
||||
"vilvl.h $vr2, $vr11, $vr9 \n"
|
||||
"vilvh.h $vr3, $vr11, $vr9 \n"
|
||||
"vilvl.h $vr4, $vr14, $vr12 \n"
|
||||
"vilvh.h $vr5, $vr14, $vr12 \n"
|
||||
"vilvl.h $vr6, $vr15, $vr13 \n"
|
||||
"vilvh.h $vr7, $vr15, $vr13 \n"
|
||||
|
||||
"vilvl.w $vr8, $vr4, $vr0 \n"
|
||||
"vilvh.w $vr9, $vr4, $vr0 \n"
|
||||
"vilvl.w $vr10, $vr5, $vr1 \n"
|
||||
"vilvh.w $vr11, $vr5, $vr1 \n"
|
||||
"vilvl.w $vr12, $vr6, $vr2 \n"
|
||||
"vilvh.w $vr13, $vr6, $vr2 \n"
|
||||
"vilvl.w $vr14, $vr7, $vr3 \n"
|
||||
"vilvh.w $vr15, $vr7, $vr3 \n"
|
||||
|
||||
"vstelm.d $vr8, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr8, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr9, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr9, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr10, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr10, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr11, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr11, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr12, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr12, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr13, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr13, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr14, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr14, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr15, %[dst], 0, 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vstelm.d $vr15, %[dst], 0, 1 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"addi.w %[w], %[w], -1 \n"
|
||||
"bnez %[w], 1b \n"
|
||||
"2: \n"
|
||||
: [src] "+r"(src), // %[src]
|
||||
[dst] "+r"(dst), // %[dst]
|
||||
[w] "+r"(width), // %[w]
|
||||
[t] "=&r"(t) // %[t]
|
||||
: [s] "r"(s), // %[s]
|
||||
[d] "r"(d) // %[d]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14",
|
||||
"$vr15");
|
||||
}
|
||||
|
||||
void TransposeUVWx8_LSX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst_a,
|
||||
int dst_stride_a,
|
||||
uint8_t* dst_b,
|
||||
int dst_stride_b,
|
||||
int width) {
|
||||
const ptrdiff_t s = src_stride;
|
||||
const ptrdiff_t da = dst_stride_a;
|
||||
const ptrdiff_t db = dst_stride_b;
|
||||
const uint8_t* t;
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 3 \n"
|
||||
"beqz %[w], 2f \n"
|
||||
"1: \n"
|
||||
"move %[t], %[src] \n"
|
||||
"vld $vr0, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr1, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr2, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr3, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr4, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr5, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr6, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr7, %[t], 0 \n"
|
||||
"addi.d %[src], %[src], 16 \n"
|
||||
|
||||
"vilvl.b $vr8, $vr1, $vr0 \n"
|
||||
"vilvh.b $vr9, $vr1, $vr0 \n"
|
||||
"vilvl.b $vr10, $vr3, $vr2 \n"
|
||||
"vilvh.b $vr11, $vr3, $vr2 \n"
|
||||
"vilvl.b $vr12, $vr5, $vr4 \n"
|
||||
"vilvh.b $vr13, $vr5, $vr4 \n"
|
||||
"vilvl.b $vr14, $vr7, $vr6 \n"
|
||||
"vilvh.b $vr15, $vr7, $vr6 \n"
|
||||
|
||||
"vilvl.h $vr0, $vr10, $vr8 \n"
|
||||
"vilvh.h $vr1, $vr10, $vr8 \n"
|
||||
"vilvl.h $vr2, $vr11, $vr9 \n"
|
||||
"vilvh.h $vr3, $vr11, $vr9 \n"
|
||||
"vilvl.h $vr4, $vr14, $vr12 \n"
|
||||
"vilvh.h $vr5, $vr14, $vr12 \n"
|
||||
"vilvl.h $vr6, $vr15, $vr13 \n"
|
||||
"vilvh.h $vr7, $vr15, $vr13 \n"
|
||||
|
||||
"vilvl.w $vr8, $vr4, $vr0 \n"
|
||||
"vilvh.w $vr9, $vr4, $vr0 \n"
|
||||
"vilvl.w $vr10, $vr5, $vr1 \n"
|
||||
"vilvh.w $vr11, $vr5, $vr1 \n"
|
||||
"vilvl.w $vr12, $vr6, $vr2 \n"
|
||||
"vilvh.w $vr13, $vr6, $vr2 \n"
|
||||
"vilvl.w $vr14, $vr7, $vr3 \n"
|
||||
"vilvh.w $vr15, $vr7, $vr3 \n"
|
||||
|
||||
"vstelm.d $vr8, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr8, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr9, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr9, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr10, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr10, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr11, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr11, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr12, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr12, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr13, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr13, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr14, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr14, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"vstelm.d $vr15, %[dst_a], 0, 0 \n"
|
||||
"add.d %[dst_a], %[dst_a], %[da] \n"
|
||||
"vstelm.d $vr15, %[dst_b], 0, 1 \n"
|
||||
"add.d %[dst_b], %[dst_b], %[db] \n"
|
||||
"addi.w %[w], %[w], -1 \n"
|
||||
"bnez %[w], 1b \n"
|
||||
"2: \n"
|
||||
: [src] "+r"(src), // %[src]
|
||||
[dst_a] "+r"(dst_a), // %[dst_a]
|
||||
[dst_b] "+r"(dst_b), // %[dst_b]
|
||||
[w] "+r"(width), // %[w]
|
||||
[t] "=&r"(t) // %[t]
|
||||
: [s] "r"(s), // %[s]
|
||||
[da] "r"(da), // %[da]
|
||||
[db] "r"(db) // %[db]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14",
|
||||
"$vr15");
|
||||
}
|
||||
|
||||
void TransposeWx4_32_LSX(const uint8_t* src,
|
||||
int src_stride,
|
||||
uint8_t* dst,
|
||||
int dst_stride,
|
||||
int width) {
|
||||
const ptrdiff_t s = src_stride;
|
||||
const ptrdiff_t s2 = s * 2;
|
||||
const ptrdiff_t s3 = s + s2;
|
||||
const ptrdiff_t s4 = s * 4;
|
||||
uint8_t* dst0 = dst;
|
||||
uint8_t* dst1 = dst0 + dst_stride;
|
||||
uint8_t* dst2 = dst1 + dst_stride;
|
||||
uint8_t* dst3 = dst2 + dst_stride;
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 2 \n"
|
||||
"beqz %[w], 2f \n"
|
||||
"1: \n"
|
||||
"vld $vr0, %[src], 0 \n"
|
||||
"vldx $vr1, %[src], %[s] \n"
|
||||
"vldx $vr2, %[src], %[s2] \n"
|
||||
"vldx $vr3, %[src], %[s3] \n"
|
||||
"add.d %[src], %[src], %[s4] \n"
|
||||
|
||||
"vilvl.w $vr4, $vr1, $vr0 \n"
|
||||
"vilvh.w $vr5, $vr1, $vr0 \n"
|
||||
"vilvl.w $vr6, $vr3, $vr2 \n"
|
||||
"vilvh.w $vr7, $vr3, $vr2 \n"
|
||||
|
||||
"vilvl.d $vr0, $vr6, $vr4 \n"
|
||||
"vilvh.d $vr1, $vr6, $vr4 \n"
|
||||
"vilvl.d $vr2, $vr7, $vr5 \n"
|
||||
"vilvh.d $vr3, $vr7, $vr5 \n"
|
||||
|
||||
"vst $vr0, %[dst0], 0 \n"
|
||||
"vst $vr1, %[dst1], 0 \n"
|
||||
"vst $vr2, %[dst2], 0 \n"
|
||||
"vst $vr3, %[dst3], 0 \n"
|
||||
"addi.d %[dst0], %[dst0], 16 \n"
|
||||
"addi.d %[dst1], %[dst1], 16 \n"
|
||||
"addi.d %[dst2], %[dst2], 16 \n"
|
||||
"addi.d %[dst3], %[dst3], 16 \n"
|
||||
"addi.w %[w], %[w], -1 \n"
|
||||
"bnez %[w], 1b \n"
|
||||
"2: \n"
|
||||
: [src] "+r"(src), // %[src]
|
||||
[dst0] "+r"(dst0), // %[dst0]
|
||||
[dst1] "+r"(dst1), // %[dst1]
|
||||
[dst2] "+r"(dst2), // %[dst2]
|
||||
[dst3] "+r"(dst3), // %[dst3]
|
||||
[w] "+r"(width) // %[w]
|
||||
: [s] "r"(s), // %[s]
|
||||
[s2] "r"(s2), // %[s2]
|
||||
[s3] "r"(s3), // %[s3]
|
||||
[s4] "r"(s4) // %[s4]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
}
|
||||
|
||||
void TransposeWx8_16_LSX(const uint16_t* src,
|
||||
int src_stride,
|
||||
uint16_t* dst,
|
||||
int dst_stride,
|
||||
int width) {
|
||||
const ptrdiff_t s = (ptrdiff_t)src_stride * 2;
|
||||
const ptrdiff_t d = (ptrdiff_t)dst_stride * 2;
|
||||
const uint8_t* src_b = (const uint8_t*)src;
|
||||
uint8_t* dst_b = (uint8_t*)dst;
|
||||
const uint8_t* t;
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 3 \n"
|
||||
"beqz %[w], 2f \n"
|
||||
"1: \n"
|
||||
"move %[t], %[src] \n"
|
||||
"vld $vr0, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr1, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr2, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr3, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr4, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr5, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr6, %[t], 0 \n"
|
||||
"add.d %[t], %[t], %[s] \n"
|
||||
"vld $vr7, %[t], 0 \n"
|
||||
"addi.d %[src], %[src], 16 \n"
|
||||
|
||||
"vilvl.h $vr8, $vr1, $vr0 \n"
|
||||
"vilvh.h $vr9, $vr1, $vr0 \n"
|
||||
"vilvl.h $vr10, $vr3, $vr2 \n"
|
||||
"vilvh.h $vr11, $vr3, $vr2 \n"
|
||||
"vilvl.h $vr12, $vr5, $vr4 \n"
|
||||
"vilvh.h $vr13, $vr5, $vr4 \n"
|
||||
"vilvl.h $vr14, $vr7, $vr6 \n"
|
||||
"vilvh.h $vr15, $vr7, $vr6 \n"
|
||||
|
||||
"vilvl.w $vr0, $vr10, $vr8 \n"
|
||||
"vilvh.w $vr1, $vr10, $vr8 \n"
|
||||
"vilvl.w $vr2, $vr11, $vr9 \n"
|
||||
"vilvh.w $vr3, $vr11, $vr9 \n"
|
||||
"vilvl.w $vr4, $vr14, $vr12 \n"
|
||||
"vilvh.w $vr5, $vr14, $vr12 \n"
|
||||
"vilvl.w $vr6, $vr15, $vr13 \n"
|
||||
"vilvh.w $vr7, $vr15, $vr13 \n"
|
||||
|
||||
"vilvl.d $vr8, $vr4, $vr0 \n"
|
||||
"vilvh.d $vr9, $vr4, $vr0 \n"
|
||||
"vilvl.d $vr10, $vr5, $vr1 \n"
|
||||
"vilvh.d $vr11, $vr5, $vr1 \n"
|
||||
"vilvl.d $vr12, $vr6, $vr2 \n"
|
||||
"vilvh.d $vr13, $vr6, $vr2 \n"
|
||||
"vilvl.d $vr14, $vr7, $vr3 \n"
|
||||
"vilvh.d $vr15, $vr7, $vr3 \n"
|
||||
|
||||
"vst $vr8, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr9, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr10, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr11, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr12, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr13, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr14, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"vst $vr15, %[dst], 0 \n"
|
||||
"add.d %[dst], %[dst], %[d] \n"
|
||||
"addi.w %[w], %[w], -1 \n"
|
||||
"bnez %[w], 1b \n"
|
||||
"2: \n"
|
||||
: [src] "+r"(src_b), // %[src]
|
||||
[dst] "+r"(dst_b), // %[dst]
|
||||
[w] "+r"(width), // %[w]
|
||||
[t] "=&r"(t) // %[t]
|
||||
: [s] "r"(s), // %[s]
|
||||
[d] "r"(d) // %[d]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14",
|
||||
"$vr15");
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
#endif
|
||||
|
||||
#endif // !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
File diff suppressed because it is too large
Load Diff
3112
source/row_lsx.cc
3112
source/row_lsx.cc
File diff suppressed because it is too large
Load Diff
@ -8,34 +8,18 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "libyuv/row.h"
|
||||
#include "libyuv/scale_row.h"
|
||||
|
||||
#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
#if (!defined(LIBYUV_DISABLE_LSX) || !defined(LIBYUV_DISABLE_LASX)) && \
|
||||
defined(__loongarch_lp64)
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace libyuv {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static const uint64_t kScale38Shuf[2] = {0x13100e0b08060300ULL,
|
||||
0x000000001e1b1816ULL};
|
||||
static const uint64_t kScale38BoxShuf[2] = {0x0a08160604120200ULL,
|
||||
0x000000001e0e0c1aULL};
|
||||
static const uint64_t kScale34Shuf[2] = {0x0908070504030100ULL,
|
||||
0x000000000f0d0c0bULL};
|
||||
static const uint64_t kScale34BoxLo[2] = {0x0504030202010100ULL,
|
||||
0x0000000007060605ULL};
|
||||
static const uint64_t kScale34BoxHi[2] = {0x0d0c0b0a0a090908ULL,
|
||||
0x000000000f0e0e0dULL};
|
||||
static const uint64_t kScale34BoxWt[2] = {0x0103030102020103ULL,
|
||||
0x0000000003010202ULL};
|
||||
static const uint64_t kScale34Pack12[2] = {0x0908050403020100ULL,
|
||||
0x000000000d0c0b0aULL};
|
||||
static const uint64_t kRamp0123[2] = {0x0000000100000000ULL,
|
||||
0x0000000300000002ULL};
|
||||
|
||||
#ifdef HAS_SCALEARGBROWDOWN2_LSX
|
||||
void ScaleARGBRowDown2_LSX(const uint8_t* src_argb,
|
||||
ptrdiff_t src_stride,
|
||||
uint8_t* dst_argb,
|
||||
@ -129,7 +113,9 @@ void ScaleARGBRowDown2Box_LSX(const uint8_t* src_argb,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
}
|
||||
#endif // HAS_SCALEARGBROWDOWN2_LSX
|
||||
|
||||
#ifdef HAS_SCALEARGBROWDOWNEVEN_LSX
|
||||
void ScaleARGBRowDownEven_LSX(const uint8_t* src_argb,
|
||||
ptrdiff_t src_stride,
|
||||
int32_t src_stepx,
|
||||
@ -235,7 +221,9 @@ void ScaleARGBRowDownEvenBox_LSX(const uint8_t* src_argb,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
}
|
||||
#endif // HAS_SCALEARGBROWDOWNEVEN_LSX
|
||||
|
||||
#ifdef HAS_SCALEROWDOWN2_LSX
|
||||
void ScaleRowDown2_LSX(const uint8_t* src_ptr,
|
||||
ptrdiff_t src_stride,
|
||||
uint8_t* dst,
|
||||
@ -323,7 +311,9 @@ void ScaleRowDown2Box_LSX(const uint8_t* src_ptr,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
}
|
||||
#endif // HAS_SCALEROWDOWN2_LSX
|
||||
|
||||
#ifdef HAS_SCALEROWDOWN4_LSX
|
||||
void ScaleRowDown4_LSX(const uint8_t* src_ptr,
|
||||
ptrdiff_t src_stride,
|
||||
uint8_t* dst,
|
||||
@ -406,6 +396,13 @@ void ScaleRowDown4Box_LSX(const uint8_t* src_ptr,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
}
|
||||
#endif // HAS_SCALEROWDOWN4_LSX
|
||||
|
||||
#ifdef HAS_SCALEROWDOWN38_LSX
|
||||
static const uint64_t kScale38Shuf[2] = {0x13100e0b08060300ULL,
|
||||
0x000000001e1b1816ULL};
|
||||
static const uint64_t kScale38BoxShuf[2] = {0x0a08160604120200ULL,
|
||||
0x000000001e0e0c1aULL};
|
||||
|
||||
void ScaleRowDown38_LSX(const uint8_t* src_ptr,
|
||||
ptrdiff_t src_stride,
|
||||
@ -553,7 +550,9 @@ void ScaleRowDown38_3_Box_LSX(const uint8_t* src_ptr,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11");
|
||||
}
|
||||
#endif // HAS_SCALEROWDOWN38_LSX
|
||||
|
||||
#ifdef HAS_SCALEADDROW_LSX
|
||||
void ScaleAddRow_LSX(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) {
|
||||
asm volatile(
|
||||
"srli.w %[w], %[w], 4 \n"
|
||||
@ -580,7 +579,9 @@ void ScaleAddRow_LSX(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) {
|
||||
:
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5");
|
||||
}
|
||||
#endif // HAS_SCALEADDROW_LSX
|
||||
|
||||
#ifdef HAS_SCALEUVADDCOLS3_LSX
|
||||
static const uint8_t kScaleUVAddCols3Shuf[] = {
|
||||
0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 4, 5, 6, 7,
|
||||
4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 8, 9, 10, 11,
|
||||
@ -641,7 +642,15 @@ void ScaleUVAddCols3_LSX(int dst_width,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9", "$vr10", "$vr11", "$vr12", "$vr13");
|
||||
}
|
||||
#endif // HAS_SCALEUVADDCOLS3_LSX
|
||||
|
||||
#if defined(HAS_SCALEFILTERCOLS_LSX) || defined(HAS_SCALEARGBCOLS_LSX) || \
|
||||
defined(HAS_SCALEARGBFILTERCOLS_LSX)
|
||||
static const uint64_t kRamp0123[2] = {0x0000000100000000ULL,
|
||||
0x0000000300000002ULL};
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SCALEFILTERCOLS_LSX
|
||||
void ScaleFilterCols_LSX(uint8_t* dst_ptr,
|
||||
const uint8_t* src_ptr,
|
||||
int dst_width,
|
||||
@ -706,7 +715,9 @@ void ScaleFilterCols_LSX(uint8_t* dst_ptr,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7");
|
||||
}
|
||||
#endif // HAS_SCALEFILTERCOLS_LSX
|
||||
|
||||
#ifdef HAS_SCALEARGBCOLS_LSX
|
||||
void ScaleARGBCols_LSX(uint8_t* dst_argb,
|
||||
const uint8_t* src_argb,
|
||||
int dst_width,
|
||||
@ -757,7 +768,9 @@ void ScaleARGBCols_LSX(uint8_t* dst_argb,
|
||||
[ramp] "r"(kRamp0123) // %[ramp]
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3");
|
||||
}
|
||||
#endif // HAS_SCALEARGBCOLS_LSX
|
||||
|
||||
#ifdef HAS_SCALEARGBFILTERCOLS_LSX
|
||||
void ScaleARGBFilterCols_LSX(uint8_t* dst_argb,
|
||||
const uint8_t* src_argb,
|
||||
int dst_width,
|
||||
@ -826,6 +839,19 @@ void ScaleARGBFilterCols_LSX(uint8_t* dst_argb,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8");
|
||||
}
|
||||
#endif // HAS_SCALEARGBFILTERCOLS_LSX
|
||||
|
||||
#ifdef HAS_SCALEROWDOWN34_LSX
|
||||
static const uint64_t kScale34Shuf[2] = {0x0908070504030100ULL,
|
||||
0x000000000f0d0c0bULL};
|
||||
static const uint64_t kScale34BoxLo[2] = {0x0504030202010100ULL,
|
||||
0x0000000007060605ULL};
|
||||
static const uint64_t kScale34BoxHi[2] = {0x0d0c0b0a0a090908ULL,
|
||||
0x000000000f0e0e0dULL};
|
||||
static const uint64_t kScale34BoxWt[2] = {0x0103030102020103ULL,
|
||||
0x0000000003010202ULL};
|
||||
static const uint64_t kScale34Pack12[2] = {0x0908050403020100ULL,
|
||||
0x000000000d0c0b0aULL};
|
||||
|
||||
void ScaleRowDown34_LSX(const uint8_t* src_ptr,
|
||||
ptrdiff_t src_stride,
|
||||
@ -966,10 +992,12 @@ void ScaleRowDown34_1_Box_LSX(const uint8_t* src_ptr,
|
||||
: "memory", "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6",
|
||||
"$vr7", "$vr8", "$vr9");
|
||||
}
|
||||
#endif // HAS_SCALEROWDOWN34_LSX
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
#endif
|
||||
|
||||
#endif // !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx)
|
||||
#endif // (!defined(LIBYUV_DISABLE_LSX) || !defined(LIBYUV_DISABLE_LASX)) &&
|
||||
// defined(__loongarch_lp64)
|
||||
@ -338,11 +338,19 @@ TEST_F(LibYUVCompareTest, BenchmarkHammingDistance_Opt) {
|
||||
#elif defined(HAS_HAMMINGDISTANCE_LASX)
|
||||
if (TestCpuFlag(kCpuHasLASX)) {
|
||||
h1 = HammingDistance_LASX(src_a, src_b, kMaxWidth);
|
||||
} else {
|
||||
#if defined(HAS_HAMMINGDISTANCE_LSX)
|
||||
} else if (TestCpuFlag(kCpuHasLSX)) {
|
||||
h1 = HammingDistance_LSX(src_a, src_b, kMaxWidth);
|
||||
#endif
|
||||
} else {
|
||||
h1 = HammingDistance_C(src_a, src_b, kMaxWidth);
|
||||
}
|
||||
#elif defined(HAS_HAMMINGDISTANCE_LSX)
|
||||
h1 = HammingDistance_LSX(src_a, src_b, kMaxWidth);
|
||||
if (TestCpuFlag(kCpuHasLSX)) {
|
||||
h1 = HammingDistance_LSX(src_a, src_b, kMaxWidth);
|
||||
} else {
|
||||
h1 = HammingDistance_C(src_a, src_b, kMaxWidth);
|
||||
}
|
||||
#elif defined(HAS_HAMMINGDISTANCE_WASMSIMD)
|
||||
h1 = HammingDistance_WASMSIMD(src_a, src_b, kMaxWidth);
|
||||
#elif defined(HAS_HAMMINGDISTANCE_HVX)
|
||||
@ -493,11 +501,19 @@ TEST_F(LibYUVCompareTest, TestHammingDistance_Opt) {
|
||||
#elif defined(HAS_HAMMINGDISTANCE_LASX)
|
||||
if (TestCpuFlag(kCpuHasLASX)) {
|
||||
h1 = HammingDistance_LASX(src_a, src_b, kMaxWidth);
|
||||
} else {
|
||||
#if defined(HAS_HAMMINGDISTANCE_LSX)
|
||||
} else if (TestCpuFlag(kCpuHasLSX)) {
|
||||
h1 = HammingDistance_LSX(src_a, src_b, kMaxWidth);
|
||||
#endif
|
||||
} else {
|
||||
h1 = HammingDistance_C(src_a, src_b, kMaxWidth);
|
||||
}
|
||||
#elif defined(HAS_HAMMINGDISTANCE_LSX)
|
||||
h1 = HammingDistance_LSX(src_a, src_b, kMaxWidth);
|
||||
if (TestCpuFlag(kCpuHasLSX)) {
|
||||
h1 = HammingDistance_LSX(src_a, src_b, kMaxWidth);
|
||||
} else {
|
||||
h1 = HammingDistance_C(src_a, src_b, kMaxWidth);
|
||||
}
|
||||
#elif defined(HAS_HAMMINGDISTANCE_WASMSIMD)
|
||||
h1 = HammingDistance_WASMSIMD(src_a, src_b, kMaxWidth);
|
||||
#elif defined(HAS_HAMMINGDISTANCE_HVX)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user