diff --git a/lib/std/zig/system/windows.zig b/lib/std/zig/system/windows.zig index cd40be514b7e2411d0ccf52e8ecd85ca3657ca1a..31f4b2cd4c2d960f073417db434f7c00d1b0b2d9 100644 --- a/lib/std/zig/system/windows.zig +++ b/lib/std/zig/system/windows.zig @@ -192,19 +192,15 @@ fn setFeature(comptime Feature: type, cpu: *Target.Cpu, feature: Feature, enable if (enabled) cpu.features.addFeature(idx) else cpu.features.removeFeature(idx); } -fn getCpuCount() usize { - return std.os.windows.peb().NumberOfProcessors; -} - /// If the fine-grained detection of CPU features via Win registry fails, /// we fallback to a generic CPU model but we override the feature set /// using `SharedUserData` contents. /// This is effectively what LLVM does for all ARM chips on Windows. fn genericCpuAndNativeFeatures(arch: Target.Cpu.Arch) Target.Cpu { - var cpu = Target.Cpu{ + var cpu: Target.Cpu = .{ .arch = arch, .model = Target.Cpu.Model.generic(arch), - .features = Target.Cpu.Feature.Set.empty, + .features = .empty, }; switch (arch) { @@ -262,52 +258,39 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu { const current_arch = builtin.cpu.arch; const cpu: ?Target.Cpu = switch (current_arch) { .aarch64, .aarch64_be => blk: { - var cores: [128]Target.Cpu = undefined; - const core_count = getCpuCount(); + var registers: [12]u64 = undefined; - if (core_count > cores.len) break :blk null; + // CP 4000 -> MIDR_EL1 + // CP 4020 -> ID_AA64PFR0_EL1 + // CP 4021 -> ID_AA64PFR1_EL1 + // CP 4028 -> ID_AA64DFR0_EL1 + // CP 4029 -> ID_AA64DFR1_EL1 + // CP 402C -> ID_AA64AFR0_EL1 + // CP 402D -> ID_AA64AFR1_EL1 + // CP 4030 -> ID_AA64ISAR0_EL1 + // CP 4031 -> ID_AA64ISAR1_EL1 + // CP 4038 -> ID_AA64MMFR0_EL1 + // CP 4039 -> ID_AA64MMFR1_EL1 + // CP 403A -> ID_AA64MMFR2_EL1 + getCpuInfoFromRegistry(0, .{ + .{ .key = "CP 4000", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[0])) }, + .{ .key = "CP 4020", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[1])) }, + .{ .key = "CP 4021", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[2])) }, + .{ .key = "CP 4028", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[3])) }, + .{ .key = "CP 4029", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[4])) }, + .{ .key = "CP 402C", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[5])) }, + .{ .key = "CP 402D", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[6])) }, + .{ .key = "CP 4030", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[7])) }, + .{ .key = "CP 4031", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[8])) }, + .{ .key = "CP 4038", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[9])) }, + .{ .key = "CP 4039", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[10])) }, + .{ .key = "CP 403A", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[11])) }, + }) catch break :blk null; - var i: usize = 0; - while (i < core_count) : (i += 1) { - // Backing datastore - var registers: [12]u64 = undefined; - - // Registry key to system ID register mapping - // CP 4000 -> MIDR_EL1 - // CP 4020 -> ID_AA64PFR0_EL1 - // CP 4021 -> ID_AA64PFR1_EL1 - // CP 4028 -> ID_AA64DFR0_EL1 - // CP 4029 -> ID_AA64DFR1_EL1 - // CP 402C -> ID_AA64AFR0_EL1 - // CP 402D -> ID_AA64AFR1_EL1 - // CP 4030 -> ID_AA64ISAR0_EL1 - // CP 4031 -> ID_AA64ISAR1_EL1 - // CP 4038 -> ID_AA64MMFR0_EL1 - // CP 4039 -> ID_AA64MMFR1_EL1 - // CP 403A -> ID_AA64MMFR2_EL1 - getCpuInfoFromRegistry(i, .{ - .{ .key = "CP 4000", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[0])) }, - .{ .key = "CP 4020", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[1])) }, - .{ .key = "CP 4021", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[2])) }, - .{ .key = "CP 4028", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[3])) }, - .{ .key = "CP 4029", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[4])) }, - .{ .key = "CP 402C", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[5])) }, - .{ .key = "CP 402D", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[6])) }, - .{ .key = "CP 4030", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[7])) }, - .{ .key = "CP 4031", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[8])) }, - .{ .key = "CP 4038", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[9])) }, - .{ .key = "CP 4039", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[10])) }, - .{ .key = "CP 403A", .value_type = REG.ValueType.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[11])) }, - }) catch break :blk null; - - cores[i] = @import("arm.zig").aarch64.detectNativeCpuAndFeatures(current_arch, registers) orelse - break :blk null; - } - - // Pick the first core, usually LITTLE in big.LITTLE architecture. - break :blk cores[0]; + break :blk @import("arm.zig").aarch64.detectNativeCpuAndFeatures(current_arch, registers); }, else => null, }; + return cpu orelse genericCpuAndNativeFeatures(current_arch); }