mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-21 13:14:59 -07:00
src: enable_target_feature should add features, not overwrite
`llvm_features` being empty is the default state, and implies the presence of certain features. Previously if any target features were explicitly enabled by the `enable_target_feature` attribute, they were added comma separated to `llvm_features`. For example: `lzcnt,popcnt,...,sse4.2,sse` This was causing LLVM to try to target a CPU that *ONLY* has the explicitly enabled features. This now will prefix explicitly enabled features with a `+`, and preserve the existing `llvm_features` string by appending to it if it is set.
This commit is contained in:
@@ -1493,7 +1493,7 @@ gb_internal void enable_target_feature(TokenPos pos, String const &target_featur
|
||||
}
|
||||
|
||||
|
||||
gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes) {
|
||||
gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes, bool with_plus) {
|
||||
isize len = 0;
|
||||
isize i = 0;
|
||||
for (String const &feature : build_context.target_features_set) {
|
||||
@@ -1502,6 +1502,7 @@ gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bo
|
||||
}
|
||||
len += feature.len;
|
||||
if (with_quotes) len += 2;
|
||||
if (with_plus) len += 1;
|
||||
i += 1;
|
||||
}
|
||||
char *features = gb_alloc_array(allocator, char, len+1);
|
||||
@@ -1513,6 +1514,7 @@ gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bo
|
||||
}
|
||||
|
||||
if (with_quotes) features[len++] = '"';
|
||||
if (with_plus) features[len++] = '+';
|
||||
gb_memmove(features + len, feature.text, feature.len);
|
||||
len += feature.len;
|
||||
if (with_quotes) features[len++] = '"';
|
||||
|
||||
+40
-1
@@ -2531,7 +2531,46 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
|
||||
*/
|
||||
|
||||
if (build_context.target_features_set.entries.count != 0) {
|
||||
llvm_features = target_features_set_to_cstring(permanent_allocator(), false);
|
||||
// Prefix all of the features with a `+`, because we are
|
||||
// enabling additional features.
|
||||
char const *additional_features = target_features_set_to_cstring(permanent_allocator(), false, true);
|
||||
|
||||
String f_string = make_string_c(llvm_features);
|
||||
String a_string = make_string_c(additional_features);
|
||||
isize f_len = f_string.len;
|
||||
|
||||
if (f_len == 0) {
|
||||
// The common case is that llvm_features is empty, so
|
||||
// the target_features_set additions can be used as is.
|
||||
llvm_features = additional_features;
|
||||
} else {
|
||||
// The user probably specified `-microarch:native`, so
|
||||
// llvm_features is populated by LLVM's idea of what
|
||||
// the host CPU supports.
|
||||
//
|
||||
// As far as I can tell, (which is barely better than
|
||||
// wild guessing), a bitset is formed by parsing the
|
||||
// string left to right.
|
||||
//
|
||||
// So, llvm_features + ',' + additonal_features, will
|
||||
// makes the target_features_set override llvm_features.
|
||||
|
||||
char *tmp = gb_alloc_array(permanent_allocator(), char, f_len + 1 + a_string.len + 1);
|
||||
isize len = 0;
|
||||
|
||||
// tmp = f_string
|
||||
gb_memmove(tmp, f_string.text, f_string.len);
|
||||
len += f_string.len;
|
||||
// tmp += ','
|
||||
tmp[len++] = ',';
|
||||
// tmp += a_string
|
||||
gb_memmove(tmp + len, a_string.text, a_string.len);
|
||||
len += a_string.len;
|
||||
// tmp += NUL
|
||||
tmp[len++] = 0;
|
||||
|
||||
llvm_features = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// GB_ASSERT_MSG(LLVMTargetHasAsmBackend(target));
|
||||
|
||||
Reference in New Issue
Block a user