mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
CrossTarget.cpu_model: communicate intent precisely
This commit is contained in:
parent
aa13f339d4
commit
4591236ae1
@ -7,11 +7,10 @@ const mem = std.mem;
|
||||
/// The purpose of this abstraction is to provide meaningful and unsurprising defaults.
|
||||
/// This struct does reference any resources and it is copyable.
|
||||
pub const CrossTarget = struct {
|
||||
/// `null` means native. If this is `null` then `cpu_model` must be `null`.
|
||||
/// `null` means native.
|
||||
cpu_arch: ?Target.Cpu.Arch = null,
|
||||
|
||||
/// `null` means native. If this is non-null, `cpu_arch` must be specified.
|
||||
cpu_model: ?*const Target.Cpu.Model = null,
|
||||
cpu_model: CpuModel = CpuModel.determined_by_cpu_arch,
|
||||
|
||||
/// Sparse set of CPU features to add to the set from `cpu_model`.
|
||||
cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
|
||||
@ -41,6 +40,20 @@ pub const CrossTarget = struct {
|
||||
/// based on the `os_tag`.
|
||||
dynamic_linker: DynamicLinker = DynamicLinker{},
|
||||
|
||||
pub const CpuModel = union(enum) {
|
||||
/// Always native
|
||||
native,
|
||||
|
||||
/// Always baseline
|
||||
baseline,
|
||||
|
||||
/// If CPU Architecture is native, then the CPU model will be native. Otherwise,
|
||||
/// it will be baseline.
|
||||
determined_by_cpu_arch,
|
||||
|
||||
explicit: *const Target.Cpu.Model,
|
||||
};
|
||||
|
||||
pub const OsVersion = union(enum) {
|
||||
none: void,
|
||||
semver: SemVer,
|
||||
@ -54,7 +67,7 @@ pub const CrossTarget = struct {
|
||||
pub fn fromTarget(target: Target) CrossTarget {
|
||||
var result: CrossTarget = .{
|
||||
.cpu_arch = target.cpu.arch,
|
||||
.cpu_model = target.cpu.model,
|
||||
.cpu_model = .{ .explicit = target.cpu.model },
|
||||
.os_tag = target.os.tag,
|
||||
.os_version_min = undefined,
|
||||
.os_version_max = undefined,
|
||||
@ -266,11 +279,11 @@ pub const CrossTarget = struct {
|
||||
const add_set = &result.cpu_features_add;
|
||||
const sub_set = &result.cpu_features_sub;
|
||||
if (mem.eql(u8, cpu_name, "native")) {
|
||||
result.cpu_model = null;
|
||||
result.cpu_model = .native;
|
||||
} else if (mem.eql(u8, cpu_name, "baseline")) {
|
||||
result.cpu_model = Target.Cpu.Model.baseline(arch);
|
||||
result.cpu_model = .baseline;
|
||||
} else {
|
||||
result.cpu_model = try arch.parseCpuModel(cpu_name);
|
||||
result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
|
||||
}
|
||||
|
||||
while (index < cpu_features.len) {
|
||||
@ -300,10 +313,6 @@ pub const CrossTarget = struct {
|
||||
return error.UnknownCpuFeature;
|
||||
}
|
||||
}
|
||||
} else if (arch_is_native) {
|
||||
result.cpu_model = null;
|
||||
} else {
|
||||
result.cpu_model = Target.Cpu.Model.baseline(arch);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -311,24 +320,33 @@ pub const CrossTarget = struct {
|
||||
|
||||
/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
|
||||
pub fn getCpu(self: CrossTarget) Target.Cpu {
|
||||
if (self.cpu_arch) |arch| {
|
||||
if (self.cpu_model) |model| {
|
||||
var adjusted_model = model.toCpu(arch);
|
||||
self.updateCpuFeatures(&adjusted_model.features);
|
||||
return adjusted_model;
|
||||
} else {
|
||||
var adjusted_baseline = Target.Cpu.baseline(arch);
|
||||
switch (self.cpu_model) {
|
||||
.native => {
|
||||
// This works when doing `zig build` because Zig generates a build executable using
|
||||
// native CPU model & features. However this will not be accurate otherwise, and
|
||||
// will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
|
||||
return Target.current.cpu;
|
||||
},
|
||||
.baseline => {
|
||||
var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
|
||||
self.updateCpuFeatures(&adjusted_baseline.features);
|
||||
return adjusted_baseline;
|
||||
}
|
||||
} else {
|
||||
assert(self.cpu_model == null);
|
||||
assert(self.cpu_features_sub.isEmpty());
|
||||
assert(self.cpu_features_add.isEmpty());
|
||||
// This works when doing `zig build` because Zig generates a build executable using
|
||||
// native CPU model & features. However this will not be accurate otherwise, and
|
||||
// will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
|
||||
return Target.current.cpu;
|
||||
},
|
||||
.determined_by_cpu_arch => if (self.cpu_arch == null) {
|
||||
// This works when doing `zig build` because Zig generates a build executable using
|
||||
// native CPU model & features. However this will not be accurate otherwise, and
|
||||
// will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
|
||||
return Target.current.cpu;
|
||||
} else {
|
||||
var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
|
||||
self.updateCpuFeatures(&adjusted_baseline.features);
|
||||
return adjusted_baseline;
|
||||
},
|
||||
.explicit => |model| {
|
||||
var adjusted_model = model.toCpu(self.getCpuArch());
|
||||
self.updateCpuFeatures(&adjusted_model.features);
|
||||
return adjusted_model;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -461,7 +479,8 @@ pub const CrossTarget = struct {
|
||||
}
|
||||
|
||||
pub fn isNative(self: CrossTarget) bool {
|
||||
return self.cpu_arch == null and self.cpu_model == null and
|
||||
return self.cpu_arch == null and
|
||||
(self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
|
||||
self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and
|
||||
self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
|
||||
self.abi == null and self.dynamic_linker.get() == null;
|
||||
|
||||
@ -191,18 +191,18 @@ pub const NativeTargetInfo = struct {
|
||||
/// deinitialization method.
|
||||
/// TODO Remove the Allocator requirement from this function.
|
||||
pub fn detect(allocator: *Allocator, cross_target: CrossTarget) DetectError!NativeTargetInfo {
|
||||
const cpu = blk: {
|
||||
const arch = cross_target.getCpuArch();
|
||||
if (cross_target.cpu_model) |model| {
|
||||
var adjusted_model = model.toCpu(arch);
|
||||
const cpu = switch (cross_target.cpu_model) {
|
||||
.native => detectNativeCpuAndFeatures(cross_target),
|
||||
.baseline => baselineCpuAndFeatures(cross_target),
|
||||
.determined_by_cpu_arch => if (cross_target.cpu_arch == null)
|
||||
detectNativeCpuAndFeatures(cross_target)
|
||||
else
|
||||
baselineCpuAndFeatures(cross_target),
|
||||
.explicit => |model| blk: {
|
||||
var adjusted_model = model.toCpu(cross_target.getCpuArch());
|
||||
cross_target.updateCpuFeatures(&adjusted_model.features);
|
||||
break :blk adjusted_model;
|
||||
} else {
|
||||
// TODO Detect native CPU model & features. Until that is implemented we use baseline.
|
||||
var adjusted_baseline = Target.Cpu.baseline(arch);
|
||||
cross_target.updateCpuFeatures(&adjusted_baseline.features);
|
||||
break :blk adjusted_baseline;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var os = Target.Os.defaultVersionRange(cross_target.getOsTag());
|
||||
@ -758,4 +758,15 @@ pub const NativeTargetInfo = struct {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn detectNativeCpuAndFeatures(cross_target: CrossTarget) Target.Cpu {
|
||||
// TODO Detect native CPU model & features. Until that is implemented we use baseline.
|
||||
return baselineCpuAndFeatures(cross_target);
|
||||
}
|
||||
|
||||
fn baselineCpuAndFeatures(cross_target: CrossTarget) Target.Cpu {
|
||||
var adjusted_baseline = Target.Cpu.baseline(cross_target.getCpuArch());
|
||||
cross_target.updateCpuFeatures(&adjusted_baseline.features);
|
||||
return adjusted_baseline;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1154,7 +1154,7 @@ fn enumInt(comptime Enum: type, int: c_int) Enum {
|
||||
|
||||
fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target {
|
||||
var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target);
|
||||
if (cross_target.cpu_arch == null or cross_target.cpu_model == null) {
|
||||
if (cross_target.cpu_arch == null or cross_target.cpu_model == .native) {
|
||||
// TODO We want to just use detected_info.target but implementing
|
||||
// CPU model & feature detection is todo so here we rely on LLVM.
|
||||
const llvm = @import("llvm.zig");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user