Add loongarch support

LSX and LASX are enabled by default if compiler supports them.
This commit is contained in:
yuanhecai 2022-05-31 19:10:05 +08:00 committed by Sam Lantinga
parent 9703f23663
commit 17f63e53f8
5 changed files with 268 additions and 0 deletions

127
configure vendored
View File

@ -838,6 +838,8 @@ enable_3dnow
enable_sse enable_sse
enable_sse2 enable_sse2
enable_sse3 enable_sse3
enable_lsx
enable_lasx
enable_altivec enable_altivec
enable_oss enable_oss
enable_alsa enable_alsa
@ -1620,6 +1622,8 @@ Optional Features:
--enable-sse use SSE assembly routines [default=yes] --enable-sse use SSE assembly routines [default=yes]
--enable-sse2 use SSE2 assembly routines [default=maybe] --enable-sse2 use SSE2 assembly routines [default=maybe]
--enable-sse3 use SSE3 assembly routines [default=maybe] --enable-sse3 use SSE3 assembly routines [default=maybe]
--enable-lsx use LSX assembly routines [default=yes]
--enable-lasx use LASX assembly routines [default=yes]
--enable-altivec use Altivec assembly routines [default=yes] --enable-altivec use Altivec assembly routines [default=yes]
--enable-oss support the OSS audio API [default=maybe] --enable-oss support the OSS audio API [default=maybe]
--enable-alsa support the ALSA audio API [default=yes] --enable-alsa support the ALSA audio API [default=yes]
@ -18769,6 +18773,129 @@ $as_echo "#define HAVE_IMMINTRIN_H 1" >>confdefs.h
fi fi
# Check whether --enable-lsx was given.
if test "${enable_lsx+set}" = set; then :
enableval=$enable_lsx;
else
enable_lsx=yes
fi
if test x$enable_lsx = xyes; then
save_CFLAGS="$CFLAGS"
have_gcc_lsx=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -mlsx option" >&5
$as_echo_n "checking for GCC -mlsx option... " >&6; }
lsx_CFLAGS="-mlsx"
CFLAGS="$save_CFLAGS $lsx_CFLAGS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifndef __loongarch_sx
#error Assembler CPP flag not enabled
#endif
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
have_gcc_lsx=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_lsx" >&5
$as_echo "$have_gcc_lsx" >&6; }
CFLAGS="$save_CFLAGS"
if test x$have_gcc_lsx = xyes; then
EXTRA_CFLAGS="$EXTRA_CFLAGS $lsx_CFLAGS"
SUMMARY_math="${SUMMARY_math} lsx"
fi
fi
ac_fn_c_check_header_mongrel "$LINENO" "lsxintrin.h" "ac_cv_header_lsxintrin_h" "$ac_includes_default"
if test "x$ac_cv_header_lsxintrin_h" = xyes; then :
have_lsx_h_hdr=yes
else
have_lsx_h_hdr=no
fi
if test x$have_lsx_h_hdr = xyes; then
$as_echo "#define HAVE_LSXINTRIN_H 1" >>confdefs.h
fi
# Check whether --enable-lasx was given.
if test "${enable_lasx+set}" = set; then :
enableval=$enable_lasx;
else
enable_LASX=yes
fi
if test x$enable_LASX = xyes; then
save_CFLAGS="$CFLAGS"
have_gcc_lasx=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -mlasx option" >&5
$as_echo_n "checking for GCC -mlasx option... " >&6; }
lasx_CFLAGS="-mlasx"
CFLAGS="$save_CFLAGS $lasx_CFLAGS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifndef __loongarch_asx
#error Assembler CPP flag not enabled
#endif
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
have_gcc_lasx=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_lasx" >&5
$as_echo "$have_gcc_lasx" >&6; }
CFLAGS="$save_CFLAGS"
if test x$have_gcc_lasx = xyes; then
EXTRA_CFLAGS="$EXTRA_CFLAGS $lasx_CFLAGS"
SUMMARY_math="${SUMMARY_math} lasx"
fi
fi
ac_fn_c_check_header_mongrel "$LINENO" "lasxintrin.h" "ac_cv_header_lasxintrin_h" "$ac_includes_default"
if test "x$ac_cv_header_lasxintrin_h" = xyes; then :
have_lasx_h_hdr=yes
else
have_lasx_h_hdr=no
fi
if test x$have_lasx_h_hdr = xyes; then
$as_echo "#define HAVE_LASXINTRIN_H 1" >>confdefs.h
fi
# Check whether --enable-altivec was given. # Check whether --enable-altivec was given.
if test "${enable_altivec+set}" = set; then : if test "${enable_altivec+set}" = set; then :
enableval=$enable_altivec; enableval=$enable_altivec;

