| ... | ... | @@ -3,6 +3,24 @@ const std = @import("std"); |
| 3 | 3 | |
| 4 | 4 | const native_arch = builtin.target.cpu.arch; |
| 5 | 5 | |
| 6 | fn 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 | |
| 6 | 24 | const aarch64 = struct { |
| 7 | 25 | fn sysctlReg(key: c_int) ?u64 { |
| 8 | 26 | const mib: [2]c_int = [_]c_int{ |
| ... | ... | @@ -43,6 +61,37 @@ const aarch64 = struct { |
| 43 | 61 | } |
| 44 | 62 | }; |
| 45 | 63 | |
| 64 | const 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 | |
| 46 | 95 | const powerpc = struct { |
| 47 | 96 | const models = .{ |
| 48 | 97 | .{ "601", &std.Target.powerpc.cpu.@"601" }, |
| ... | ... | @@ -72,22 +121,8 @@ const powerpc = struct { |
| 72 | 121 | }; |
| 73 | 122 | |
| 74 | 123 | fn detectNativeCpu(arch: std.Target.Cpu.Arch) ?std.Target.Cpu { |
| 75 | | const mib: [2]c_int = [_]c_int{ |
| 76 | | std.c.CTL.HW, |
| 77 | | std.c.HW.MODEL, |
| 78 | | }; |
| 79 | 124 | var buf: [64:0]u8 = undefined; |
| 80 | | var len: usize = buf.len + 1; |
| 81 | | |
| 82 | | std.posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) { |
| 83 | | error.NameTooLong => unreachable, |
| 84 | | error.PermissionDenied => unreachable, |
| 85 | | error.SystemResources => unreachable, |
| 86 | | error.UnknownName => unreachable, |
| 87 | | error.Unexpected => return null, |
| 88 | | }; |
| 89 | | |
| 90 | | const name = buf[0 .. len - 1 :0]; |
| 125 | const name = hwModelName(&buf) orelse return null; |
| 91 | 126 | |
| 92 | 127 | inline for (models) |pair| { |
| 93 | 128 | if (std.mem.startsWith(u8, name, pair[0])) return pair[1].toCpu(arch); |
| ... | ... | @@ -100,6 +135,7 @@ const powerpc = struct { |
| 100 | 135 | pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu { |
| 101 | 136 | return switch (native_arch) { |
| 102 | 137 | .aarch64 => aarch64.detectNativeCpuAndFeatures(native_arch), |
| 138 | .arm => arm.detectNativeCpu(native_arch), |
| 103 | 139 | .powerpc, .powerpc64 => powerpc.detectNativeCpu(native_arch), |
| 104 | 140 | else => null, |
| 105 | 141 | }; |