authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-28 18:31:46-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-28 18:31:46-05:00
log4591236ae1de25e55a7d134d5cc0dcc3e1ad6a6e
treea3a592284d8d235ba490583b5f4acd11869ec8c4
parentaa13f339d4d91f8e39f005821c172290e1a0227f
signature Commit is signed but in an unrecognized format.

CrossTarget.cpu_model: communicate intent precisely


3 files changed, 68 insertions(+), 38 deletions(-)

lib/std/zig/cross_target.zig+46-27
...@@ -7,11 +7,10 @@ const mem = std.mem;...@@ -7,11 +7,10 @@ const mem = std.mem;
7/// The purpose of this abstraction is to provide meaningful and unsurprising defaults.7/// The purpose of this abstraction is to provide meaningful and unsurprising defaults.
8/// This struct does reference any resources and it is copyable.8/// This struct does reference any resources and it is copyable.
9pub const CrossTarget = struct {9pub const CrossTarget = struct {
10 /// `null` means native. If this is `null` then `cpu_model` must be `null`.10 /// `null` means native.
11 cpu_arch: ?Target.Cpu.Arch = null,11 cpu_arch: ?Target.Cpu.Arch = null,
1212
13 /// `null` means native. If this is non-null, `cpu_arch` must be specified.13 cpu_model: CpuModel = CpuModel.determined_by_cpu_arch,
14 cpu_model: ?*const Target.Cpu.Model = null,
1514
16 /// Sparse set of CPU features to add to the set from `cpu_model`.15 /// Sparse set of CPU features to add to the set from `cpu_model`.
17 cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,16 cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
...@@ -41,6 +40,20 @@ pub const CrossTarget = struct {...@@ -41,6 +40,20 @@ pub const CrossTarget = struct {
41 /// based on the `os_tag`.40 /// based on the `os_tag`.
42 dynamic_linker: DynamicLinker = DynamicLinker{},41 dynamic_linker: DynamicLinker = DynamicLinker{},
4342
43 pub const CpuModel = union(enum) {
44 /// Always native
45 native,
46
47 /// Always baseline
48 baseline,
49
50 /// If CPU Architecture is native, then the CPU model will be native. Otherwise,
51 /// it will be baseline.
52 determined_by_cpu_arch,
53
54 explicit: *const Target.Cpu.Model,
55 };
56
44 pub const OsVersion = union(enum) {57 pub const OsVersion = union(enum) {
45 none: void,58 none: void,
46 semver: SemVer,59 semver: SemVer,
...@@ -54,7 +67,7 @@ pub const CrossTarget = struct {...@@ -54,7 +67,7 @@ pub const CrossTarget = struct {
54 pub fn fromTarget(target: Target) CrossTarget {67 pub fn fromTarget(target: Target) CrossTarget {
55 var result: CrossTarget = .{68 var result: CrossTarget = .{
56 .cpu_arch = target.cpu.arch,69 .cpu_arch = target.cpu.arch,
57 .cpu_model = target.cpu.model,70 .cpu_model = .{ .explicit = target.cpu.model },
58 .os_tag = target.os.tag,71 .os_tag = target.os.tag,
59 .os_version_min = undefined,72 .os_version_min = undefined,
60 .os_version_max = undefined,73 .os_version_max = undefined,
...@@ -266,11 +279,11 @@ pub const CrossTarget = struct {...@@ -266,11 +279,11 @@ pub const CrossTarget = struct {
266 const add_set = &result.cpu_features_add;279 const add_set = &result.cpu_features_add;
267 const sub_set = &result.cpu_features_sub;280 const sub_set = &result.cpu_features_sub;
268 if (mem.eql(u8, cpu_name, "native")) {281 if (mem.eql(u8, cpu_name, "native")) {
269 result.cpu_model = null;282 result.cpu_model = .native;
270 } else if (mem.eql(u8, cpu_name, "baseline")) {283 } else if (mem.eql(u8, cpu_name, "baseline")) {
271 result.cpu_model = Target.Cpu.Model.baseline(arch);284 result.cpu_model = .baseline;
272 } else {285 } else {
273 result.cpu_model = try arch.parseCpuModel(cpu_name);286 result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
274 }287 }
275288
276 while (index < cpu_features.len) {289 while (index < cpu_features.len) {
...@@ -300,10 +313,6 @@ pub const CrossTarget = struct {...@@ -300,10 +313,6 @@ pub const CrossTarget = struct {
300 return error.UnknownCpuFeature;313 return error.UnknownCpuFeature;
301 }314 }
302 }315 }
303 } else if (arch_is_native) {
304 result.cpu_model = null;
305 } else {
306 result.cpu_model = Target.Cpu.Model.baseline(arch);
307 }316 }
308317
309 return result;318 return result;
...@@ -311,24 +320,33 @@ pub const CrossTarget = struct {...@@ -311,24 +320,33 @@ pub const CrossTarget = struct {
311320
312 /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.321 /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
313 pub fn getCpu(self: CrossTarget) Target.Cpu {322 pub fn getCpu(self: CrossTarget) Target.Cpu {
314 if (self.cpu_arch) |arch| {323 switch (self.cpu_model) {
315 if (self.cpu_model) |model| {324 .native => {
316 var adjusted_model = model.toCpu(arch);325 // This works when doing `zig build` because Zig generates a build executable using
317 self.updateCpuFeatures(&adjusted_model.features);326 // native CPU model & features. However this will not be accurate otherwise, and
318 return adjusted_model;327 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
328 return Target.current.cpu;
329 },
330 .baseline => {
331 var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
332 self.updateCpuFeatures(&adjusted_baseline.features);
333 return adjusted_baseline;
334 },
335 .determined_by_cpu_arch => if (self.cpu_arch == null) {
336 // This works when doing `zig build` because Zig generates a build executable using
337 // native CPU model & features. However this will not be accurate otherwise, and
338 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
339 return Target.current.cpu;
319 } else {340 } else {
320 var adjusted_baseline = Target.Cpu.baseline(arch);341 var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
321 self.updateCpuFeatures(&adjusted_baseline.features);342 self.updateCpuFeatures(&adjusted_baseline.features);
322 return adjusted_baseline;343 return adjusted_baseline;
323 }344 },
324 } else {345 .explicit => |model| {
325 assert(self.cpu_model == null);346 var adjusted_model = model.toCpu(self.getCpuArch());
326 assert(self.cpu_features_sub.isEmpty());347 self.updateCpuFeatures(&adjusted_model.features);
327 assert(self.cpu_features_add.isEmpty());348 return adjusted_model;
328 // This works when doing `zig build` because Zig generates a build executable using349 },
329 // native CPU model & features. However this will not be accurate otherwise, and
330 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
331 return Target.current.cpu;
332 }350 }
333 }351 }
334352
...@@ -461,7 +479,8 @@ pub const CrossTarget = struct {...@@ -461,7 +479,8 @@ pub const CrossTarget = struct {
461 }479 }
462480
463 pub fn isNative(self: CrossTarget) bool {481 pub fn isNative(self: CrossTarget) bool {
464 return self.cpu_arch == null and self.cpu_model == null and482 return self.cpu_arch == null and
483 (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
465 self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and484 self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and
466 self.os_tag == null and self.os_version_min == null and self.os_version_max == null and485 self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
467 self.abi == null and self.dynamic_linker.get() == null;486 self.abi == null and self.dynamic_linker.get() == null;
lib/std/zig/system.zig+21-10
...@@ -191,18 +191,18 @@ pub const NativeTargetInfo = struct {...@@ -191,18 +191,18 @@ pub const NativeTargetInfo = struct {
191 /// deinitialization method.191 /// deinitialization method.
192 /// TODO Remove the Allocator requirement from this function.192 /// TODO Remove the Allocator requirement from this function.
193 pub fn detect(allocator: *Allocator, cross_target: CrossTarget) DetectError!NativeTargetInfo {193 pub fn detect(allocator: *Allocator, cross_target: CrossTarget) DetectError!NativeTargetInfo {
194 const cpu = blk: {194 const cpu = switch (cross_target.cpu_model) {
195 const arch = cross_target.getCpuArch();195 .native => detectNativeCpuAndFeatures(cross_target),
196 if (cross_target.cpu_model) |model| {196 .baseline => baselineCpuAndFeatures(cross_target),
197 var adjusted_model = model.toCpu(arch);197 .determined_by_cpu_arch => if (cross_target.cpu_arch == null)
198 detectNativeCpuAndFeatures(cross_target)
199 else
200 baselineCpuAndFeatures(cross_target),
201 .explicit => |model| blk: {
202 var adjusted_model = model.toCpu(cross_target.getCpuArch());
198 cross_target.updateCpuFeatures(&adjusted_model.features);203 cross_target.updateCpuFeatures(&adjusted_model.features);
199 break :blk adjusted_model;204 break :blk adjusted_model;
200 } else {205 },
201 // TODO Detect native CPU model & features. Until that is implemented we use baseline.
202 var adjusted_baseline = Target.Cpu.baseline(arch);
203 cross_target.updateCpuFeatures(&adjusted_baseline.features);
204 break :blk adjusted_baseline;
205 }
206 };206 };
207207
208 var os = Target.Os.defaultVersionRange(cross_target.getOsTag());208 var os = Target.Os.defaultVersionRange(cross_target.getOsTag());
...@@ -758,4 +758,15 @@ pub const NativeTargetInfo = struct {...@@ -758,4 +758,15 @@ pub const NativeTargetInfo = struct {
758 }758 }
759 }759 }
760 }760 }
761
762 fn detectNativeCpuAndFeatures(cross_target: CrossTarget) Target.Cpu {
763 // TODO Detect native CPU model & features. Until that is implemented we use baseline.
764 return baselineCpuAndFeatures(cross_target);
765 }
766
767 fn baselineCpuAndFeatures(cross_target: CrossTarget) Target.Cpu {
768 var adjusted_baseline = Target.Cpu.baseline(cross_target.getCpuArch());
769 cross_target.updateCpuFeatures(&adjusted_baseline.features);
770 return adjusted_baseline;
771 }
761};772};
src-self-hosted/stage2.zig+1-1
...@@ -1154,7 +1154,7 @@ fn enumInt(comptime Enum: type, int: c_int) Enum {...@@ -1154,7 +1154,7 @@ fn enumInt(comptime Enum: type, int: c_int) Enum {
11541154
1155fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target {1155fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target {
1156 var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target);1156 var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target);
1157 if (cross_target.cpu_arch == null or cross_target.cpu_model == null) {1157 if (cross_target.cpu_arch == null or cross_target.cpu_model == .native) {
1158 // TODO We want to just use detected_info.target but implementing1158 // TODO We want to just use detected_info.target but implementing
1159 // CPU model & feature detection is todo so here we rely on LLVM.1159 // CPU model & feature detection is todo so here we rely on LLVM.
1160 const llvm = @import("llvm.zig");1160 const llvm = @import("llvm.zig");