diff --git a/module-template/CMakeLists.txt b/module-template/CMakeLists.txt index 2757a8d96d..0c177fa14d 100644 --- a/module-template/CMakeLists.txt +++ b/module-template/CMakeLists.txt @@ -103,6 +103,10 @@ set_target_properties(${MODULE_NAME} PROPERTIES set_source_files_properties("${MODULE_TABLES}" PROPERTIES HEADER_FILE_ONLY TRUE GENERATED TRUE) target_compile_definitions(${MODULE_NAME} PRIVATE MODULE_GAME_ID="${GAME_ID}") +# Generated sources default DOLRECOMP_CPU_HEADER to "cpu/cpu.h", which is +# DolRecomp's standalone layout. A module compiles against GXRuntime, where the +# same header is core/cpu.h. The override hook exists for exactly this case. +target_compile_definitions(${MODULE_NAME} PRIVATE DOLRECOMP_CPU_HEADER="core/cpu.h") target_include_directories(${MODULE_NAME} PRIVATE "${GENERATED_DIR}" diff --git a/module-template/module_export.c b/module-template/module_export.c index 2a02ef6863..ad3a0d2e13 100644 --- a/module-template/module_export.c +++ b/module-template/module_export.c @@ -8,6 +8,24 @@ #include "StaticRecompABI.h" +/* The x86-64-v3 dispatch path is compiled only when the module was generated + * with that variant (dolrecomp --targets ... x86-64-v3). moderngekko-port does + * not pass --targets, so normally it is absent, and referencing it breaks the + * build two ways on x86-64 with clang or gcc: + * + * module_export.c:23: error: invalid cpu feature string for builtin + * module_export.c:24: error: invalid cpu feature string for builtin + * module_export.c:35: error: call to undeclared function + * 'dolrecomp_call__x86_64_v3' + * + * clang does not accept "movbe" or "lzcnt" for __builtin_cpu_supports, and the + * v3 entry point is neither declared nor defined. Both went unnoticed because + * the two configurations built regularly fold the whole thing away first: under + * MSVC and on non-x86-64 targets the guard below is false, so the body is a + * constant 0 and the call is dead-code eliminated before the compiler sees it. */ +#if defined(DOLRECOMP_MODULE_HAVE_X86_64_V3) +int dolrecomp_call__x86_64_v3(CPUState* ctx, u32 address); + static int host_has_x86_64_v3(void) { #if defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__)) @@ -19,20 +37,21 @@ static int host_has_x86_64_v3(void) __builtin_cpu_supports("avx2") && __builtin_cpu_supports("fma") && __builtin_cpu_supports("bmi") && - __builtin_cpu_supports("bmi2") && - __builtin_cpu_supports("movbe") && - __builtin_cpu_supports("lzcnt"); + __builtin_cpu_supports("bmi2"); } return supported; #else return 0; #endif } +#endif static int selected_dispatch(CPUState* ctx, u32 address) { +#if defined(DOLRECOMP_MODULE_HAVE_X86_64_V3) if (host_has_x86_64_v3()) return dolrecomp_call__x86_64_v3(ctx, address); +#endif return dolrecomp_call(ctx, address); }