commit 8b220cd746384c43e8406b70e93f76afe7a6db48 (tree)
parent 34c2b5e9d1b15ab9d8988f7919df967f3c405187
Author: xtex <xtex@astrafall.org>
Date: Sun, 8 Mar 2026 09:40:23 +0800
std.zig.system.loongarch: take HWCAP into consideration
We prefer information from HWCAP than CPUCFG and
assume those features unavailable if HWCAP is not available.
This is because many features require kernel support
(e.g. context switching support).
Follow-up: 37288e53ae4e ("std.zig.system.loongarch: implement individual cpu feature bit tests (#30915)")
Change-Id: I0a610b2c4fc751f0f159e79e01bb9f6fb7588ccf
Signed-off-by: xtex <xtex@astrafall.org>
Diffstat:
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/lib/std/zig/system/loongarch.zig b/lib/std/zig/system/loongarch.zig
@@ -31,21 +31,37 @@ pub fn detectNativeCpuAndFeatures(
cpu.features.addFeatureSet(cpu.model.features);
- const cfg1 = cpucfg(1);
const cfg2 = cpucfg(2);
const cfg3 = cpucfg(3);
- setFeature(&cpu, .ual, bit(cfg1, 20));
+ if (builtin.os.tag == .linux) {
+ const HWCAP = std.os.linux.HWCAP;
+ const hwcap_bits: usize = if (builtin.link_libc)
+ std.c.getauxval(std.elf.AT_HWCAP)
+ else
+ std.os.linux.getauxval(std.elf.AT_HWCAP);
- const has_fpu = bit(cfg2, 0);
- setFeature(&cpu, .f, has_fpu and bit(cfg2, 1));
- setFeature(&cpu, .d, has_fpu and bit(cfg2, 2));
+ setFeature(&cpu, .ual, (hwcap_bits & HWCAP.UAL) != 0);
- setFeature(&cpu, .lsx, bit(cfg2, 6));
- setFeature(&cpu, .lasx, bit(cfg2, 7));
- setFeature(&cpu, .lvz, bit(cfg2, 10));
+ const has_fpu = (hwcap_bits & HWCAP.FPU) != 0;
+ setFeature(&cpu, .f, has_fpu and bit(cfg2, 1));
+ setFeature(&cpu, .d, has_fpu and bit(cfg2, 2));
+ setFeature(&cpu, .lsx, (hwcap_bits & HWCAP.LSX) != 0);
+ setFeature(&cpu, .lasx, (hwcap_bits & HWCAP.LASX) != 0);
- setFeature(&cpu, .lbt, bit(cfg2, 18) and bit(cfg2, 19) and bit(cfg2, 20));
+ setFeature(&cpu, .lvz, (hwcap_bits & HWCAP.LVZ) != 0);
+ setFeature(&cpu, .lbt, (hwcap_bits & HWCAP.LBT_X86) != 0 and (hwcap_bits & HWCAP.LBT_ARM) != 0 and (hwcap_bits & HWCAP.LBT_MIPS) != 0);
+ } else {
+ setFeature(&cpu, .ual, false);
+
+ setFeature(&cpu, .f, false);
+ setFeature(&cpu, .d, false);
+ setFeature(&cpu, .lsx, false);
+ setFeature(&cpu, .lasx, false);
+
+ setFeature(&cpu, .lvz, false);
+ setFeature(&cpu, .lbt, false);
+ }
setFeature(&cpu, .frecipe, bit(cfg2, 25));
setFeature(&cpu, .div32, bit(cfg2, 26));