authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-20 12:41:18-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-20 12:41:18-05:00
logbf82929557f0b116979261c522c62cf6393a08f2
tree2d6a30785f9245cb06b2dbc36eaf7bfff028ee67
parent8f29d1407350190e1e641ca55f870f00b53d0246
signaturelock-open Commit is signed but in an unrecognized format.

fix std.Target.Arch.parseCpuFeatureSet


2 files changed, 42 insertions(+), 22 deletions(-)

lib/std/target.zig+41-21
...@@ -228,30 +228,40 @@ pub const Target = union(enum) {...@@ -228,30 +228,40 @@ pub const Target = union(enum) {
228228
229 var it = mem.tokenize(features_text, ",");229 var it = mem.tokenize(features_text, ",");
230 while (it.next()) |item_text| {230 while (it.next()) |item_text| {
231 const feature_name = blk: {231 var feature_name: []const u8 = undefined;
232 if (mem.startsWith(u8, item_text, "+")) {232 var op: enum {
233 switch (mode) {233 add,
234 .unknown, .baseline => mode = .baseline,234 sub,
235 .whitelist => return error.InvalidCpuFeatures,235 } = undefined;
236 }236 if (mem.startsWith(u8, item_text, "+")) {
237 break :blk item_text[1..];237 switch (mode) {
238 } else if (mem.startsWith(u8, item_text, "-")) {238 .unknown, .baseline => mode = .baseline,
239 switch (mode) {239 .whitelist => return error.InvalidCpuFeatures,
240 .unknown, .baseline => mode = .baseline,
241 .whitelist => return error.InvalidCpuFeatures,
242 }
243 break :blk item_text[1..];
244 } else {
245 switch (mode) {
246 .unknown, .whitelist => mode = .whitelist,
247 .baseline => return error.InvalidCpuFeatures,
248 }
249 break :blk item_text;
250 }240 }
251 };241 op = .add;
242 feature_name = item_text[1..];
243 } else if (mem.startsWith(u8, item_text, "-")) {
244 switch (mode) {
245 .unknown, .baseline => mode = .baseline,
246 .whitelist => return error.InvalidCpuFeatures,
247 }
248 op = .sub;
249 feature_name = item_text[1..];
250 } else {
251 switch (mode) {
252 .unknown, .whitelist => mode = .whitelist,
253 .baseline => return error.InvalidCpuFeatures,
254 }
255 op = .add;
256 feature_name = item_text;
257 }
252 for (arch.allFeaturesList()) |feature, index| {258 for (arch.allFeaturesList()) |feature, index| {
253 if (mem.eql(u8, feature_name, feature.name)) {259 if (mem.eql(u8, feature_name, feature.name)) {
254 set |= @splat(2, @as(Cpu.Feature.Set, 1) << @intCast(u7, index));260 const one_bit = @as(Cpu.Feature.Set, 1) << @intCast(u7, index);
261 switch (op) {
262 .add => set |= @splat(2, one_bit),
263 .sub => set &= @splat(2, ~one_bit),
264 }
255 break;265 break;
256 }266 }
257 } else {267 } else {
...@@ -1050,3 +1060,13 @@ pub const Target = union(enum) {...@@ -1050,3 +1060,13 @@ pub const Target = union(enum) {
1050 return .unavailable;1060 return .unavailable;
1051 }1061 }
1052};1062};
1063
1064test "parseCpuFeatureSet" {
1065 const set = try @as(Target.Arch, .x86_64).parseCpuFeatureSet("-sse,-avx,-cx8");
1066 std.testing.expect(!Target.x86.featureSetHas(set, .sse));
1067 std.testing.expect(!Target.x86.featureSetHas(set, .avx));
1068 std.testing.expect(!Target.x86.featureSetHas(set, .cx8));
1069 // These are expected because they are part of the baseline
1070 std.testing.expect(Target.x86.featureSetHas(set, .cmov));
1071 std.testing.expect(Target.x86.featureSetHas(set, .fxsr));
1072}
src-self-hosted/stage1.zig+1-1
...@@ -617,7 +617,7 @@ const Stage2CpuFeatures = struct {...@@ -617,7 +617,7 @@ const Stage2CpuFeatures = struct {
617 if (mem.eql(u8, llvm_feat, this_llvm_name)) {617 if (mem.eql(u8, llvm_feat, this_llvm_name)) {
618 switch (op) {618 switch (op) {
619 .add => set |= @as(Target.Cpu.Feature.Set, 1) << @intCast(u7, index),619 .add => set |= @as(Target.Cpu.Feature.Set, 1) << @intCast(u7, index),
620 .sub => set &= ~@as(Target.Cpu.Feature.Set, 1) << @intCast(u7, index),620 .sub => set &= ~(@as(Target.Cpu.Feature.Set, 1) << @intCast(u7, index)),
621 }621 }
622 break;622 break;
623 }623 }