authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-06 15:44:16+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-06 15:44:16+02:00
log79a9897cdcb3a03df14ba770f6d75c552264041b
tree09e1abe1bb714e83e228b5d7120214192cb897ab
parent07811f47965cf850bfaba3cafdab47408d31853a
parent6bee34ee56ab0fd6da1903924efa8816494ba3f6

Merge pull request '`std.zig.system`: more CPU detection enhancements for FreeBSD and OpenBSD' (#36771) from alexrp/zig:more-cpu-detection into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36771

6 files changed, 354 insertions(+), 102 deletions(-)

lib/std/c.zig+53-1
...@@ -1330,8 +1330,16 @@ pub const IOV_MAX = switch (native_os) {...@@ -1330,8 +1330,16 @@ pub const IOV_MAX = switch (native_os) {
1330};1330};
1331pub const CTL = switch (native_os) {1331pub const CTL = switch (native_os) {
1332 .freebsd => struct {1332 .freebsd => struct {
1333 pub const SYSCTL = 0;
1333 pub const KERN = 1;1334 pub const KERN = 1;
1335 pub const VM = 2;
1336 pub const VFS = 3;
1337 pub const NET = 4;
1334 pub const DEBUG = 5;1338 pub const DEBUG = 5;
1339 pub const HW = 6;
1340 pub const MACHDEP = 7;
1341 pub const USER = 8;
1342 pub const P1003_1B = 9;
1335 },1343 },
1336 .netbsd => struct {1344 .netbsd => struct {
1337 pub const KERN = 1;1345 pub const KERN = 1;
...@@ -1387,6 +1395,51 @@ pub const CPU = switch (native_os) {...@@ -1387,6 +1395,51 @@ pub const CPU = switch (native_os) {
1387 },1395 },
1388 else => void,1396 else => void,
1389};1397};
1398pub const HW = switch (native_os) {
1399 .freebsd => struct {
1400 pub const MACHINE = 1;
1401 pub const MODEL = 2;
1402 pub const NCPU = 3;
1403 pub const BYTEORDER = 4;
1404 pub const PHYSMEM = 5;
1405 pub const USERMEM = 6;
1406 pub const PAGESIZE = 7;
1407 pub const DISKNAMES = 8;
1408 pub const DISKSTATS = 9;
1409 pub const FLOATINGPT = 10;
1410 pub const MACHINE_ARCH = 11;
1411 pub const REALMEM = 12;
1412 },
1413 .openbsd => struct {
1414 pub const MACHINE = 1;
1415 pub const MODEL = 2;
1416 pub const NCPU = 3;
1417 pub const BYTEORDER = 4;
1418 pub const PHYSMEM = 5;
1419 pub const USERMEM = 6;
1420 pub const PAGESIZE = 7;
1421 pub const DISKNAMES = 8;
1422 pub const DISKSTATS = 9;
1423 pub const DISKCOUNT = 10;
1424 pub const SENSORS = 11;
1425 pub const CPUSPEED = 12;
1426 pub const SETPERF = 13;
1427 pub const VENDOR = 14;
1428 pub const PRODUCT = 15;
1429 pub const VERSION = 16;
1430 pub const SERIALNO = 17;
1431 pub const UUID = 18;
1432 pub const PHYSMEM64 = 19;
1433 pub const USERMEM64 = 20;
1434 pub const NCPUFOUND = 21;
1435 pub const ALLOWPOWERDOWN = 22;
1436 pub const PERFPOLICY = 23;
1437 pub const SMT = 24;
1438 pub const NCPUONLINE = 25;
1439 pub const POWER = 26;
1440 },
1441 else => void,
1442};
1390pub const KERN = switch (native_os) {1443pub const KERN = switch (native_os) {
1391 .freebsd => struct {1444 .freebsd => struct {
1392 /// struct: process entries1445 /// struct: process entries
...@@ -11325,7 +11378,6 @@ pub const writev_pos = haiku.writev_pos;...@@ -11325,7 +11378,6 @@ pub const writev_pos = haiku.writev_pos;
1132511378
11326pub const AUTH = openbsd.AUTH;11379pub const AUTH = openbsd.AUTH;
11327pub const BI = openbsd.BI;11380pub const BI = openbsd.BI;
11328pub const HW = openbsd.HW;
11329pub const PTHREAD_STACK_MIN = openbsd.PTHREAD_STACK_MIN;11381pub const PTHREAD_STACK_MIN = openbsd.PTHREAD_STACK_MIN;
11330pub const TCFLUSH = openbsd.TCFLUSH;11382pub const TCFLUSH = openbsd.TCFLUSH;
11331pub const TCIO = openbsd.TCIO;11383pub const TCIO = openbsd.TCIO;
lib/std/c/openbsd.zig-29
...@@ -273,35 +273,6 @@ pub const MAX_PAGE_SHIFT = switch (builtin.cpu.arch) {...@@ -273,35 +273,6 @@ pub const MAX_PAGE_SHIFT = switch (builtin.cpu.arch) {
273 .sparc64 => 13,273 .sparc64 => 13,
274};274};
275275
276pub const HW = struct {
277 pub const MACHINE = 1;
278 pub const MODEL = 2;
279 pub const NCPU = 3;
280 pub const BYTEORDER = 4;
281 pub const PHYSMEM = 5;
282 pub const USERMEM = 6;
283 pub const PAGESIZE = 7;
284 pub const DISKNAMES = 8;
285 pub const DISKSTATS = 9;
286 pub const DISKCOUNT = 10;
287 pub const SENSORS = 11;
288 pub const CPUSPEED = 12;
289 pub const SETPERF = 13;
290 pub const VENDOR = 14;
291 pub const PRODUCT = 15;
292 pub const VERSION = 16;
293 pub const SERIALNO = 17;
294 pub const UUID = 18;
295 pub const PHYSMEM64 = 19;
296 pub const USERMEM64 = 20;
297 pub const NCPUFOUND = 21;
298 pub const ALLOWPOWERDOWN = 22;
299 pub const PERFPOLICY = 23;
300 pub const SMT = 24;
301 pub const NCPUONLINE = 25;
302 pub const POWER = 26;
303};
304
305pub const PTHREAD_STACK_MIN = switch (builtin.cpu.arch) {276pub const PTHREAD_STACK_MIN = switch (builtin.cpu.arch) {
306 .sparc64 => 1 << 13,277 .sparc64 => 1 << 13,
307 .mips64 => 1 << 14,278 .mips64 => 1 << 14,
lib/std/zig/system.zig+3
...@@ -1203,6 +1203,9 @@ test {...@@ -1203,6 +1203,9 @@ test {
1203 _ = NativePaths;1203 _ = NativePaths;
12041204
1205 _ = darwin;1205 _ = darwin;
1206 _ = freebsd;
1206 _ = linux;1207 _ = linux;
1208 _ = netbsd;
1209 _ = openbsd;
1207 _ = windows;1210 _ = windows;
1208}1211}
lib/std/zig/system/freebsd.zig+128-18
...@@ -3,34 +3,144 @@ const std = @import("std");...@@ -3,34 +3,144 @@ const std = @import("std");
33
4const native_arch = builtin.target.cpu.arch;4const native_arch = builtin.target.cpu.arch;
55
6fn hwModelName(buf: [:0]u8) ?[:0]const u8 {
7 const mib: [2]c_int = [_]c_int{
8 std.c.CTL.HW,
9 std.c.HW.MODEL,
10 };
11 var len: usize = buf.len + 1;
12
13 std.posix.sysctl(&mib, buf.ptr, &len, null, 0) catch |err| switch (err) {
14 error.NameTooLong => unreachable,
15 error.PermissionDenied => unreachable,
16 error.SystemResources => unreachable,
17 error.UnknownName => unreachable,
18 error.Unexpected => return null,
19 };
20
21 return buf[0 .. len - 1 :0];
22}
23
6const aarch64 = struct {24const aarch64 = struct {
7 inline fn mrs(comptime feat_reg: []const u8) u64 {25 inline fn mrs(comptime feat_reg: []const u8) u64 {
8 return asm ("mrs %[ret], " ++ feat_reg26 return asm ("mrs %[ret], " ++ feat_reg
9 : [ret] "=r" (-> u64),27 : [ret] "=r" (-> u64),
10 );28 );
11 }29 }
30
31 fn detectNativeCpuAndFeatures(arch: std.Target.Cpu.Arch) std.Target.Cpu {
32 const registers = [12]u64{
33 aarch64.mrs("MIDR_EL1"),
34 aarch64.mrs("ID_AA64PFR0_EL1"),
35 aarch64.mrs("ID_AA64PFR1_EL1"),
36 aarch64.mrs("ID_AA64DFR0_EL1"),
37 aarch64.mrs("ID_AA64DFR1_EL1"),
38 aarch64.mrs("ID_AA64AFR0_EL1"),
39 aarch64.mrs("ID_AA64AFR1_EL1"),
40 aarch64.mrs("ID_AA64ISAR0_EL1"),
41 aarch64.mrs("ID_AA64ISAR1_EL1"),
42 aarch64.mrs("ID_AA64MMFR0_EL1"),
43 aarch64.mrs("ID_AA64MMFR1_EL1"),
44 aarch64.mrs("ID_AA64MMFR2_EL1"),
45 };
46
47 return @import("arm.zig").aarch64.detectNativeCpuAndFeatures(arch, registers);
48 }
49};
50
51const arm = struct {
52 const models = .{
53 .{ "ARM ARM1176", &std.Target.arm.cpu.arm1176jzf_s },
54 .{ "ARM Cortex-A12", &std.Target.arm.cpu.cortex_a12 },
55 .{ "ARM Cortex-A15", &std.Target.arm.cpu.cortex_a15 },
56 .{ "ARM Cortex-A17", &std.Target.arm.cpu.cortex_a17 },
57 .{ "ARM Cortex-A53", &std.Target.arm.cpu.cortex_a53 },
58 .{ "ARM Cortex-A57", &std.Target.arm.cpu.cortex_a57 },
59 .{ "ARM Cortex-A5", &std.Target.arm.cpu.cortex_a5 },
60 .{ "ARM Cortex-A72", &std.Target.arm.cpu.cortex_a72 },
61 .{ "ARM Cortex-A73", &std.Target.arm.cpu.cortex_a73 },
62 .{ "ARM Cortex-A7", &std.Target.arm.cpu.cortex_a7 },
63 .{ "ARM Cortex-A8", &std.Target.arm.cpu.cortex_a8 },
64 .{ "ARM Cortex-A9", &std.Target.arm.cpu.cortex_a9 },
65 .{ "Qualcomm Krait 300", &std.Target.arm.cpu.krait },
66 };
67
68 fn detectNativeCpu(arch: std.Target.Cpu.Arch) ?std.Target.Cpu {
69 var buf: [64:0]u8 = undefined;
70 const name = hwModelName(&buf) orelse return null;
71
72 inline for (models) |pair| {
73 if (std.mem.startsWith(u8, name, pair[0])) return pair[1].toCpu(arch);
74 }
75
76 return null;
77 }
78};
79
80const powerpc = struct {
81 const models = .{
82 .{ "Freescale e500v1 core", &std.Target.powerpc.cpu.e500 },
83 .{ "Freescale e500v2 core", &std.Target.powerpc.cpu.e500 }, // TODO: This should have efpu2.
84 .{ "Freescale e500mc core", &std.Target.powerpc.cpu.e500mc },
85 .{ "Freescale e5500 core", &std.Target.powerpc.cpu.e5500 },
86 .{ "Freescale e6500 core", &std.Target.powerpc.cpu.e5500 }, // TODO: This should have altivec.
87 .{ "IBM Cell Broadband Engine", &std.Target.powerpc.cpu.ppc64 },
88 .{ "IBM PowerPC 750FX", &std.Target.powerpc.cpu.@"750" },
89 .{ "IBM PowerPC 970", &std.Target.powerpc.cpu.@"970" },
90 .{ "IBM PowerPC 970FX", &std.Target.powerpc.cpu.@"970" },
91 .{ "IBM PowerPC 970GX", &std.Target.powerpc.cpu.@"970" },
92 .{ "IBM PowerPC 970MP", &std.Target.powerpc.cpu.@"970" },
93 .{ "IBM POWER4", &std.Target.powerpc.cpu.pwr4 },
94 .{ "IBM POWER4+", &std.Target.powerpc.cpu.pwr4 },
95 .{ "IBM POWER5", &std.Target.powerpc.cpu.pwr5 },
96 .{ "IBM POWER5+", &std.Target.powerpc.cpu.pwr5x },
97 .{ "IBM POWER6", &std.Target.powerpc.cpu.pwr6 },
98 .{ "IBM POWER7", &std.Target.powerpc.cpu.pwr7 },
99 .{ "IBM POWER7+", &std.Target.powerpc.cpu.pwr7 },
100 .{ "IBM POWER8E", &std.Target.powerpc.cpu.pwr8 },
101 .{ "IBM POWER8NVL", &std.Target.powerpc.cpu.pwr8 },
102 .{ "IBM POWER8", &std.Target.powerpc.cpu.pwr8 },
103 .{ "IBM POWER9", &std.Target.powerpc.cpu.pwr9 },
104 .{ "IBM POWER10", &std.Target.powerpc.cpu.pwr10 },
105 .{ "IBM POWER11", &std.Target.powerpc.cpu.pwr11 },
106 .{ "Motorola PowerPC 601", &std.Target.powerpc.cpu.@"601" },
107 .{ "Motorola PowerPC 602", &std.Target.powerpc.cpu.@"602" },
108 .{ "Motorola PowerPC 603", &std.Target.powerpc.cpu.@"603" },
109 .{ "Motorola PowerPC 603e", &std.Target.powerpc.cpu.@"603e" },
110 .{ "Motorola PowerPC 603ev", &std.Target.powerpc.cpu.@"603ev" },
111 .{ "Motorola PowerPC 604", &std.Target.powerpc.cpu.@"604" },
112 .{ "Motorola PowerPC 604ev", &std.Target.powerpc.cpu.@"604e" },
113 .{ "Motorola PowerPC 620", &std.Target.powerpc.cpu.@"620" },
114 .{ "Motorola PowerPC 750", &std.Target.powerpc.cpu.@"750" },
115 .{ "Motorola PowerPC 7400", &std.Target.powerpc.cpu.@"7400" },
116 .{ "Motorola PowerPC 7410", &std.Target.powerpc.cpu.@"7400" },
117 .{ "Motorola PowerPC 7450", &std.Target.powerpc.cpu.@"7450" },
118 .{ "Motorola PowerPC 7455", &std.Target.powerpc.cpu.@"7450" },
119 .{ "Motorola PowerPC 7457", &std.Target.powerpc.cpu.@"7450" },
120 .{ "Motorola PowerPC 7457", &std.Target.powerpc.cpu.@"7450" },
121 .{ "Motorola PowerPC 7447A", &std.Target.powerpc.cpu.@"7450" },
122 .{ "Motorola PowerPC 7448", &std.Target.powerpc.cpu.@"7450" },
123 .{ "Motorola PowerPC 8240", &std.Target.powerpc.cpu.@"603e" },
124 .{ "Motorola PowerPC 8245", &std.Target.powerpc.cpu.@"603e" },
125 };
126
127 fn detectNativeCpu(arch: std.Target.Cpu.Arch) ?std.Target.Cpu {
128 var buf: [64:0]u8 = undefined;
129 const name = hwModelName(&buf) orelse return null;
130
131 inline for (models) |pair| {
132 if (std.mem.eql(u8, name, pair[0])) return pair[1].toCpu(arch);
133 }
134
135 return null;
136 }
12};137};
13138
14pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu {139pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu {
15 return switch (native_arch) {140 return switch (native_arch) {
16 .aarch64, .aarch64_be => b: {141 .aarch64 => aarch64.detectNativeCpuAndFeatures(native_arch),
17 const registers = [12]u64{142 .arm => arm.detectNativeCpu(native_arch),
18 aarch64.mrs("MIDR_EL1"),143 .powerpc64, .powerpc64le => powerpc.detectNativeCpu(native_arch),
19 aarch64.mrs("ID_AA64PFR0_EL1"),
20 aarch64.mrs("ID_AA64PFR1_EL1"),
21 aarch64.mrs("ID_AA64DFR0_EL1"),
22 aarch64.mrs("ID_AA64DFR1_EL1"),
23 aarch64.mrs("ID_AA64AFR0_EL1"),
24 aarch64.mrs("ID_AA64AFR1_EL1"),
25 aarch64.mrs("ID_AA64ISAR0_EL1"),
26 aarch64.mrs("ID_AA64ISAR1_EL1"),
27 aarch64.mrs("ID_AA64MMFR0_EL1"),
28 aarch64.mrs("ID_AA64MMFR1_EL1"),
29 aarch64.mrs("ID_AA64MMFR2_EL1"),
30 };
31
32 break :b @import("arm.zig").aarch64.detectNativeCpuAndFeatures(native_arch, registers);
33 },
34 else => null,144 else => null,
35 };145 };
36}146}
lib/std/zig/system/netbsd.zig+36-34
...@@ -32,44 +32,46 @@ const aarch64 = struct {...@@ -32,44 +32,46 @@ const aarch64 = struct {
32 clidr: u64,32 clidr: u64,
33 ctr: u64,33 ctr: u64,
34 };34 };
35
36 fn detectNativeCpuAndFeatures(arch: std.Target.Cpu.Arch) ?std.Target.Cpu {
37 var value: aarch64.sysctl_cpu_id = undefined;
38 var len: usize = @sizeOf(@TypeOf(value));
39 switch (std.posix.errno(std.c.sysctlbyname("machdep.cpu0.cpu_id", &value, &len, null, 0))) {
40 .SUCCESS => {},
41 .FAULT => unreachable,
42 .INVAL => unreachable,
43 .ISDIR => unreachable,
44 .NOENT => unreachable, // 👻
45 .NOMEM => {}, // `aarch64.sysctl_cpu_id` has grown upstream, harmless
46 .NOTDIR => unreachable,
47 .NOTEMPTY => unreachable,
48 .OPNOTSUPP => unreachable,
49 .PERM => unreachable,
50 else => return null,
51 }
52
53 const registers = [12]u64{
54 value.midr,
55 value.aa64pfr0,
56 value.aa64pfr1,
57 value.aa64dfr0,
58 value.aa64dfr1,
59 0, // ID_AA64AFR0_EL1
60 0, // ID_AA64AFR1_EL1
61 value.aa64isar0,
62 value.aa64isar1,
63 value.aa64mmfr0,
64 value.aa64mmfr1,
65 value.aa64mmfr2,
66 };
67
68 return @import("arm.zig").aarch64.detectNativeCpuAndFeatures(arch, registers);
69 }
35};70};
3671
37pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu {72pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu {
38 return switch (native_arch) {73 return switch (native_arch) {
39 .aarch64, .aarch64_be => b: {74 .aarch64, .aarch64_be => aarch64.detectNativeCpuAndFeatures(native_arch),
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,75 else => null,
74 };76 };
75}77}
lib/std/zig/system/openbsd.zig+134-20
...@@ -3,8 +3,26 @@ const std = @import("std");...@@ -3,8 +3,26 @@ const std = @import("std");
33
4const native_arch = builtin.target.cpu.arch;4const native_arch = builtin.target.cpu.arch;
55
6fn hwModelName(buf: [:0]u8) ?[:0]const u8 {
7 const mib: [2]c_int = [_]c_int{
8 std.c.CTL.HW,
9 std.c.HW.MODEL,
10 };
11 var len: usize = buf.len + 1;
12
13 std.posix.sysctl(&mib, buf.ptr, &len, null, 0) catch |err| switch (err) {
14 error.NameTooLong => unreachable,
15 error.PermissionDenied => unreachable,
16 error.SystemResources => unreachable,
17 error.UnknownName => unreachable,
18 error.Unexpected => return null,
19 };
20
21 return buf[0 .. len - 1 :0];
22}
23
6const aarch64 = struct {24const aarch64 = struct {
7 fn sysctlReg(key: c_int) u64 {25 fn sysctlReg(key: c_int) ?u64 {
8 const mib: [2]c_int = [_]c_int{26 const mib: [2]c_int = [_]c_int{
9 std.c.CTL.MACHDEP,27 std.c.CTL.MACHDEP,
10 key,28 key,
...@@ -17,33 +35,129 @@ const aarch64 = struct {...@@ -17,33 +35,129 @@ const aarch64 = struct {
17 error.PermissionDenied => unreachable,35 error.PermissionDenied => unreachable,
18 error.SystemResources => unreachable,36 error.SystemResources => unreachable,
19 error.UnknownName => unreachable,37 error.UnknownName => unreachable,
20 error.Unexpected => return 0,38 error.Unexpected => return null,
21 };39 };
2240
23 return value;41 return value;
24 }42 }
43
44 fn detectNativeCpuAndFeatures(arch: std.Target.Cpu.Arch) ?std.Target.Cpu {
45 const registers = [12]u64{
46 0, // MIDR_EL1
47 sysctlReg(std.c.CPU.AA64PFR0) orelse return null,
48 sysctlReg(std.c.CPU.AA64PFR1) orelse return null,
49 0, // ID_AA64DFR0_EL1
50 0, // ID_AA64DFR1_EL1
51 0, // ID_AA64AFR0_EL1
52 0, // ID_AA64AFR1_EL1
53 sysctlReg(std.c.CPU.ID_AA64ISAR0) orelse return null,
54 sysctlReg(std.c.CPU.ID_AA64ISAR1) orelse return null,
55 sysctlReg(std.c.CPU.ID_AA64MMFR0) orelse return null,
56 sysctlReg(std.c.CPU.ID_AA64MMFR1) orelse return null,
57 sysctlReg(std.c.CPU.ID_AA64MMFR2) orelse return null,
58 };
59
60 return @import("arm.zig").aarch64.detectNativeCpuAndFeatures(arch, registers);
61 }
62};
63
64const arm = struct {
65 const models = .{
66 .{ "ARM Cortex-A12", &std.Target.arm.cpu.cortex_a12 },
67 .{ "ARM Cortex-A15", &std.Target.arm.cpu.cortex_a15 },
68 .{ "ARM Cortex-A17", &std.Target.arm.cpu.cortex_a17 },
69 .{ "ARM Cortex-A32", &std.Target.arm.cpu.cortex_a32 },
70 .{ "ARM Cortex-A35", &std.Target.arm.cpu.cortex_a35 },
71 .{ "ARM Cortex-A53", &std.Target.arm.cpu.cortex_a53 },
72 .{ "ARM Cortex-A55", &std.Target.arm.cpu.cortex_a55 },
73 .{ "ARM Cortex-A57", &std.Target.arm.cpu.cortex_a57 },
74 .{ "ARM Cortex-A5", &std.Target.arm.cpu.cortex_a5 },
75 .{ "ARM Cortex-A72", &std.Target.arm.cpu.cortex_a72 },
76 .{ "ARM Cortex-A73", &std.Target.arm.cpu.cortex_a73 },
77 .{ "ARM Cortex-A75", &std.Target.arm.cpu.cortex_a75 },
78 .{ "ARM Cortex-A7", &std.Target.arm.cpu.cortex_a7 },
79 .{ "ARM Cortex-A8", &std.Target.arm.cpu.cortex_a8 },
80 .{ "ARM Cortex-A9", &std.Target.arm.cpu.cortex_a9 },
81 };
82
83 fn detectNativeCpu(arch: std.Target.Cpu.Arch) ?std.Target.Cpu {
84 var buf: [64:0]u8 = undefined;
85 const name = hwModelName(&buf) orelse return null;
86
87 inline for (models) |pair| {
88 if (std.mem.startsWith(u8, name, pair[0])) return pair[1].toCpu(arch);
89 }
90
91 return null;
92 }
93};
94
95const powerpc = struct {
96 const models = .{
97 .{ "601", &std.Target.powerpc.cpu.@"601" },
98 .{ "603ev", &std.Target.powerpc.cpu.@"603ev" },
99 .{ "603e", &std.Target.powerpc.cpu.@"603e" },
100 .{ "603", &std.Target.powerpc.cpu.@"603" },
101 .{ "604ev", &std.Target.powerpc.cpu.@"604e" },
102 .{ "604", &std.Target.powerpc.cpu.@"604" },
103 .{ "7400", &std.Target.powerpc.cpu.@"7400" },
104 .{ "7410", &std.Target.powerpc.cpu.@"7400" },
105 .{ "7450", &std.Target.powerpc.cpu.@"7450" },
106 .{ "7451", &std.Target.powerpc.cpu.@"7450" },
107 .{ "7455", &std.Target.powerpc.cpu.@"7450" },
108 .{ "7457", &std.Target.powerpc.cpu.@"7450" },
109 .{ "7447A", &std.Target.powerpc.cpu.@"7450" },
110 .{ "7448", &std.Target.powerpc.cpu.@"7450" },
111 .{ "750FX", &std.Target.powerpc.cpu.@"750" },
112 .{ "750", &std.Target.powerpc.cpu.@"750" },
113 .{ "970FX", &std.Target.powerpc.cpu.@"970" },
114 .{ "970MP", &std.Target.powerpc.cpu.@"970" },
115 .{ "970", &std.Target.powerpc.cpu.@"970" },
116 .{ "IBM POWER8E", &std.Target.powerpc.cpu.pwr8 },
117 .{ "IBM POWER8NVL", &std.Target.powerpc.cpu.pwr8 },
118 .{ "IBM POWER8", &std.Target.powerpc.cpu.pwr8 },
119 .{ "IBM POWER9P", &std.Target.powerpc.cpu.pwr9 },
120 .{ "IBM POWER9", &std.Target.powerpc.cpu.pwr9 },
121 };
122
123 fn detectNativeCpu(arch: std.Target.Cpu.Arch) ?std.Target.Cpu {
124 var buf: [64:0]u8 = undefined;
125 const name = hwModelName(&buf) orelse return null;
126
127 inline for (models) |pair| {
128 if (std.mem.startsWith(u8, name, pair[0])) return pair[1].toCpu(arch);
129 }
130
131 return null;
132 }
133};
134
135const riscv = struct {
136 const models = .{
137 .{ "SiFive U5", &std.Target.riscv.cpu.sifive_u54 },
138 .{ "SiFive U7", &std.Target.riscv.cpu.sifive_u74 },
139 .{ "SpacemiT X60", &std.Target.riscv.cpu.spacemit_x60 },
140 .{ "SpacemiT X100", &std.Target.riscv.cpu.spacemit_x100 },
141 };
142
143 fn detectNativeCpu(arch: std.Target.Cpu.Arch) ?std.Target.Cpu {
144 var buf: [64:0]u8 = undefined;
145 const name = hwModelName(&buf) orelse return null;
146
147 inline for (models) |pair| {
148 if (std.mem.startsWith(u8, name, pair[0])) return pair[1].toCpu(arch);
149 }
150
151 return null;
152 }
25};153};
26154
27pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu {155pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu {
28 return switch (native_arch) {156 return switch (native_arch) {
29 .aarch64, .aarch64_be => b: {157 .aarch64 => aarch64.detectNativeCpuAndFeatures(native_arch),
30 const registers = [12]u64{158 .arm => arm.detectNativeCpu(native_arch),
31 0, // MIDR_EL1159 .powerpc, .powerpc64 => powerpc.detectNativeCpu(native_arch),
32 aarch64.sysctlReg(std.c.CPU.AA64PFR0),160 .riscv64 => riscv.detectNativeCpu(native_arch),
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,161 else => null,
48 };162 };
49}163}