diff --git a/platform/linuxbsd/godot_linuxbsd.cpp b/platform/linuxbsd/godot_linuxbsd.cpp index 9a4372e61da..8bda6d932c1 100644 --- a/platform/linuxbsd/godot_linuxbsd.cpp +++ b/platform/linuxbsd/godot_linuxbsd.cpp @@ -41,6 +41,18 @@ #include #endif +#if defined(__x86_64) || defined(__x86_64__) +void __cpuid(int *r_cpuinfo, int p_info) { + // Note: Some compilers have a buggy `__cpuid` intrinsic, using inline assembly (based on LLVM-20 implementation) instead. + __asm__ __volatile__( + "xchgq %%rbx, %q1;" + "cpuid;" + "xchgq %%rbx, %q1;" + : "=a"(r_cpuinfo[0]), "=r"(r_cpuinfo[1]), "=c"(r_cpuinfo[2]), "=d"(r_cpuinfo[3]) + : "0"(p_info)); +} +#endif + // For export templates, add a section; the exporter will patch it to enclose // the data appended to the executable (bundled PCK). #if !defined(TOOLS_ENABLED) && defined(__GNUC__) @@ -54,6 +66,27 @@ extern "C" const char *pck_section_dummy_call() { #endif int main(int argc, char *argv[]) { +#if defined(__x86_64) || defined(__x86_64__) + int cpuinfo[4]; + __cpuid(cpuinfo, 0x01); + + if (!(cpuinfo[2] & (1 << 20))) { + printf("A CPU with SSE4.2 instruction set support is required.\n"); + + int ret = system("zenity --warning --title \"Godot Engine\" --text \"A CPU with SSE4.2 instruction set support is required.\" 2> /dev/null"); + if (ret != 0) { + ret = system("kdialog --title \"Godot Engine\" --sorry \"A CPU with SSE4.2 instruction set support is required.\" 2> /dev/null"); + } + if (ret != 0) { + ret = system("Xdialog --title \"Godot Engine\" --msgbox \"A CPU with SSE4.2 instruction set support is required.\" 0 0 2> /dev/null"); + } + if (ret != 0) { + ret = system("xmessage -center -title \"Godot Engine\" \"A CPU with SSE4.2 instruction set support is required.\" 2> /dev/null"); + } + abort(); + } +#endif + #if defined(SANITIZERS_ENABLED) // Note: Set stack size to be at least 30 MB (vs 8 MB default) to avoid overflow, address sanitizer can increase stack usage up to 3 times. struct rlimit stack_lim = { 0x1E00000, 0x1E00000 };