Add cpu/feature specification to cmndline
parent
c8f1e0d6d8
commit
bd6ef21f85
|
@ -531,12 +531,12 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
|
|||
|
||||
// ABI warning
|
||||
export fn stage2_list_features_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void {
|
||||
print_features_for_arch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| {
|
||||
printFeaturesForArch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| {
|
||||
std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) });
|
||||
};
|
||||
}
|
||||
|
||||
fn print_features_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {
|
||||
fn printFeaturesForArch(arch_name: []const u8, show_subfeatures: bool) !void {
|
||||
const stdout_stream = &std.io.getStdOut().outStream().stream;
|
||||
|
||||
const arch = Target.parseArchTag(arch_name) catch {
|
||||
|
@ -575,12 +575,12 @@ fn print_features_for_arch(arch_name: []const u8, show_subfeatures: bool) !void
|
|||
|
||||
// ABI warning
|
||||
export fn stage2_list_cpus_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_subfeatures: bool) void {
|
||||
print_cpus_for_arch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| {
|
||||
printCpusForArch(arch_name_ptr[0..arch_name_len], show_subfeatures) catch |err| {
|
||||
std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) });
|
||||
};
|
||||
}
|
||||
|
||||
fn print_cpus_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {
|
||||
fn printCpusForArch(arch_name: []const u8, show_subfeatures: bool) !void {
|
||||
const stdout_stream = &std.io.getStdOut().outStream().stream;
|
||||
|
||||
const arch = Target.parseArchTag(arch_name) catch {
|
||||
|
@ -618,3 +618,90 @@ fn print_cpus_for_arch(arch_name: []const u8, show_subfeatures: bool) !void {
|
|||
}
|
||||
|
||||
// use target_arch_name(ZigLLVM_ArchType) to get name from main.cpp 'target'.
|
||||
// ABI warning
|
||||
export fn stage2_validate_cpu_and_features(
|
||||
arch_name: [*:0]const u8,
|
||||
cpu: ?[*:0]const u8,
|
||||
features: ?[*:0]const u8,
|
||||
) bool {
|
||||
const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_name)) catch {
|
||||
std.debug.warn("Failed to parse arch '{}'\nInvoke 'zig targets' for a list of valid architectures\n", .{ arch_name });
|
||||
return false;
|
||||
};
|
||||
|
||||
const res = validateCpuAndFeatures(
|
||||
arch,
|
||||
if (cpu) |def_cpu| std.mem.toSliceConst(u8, def_cpu) else "",
|
||||
if (features) |def_features| std.mem.toSliceConst(u8, def_features) else "");
|
||||
|
||||
switch (res) {
|
||||
.Ok => return true,
|
||||
.InvalidCpu => |invalid_cpu| {
|
||||
std.debug.warn("Invalid CPU '{}'\n", .{ invalid_cpu });
|
||||
return false;
|
||||
},
|
||||
.InvalidFeaturesString => {
|
||||
std.debug.warn("Invalid features string\n", .{});
|
||||
std.debug.warn("Must have format \"+yes_feature,-no_feature\"\n", .{});
|
||||
return false;
|
||||
},
|
||||
.InvalidFeature => |invalid_feature| {
|
||||
std.debug.warn("Invalid feature '{}'\n", .{ invalid_feature });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ValidateCpuAndFeaturesResult = union(enum) {
|
||||
Ok,
|
||||
InvalidCpu: []const u8,
|
||||
InvalidFeaturesString,
|
||||
InvalidFeature: []const u8,
|
||||
};
|
||||
|
||||
fn validateCpuAndFeatures(arch: @TagType(std.Target.Arch), cpu: []const u8, features: []const u8) ValidateCpuAndFeaturesResult {
|
||||
|
||||
const known_cpus = std.target.getCpusForArch(arch);
|
||||
const known_features = std.target.getFeaturesForArch(arch);
|
||||
|
||||
if (cpu.len > 0) {
|
||||
var found_cpu = false;
|
||||
for (known_cpus) |known_cpu| {
|
||||
if (std.mem.eql(u8, cpu, known_cpu.name)) {
|
||||
found_cpu = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_cpu) {
|
||||
return .{ .InvalidCpu = cpu };
|
||||
}
|
||||
}
|
||||
|
||||
if (features.len > 0) {
|
||||
var start: usize = 0;
|
||||
while (start < features.len) {
|
||||
const next_comma_pos = std.mem.indexOfScalar(u8, features[start..], ',') orelse features.len - start;
|
||||
var feature = features[start..start+next_comma_pos];
|
||||
|
||||
if (feature.len < 2) return .{ .InvalidFeaturesString = {} };
|
||||
|
||||
if (feature[0] != '+' and feature[0] != '-') return .{ .InvalidFeaturesString = {} };
|
||||
feature = feature[1..];
|
||||
|
||||
var found_feature = false;
|
||||
for (known_features) |known_feature| {
|
||||
if (std.mem.eql(u8, feature, known_feature.name)) {
|
||||
found_feature = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_feature) return .{ .InvalidFeature = feature };
|
||||
|
||||
start += next_comma_pos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return .{ .Ok = {} };
|
||||
}
|
||||
|
|
|
@ -2215,6 +2215,9 @@ struct CodeGen {
|
|||
|
||||
const char **clang_argv;
|
||||
size_t clang_argv_len;
|
||||
|
||||
const char *llvm_cpu;
|
||||
const char *llvm_features;
|
||||
};
|
||||
|
||||
struct ZigVar {
|
||||
|
|
|
@ -8800,6 +8800,15 @@ static void init(CodeGen *g) {
|
|||
target_specific_features = "";
|
||||
}
|
||||
|
||||
// Override CPU and features if non-null.
|
||||
if (g->llvm_cpu != nullptr) {
|
||||
target_specific_cpu_args = g->llvm_cpu;
|
||||
}
|
||||
|
||||
if (g->llvm_features != nullptr) {
|
||||
target_specific_features = g->llvm_features;
|
||||
}
|
||||
|
||||
g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
|
||||
target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
|
||||
LLVMCodeModelDefault, g->function_sections);
|
||||
|
|
16
src/main.cpp
16
src/main.cpp
|
@ -100,6 +100,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
|
|||
" --override-lib-dir [arg] override path to Zig lib directory\n"
|
||||
" -ffunction-sections places each function in a separate section\n"
|
||||
" -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
|
||||
" --cpu [cpu] compile for [cpu] on the current target\n"
|
||||
" --features [feature_str] compile with features in [feature_str] on the current target\n"
|
||||
"\n"
|
||||
"Link Options:\n"
|
||||
" --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
|
||||
|
@ -533,6 +535,8 @@ int main(int argc, char **argv) {
|
|||
WantStackCheck want_stack_check = WantStackCheckAuto;
|
||||
WantCSanitize want_sanitize_c = WantCSanitizeAuto;
|
||||
bool function_sections = false;
|
||||
const char *cpu = "";
|
||||
const char *features = "";
|
||||
|
||||
const char *targets_list_features_arch = nullptr;
|
||||
const char *targets_list_cpus_arch = nullptr;
|
||||
|
@ -951,6 +955,10 @@ int main(int argc, char **argv) {
|
|||
targets_list_features_arch = argv[i];
|
||||
} else if (strcmp(arg, "--list-cpus") == 0) {
|
||||
targets_list_cpus_arch = argv[i];
|
||||
} else if (strcmp(arg, "--cpu") == 0) {
|
||||
cpu = argv[i];
|
||||
} else if (strcmp(arg, "--features") == 0) {
|
||||
features = argv[i];
|
||||
}else {
|
||||
fprintf(stderr, "Invalid argument: %s\n", arg);
|
||||
return print_error_usage(arg0);
|
||||
|
@ -1248,6 +1256,7 @@ int main(int argc, char **argv) {
|
|||
g->system_linker_hack = system_linker_hack;
|
||||
g->function_sections = function_sections;
|
||||
|
||||
|
||||
for (size_t i = 0; i < lib_dirs.length; i += 1) {
|
||||
codegen_add_lib_dir(g, lib_dirs.at(i));
|
||||
}
|
||||
|
@ -1269,6 +1278,13 @@ int main(int argc, char **argv) {
|
|||
codegen_add_rpath(g, rpath_list.at(i));
|
||||
}
|
||||
|
||||
if (!stage2_validate_cpu_and_features(target_arch_name(target.arch), cpu, features)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
g->llvm_cpu = cpu;
|
||||
g->llvm_features = features;
|
||||
|
||||
codegen_set_rdynamic(g, rdynamic);
|
||||
if (mmacosx_version_min && mios_version_min) {
|
||||
fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n");
|
||||
|
|
|
@ -91,3 +91,4 @@ void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_coun
|
|||
|
||||
void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}
|
||||
void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}
|
||||
bool stage2_validate_cpu_and_features(const char *arch_name, const char *cpu, const char *features) { return true; }
|
||||
|
|
|
@ -180,4 +180,7 @@ ZIG_EXTERN_C void stage2_list_features_for_arch(const char *arch_name_ptr, size_
|
|||
// ABI warning
|
||||
ZIG_EXTERN_C void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures);
|
||||
|
||||
// ABI warning
|
||||
ZIG_EXTERN_C bool stage2_validate_cpu_and_features(const char *arch_name, const char *cpu, const char *features);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue