diff --git a/src/build/build_options.c b/src/build/build_options.c index 6ebd12f40..23aa22ec3 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -532,7 +532,7 @@ static void parse_option(BuildOptions *options) } if ((argopt = match_argopt("x86vec"))) { - options->x86_vector_capability = (X86VectorCapability)parse_multi_option(argopt, 5, vector_capability); + options->x86_vector_capability = (X86VectorCapability)parse_multi_option(argopt, 6, vector_capability); return; } if ((argopt = match_argopt("reloc"))) diff --git a/src/build/build_options.h b/src/build/build_options.h index 8f5cfb515..a942afb54 100644 --- a/src/build/build_options.h +++ b/src/build/build_options.h @@ -143,14 +143,16 @@ typedef enum X86VECTOR_SSE = 2, X86VECTOR_AVX = 3, X86VECTOR_AVX512 = 4, + X86VECTOR_NATIVE = 5, } X86VectorCapability; -static const char *vector_capability[5] = { +static const char *vector_capability[6] = { [X86VECTOR_NONE] = "none", [X86VECTOR_MMX] = "mmx", [X86VECTOR_SSE] = "sse", [X86VECTOR_AVX] = "avx", [X86VECTOR_AVX512] = "avx512", + [X86VECTOR_NATIVE] = "native" }; typedef enum diff --git a/src/build/project.c b/src/build/project.c index cea687791..52050ae08 100644 --- a/src/build/project.c +++ b/src/build/project.c @@ -318,7 +318,7 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg if (wincrt > -1) target->win.crt_linking = (WinCrtLinking)wincrt; // x86vec - int x86vec = get_valid_string_setting(json, "x86vec", type, vector_capability, 0, 5, "none, mmx, sse, avx or avx512"); + int x86vec = get_valid_string_setting(json, "x86vec", type, vector_capability, 0, 6, "none, native, mmx, sse, avx or avx512"); if (x86vec > -1) target->feature.x86_vector_capability = x86vec; // winsdk diff --git a/src/compiler/target.c b/src/compiler/target.c index c6b9e38be..e841d93d0 100644 --- a/src/compiler/target.c +++ b/src/compiler/target.c @@ -443,6 +443,32 @@ static inline void target_setup_x86_abi(BuildTarget *target) } } +X86VectorCapability x64_vector_capability_from_host(void) +{ + char *features = LLVMGetHostCPUFeatures(); + if (strstr(features, "+avx512")) + { + LLVMDisposeMessage(features); + return X86VECTOR_AVX512; + } + else if (strstr(features, "+avx")) + { + LLVMDisposeMessage(features); + return X86VECTOR_AVX; + } + else if (strstr(features, "+sse")) + { + LLVMDisposeMessage(features); + return X86VECTOR_SSE; + } + else if (strstr(features, "+mmx")) + { + LLVMDisposeMessage(features); + return X86VECTOR_MMX; + } + LLVMDisposeMessage(features); + return X86VECTOR_NONE; +} static inline void target_setup_x64_abi(BuildTarget *target) { @@ -461,7 +487,6 @@ static inline void target_setup_x64_abi(BuildTarget *target) if (target->feature.soft_float == SOFT_FLOAT_YES) platform_target.x64.soft_float = true; if (platform_target.environment_type == ENV_TYPE_GNU) { - //platform_target.x64.is_mingw64 = platform_target.x64.is_win64; if (platform_target.x64.is_win64) DEBUG_LOG("Mingw"); } @@ -469,6 +494,7 @@ static inline void target_setup_x64_abi(BuildTarget *target) { platform_target.x64.pass_int128_vector_in_mem = true; } + if (capability == X86VECTOR_NATIVE) capability = x64_vector_capability_from_host(); switch (capability) { case X86VECTOR_AVX: @@ -1252,6 +1278,14 @@ void *llvm_target_machine_create(void) { case X86VECTOR_DEFAULT: UNREACHABLE + case X86VECTOR_NATIVE: + { + char *features = LLVMGetHostCPUFeatures(); + scratch_buffer_append(features); + scratch_buffer_append_char(','); + LLVMDisposeMessage(features); + break; + } case X86VECTOR_NONE: scratch_buffer_append("-sse,-avx,-mmx,"); break; diff --git a/src/version.h b/src/version.h index 23209430f..e74b92951 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.3.128" \ No newline at end of file +#define COMPILER_VERSION "0.3.129" \ No newline at end of file