Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 45 additions & 45 deletions lib/std/zig/system.zig
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
os.version_range.linux.android = android;
}

const cpu = switch (query.cpu_model) {
var cpu = switch (query.cpu_model) {
.native => detectNativeCpuAndFeatures(query_cpu_arch, os, query),
.baseline => Target.Cpu.baseline(query_cpu_arch, os),
.determined_by_arch_os => if (query.cpu_arch == null)
Expand All @@ -354,55 +354,22 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
break :backup_cpu_detection Target.Cpu.baseline(query_cpu_arch, os);
};

var result = try detectAbiAndDynamicLinker(cpu, os, query);

// It's possible that we detect the native ABI, but fail to detect the OS version or were told
// to use the default OS version range. In that case, while we can't determine the exact native
// OS version, we do at least know that some ABIs require a particular OS version (by way of
// `std.zig.target.available_libcs`). So in this case, adjust the OS version to the minimum that
// we know is required.
if (result.abi != query_abi and query.os_version_min == null) {
const result_ver_range = &result.os.version_range;
const abi_ver_range = result.os.tag.defaultVersionRange(result.cpu.arch, result.abi).version_range;

switch (result.os.tag.versionRangeTag()) {
.none => {},
.semver => if (result_ver_range.semver.min.order(abi_ver_range.semver.min) == .lt) {
result_ver_range.semver.min = abi_ver_range.semver.min;
},
inline .hurd, .linux => |t| {
if (@field(result_ver_range, @tagName(t)).range.min.order(@field(abi_ver_range, @tagName(t)).range.min) == .lt) {
@field(result_ver_range, @tagName(t)).range.min = @field(abi_ver_range, @tagName(t)).range.min;
}

if (@field(result_ver_range, @tagName(t)).glibc.order(@field(abi_ver_range, @tagName(t)).glibc) == .lt and
query.glibc_version == null)
{
@field(result_ver_range, @tagName(t)).glibc = @field(abi_ver_range, @tagName(t)).glibc;
}
},
.windows => if (!result_ver_range.windows.min.isAtLeast(abi_ver_range.windows.min)) {
result_ver_range.windows.min = abi_ver_range.windows.min;
},
}
}

// For x86, we need to populate some CPU feature flags depending on architecture
// and mode:
// * 16bit_mode => if the abi is code16
// * 32bit_mode => if the arch is x86
// However, the "mode" flags can be used as overrides, so if the user explicitly
// sets one of them, that takes precedence.
switch (result.cpu.arch) {
switch (query_cpu_arch) {
.x86 => {
if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{
.@"16bit_mode", .@"32bit_mode",
})) {
switch (result.abi) {
.code16 => result.cpu.features.addFeature(
switch (query_abi) {
.code16 => cpu.features.addFeature(
@intFromEnum(Target.x86.Feature.@"16bit_mode"),
),
else => result.cpu.features.addFeature(
else => cpu.features.addFeature(
@intFromEnum(Target.x86.Feature.@"32bit_mode"),
),
}
Expand All @@ -413,32 +380,65 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
// What do we do if the user specifies +thumb_mode?
},
.thumb, .thumbeb => {
result.cpu.features.addFeature(
cpu.features.addFeature(
@intFromEnum(Target.arm.Feature.thumb_mode),
);
},
else => {},
}
updateCpuFeatures(
&result.cpu.features,
result.cpu.arch.allFeaturesList(),
&cpu.features,
cpu.arch.allFeaturesList(),
query.cpu_features_add,
query.cpu_features_sub,
);

if (result.cpu.arch == .hexagon) {
if (cpu.arch == .hexagon) {
// Both LLVM and LLD have broken support for the small data area. Yet LLVM has the feature
// on by default for all Hexagon CPUs. Clang sort of solves this by defaulting the `-gpsize`
// command line parameter for the Hexagon backend to 0, so that no constants get placed in
// the SDA. (This of course breaks down if the user passes `-G <n>` to Clang...) We can't do
// the `-gpsize` hack because we can have multiple concurrent LLVM emit jobs, and command
// line options in LLVM are shared globally. So just force this feature off. Lovely stuff.
result.cpu.features.removeFeature(@intFromEnum(Target.hexagon.Feature.small_data));
cpu.features.removeFeature(@intFromEnum(Target.hexagon.Feature.small_data));
}

// https://github.com/llvm/llvm-project/issues/105978
if (result.cpu.arch.isArm() and result.floatAbi() == .soft) {
result.cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2));
if (cpu.arch.isArm() and query_abi.floatAbi() == .soft) {
cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2));
}

var result = try detectAbiAndDynamicLinker(cpu, os, query);

// It's possible that we detect the native ABI, but fail to detect the OS version or were told
// to use the default OS version range. In that case, while we can't determine the exact native
// OS version, we do at least know that some ABIs require a particular OS version (by way of
// `std.zig.target.available_libcs`). So in this case, adjust the OS version to the minimum that
// we know is required.
if (result.abi != query_abi and query.os_version_min == null) {
const result_ver_range = &result.os.version_range;
const abi_ver_range = result.os.tag.defaultVersionRange(result.cpu.arch, result.abi).version_range;

switch (result.os.tag.versionRangeTag()) {
.none => {},
.semver => if (result_ver_range.semver.min.order(abi_ver_range.semver.min) == .lt) {
result_ver_range.semver.min = abi_ver_range.semver.min;
},
inline .hurd, .linux => |t| {
if (@field(result_ver_range, @tagName(t)).range.min.order(@field(abi_ver_range, @tagName(t)).range.min) == .lt) {
@field(result_ver_range, @tagName(t)).range.min = @field(abi_ver_range, @tagName(t)).range.min;
}

if (@field(result_ver_range, @tagName(t)).glibc.order(@field(abi_ver_range, @tagName(t)).glibc) == .lt and
query.glibc_version == null)
{
@field(result_ver_range, @tagName(t)).glibc = @field(abi_ver_range, @tagName(t)).glibc;
}
},
.windows => if (!result_ver_range.windows.min.isAtLeast(abi_ver_range.windows.min)) {
result_ver_range.windows.min = abi_ver_range.windows.min;
},
}
}

return result;
Expand Down
Loading