diff --git a/meson.build b/meson.build index 2ef0b88e6d3..2c3cbdd9b17 100644 --- a/meson.build +++ b/meson.build @@ -1285,6 +1285,11 @@ elif host_machine.cpu_family().startswith('ppc64') and host_machine.endian() == with_asm_arch = 'ppc64le' pre_args += ['-DUSE_PPC64LE_ASM'] endif +elif host_machine.cpu_family() == 'mips64' and host_machine.endian() == 'little' + if system_has_kms_drm + with_asm_arch = 'mips64el' + pre_args += ['-DUSE_MIPS64EL_ASM'] + endif endif # Check for standard headers and functions diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index 4f3e696816c..44d07fe69c6 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -464,6 +464,12 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT, #endif #endif +#if defined(PIPE_ARCH_MIPS64) + MAttrs.push_back(util_get_cpu_caps()->has_msa ? "+msa" : "-msa"); + /* MSA requires a 64-bit FPU register file */ + MAttrs.push_back("+fp64"); +#endif + builder.setMAttrs(MAttrs); if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) { @@ -516,6 +522,19 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT, MCPU = "pwr8"; #endif #endif + +#if defined(PIPE_ARCH_MIPS64) + /* + * ls3a4000 CPU and ls2k1000 SoC is a mips64r5 compatible with MSA SIMD + * instruction set implemented, while ls3a3000 is mips64r2 compatible + * only. getHostCPUName() return "generic" on all loongson + * mips CPU currently. So we override the MCPU to mips64r5 if MSA is + * implemented, feedback to mips64r2 for all other ordinary mips64 cpu. + */ + if (MCPU == "generic") + MCPU = util_get_cpu_caps()->has_msa ? "mips64r5" : "mips64r2"; +#endif + builder.setMCPU(MCPU); if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) { debug_printf("llc -mcpu option: %s\n", MCPU.str().c_str()); diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index f02dfa89314..978aa455ecb 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -122,6 +122,14 @@ #define PIPE_ARCH_AARCH64 #endif +#if defined(__mips64) && defined(__LP64__) +#define PIPE_ARCH_MIPS64 +#endif + +#if defined(__mips__) +#define PIPE_ARCH_MIPS +#endif + /* * Endian detection. */ diff --git a/src/util/u_cpu_detect.c b/src/util/u_cpu_detect.c index e8664a66933..9aea9e798bb 100644 --- a/src/util/u_cpu_detect.c +++ b/src/util/u_cpu_detect.c @@ -434,6 +434,29 @@ check_os_arm_support(void) } #endif /* PIPE_ARCH_ARM || PIPE_ARCH_AARCH64 */ +#if defined(PIPE_ARCH_MIPS64) +static void +check_os_mips64_support(void) +{ + Elf64_auxv_t aux; + int fd; + + fd = open("/proc/self/auxv", O_RDONLY | O_CLOEXEC); + if (fd >= 0) { + while (read(fd, &aux, sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) { + if (aux.a_type == AT_HWCAP) { + uint64_t hwcap = aux.a_un.a_val; + + util_cpu_caps.has_msa = (hwcap >> 1) & 1; + break; + } + } + close (fd); + } +} +#endif /* PIPE_ARCH_MIPS64 */ + + static void get_cpu_topology(void) { @@ -784,6 +807,10 @@ util_cpu_detect_once(void) check_os_altivec_support(); #endif /* PIPE_ARCH_PPC */ +#if defined(PIPE_ARCH_MIPS64) + check_os_mips64_support(); +#endif /* PIPE_ARCH_MIPS64 */ + get_cpu_topology(); if (debug_get_option_dump_cpu()) { @@ -811,6 +838,7 @@ util_cpu_detect_once(void) printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); printf("util_cpu_caps.has_vsx = %u\n", util_cpu_caps.has_vsx); printf("util_cpu_caps.has_neon = %u\n", util_cpu_caps.has_neon); + printf("util_cpu_caps.has_msa = %u\n", util_cpu_caps.has_msa); printf("util_cpu_caps.has_daz = %u\n", util_cpu_caps.has_daz); printf("util_cpu_caps.has_avx512f = %u\n", util_cpu_caps.has_avx512f); printf("util_cpu_caps.has_avx512dq = %u\n", util_cpu_caps.has_avx512dq); diff --git a/src/util/u_cpu_detect.h b/src/util/u_cpu_detect.h index 3e78445f058..9fd4dd289df 100644 --- a/src/util/u_cpu_detect.h +++ b/src/util/u_cpu_detect.h @@ -101,6 +101,7 @@ struct util_cpu_caps_t { unsigned has_vsx:1; unsigned has_daz:1; unsigned has_neon:1; + unsigned has_msa:1; unsigned has_avx512f:1; unsigned has_avx512dq:1;