From 0f016b368de2ac93a298ab771646931329062fb5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 20 Feb 2020 18:31:17 -0500 Subject: [PATCH] support -mcpu=baseline, both in stage1 and stage2 See e381a42de9c0f0c5439a926b0ac99026a0373f49 for more details. This is set up so that if we wish to make "baseline" depend on the OS in the future, it is possible to do that. --- lib/std/target.zig | 32 ++++++++++++++++++-------------- src-self-hosted/stage2.zig | 4 ++-- src/stage2.cpp | 27 ++++++++++++++++++--------- test/compile_errors.zig | 3 +-- test/tests.zig | 8 ++++---- test/translate_c.zig | 3 +-- 6 files changed, 44 insertions(+), 33 deletions(-) diff --git a/lib/std/target.zig b/lib/std/target.zig index 3d04e3424e..875ccda57f 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -726,8 +726,7 @@ pub const Target = union(enum) { /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e" /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features /// to remove from the set. - /// The default value of `null` means to use the "baseline" feature set. - cpu: ?[]const u8 = null, + cpu_features: []const u8 = "baseline", }; pub fn parse(args: ParseOptions) !Target { @@ -742,23 +741,29 @@ pub const Target = union(enum) { const abi = if (abi_name) |n| try Abi.parse(n) else Abi.default(arch, os); const all_features = arch.allFeaturesList(); - const cpu: Cpu = if (args.cpu) |cpu_text| blk: { - var index: usize = 0; - while (index < cpu_text.len and cpu_text[index] != '+' and cpu_text[index] != '-') { - index += 1; - } - const cpu_name = cpu_text[0..index]; + var index: usize = 0; + while (index < args.cpu_features.len and + args.cpu_features[index] != '+' and + args.cpu_features[index] != '-') + { + index += 1; + } + const cpu_name = args.cpu_features[0..index]; + const cpu: Cpu = if (mem.eql(u8, cpu_name, "baseline")) Cpu.baseline(arch) else blk: { const cpu_model = try arch.parseCpuModel(cpu_name); var set = cpu_model.features; - while (index < cpu_text.len) { - const op = cpu_text[index]; + while (index < args.cpu_features.len) { + const op = args.cpu_features[index]; index += 1; const start = index; - while (index < cpu_text.len and cpu_text[index] != '+' and cpu_text[index] != '-') { + while (index < args.cpu_features.len and + args.cpu_features[index] != '+' and + args.cpu_features[index] != '-') + { index += 1; } - const feature_name = cpu_text[start..index]; + const feature_name = args.cpu_features[start..index]; for (all_features) |feature, feat_index_usize| { const feat_index = @intCast(Cpu.Feature.Set.Index, feat_index_usize); if (mem.eql(u8, feature_name, feature.name)) { @@ -779,8 +784,7 @@ pub const Target = union(enum) { .model = cpu_model, .features = set, }; - } else Cpu.baseline(arch); - + }; var cross = Cross{ .cpu = cpu, .os = os, diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index 048686190d..f7c4306cd5 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -675,8 +675,8 @@ fn stage2TargetParse( ) !void { const target: Target = if (zig_triple_oz) |zig_triple_z| blk: { const zig_triple = mem.toSliceConst(u8, zig_triple_z); - const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else null; - break :blk try Target.parse(.{ .arch_os_abi = zig_triple, .cpu = mcpu }); + const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else "baseline"; + break :blk try Target.parse(.{ .arch_os_abi = zig_triple, .cpu_features = mcpu }); } else Target.Native; try stage1_target.fromTarget(target); diff --git a/src/stage2.cpp b/src/stage2.cpp index f3ae03242e..035ce5a008 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -97,10 +97,20 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons if (zig_triple == nullptr) { get_native_target(target); - target->llvm_cpu_name = ZigLLVMGetHostCPUName(); - target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); - target->builtin_str = "Target.Cpu.baseline(arch);\n"; - target->cache_hash = "native\n\n"; + if (mcpu == nullptr) { + target->llvm_cpu_name = ZigLLVMGetHostCPUName(); + target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); + target->builtin_str = "Target.Cpu.baseline(arch);\n"; + target->cache_hash = "native\n\n"; + } else if (strcmp(mcpu, "baseline") == 0) { + target->llvm_cpu_name = ""; + target->llvm_cpu_features = ""; + target->builtin_str = "Target.Cpu.baseline(arch);\n"; + target->cache_hash = "baseline\n\n"; + } else { + const char *msg = "stage0 can't handle CPU/features in the target"; + stage2_panic(msg, strlen(msg)); + } } else { // first initialize all to zero *target = {}; @@ -135,15 +145,14 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons target->abi = target_default_abi(target->arch, target->os); } + if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) { + const char *msg = "stage0 can't handle CPU/features in the target"; + stage2_panic(msg, strlen(msg)); + } target->builtin_str = "Target.Cpu.baseline(arch);\n"; target->cache_hash = "\n\n"; } - if (mcpu != nullptr) { - const char *msg = "stage0 can't handle CPU/features in the target"; - stage2_panic(msg, strlen(msg)); - } - return ErrorNone; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 9f2b3716b0..4d133a1b5c 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -350,8 +350,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { }); tc.target = Target{ .Cross = .{ - .arch = .wasm32, - .cpu_features = Target.Arch.wasm32.getBaselineCpuFeatures(), + .cpu = Target.Cpu.baseline(.wasm32), .os = .wasi, .abi = .none, }, diff --git a/test/tests.zig b/test/tests.zig index 3190126208..f12f7f83d4 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -135,13 +135,13 @@ const test_targets = blk: { TestTarget{ .target = Target.parse(.{ .arch_os_abi = "arm-linux-none", - .cpu = "generic+v8a", + .cpu_features = "generic+v8a", }) catch unreachable, }, TestTarget{ .target = Target.parse(.{ .arch_os_abi = "arm-linux-musleabihf", - .cpu = "generic+v8a", + .cpu_features = "generic+v8a", }) catch unreachable, .link_libc = true, }, @@ -149,7 +149,7 @@ const test_targets = blk: { //TestTarget{ // .target = Target.parse(.{ // .arch_os_abi = "arm-linux-gnueabihf", - // .cpu = "generic+v8a", + // .cpu_features = "generic+v8a", // }) catch unreachable, // .link_libc = true, //}, @@ -449,7 +449,7 @@ pub fn addPkgTests( const ArchTag = @TagType(builtin.Arch); if (test_target.disable_native and test_target.target.getOs() == builtin.os and - @as(ArchTag, test_target.target.getArch()) == @as(ArchTag, builtin.arch)) + test_target.target.getArch() == builtin.arch) { continue; } diff --git a/test/translate_c.zig b/test/translate_c.zig index b69142e864..2351a6c94f 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -1095,10 +1095,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { cases.addWithTarget("Calling convention", tests.Target{ .Cross = .{ + .cpu = Target.Cpu.baseline(.i386), .os = .linux, - .arch = .i386, .abi = .none, - .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(), }, }, \\void __attribute__((fastcall)) foo1(float *a);