| ... | ... | @@ -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 | inline fn mrs(comptime feat_reg: []const u8) u64 { |
| 8 | 26 | return asm ("mrs %[ret], " ++ feat_reg |
| ... | ... | @@ -30,6 +48,35 @@ const aarch64 = struct { |
| 30 | 48 | } |
| 31 | 49 | }; |
| 32 | 50 | |
| 51 | const 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 | |
| 33 | 80 | const powerpc = struct { |
| 34 | 81 | const models = .{ |
| 35 | 82 | .{ "Freescale e500v1 core", &std.Target.powerpc.cpu.e500 }, |
| ... | ... | @@ -78,22 +125,8 @@ const powerpc = struct { |
| 78 | 125 | }; |
| 79 | 126 | |
| 80 | 127 | fn detectNativeCpu(arch: std.Target.Cpu.Arch) ?std.Target.Cpu { |
| 81 | | const mib: [2]c_int = [_]c_int{ |
| 82 | | std.c.CTL.HW, |
| 83 | | std.c.HW.MODEL, |
| 84 | | }; |
| 85 | 128 | var buf: [64:0]u8 = undefined; |
| 86 | | var len: usize = buf.len + 1; |
| 87 | | |
| 88 | | std.posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) { |
| 89 | | error.NameTooLong => unreachable, |
| 90 | | error.PermissionDenied => unreachable, |
| 91 | | error.SystemResources => unreachable, |
| 92 | | error.UnknownName => unreachable, |
| 93 | | error.Unexpected => return null, |
| 94 | | }; |
| 95 | | |
| 96 | | const name = buf[0 .. len - 1 :0]; |
| 129 | const name = hwModelName(&buf) orelse return null; |
| 97 | 130 | |
| 98 | 131 | inline for (models) |pair| { |
| 99 | 132 | if (std.mem.eql(u8, name, pair[0])) return pair[1].toCpu(arch); |
| ... | ... | @@ -106,6 +139,7 @@ const powerpc = struct { |
| 106 | 139 | pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu { |
| 107 | 140 | return switch (native_arch) { |
| 108 | 141 | .aarch64 => aarch64.detectNativeCpuAndFeatures(native_arch), |
| 142 | .arm => arm.detectNativeCpu(native_arch), |
| 109 | 143 | .powerpc64, .powerpc64le => powerpc.detectNativeCpu(native_arch), |
| 110 | 144 | else => null, |
| 111 | 145 | }; |