View File

@ -852,6 +852,70 @@ dnl Check for various instruction support
fi fi
fi fi
AC_ARG_ENABLE(lsx,
[AC_HELP_STRING([--enable-lsx], [use LSX assembly routines [default=yes]])],
, enable_lsx=yes)
if test x$enable_lsx = xyes; then
save_CFLAGS="$CFLAGS"
have_gcc_lsx=no
AC_MSG_CHECKING(for GCC -mlsx option)
lsx_CFLAGS="-mlsx"
CFLAGS="$save_CFLAGS $lsx_CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifndef __loongarch_sx
#error Assembler CPP flag not enabled
#endif
]], [])], [have_gcc_lsx=yes], [])
AC_MSG_RESULT($have_gcc_lsx)
CFLAGS="$save_CFLAGS"
if test x$have_gcc_lsx = xyes; then
EXTRA_CFLAGS="$EXTRA_CFLAGS $lsx_CFLAGS"
SUMMARY_math="${SUMMARY_math} lsx"
fi
fi
AC_MSG_CHECKING(for lsxintrin.h)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <lsxintrin.h>]])],
[have_lsxintrin_h_hdr=yes],[have_lsxintrin_h_hdr=no])
AC_MSG_RESULT($have_lsxintrin_h_hdr)
if test x$have_lsxintrin_h_hdr = xyes; then
AC_DEFINE(HAVE_LSXINTRIN_H, 1, [ ])
fi
AC_ARG_ENABLE(lasx,
[AC_HELP_STRING([--enable-lasx], [use LASX assembly routines [default=yes]])],
, enable_LASX=yes)
if test x$enable_LASX = xyes; then
save_CFLAGS="$CFLAGS"
have_gcc_lasx=no
AC_MSG_CHECKING(for GCC -mlasx option)
lasx_CFLAGS="-mlasx"
CFLAGS="$save_CFLAGS $lasx_CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifndef __loongarch_asx
#error Assembler CPP flag not enabled
#endif
]], [])], [have_gcc_lasx=yes], [])
AC_MSG_RESULT($have_gcc_lasx)
CFLAGS="$save_CFLAGS"
if test x$have_gcc_lasx = xyes; then
EXTRA_CFLAGS="$EXTRA_CFLAGS $lasx_CFLAGS"
SUMMARY_math="${SUMMARY_math} lasx"
fi
fi
AC_MSG_CHECKING(for lasxintrin.h)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <lasxintrin.h>]])],
[have_lasxintrin_h_hdr=yes],[have_lasxintrin_h_hdr=no])
AC_MSG_RESULT($have_lasxintrin_h_hdr)
if test x$have_lasxintrin_h_hdr = xyes; then
AC_DEFINE(HAVE_LASXINTRIN_H, 1, [ ])
fi
dnl See if the OSS audio interface is supported dnl See if the OSS audio interface is supported
CheckOSS() CheckOSS()
{ {

View File

@ -229,6 +229,8 @@
#undef HAVE_LIBUDEV_H #undef HAVE_LIBUDEV_H
#undef HAVE_LIBSAMPLERATE_H #undef HAVE_LIBSAMPLERATE_H
#undef HAVE_LIBDECOR_H #undef HAVE_LIBDECOR_H
#undef HAVE_LSXINTRIN_H
#undef HAVE_LASXINTRIN_H
#undef HAVE_DDRAW_H #undef HAVE_DDRAW_H
#undef HAVE_DINPUT_H #undef HAVE_DINPUT_H

View File

@ -98,6 +98,14 @@ _m_prefetch(void *__P)
#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H) #if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H)
#include <mm3dnow.h> #include <mm3dnow.h>
#endif #endif
#if defined(__loongarch_sx) && !defined(SDL_DISABLE_LSX_H)
#include <lsxintrin.h>
#define __LSX__
#endif
#if defined(__loongarch_asx) && !defined(SDL_DISABLE_LASX_H)
#include <lasxintrin.h>
#define __LASX__
#endif
#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) #if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
#include <immintrin.h> #include <immintrin.h>
#else #else
@ -433,6 +441,28 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void);
*/ */
extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void); extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void);
/**
* Determine whether the CPU has LSX (LOONGARCH SIMD) features.
*
* This always returns false on CPUs that aren't using LOONGARCH instruction sets.
*
* \returns SDL_TRUE if the CPU has LOONGARCH LSX features or SDL_FALSE if not.
*
* \since This function is available since SDL 2.0.23.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasLSX(void);
/**
* Determine whether the CPU has LASX (LOONGARCH SIMD) features.
*
* This always returns false on CPUs that aren't using LOONGARCH instruction sets.
*
* \returns SDL_TRUE if the CPU has LOONGARCH LASX features or SDL_FALSE if not.
*
* \since This function is available since SDL 2.0.23.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasLASX(void);
/** /**
* Get the amount of RAM configured in the system. * Get the amount of RAM configured in the system.
* *

View File

@ -112,6 +112,12 @@
#define CPU_HAS_NEON (1 << 11) #define CPU_HAS_NEON (1 << 11)
#define CPU_HAS_AVX512F (1 << 12) #define CPU_HAS_AVX512F (1 << 12)
#define CPU_HAS_ARM_SIMD (1 << 13) #define CPU_HAS_ARM_SIMD (1 << 13)
#define CPU_HAS_LSX (1 << 14)
#define CPU_HAS_LASX (1 << 15)
#define CPU_CFG2 0x2
#define CPU_CFG2_LSX (1 << 6)
#define CPU_CFG2_LASX (1 << 7)
#if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__ && !__FreeBSD__ #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__ && !__FreeBSD__
/* This is the brute force way of detecting instruction sets... /* This is the brute force way of detecting instruction sets...
@ -508,6 +514,23 @@ CPU_haveNEON(void)
#endif #endif
} }
static int
CPU_readCPUCFG(void)
{
uint32_t cfg2 = 0;
#if defined __loongarch__
__asm__ volatile(
"cpucfg %0, %1 \n\t"
: "+&r"(cfg2)
: "r"(CPU_CFG2)
);
#endif
return cfg2;
}
#define CPU_haveLSX() (CPU_readCPUCFG() & CPU_CFG2_LSX)
#define CPU_haveLASX() (CPU_readCPUCFG() & CPU_CFG2_LASX)
#if defined(__e2k__) #if defined(__e2k__)
inline int inline int
CPU_have3DNow(void) CPU_have3DNow(void)
@ -885,6 +908,14 @@ SDL_GetCPUFeatures(void)
SDL_CPUFeatures |= CPU_HAS_NEON; SDL_CPUFeatures |= CPU_HAS_NEON;
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16); SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
} }
if (CPU_haveLSX()) {
SDL_CPUFeatures |= CPU_HAS_LSX;
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
}
if (CPU_haveLASX()) {
SDL_CPUFeatures |= CPU_HAS_LASX;
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
}
} }
return SDL_CPUFeatures; return SDL_CPUFeatures;
} }
@ -974,6 +1005,18 @@ SDL_HasNEON(void)
return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON); return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON);
} }
SDL_bool
SDL_HasLSX(void)
{
return CPU_FEATURE_AVAILABLE(CPU_HAS_LSX);
}
SDL_bool
SDL_HasLASX(void)
{
return CPU_FEATURE_AVAILABLE(CPU_HAS_LASX);
}
static int SDL_SystemRAM = 0; static int SDL_SystemRAM = 0;
int int
@ -1170,6 +1213,8 @@ main()
printf("AVX-512F: %d\n", SDL_HasAVX512F()); printf("AVX-512F: %d\n", SDL_HasAVX512F());
printf("ARM SIMD: %d\n", SDL_HasARMSIMD()); printf("ARM SIMD: %d\n", SDL_HasARMSIMD());
printf("NEON: %d\n", SDL_HasNEON()); printf("NEON: %d\n", SDL_HasNEON());
printf("LSX: %d\n", SDL_HasLSX());
printf("LASX: %d\n", SDL_HasLASX());
printf("RAM: %d MB\n", SDL_GetSystemRAM()); printf("RAM: %d MB\n", SDL_GetSystemRAM());
return 0; return 0;
} }