| author | |
| committer | |
| log | 6208e74145791c2f03e80e93caec4f87c60e638f |
| tree | b9079c44e84e7b9640e8773374f907dcbce5e282 |
| parent | f1c2ae271cd0e9caac332a456ff8dbd2fc4c277a |
| signature |
ref #45913 files changed, 63 insertions(+), 6 deletions(-)
lib/std/zig/system.zig+2-3| ... | ... | @@ -468,9 +468,8 @@ fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: T |
| 468 | 468 | // although it is a runtime value, is guaranteed to be one of the architectures in the set |
| 469 | 469 | // of the respective switch prong. |
| 470 | 470 | switch (builtin.cpu.arch) { |
| 471 | .x86_64, .x86 => { | |
| 472 | return @import("system/x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, query); | |
| 473 | }, | |
| 471 | .loongarch32, .loongarch64 => return @import("system/loongarch.zig").detectNativeCpuAndFeatures(cpu_arch, os, query), | |
| 472 | .x86_64, .x86 => return @import("system/x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, query), | |
| 474 | 473 | else => {}, |
| 475 | 474 | } |
| 476 | 475 |
lib/std/zig/system/loongarch.zig created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | pub fn detectNativeCpuAndFeatures( | |
| 5 | arch: std.Target.Cpu.Arch, | |
| 6 | os: std.Target.Os, | |
| 7 | query: std.Target.Query, | |
| 8 | ) ?std.Target.Cpu { | |
| 9 | _ = os; | |
| 10 | _ = query; | |
| 11 | ||
| 12 | // Clearly this code could do better in the future by actually querying specific CPU features | |
| 13 | // with the cpucfg instruction like on x86. But with the small number of well-known LoongArch | |
| 14 | // models that exist at the moment, simply checking the PRID is plenty. | |
| 15 | var cpu: std.Target.Cpu = .{ | |
| 16 | .arch = arch, | |
| 17 | .model = switch (cpucfg(0) & 0xf000) { | |
| 18 | else => return null, | |
| 19 | 0xc000 => &std.Target.loongarch.cpu.la464, | |
| 20 | 0xd000 => &std.Target.loongarch.cpu.la664, | |
| 21 | }, | |
| 22 | .features = .empty, | |
| 23 | }; | |
| 24 | ||
| 25 | cpu.features.addFeatureSet(cpu.model.features); | |
| 26 | cpu.features.populateDependencies(cpu.arch.allFeaturesList()); | |
| 27 | ||
| 28 | return cpu; | |
| 29 | } | |
| 30 | ||
| 31 | /// This is a workaround for the C backend until zig has the ability to put | |
| 32 | /// C code in inline assembly. | |
| 33 | extern fn zig_loongarch_cpucfg(word: u32, result: *u32) callconv(.c) void; | |
| 34 | ||
| 35 | fn cpucfg(word: u32) u32 { | |
| 36 | var result: u32 = undefined; | |
| 37 | ||
| 38 | if (builtin.zig_backend == .stage2_c) { | |
| 39 | zig_loongarch_cpucfg(word, &result); | |
| 40 | } else { | |
| 41 | asm ("cpucfg %[result], %[word]" | |
| 42 | : [result] "=r" (result), | |
| 43 | : [word] "r" (word), | |
| 44 | ); | |
| 45 | } | |
| 46 | ||
| 47 | return result; | |
| 48 | } |
lib/zig.h+13-3| ... | ... | @@ -4195,7 +4195,17 @@ static inline void* zig_x86_64_windows_teb(void) { |
| 4195 | 4195 | |
| 4196 | 4196 | #endif |
| 4197 | 4197 | |
| 4198 | #if defined(zig_x86) | |
| 4198 | #if defined(zig_loongarch) | |
| 4199 | ||
| 4200 | static inline void zig_loongarch_cpucfg(uint32_t word, uint32_t* result) { | |
| 4201 | #if defined(zig_gnuc_asm) | |
| 4202 | __asm__("cpucfg %[result], %[word]" : [result] "=r" (result) : [word] "r" (word)); | |
| 4203 | #else | |
| 4204 | *result = 0; | |
| 4205 | #endif | |
| 4206 | } | |
| 4207 | ||
| 4208 | #elif defined(zig_x86) | |
| 4199 | 4209 | |
| 4200 | 4210 | static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { |
| 4201 | 4211 | #if defined(zig_msvc) |
| ... | ... | @@ -4206,7 +4216,7 @@ static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax |
| 4206 | 4216 | *ecx = (uint32_t)cpu_info[2]; |
| 4207 | 4217 | *edx = (uint32_t)cpu_info[3]; |
| 4208 | 4218 | #elif defined(zig_gnuc_asm) |
| 4209 | __asm__("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf_id), "c"(subid)); | |
| 4219 | __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (leaf_id), "c" (subid)); | |
| 4210 | 4220 | #else |
| 4211 | 4221 | *eax = 0; |
| 4212 | 4222 | *ebx = 0; |
| ... | ... | @@ -4221,7 +4231,7 @@ static inline uint32_t zig_x86_get_xcr0(void) { |
| 4221 | 4231 | #elif defined(zig_gnuc_asm) |
| 4222 | 4232 | uint32_t eax; |
| 4223 | 4233 | uint32_t edx; |
| 4224 | __asm__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0)); | |
| 4234 | __asm__("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); | |
| 4225 | 4235 | return eax; |
| 4226 | 4236 | #else |
| 4227 | 4237 | *eax = 0; |