Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions module-template/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down
25 changes: 22 additions & 3 deletions module-template/module_export.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__))
Expand All @@ -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);
}

Expand Down