zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 1f7babbc80211e12c9a38ff2196d6ff8c5a19302 (tree)
parent 0abaee79af462f4264717f88af052fb00eefde7c
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Tue, 21 Jan 2020 03:01:20 -0500

properly forward baseline target cpu features to llvm

Diffstat:
Msrc-self-hosted/stage1.zig | 84++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/codegen.cpp | 2++
Msrc/main.cpp | 2+-
Msrc/userland.cpp | 2+-
Msrc/userland.h | 3++-
5 files changed, 59 insertions(+), 34 deletions(-)

diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig @@ -627,7 +627,7 @@ const Stage2CpuFeatures = struct { const Self = @This(); - fn createBaseline(allocator: *mem.Allocator) !*Self { + fn createBaseline(allocator: *mem.Allocator, arch: Target.Arch) !*Self { const self = try allocator.create(Self); errdefer allocator.destroy(self); @@ -641,10 +641,11 @@ const Stage2CpuFeatures = struct { .allocator = allocator, .cpu_features = .baseline, .llvm_cpu_name = null, - .llvm_features_str = null, + .llvm_features_str = try initLLVMFeatures(allocator, arch, arch.baselineFeatures()), .builtin_str = builtin_str, .cache_hash = cache_hash, }; + return self; } @@ -658,7 +659,7 @@ const Stage2CpuFeatures = struct { const arch = target.Cross.arch; const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name_z, llvm_cpu_features); switch (cpu_features) { - .baseline => return createBaseline(allocator), + .baseline => return createBaseline(allocator, arch), .cpu => |cpu| return createFromCpu(allocator, arch, cpu), .features => |features| return createFromCpuFeatures(allocator, arch, features), } @@ -688,31 +689,13 @@ const Stage2CpuFeatures = struct { return self; } - fn createFromCpuFeatures( + fn initLLVMFeatures( allocator: *mem.Allocator, arch: Target.Arch, feature_set: Target.Cpu.Feature.Set, - ) !*Self { - const self = try allocator.create(Self); - errdefer allocator.destroy(self); - - const cache_hash = try std.fmt.allocPrint0(allocator, "\n{x}", .{feature_set}); - errdefer allocator.free(cache_hash); - - const generic_arch_name = arch.genericName(); - var builtin_str_buffer = try std.Buffer.allocPrint( - allocator, - \\CpuFeatures{{ - \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ - \\ - , - .{ generic_arch_name, generic_arch_name }, - ); - defer builtin_str_buffer.deinit(); - + ) ![*:0]const u8 { var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); defer llvm_features_buffer.deinit(); - // First, disable all features. // This way, we only get the ones the user requests. const all_features = arch.allFeaturesList(); @@ -723,7 +706,6 @@ const Stage2CpuFeatures = struct { try llvm_features_buffer.append(","); } } - for (all_features) |feature, index| { if (!feature_set.isEnabled(@intCast(u8, index))) continue; @@ -732,15 +714,43 @@ const Stage2CpuFeatures = struct { try llvm_features_buffer.append(llvm_name); try llvm_features_buffer.append(","); } - - try builtin_str_buffer.append(" ."); - try builtin_str_buffer.append(feature.name); - try builtin_str_buffer.append(",\n"); } if (mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")) { llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); } + return llvm_features_buffer.toOwnedSlice().ptr; + } + + fn createFromCpuFeatures( + allocator: *mem.Allocator, + arch: Target.Arch, + feature_set: Target.Cpu.Feature.Set, + ) !*Self { + const self = try allocator.create(Self); + errdefer allocator.destroy(self); + + const cache_hash = try std.fmt.allocPrint0(allocator, "\n{x}", .{feature_set}); + errdefer allocator.free(cache_hash); + + const generic_arch_name = arch.genericName(); + var builtin_str_buffer = try std.Buffer.allocPrint( + allocator, + \\CpuFeatures{{ + \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ + \\ + , + .{ generic_arch_name, generic_arch_name }, + ); + defer builtin_str_buffer.deinit(); + + for (arch.allFeaturesList()) |feature, index| { + if (!feature_set.isEnabled(@intCast(u8, index))) continue; + + try builtin_str_buffer.append(" ."); + try builtin_str_buffer.append(feature.name); + try builtin_str_buffer.append(",\n"); + } try builtin_str_buffer.append( \\ }), @@ -752,7 +762,7 @@ const Stage2CpuFeatures = struct { .allocator = allocator, .cpu_features = .{ .features = feature_set }, .llvm_cpu_name = null, - .llvm_features_str = llvm_features_buffer.toOwnedSlice().ptr, + .llvm_features_str = try initLLVMFeatures(allocator, arch, feature_set), .builtin_str = builtin_str_buffer.toOwnedSlice(), .cache_hash = cache_hash, }; @@ -843,13 +853,25 @@ fn parseFeatures(zig_triple: [*:0]const u8, features_text: [*:0]const u8) !*Stag } // ABI warning -export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures) Error { - result.* = Stage2CpuFeatures.createBaseline(std.heap.c_allocator) catch |err| switch (err) { +export fn stage2_cpu_features_baseline(result: **Stage2CpuFeatures, zig_triple: [*:0]const u8) Error { + result.* = cpuFeaturesBaseline(zig_triple) catch |err| switch (err) { error.OutOfMemory => return .OutOfMemory, + error.UnknownArchitecture => return .UnknownArchitecture, + error.UnknownSubArchitecture => return .UnknownSubArchitecture, + error.UnknownOperatingSystem => return .UnknownOperatingSystem, + error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface, + error.MissingOperatingSystem => return .MissingOperatingSystem, + error.MissingArchitecture => return .MissingArchitecture, }; return .None; } +fn cpuFeaturesBaseline(zig_triple: [*:0]const u8) !*Stage2CpuFeatures { + const target = try Target.parse(mem.toSliceConst(u8, zig_triple)); + const arch = target.Cross.arch; + return Stage2CpuFeatures.createBaseline(std.heap.c_allocator, arch); +} + // ABI warning export fn stage2_cpu_features_llvm( result: **Stage2CpuFeatures, diff --git a/src/codegen.cpp b/src/codegen.cpp @@ -8802,6 +8802,8 @@ static void init(CodeGen *g) { target_specific_cpu_args = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features); target_specific_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features); } + //fprintf(stderr, "name=%s target_specific_cpu_args=%s\n", buf_ptr(g->root_out_name), target_specific_cpu_args); + //fprintf(stderr, "name=%s target_specific_features=%s\n", buf_ptr(g->root_out_name), target_specific_features); g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, diff --git a/src/main.cpp b/src/main.cpp @@ -1005,7 +1005,7 @@ int main(int argc, char **argv) { return main_exit(root_progress_node, EXIT_FAILURE); } } else { - if ((err = stage2_cpu_features_baseline(&target.cpu_features))) { + if ((err = stage2_cpu_features_baseline(&target.cpu_features, buf_ptr(&zig_triple_buf)))) { fprintf(stderr, "unable to determine baseline CPU features: %s\n", err_str(err)); return main_exit(root_progress_node, EXIT_FAILURE); } diff --git a/src/userland.cpp b/src/userland.cpp @@ -104,7 +104,7 @@ Error stage2_cpu_features_parse_features(Stage2CpuFeatures **out, const char *zi const char *msg = "stage0 called stage2_cpu_features_parse_features"; stage2_panic(msg, strlen(msg)); } -Error stage2_cpu_features_baseline(Stage2CpuFeatures **out) { +Error stage2_cpu_features_baseline(Stage2CpuFeatures **out, const char *zig_triple) { Stage2CpuFeatures *result = allocate<Stage2CpuFeatures>(1, "Stage2CpuFeatures"); result->builtin_str = ".baseline;\n"; result->cache_hash = "\n\n"; diff --git a/src/userland.h b/src/userland.h @@ -192,7 +192,8 @@ ZIG_EXTERN_C Error stage2_cpu_features_parse_features(struct Stage2CpuFeatures * const char *zig_triple, const char *features); // ABI warning -ZIG_EXTERN_C Error stage2_cpu_features_baseline(struct Stage2CpuFeatures **result); +ZIG_EXTERN_C Error stage2_cpu_features_baseline(struct Stage2CpuFeatures **result, + const char *zig_triple); // ABI warning ZIG_EXTERN_C Error stage2_cpu_features_llvm(struct Stage2CpuFeatures **result,