diff --git a/mips/check.h b/mips/check.h index 10fd3addb7..9e6164044e 100644 --- a/mips/check.h +++ b/mips/check.h @@ -9,8 +9,6 @@ * For conditions of distribution and use, see the disclaimer * and license in png.h */ -#ifdef PNG_READ_SUPPORTED - #if defined(__mips_msa) && (__mips_isa_rev >= 5) # ifndef PNG_MIPS_MSA_IMPLEMENTATION # if defined(__mips_msa) @@ -44,11 +42,14 @@ # define PNG_MIPS_MMI_IMPLEMENTATION 0 #endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */ -#if PNG_MIPS_MSA_IMPLEMENTATION == 1 || PNG_MIPS_MMI_IMPLEMENTATION > 0 +#include "loongarch/check.h" + +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 ||\ + PNG_MIPS_MMI_IMPLEMENTATION > 0 ||\ + PNG_MIPS_LSX_IMPLEMENTATION > 0 # define PNG_TARGET_CODE_IMPLEMENTATION "mips/mips_init.c" /*PNG_TARGET_STORES_DATA*/ # define PNG_TARGET_IMPLEMENTS_FILTERS /*PNG_TARGET_IMPLEMENTS_EXPAND_PALETTE*/ # define PNG_TARGET_ROW_ALIGNMENT 16 -#endif /* MIPS MSA or MMI */ -#endif /* READ */ +#endif /* MIPS MSA or Loongson MMI or Loongarch SX */ diff --git a/loongarch/.editorconfig b/mips/loongarch/.editorconfig similarity index 100% rename from loongarch/.editorconfig rename to mips/loongarch/.editorconfig diff --git a/mips/loongarch/check.h b/mips/loongarch/check.h new file mode 100644 index 0000000000..1f25aeb939 --- /dev/null +++ b/mips/loongarch/check.h @@ -0,0 +1,26 @@ +/* check.h - LSX optimized filter functions + * copied from loongarch_lsx_init.c + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + * All rights reserved. + * Contributed by Jin Bo + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * Modified 2024 by John Bowler, changes + * Copyright (c) 2024 John Bowler, licensed under the libpng license: + */ +#if defined(__loongarch_sx) && defined(__GLIBC__) + /* The code uses the GNU glibc specific function getauxval so this is + * required: + */ +# if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16) +# define PNG_MIPS_LSX_IMPLEMENTATION 1 +# else +# define PNG_MIPS_LSX_IMPLEMENTATION 0 +# endif /* glibc >= 2.16 */ +#else +# define PNG_MIPS_LSX_IMPLEMENTATION 0 +#endif /* __loongarch_sx */ diff --git a/loongarch/filter_lsx_intrinsics.c b/mips/loongarch/filter_lsx_intrinsics.c similarity index 99% rename from loongarch/filter_lsx_intrinsics.c rename to mips/loongarch/filter_lsx_intrinsics.c index f1b74659b5..64f2d89b1b 100644 --- a/loongarch/filter_lsx_intrinsics.c +++ b/mips/loongarch/filter_lsx_intrinsics.c @@ -405,6 +405,3 @@ png_read_filter_row_paeth4_lsx(png_row_infop row_info, png_bytep row, n -= 4; } } - -#endif /* PNG_LOONGARCH_LSX_IMPLEMENTATION == 1 (intrinsics) */ -#endif /* PNG_READ_SUPPORTED */ diff --git a/loongarch/loongarch_lsx_init.c b/mips/loongarch/loongarch_lsx_init.c similarity index 80% rename from loongarch/loongarch_lsx_init.c rename to mips/loongarch/loongarch_lsx_init.c index e98c53bb33..80f2e94acf 100644 --- a/loongarch/loongarch_lsx_init.c +++ b/mips/loongarch/loongarch_lsx_init.c @@ -7,27 +7,20 @@ * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h + * + * Modified 2024 by John Bowler, changes + * Copyright (c) 2024 John Bowler, licensed under the libpng license. */ -#ifdef __loongarch_sx -#define png_target_impl "loongarch-sx" - #include - #include "filter_lsx_intrinsics.c" #define LA_HWCAP_LSX (1<<4) static int png_has_lsx(void) { - int flags = 0; - int flag = (int)getauxval(AT_HWCAP); - - if (flag & LA_HWCAP_LSX) - return 1; - - return 0; + return (getauxval(AT_HWCAP) & LA_HWCAP_LSX) != 0U; } -static void +static int png_init_filter_functions_lsx(png_structp pp, unsigned int bpp) { if (png_has_lsx()) @@ -45,9 +38,7 @@ png_init_filter_functions_lsx(png_structp pp, unsigned int bpp) pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_lsx; pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_lsx; } + return 1; /* using Loongarch SX extensions */ } + return 0; /* nothing done */ } - -#define png_target_init_filter_functions png_init_filter_functions_lsx - -#endif /* __loongarch_sx */ diff --git a/mips/mips_init.c b/mips/mips_init.c index f80680b5f4..14cacc8445 100644 --- a/mips/mips_init.c +++ b/mips/mips_init.c @@ -8,12 +8,13 @@ * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h - */ -/* MIPS supports two optimizations: MMI and MSA. When both are available the - * appropriate optimization is chosen at runtime using the png_set_option - * settings. * - * NOTE: see also the separate loongson code... + * Modified 2024 by John Bowler, changes + * Copyright (c) 2024 John Bowler, licensed under the libpng license + */ +/* MIPS supports three optimizations: MSA, MSI and LSX (Loongarch SX). When two + * or more are available the appropriate optimization is chosen at runtime using + * the png_set_option settings and/or runtime checks. */ #if PNG_MIPS_MSA_IMPLEMENATION == 1 # include "filter_msa_intrinsics.c" @@ -21,18 +22,30 @@ #if PNG_MIPS_MMI_IMPLEMENTATION > 0 # include "filter_mmi_inline_assembly.c" #endif +#if PNG_MIPS_LSX_IMPLEMENTATION > 0 +# include "loongarch/loongarch_lsx_init.c" +#endif static void png_init_filter_functions_mips(png_structp pp, unsigned int bpp) { -# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +# if PNG_MIPS_LSX_IMPLEMENTATION > 0 +# define png_target_impl_lsx "+lsx" + + /* TODO: put in an option check. */ + if (png_init_filter_functions_lsx(pp, bpp)) + return; + /* Else fall through to see if something else is available: */ +# else +# define png_target_impl_lsx "" +# endif + +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 /* Check the option if MSA is also supported: */ +# define png_target_impl_mmi "+mmi" # if PNG_MIPS_MSA_IMPLEMENATION == 1 -# define png_target_impl "mips-msa+msi" /* NOTE: if this is false the code below will not be executed. */ if (((pp->options >> PNG_MIPS_USE_MMI) & 3) == PNG_OPTION_ON) -# else -# define png_target_impl "mips-mmi" # endif { /* This is the MMI implementation: */ @@ -57,8 +70,12 @@ png_init_filter_functions_mips(png_structp pp, unsigned int bpp) } return; } -# else /* !(PNG_MIPS_MMI_IMPLEMENTATION > 0) */ -# define png_target_impl "mips-msa" +# else /* PNG_MIPS_MMI_IMPLEMENTATION == 0 */ +# define png_target_impl_mmi "" +# endif + +# if PNG_MIPS_MSA_IMPLEMENATION == 1 +# define png_target_impl_msa "+msa" pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_msa; if (bpp == 3) @@ -79,4 +96,11 @@ png_init_filter_functions_mips(png_structp pp, unsigned int bpp) # endif /* PNG_MIPS_MSA_IMPLEMENTATION == 1 */ } -#define png_target_init_filter_functions_impl png_init_filter_functions_mips +#if defined(png_target_impl_msa) || defined(png_target_impl_msi) ||\ + defined(png_target_impl_lsx) +# define png_target_impl "mips"\ + png_target_impl_msa png_target_impl_mmi png_target_impl_lsx +# define png_target_init_filter_functions_impl png_init_filter_functions_mips +#else +# error HARDWARE: MIPS: no implementations defined +#endif