| ... | ... | @@ -121,12 +121,12 @@ fn getCpuInfoFromRegistry( |
| 121 | 121 | else => unreachable, |
| 122 | 122 | } |
| 123 | 123 | }; |
| 124 | | const key_namee = std.unicode.utf8ToUtf16LeStringLiteral(pair.key); |
| 124 | const key_name = std.unicode.utf8ToUtf16LeStringLiteral(pair.key); |
| 125 | 125 | |
| 126 | 126 | table[i + 1] = .{ |
| 127 | 127 | .QueryRoutine = null, |
| 128 | 128 | .Flags = std.os.windows.RTL_QUERY_REGISTRY_DIRECT | std.os.windows.RTL_QUERY_REGISTRY_REQUIRED, |
| 129 | | .Name = @intToPtr([*:0]u16, @ptrToInt(key_namee)), |
| 129 | .Name = @intToPtr([*:0]u16, @ptrToInt(key_name)), |
| 130 | 130 | .EntryContext = ctx, |
| 131 | 131 | .DefaultType = REG.NONE, |
| 132 | 132 | .DefaultData = null, |
| ... | ... | @@ -155,8 +155,6 @@ fn getCpuInfoFromRegistry( |
| 155 | 155 | switch (res) { |
| 156 | 156 | .SUCCESS => { |
| 157 | 157 | inline for (pairs) |pair, i| switch (pair.value) { |
| 158 | | REG.NONE => unreachable, |
| 159 | | |
| 160 | 158 | REG.SZ, |
| 161 | 159 | REG.EXPAND_SZ, |
| 162 | 160 | REG.MULTI_SZ, |
| ... | ... | @@ -189,6 +187,12 @@ fn getCpuInfoFromRegistry( |
| 189 | 187 | } |
| 190 | 188 | } |
| 191 | 189 | |
| 190 | fn setFeature(comptime Feature: type, cpu: *Target.Cpu, feature: Feature, enabled: bool) void { |
| 191 | const idx = @as(Target.Cpu.Feature.Set.Index, @enumToInt(feature)); |
| 192 | |
| 193 | if (enabled) cpu.features.addFeature(idx) else cpu.features.removeFeature(idx); |
| 194 | } |
| 195 | |
| 192 | 196 | fn getCpuCount() usize { |
| 193 | 197 | return std.os.windows.peb().NumberOfProcessors; |
| 194 | 198 | } |
| ... | ... | @@ -298,64 +302,41 @@ fn CpuInfoParser(comptime impl: anytype) type { |
| 298 | 302 | }; |
| 299 | 303 | } |
| 300 | 304 | |
| 301 | | fn genericCpu(comptime arch: Target.Cpu.Arch) Target.Cpu { |
| 302 | | return .{ |
| 305 | /// If the fine-grained detection of CPU features via Win registry fails, |
| 306 | /// we fallback to a generic CPU model but we override the feature set |
| 307 | /// using `SharedUserData` contents. |
| 308 | /// This is effectively what LLVM does for all ARM chips on Windows. |
| 309 | fn genericCpuAndNativeFeatures(arch: Target.Cpu.Arch) Target.Cpu { |
| 310 | var cpu = Target.Cpu{ |
| 303 | 311 | .arch = arch, |
| 304 | 312 | .model = Target.Cpu.Model.generic(arch), |
| 305 | 313 | .features = Target.Cpu.Feature.Set.empty, |
| 306 | 314 | }; |
| 307 | | } |
| 308 | 315 | |
| 309 | | pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 310 | | const current_arch = builtin.cpu.arch; |
| 311 | | switch (current_arch) { |
| 316 | switch (arch) { |
| 312 | 317 | .aarch64, .aarch64_be, .aarch64_32 => { |
| 313 | | var cpu = cpu: { |
| 314 | | var maybe_cpu = ArmCpuInfoParser.parse(current_arch) catch break :cpu genericCpu(current_arch); |
| 315 | | break :cpu maybe_cpu orelse genericCpu(current_arch); |
| 316 | | }; |
| 317 | | |
| 318 | 318 | const Feature = Target.aarch64.Feature; |
| 319 | 319 | |
| 320 | 320 | // Override any features that are either present or absent |
| 321 | | if (IsProcessorFeaturePresent(PF.ARM_NEON_INSTRUCTIONS_AVAILABLE)) { |
| 322 | | cpu.features.addFeature(@enumToInt(Feature.neon)); |
| 323 | | } else { |
| 324 | | cpu.features.removeFeature(@enumToInt(Feature.neon)); |
| 325 | | } |
| 326 | | |
| 327 | | if (IsProcessorFeaturePresent(PF.ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) { |
| 328 | | cpu.features.addFeature(@enumToInt(Feature.crc)); |
| 329 | | } else { |
| 330 | | cpu.features.removeFeature(@enumToInt(Feature.crc)); |
| 331 | | } |
| 332 | | |
| 333 | | if (IsProcessorFeaturePresent(PF.ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) { |
| 334 | | cpu.features.addFeature(@enumToInt(Feature.crypto)); |
| 335 | | } else { |
| 336 | | cpu.features.removeFeature(@enumToInt(Feature.crypto)); |
| 337 | | } |
| 338 | | |
| 339 | | if (IsProcessorFeaturePresent(PF.ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE)) { |
| 340 | | cpu.features.addFeature(@enumToInt(Feature.lse)); |
| 341 | | } else { |
| 342 | | cpu.features.removeFeature(@enumToInt(Feature.lse)); |
| 343 | | } |
| 344 | | |
| 345 | | if (IsProcessorFeaturePresent(PF.ARM_V82_DP_INSTRUCTIONS_AVAILABLE)) { |
| 346 | | cpu.features.addFeature(@enumToInt(Feature.dotprod)); |
| 347 | | } else { |
| 348 | | cpu.features.removeFeature(@enumToInt(Feature.dotprod)); |
| 349 | | } |
| 321 | setFeature(Feature, &cpu, .neon, IsProcessorFeaturePresent(PF.ARM_NEON_INSTRUCTIONS_AVAILABLE)); |
| 322 | setFeature(Feature, &cpu, .crc, IsProcessorFeaturePresent(PF.ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)); |
| 323 | setFeature(Feature, &cpu, .crypto, IsProcessorFeaturePresent(PF.ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)); |
| 324 | setFeature(Feature, &cpu, .lse, IsProcessorFeaturePresent(PF.ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE)); |
| 325 | setFeature(Feature, &cpu, .dotprod, IsProcessorFeaturePresent(PF.ARM_V82_DP_INSTRUCTIONS_AVAILABLE)); |
| 326 | setFeature(Feature, &cpu, .jsconv, IsProcessorFeaturePresent(PF.ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE)); |
| 327 | }, |
| 328 | else => {}, |
| 329 | } |
| 350 | 330 | |
| 351 | | if (IsProcessorFeaturePresent(PF.ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE)) { |
| 352 | | cpu.features.addFeature(@enumToInt(Feature.jsconv)); |
| 353 | | } else { |
| 354 | | cpu.features.removeFeature(@enumToInt(Feature.jsconv)); |
| 355 | | } |
| 331 | return cpu; |
| 332 | } |
| 356 | 333 | |
| 357 | | return cpu; |
| 334 | pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 335 | const current_arch = builtin.cpu.arch; |
| 336 | switch (current_arch) { |
| 337 | .aarch64, .aarch64_be, .aarch64_32 => { |
| 338 | return ArmCpuInfoParser.parse(current_arch) catch genericCpuAndNativeFeatures(current_arch); |
| 358 | 339 | }, |
| 359 | | else => {}, |
| 340 | else => return null, |
| 360 | 341 | } |
| 361 | 342 | } |