| ... | @@ -3,6 +3,24 @@ const std = @import("std"); | ... | @@ -3,6 +3,24 @@ const std = @import("std"); |
| 3 | | 3 | |
| 4 | const native_arch = builtin.target.cpu.arch; | 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 | const aarch64 = struct { | 24 | const 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_reg | 26 | return asm ("mrs %[ret], " ++ feat_reg |
| ... | @@ -30,6 +48,35 @@ const aarch64 = struct { | ... | @@ -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 | const powerpc = struct { | 80 | const powerpc = struct { |
| 34 | const models = .{ | 81 | const models = .{ |
| 35 | .{ "Freescale e500v1 core", &std.Target.powerpc.cpu.e500 }, | 82 | .{ "Freescale e500v1 core", &std.Target.powerpc.cpu.e500 }, |
| ... | @@ -78,22 +125,8 @@ const powerpc = struct { | ... | @@ -78,22 +125,8 @@ const powerpc = struct { |
| 78 | }; | 125 | }; |
| 79 | | 126 | |
| 80 | fn detectNativeCpu(arch: std.Target.Cpu.Arch) ?std.Target.Cpu { | 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 | var buf: [64:0]u8 = undefined; | 128 | var buf: [64:0]u8 = undefined; |
| 86 | var len: usize = buf.len + 1; | 129 | const name = hwModelName(&buf) orelse return null; |
| 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]; | | |
| 97 | | 130 | |
| 98 | inline for (models) |pair| { | 131 | inline for (models) |pair| { |
| 99 | if (std.mem.eql(u8, name, pair[0])) return pair[1].toCpu(arch); | 132 | if (std.mem.eql(u8, name, pair[0])) return pair[1].toCpu(arch); |
| ... | @@ -106,6 +139,7 @@ const powerpc = struct { | ... | @@ -106,6 +139,7 @@ const powerpc = struct { |
| 106 | pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu { | 139 | pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu { |
| 107 | return switch (native_arch) { | 140 | return switch (native_arch) { |
| 108 | .aarch64 => aarch64.detectNativeCpuAndFeatures(native_arch), | 141 | .aarch64 => aarch64.detectNativeCpuAndFeatures(native_arch), |
| | 142 | .arm => arm.detectNativeCpu(native_arch), |
| 109 | .powerpc64, .powerpc64le => powerpc.detectNativeCpu(native_arch), | 143 | .powerpc64, .powerpc64le => powerpc.detectNativeCpu(native_arch), |
| 110 | else => null, | 144 | else => null, |
| 111 | }; | 145 | }; |