diff --git a/Makefile b/Makefile index a25e85df..2d95b38f 100644 --- a/Makefile +++ b/Makefile @@ -194,6 +194,25 @@ endif OBJCHK += tools/checkasm-aarch64.o endif +# RISCV64 RVV optims +ifeq ($(SYS_ARCH),RISCV64) +ifneq ($(findstring HAVE_RVV 1, $(CONFIG)),) +SRCASM_X = + +SRCS_X += + +OBJASM += +ifneq ($(findstring HAVE_BITDEPTH8 1, $(CONFIG)),) +OBJASM += $(SRCASM_X:%.S=%-8.o) +endif +ifneq ($(findstring HAVE_BITDEPTH10 1, $(CONFIG)),) +OBJASM += $(SRCASM_X:%.S=%-10.o) +endif + +OBJCHK += +endif +endif + # MSA optims ifeq ($(SYS_ARCH),MIPS) ifneq ($(findstring HAVE_MSA 1, $(CONFIG)),) diff --git a/common/cpu.c b/common/cpu.c index 887dbecb..73900db9 100644 --- a/common/cpu.c +++ b/common/cpu.c @@ -99,6 +99,8 @@ const x264_cpu_name_t x264_cpu_names[] = {"I8MM", X264_CPU_I8MM}, {"SVE", X264_CPU_SVE}, {"SVE2", X264_CPU_SVE2}, +#elif ARCH_RISCV64 + {"RVV", X264_CPU_RVV}, #elif ARCH_MIPS {"MSA", X264_CPU_MSA}, #elif ARCH_LOONGARCH @@ -459,6 +461,28 @@ uint32_t x264_cpu_detect( void ) return flags; } +#elif HAVE_RISCV64 + +#define HWCAP_RISCV64_RVV (1 << ('V' - 'A')) + +uint32_t x264_cpu_detect( void ) +{ + uint32_t flags = 0; + +#if HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO + unsigned long hwcap = x264_getauxval( AT_HWCAP ); + + if ( hwcap & HWCAP_RISCV64_RVV ) + flags |= X264_CPU_RVV; +#else +#if HAVE_RVV + flags |= X264_CPU_RVV; +#endif +#endif + + return flags; +} + #elif HAVE_AARCH64 #if defined(__linux__) || HAVE_ELF_AUX_INFO diff --git a/config.guess b/config.guess index 9921fda7..8dc6d6b2 100755 --- a/config.guess +++ b/config.guess @@ -882,6 +882,9 @@ EOF UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; diff --git a/config.sub b/config.sub index 3093784c..8355f6bc 100755 --- a/config.sub +++ b/config.sub @@ -255,6 +255,7 @@ case $basic_machine in # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | riscv64 \ | aarch64 | aarch64_be | arm64 \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ @@ -370,6 +371,7 @@ case $basic_machine in # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | riscv64-* \ | aarch64-* | aarch64_be-* | arm64*-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ diff --git a/configure b/configure index 5116bb97..d1d0a471 100755 --- a/configure +++ b/configure @@ -426,6 +426,7 @@ CONFIG_HAVE="MALLOC_H ALTIVEC ALTIVEC_H MMX ARMV6 ARMV6T2 NEON AARCH64 BEOSTHREA MSA LSX MMAP WINRT VSX ARM_INLINE_ASM STRTOK_R CLOCK_GETTIME BITDEPTH8 BITDEPTH10 ELF_AUX_INFO GETAUXVAL \ SYSCONF SYNC_FETCH_AND_ADD \ DOTPROD I8MM SVE SVE2 \ + RISCV64 RVV \ AS_ARCHEXT_DOTPROD_DIRECTIVE AS_ARCHEXT_I8MM_DIRECTIVE AS_ARCHEXT_SVE_DIRECTIVE AS_ARCHEXT_SVE2_DIRECTIVE" # parse options @@ -885,6 +886,12 @@ case $host_cpu in AS="${AS-${CC}}" fi ;; + riscv64) + ARCH="RISCV64" + stack_alignment=16 + + AS="${AS-${CC}}" + ;; s390|s390x) ARCH="S390" ;; @@ -1076,6 +1083,15 @@ if [ $asm = auto -a $ARCH = MIPS ] ; then fi fi +if [ $asm = auto -a $ARCH = RISCV64 ] ; then + define HAVE_RISCV64 + if cc_check '' '' '__asm__(".option arch, +v\n" "vsetvli t0, a0, e32, m1, ta, ma");' ; then + define HAVE_RVV + fi + + ASFLAGS="$ASFLAGS -c" +fi + if [ $asm = auto -a $ARCH = LOONGARCH ] ; then if cc_check '' '' '__asm__("xvadd.b $xr0, $xr1, $xr2");' ; then # Use HAVE_LSX as the base flag, compiler support LA SIMD(LSX and LASX) @@ -1750,7 +1766,7 @@ cat conftest.log >> config.log cat conftest.log [ "$SRCPATH" != "." ] && ln -sf ${SRCPATH}/Makefile ./Makefile -mkdir -p common/{aarch64,arm,mips,ppc,x86,loongarch} encoder extras filters/video input output tools +mkdir -p common/{aarch64,arm,mips,ppc,x86,loongarch,riscv64} encoder extras filters/video input output tools echo echo "You can run 'make' or 'make fprofiled' now." diff --git a/tools/checkasm.c b/tools/checkasm.c index 09288a62..cdd94eb6 100644 --- a/tools/checkasm.c +++ b/tools/checkasm.c @@ -115,6 +115,8 @@ static inline uint32_t read_time(void) uint64_t b = 0; asm volatile( "mrs %0, pmccntr_el0" : "=r"(b) :: "memory" ); a = b; +#elif ARCH_RISCV64 + asm volatile( "rdtime %0" : "=r"(a) :: "memory" ); #elif ARCH_MIPS asm volatile( "rdhwr %0, $2" : "=r"(a) :: "memory" ); #elif ARCH_LOONGARCH @@ -220,6 +222,8 @@ static void print_bench(void) b->cpu&X264_CPU_DOTPROD ? "dotprod" : b->cpu&X264_CPU_NEON ? "neon" : b->cpu&X264_CPU_ARMV8 ? "armv8" : +#elif ARCH_RISCV64 + b->cpu&X264_CPU_RVV ? "rvv" : #elif ARCH_MIPS b->cpu&X264_CPU_MSA ? "msa" : #elif ARCH_LOONGARCH @@ -276,6 +280,10 @@ intptr_t x264_checkasm_call_noneon( intptr_t (*func)(), int *ok, ... ); intptr_t (*x264_checkasm_call)( intptr_t (*func)(), int *ok, ... ) = x264_checkasm_call_noneon; #endif +#if ARCH_RISCV64 +intptr_t x264_checkasm_call( intptr_t (*func)(), int *ok, ... ); +#endif + #if ARCH_LOONGARCH intptr_t x264_checkasm_call( intptr_t (*func)(), int *ok, ... ); #endif @@ -3014,6 +3022,9 @@ static int check_all_flags( void ) ret |= add_flags( &cpu0, &cpu1, X264_CPU_SVE2, buf ); } #endif +#elif ARCH_RISCV64 + if( cpu_detect & X264_CPU_RVV ) + ret |= add_flags( &cpu0, &cpu1, X264_CPU_RVV, "RVV" ); #elif ARCH_MIPS if( cpu_detect & X264_CPU_MSA ) ret |= add_flags( &cpu0, &cpu1, X264_CPU_MSA, "MSA" ); @@ -3035,7 +3046,7 @@ REALIGN_STACK int main( int argc, char **argv ) if( argc > 1 && !strncmp( argv[1], "--bench", 7 ) ) { -#if !ARCH_X86 && !ARCH_X86_64 && !ARCH_PPC && !ARCH_ARM && !ARCH_AARCH64 && !ARCH_MIPS && !ARCH_LOONGARCH +#if !ARCH_X86 && !ARCH_X86_64 && !ARCH_PPC && !ARCH_ARM && !ARCH_AARCH64 && !ARCH_MIPS && !ARCH_LOONGARCH && !ARCH_RISCV64 fprintf( stderr, "no --bench for your cpu until you port rdtsc\n" ); return 1; #endif diff --git a/x264.h b/x264.h index cc22f05d..b3223cd8 100644 --- a/x264.h +++ b/x264.h @@ -182,6 +182,9 @@ typedef struct x264_nal_t #define X264_CPU_DOTPROD 0x0000040U /* AArch64 DotProd */ #define X264_CPU_I8MM 0x0000080U /* AArch64 I8MM */ +/* RISCV64 */ +#define X264_CPU_RVV 0x0000001U /* RISCV64 RVV */ + /* MIPS */ #define X264_CPU_MSA 0x0000001U /* MIPS MSA */