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
192192 if (enabled) cpu.features.addFeature(idx) else cpu.features.removeFeature(idx);
193193}
194194
195fn getCpuCount() usize {
196 return std.os.windows.peb().NumberOfProcessors;
197}
198
199195/// If the fine-grained detection of CPU features via Win registry fails,
200196/// we fallback to a generic CPU model but we override the feature set
201197/// using `SharedUserData` contents.
202198/// This is effectively what LLVM does for all ARM chips on Windows.
203199fn genericCpuAndNativeFeatures(arch: Target.Cpu.Arch) Target.Cpu {
204 var cpu = Target.Cpu{
200 var cpu: Target.Cpu = .{
205201 .arch = arch,
206202 .model = Target.Cpu.Model.generic(arch),
207 .features = Target.Cpu.Feature.Set.empty,
203 .features = .empty,
208204 };
209205
210206 switch (arch) {
......@@ -262,52 +258,39 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu {
262258 const current_arch = builtin.cpu.arch;
263259 const cpu: ?Target.Cpu = switch (current_arch) {
264260 .aarch64, .aarch64_be => blk: {
265 var cores: [128]Target.Cpu = undefined;
266 const core_count = getCpuCount();
267
268 if (core_count > cores.len) break :blk null;
269
270 var i: usize = 0;
271 while (i < core_count) : (i += 1) {
272 // Backing datastore
273 var registers: [12]u64 = undefined;
274
275 // Registry key to system ID register mapping
276 // CP 4000 -> MIDR_EL1
277 // CP 4020 -> ID_AA64PFR0_EL1
278 // CP 4021 -> ID_AA64PFR1_EL1
279 // CP 4028 -> ID_AA64DFR0_EL1
280 // CP 4029 -> ID_AA64DFR1_EL1
281 // CP 402C -> ID_AA64AFR0_EL1
282 // CP 402D -> ID_AA64AFR1_EL1
283 // CP 4030 -> ID_AA64ISAR0_EL1
284 // CP 4031 -> ID_AA64ISAR1_EL1
285 // CP 4038 -> ID_AA64MMFR0_EL1
286 // CP 4039 -> ID_AA64MMFR1_EL1
287 // CP 403A -> ID_AA64MMFR2_EL1
288 getCpuInfoFromRegistry(i, .{
289 .{ .key = "CP 4000", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[0])) },
290 .{ .key = "CP 4020", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[1])) },
291 .{ .key = "CP 4021", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[2])) },
292 .{ .key = "CP 4028", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[3])) },
293 .{ .key = "CP 4029", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[4])) },
294 .{ .key = "CP 402C", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[5])) },
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];
261 var registers: [12]u64 = undefined;
262
263 // CP 4000 -> MIDR_EL1
264 // CP 4020 -> ID_AA64PFR0_EL1
265 // CP 4021 -> ID_AA64PFR1_EL1
266 // CP 4028 -> ID_AA64DFR0_EL1
267 // CP 4029 -> ID_AA64DFR1_EL1
268 // CP 402C -> ID_AA64AFR0_EL1
269 // CP 402D -> ID_AA64AFR1_EL1
270 // CP 4030 -> ID_AA64ISAR0_EL1
271 // CP 4031 -> ID_AA64ISAR1_EL1
272 // CP 4038 -> ID_AA64MMFR0_EL1
273 // CP 4039 -> ID_AA64MMFR1_EL1
274 // CP 403A -> ID_AA64MMFR2_EL1
275 getCpuInfoFromRegistry(0, .{
276 .{ .key = "CP 4000", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[0])) },
277 .{ .key = "CP 4020", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[1])) },
278 .{ .key = "CP 4021", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[2])) },
279 .{ .key = "CP 4028", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[3])) },
280 .{ .key = "CP 4029", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[4])) },
281 .{ .key = "CP 402C", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[5])) },
282 .{ .key = "CP 402D", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[6])) },
283 .{ .key = "CP 4030", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[7])) },
284 .{ .key = "CP 4031", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[8])) },
285 .{ .key = "CP 4038", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[9])) },
286 .{ .key = "CP 4039", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[10])) },
287 .{ .key = "CP 403A", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(&registers[11])) },
288 }) catch break :blk null;
289
290 break :blk @import("arm.zig").aarch64.detectNativeCpuAndFeatures(current_arch, registers);
309291 },
310292 else => null,
311293 };
294
312295 return cpu orelse genericCpuAndNativeFeatures(current_arch);
313296}