| ... | @@ -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. |
| 9 | pub const CrossTarget = struct { | 9 | pub 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, |
| 12 | | 12 | |
| 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, | | |
| 15 | | 14 | |
| 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{}, |
| 43 | | 42 | |
| | 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 | } |
| 275 | | 288 | |
| 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 | } |
| 308 | | 317 | |
| 309 | return result; | 318 | return result; |
| ... | @@ -311,24 +320,33 @@ pub const CrossTarget = struct { | ... | @@ -311,24 +320,33 @@ pub const CrossTarget = struct { |
| 311 | | 320 | |
| 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 using | 349 | }, |
| 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 | } |
| 334 | | 352 | |
| ... | @@ -461,7 +479,8 @@ pub const CrossTarget = struct { | ... | @@ -461,7 +479,8 @@ pub const CrossTarget = struct { |
| 461 | } | 479 | } |
| 462 | | 480 | |
| 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 and | 482 | 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() and | 484 | 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 and | 485 | 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; |