Commit 1f7babbc80

Andrew Kelley <andrew@ziglang.org>
2020-01-21 09:01:20
properly forward baseline target cpu features to llvm
1 parent 0abaee7
Changed files (5)
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,
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);
         }
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";
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,
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,