authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-05 18:39:51+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-05 19:32:59+02:00
loge2216b0f105adb09e6ef2d33c6ba54002f0de627
tree134471c1c96b1a5ebe2fa1befc54513cea182714
parent311c9699cb5e7fb81d9d7e74f1d7f40a8da0079b
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.zig.system.windows: don't collect feature registers for all cores

We're only interested in one anyway!

1 files changed, 33 insertions(+), 50 deletions(-)

lib/std/zig/system/windows.zig+33-50
...@@ -192,19 +192,15 @@ fn setFeature(comptime Feature: type, cpu: *Target.Cpu, feature: Feature, enable...@@ -192,19 +192,15 @@ fn setFeature(comptime Feature: type, cpu: *Target.Cpu, feature: Feature, enable
192 if (enabled) cpu.features.addFeature(idx) else cpu.features.removeFeature(idx);192 if (enabled) cpu.features.addFeature(idx) else cpu.features.removeFeature(idx);
193}193}
194194
195fn getCpuCount() usize {
196 return std.os.windows.peb().NumberOfProcessors;
197}
198
199/// If the fine-grained detection of CPU features via Win registry fails,195/// If the fine-grained detection of CPU features via Win registry fails,
200/// we fallback to a generic CPU model but we override the feature set196/// we fallback to a generic CPU model but we override the feature set
201/// using `SharedUserData` contents.197/// using `SharedUserData` contents.
202/// This is effectively what LLVM does for all ARM chips on Windows.198/// This is effectively what LLVM does for all ARM chips on Windows.
203fn genericCpuAndNativeFeatures(arch: Target.Cpu.Arch) Target.Cpu {199fn genericCpuAndNativeFeatures(arch: Target.Cpu.Arch) Target.Cpu {
204 var cpu = Target.Cpu{200 var cpu: Target.Cpu = .{
205 .arch = arch,201 .arch = arch,
206 .model = Target.Cpu.Model.generic(arch),202 .model = Target.Cpu.Model.generic(arch),
207 .features = Target.Cpu.Feature.Set.empty,203 .features = .empty,
208 };204 };
209205
210 switch (arch) {206 switch (arch) {
...@@ -262,52 +258,39 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu {...@@ -262,52 +258,39 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu {
262 const current_arch = builtin.cpu.arch;258 const current_arch = builtin.cpu.arch;
263 const cpu: ?Target.Cpu = switch (current_arch) {259 const cpu: ?Target.Cpu = switch (current_arch) {
264 .aarch64, .aarch64_be => blk: {260 .aarch64, .aarch64_be => blk: {
265 var cores: [128]Target.Cpu = undefined;261 var registers: [12]u64 = undefined;
266 const core_count = getCpuCount();262
267263 // CP 4000 -> MIDR_EL1
268 if (core_count > cores.len) break :blk null;264 // CP 4020 -> ID_AA64PFR0_EL1
269265 // CP 4021 -> ID_AA64PFR1_EL1
270 var i: usize = 0;266 // CP 4028 -> ID_AA64DFR0_EL1
271 while (i < core_count) : (i += 1) {267 // CP 4029 -> ID_AA64DFR1_EL1
272 // Backing datastore268 // CP 402C -> ID_AA64AFR0_EL1
273 var registers: [12]u64 = undefined;269 // CP 402D -> ID_AA64AFR1_EL1
274270 // CP 4030 -> ID_AA64ISAR0_EL1
275 // Registry key to system ID register mapping271 // CP 4031 -> ID_AA64ISAR1_EL1
276 // CP 4000 -> MIDR_EL1272 // CP 4038 -> ID_AA64MMFR0_EL1
277 // CP 4020 -> ID_AA64PFR0_EL1273 // CP 4039 -> ID_AA64MMFR1_EL1
278 // CP 4021 -> ID_AA64PFR1_EL1274 // CP 403A -> ID_AA64MMFR2_EL1
279 // CP 4028 -> ID_AA64DFR0_EL1275 getCpuInfoFromRegistry(0, .{
280 // CP 4029 -> ID_AA64DFR1_EL1276 .{ .key = "CP 4000", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[0])) },
281 // CP 402C -> ID_AA64AFR0_EL1277 .{ .key = "CP 4020", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[1])) },
282 // CP 402D -> ID_AA64AFR1_EL1278 .{ .key = "CP 4021", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[2])) },
283 // CP 4030 -> ID_AA64ISAR0_EL1279 .{ .key = "CP 4028", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[3])) },
284 // CP 4031 -> ID_AA64ISAR1_EL1280 .{ .key = "CP 4029", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[4])) },
285 // CP 4038 -> ID_AA64MMFR0_EL1281 .{ .key = "CP 402C", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[5])) },
286 // CP 4039 -> ID_AA64MMFR1_EL1282 .{ .key = "CP 402D", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[6])) },
287 // CP 403A -> ID_AA64MMFR2_EL1283 .{ .key = "CP 4030", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[7])) },
288 getCpuInfoFromRegistry(i, .{284 .{ .key = "CP 4031", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[8])) },
289 .{ .key = "CP 4000", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[0])) },285 .{ .key = "CP 4038", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[9])) },
290 .{ .key = "CP 4020", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[1])) },286 .{ .key = "CP 4039", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[10])) },
291 .{ .key = "CP 4021", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[2])) },287 .{ .key = "CP 403A", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[11])) },
292 .{ .key = "CP 4028", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[3])) },288 }) catch break :blk null;
293 .{ .key = "CP 4029", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[4])) },289
294 .{ .key = "CP 402C", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[5])) },290 break :blk @import("arm.zig").aarch64.detectNativeCpuAndFeatures(current_arch, registers);
295 .{ .key = "CP 402D", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[6])) },
296 .{ .key = "CP 4030", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[7])) },
297 .{ .key = "CP 4031", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[8])) },
298 .{ .key = "CP 4038", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[9])) },
299 .{ .key = "CP 4039", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[10])) },
300 .{ .key = "CP 403A", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[11])) },
301 }) catch break :blk null;
302
303 cores[i] = @import("arm.zig").aarch64.detectNativeCpuAndFeatures(current_arch, registers) orelse
304 break :blk null;
305 }
306
307 // Pick the first core, usually LITTLE in big.LITTLE architecture.
308 break :blk cores[0];
309 },291 },
310 else => null,292 else => null,
311 };293 };
294
312 return cpu orelse genericCpuAndNativeFeatures(current_arch);295 return cpu orelse genericCpuAndNativeFeatures(current_arch);
313}296}