authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-05 09:50:22+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-05 12:40:14+02:00
log88ee09fd917b93397926aa077772c89aec92e864
treeec153500610d0ef850b817fbfafd2782cef00bb6
parente374c985067170db17dfe1a6ee83696ccbcbb529
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.zig.system: add aarch64 CPU feature/model detection for NetBSD and OpenBSD

ref https://codeberg.org/ziglang/zig/issues/36724

3 files changed, 130 insertions(+), 3 deletions(-)

lib/std/zig/system.zig+6-3
......@@ -12,10 +12,12 @@ const Io = std.Io;
1212
1313pub const NativePaths = @import("system/NativePaths.zig");
1414
15pub const windows = @import("system/windows.zig");
1615pub const darwin = @import("system/darwin.zig");
17pub const linux = @import("system/linux.zig");
1816pub const freebsd = @import("system/freebsd.zig");
17pub const linux = @import("system/linux.zig");
18pub const netbsd = @import("system/netbsd.zig");
19pub const openbsd = @import("system/openbsd.zig");
20pub const windows = @import("system/windows.zig");
1921
2022pub const Executor = union(enum) {
2123 native,
......@@ -547,12 +549,13 @@ fn detectNativeCpuAndFeatures(io: Io, cpu_arch: Target.Cpu.Arch, os: Target.Os,
547549 .freebsd => return freebsd.detectNativeCpuAndFeatures(),
548550 .linux => return linux.detectNativeCpuAndFeatures(io),
549551 .macos => return darwin.macos.detectNativeCpuAndFeatures(),
552 .netbsd => return netbsd.detectNativeCpuAndFeatures(),
553 .openbsd => return openbsd.detectNativeCpuAndFeatures(),
550554 .windows => return windows.detectNativeCpuAndFeatures(),
551555 else => {},
552556 }
553557
554558 // This architecture does not have CPU model & feature detection yet.
555 // See https://github.com/ziglang/zig/issues/4591
556559 return null;
557560}
558561
lib/std/zig/system/netbsd.zig created+75
......@@ -0,0 +1,75 @@
1const builtin = @import("builtin");
2const std = @import("std");
3
4const native_arch = builtin.target.cpu.arch;
5
6const aarch64 = struct {
7 const sysctl_cpu_id = extern struct {
8 midr: u64,
9 revidr: u64,
10 mpidr: u64,
11
12 aa64dfr0: u64,
13 aa64dfr1: u64,
14
15 aa64isar0: u64,
16 aa64isar1: u64,
17
18 aa64mmfr0: u64,
19 aa64mmfr1: u64,
20 aa64mmfr2: u64,
21
22 aa64pfr0: u64,
23 aa64pfr1: u64,
24
25 aa64zfr0: u64,
26
27 mvfr0: u32,
28 mvfr1: u32,
29 mvfr2: u32,
30 _pad: u32 = 0,
31
32 clidr: u64,
33 ctr: u64,
34 };
35};
36
37pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu {
38 return switch (native_arch) {
39 .aarch64, .aarch64_be => b: {
40 var value: aarch64.sysctl_cpu_id = undefined;
41 var len: usize = @sizeOf(@TypeOf(value));
42 switch (std.posix.errno(std.c.sysctlbyname("machdep.cpu0.cpu_id", &value, &len, null, 0))) {
43 .SUCCESS => {},
44 .FAULT => unreachable,
45 .INVAL => unreachable,
46 .ISDIR => unreachable,
47 .NOENT => unreachable, // 👻
48 .NOMEM => {}, // `aarch64.sysctl_cpu_id` has grown upstream, harmless
49 .NOTDIR => unreachable,
50 .NOTEMPTY => unreachable,
51 .OPNOTSUPP => unreachable,
52 .PERM => unreachable,
53 else => return null,
54 }
55
56 const registers = [12]u64{
57 value.midr,
58 value.aa64pfr0,
59 value.aa64pfr1,
60 value.aa64dfr0,
61 value.aa64dfr1,
62 0, // ID_AA64AFR0_EL1
63 0, // ID_AA64AFR1_EL1
64 value.aa64isar0,
65 value.aa64isar1,
66 value.aa64mmfr0,
67 value.aa64mmfr1,
68 value.aa64mmfr2,
69 };
70
71 break :b @import("arm.zig").aarch64.detectNativeCpuAndFeatures(native_arch, registers);
72 },
73 else => null,
74 };
75}
lib/std/zig/system/openbsd.zig created+49
......@@ -0,0 +1,49 @@
1const builtin = @import("builtin");
2const std = @import("std");
3
4const native_arch = builtin.target.cpu.arch;
5
6const aarch64 = struct {
7 fn sysctlReg(key: c_int) u64 {
8 const mib: [2]c_int = [_]c_int{
9 std.c.CTL.MACHDEP,
10 key,
11 };
12 var value: u64 = undefined;
13 var len: usize = @sizeOf(@TypeOf(value));
14
15 std.posix.sysctl(&mib, &value, &len, null, 0) catch |err| switch (err) {
16 error.NameTooLong => unreachable,
17 error.PermissionDenied => unreachable,
18 error.SystemResources => unreachable,
19 error.UnknownName => unreachable,
20 error.Unexpected => return 0,
21 };
22
23 return value;
24 }
25};
26
27pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu {
28 return switch (native_arch) {
29 .aarch64, .aarch64_be => b: {
30 const registers = [12]u64{
31 0, // MIDR_EL1
32 aarch64.sysctlReg(std.c.CPU.AA64PFR0),
33 aarch64.sysctlReg(std.c.CPU.AA64PFR1),
34 0, // ID_AA64DFR0_EL1
35 0, // ID_AA64DFR1_EL1
36 0, // ID_AA64AFR0_EL1
37 0, // ID_AA64AFR1_EL1
38 aarch64.sysctlReg(std.c.CPU.ID_AA64ISAR0),
39 aarch64.sysctlReg(std.c.CPU.ID_AA64ISAR1),
40 aarch64.sysctlReg(std.c.CPU.ID_AA64MMFR0),
41 aarch64.sysctlReg(std.c.CPU.ID_AA64MMFR1),
42 aarch64.sysctlReg(std.c.CPU.ID_AA64MMFR2),
43 };
44
45 break :b @import("arm.zig").aarch64.detectNativeCpuAndFeatures(native_arch, registers);
46 },
47 else => null,
48 };
49}