commit cece38bc054b801bde76603119fe695be3cb3a06 (tree)
parent 9e3eaa6be7b2b22d44205012abc4278cdd673526
Author: Alex Rønne Petersen <alex@alexrp.com>
Date: Sat, 23 May 2026 05:44:14 +0200
Merge pull request 'std.zig.system.loongarch: take HWCAP into consideration' (#31614) from AstraFall/zig:loongarch/cpu-detect into master
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31614
Reviewed-by: Alex Rønne Petersen <alex@alexrp.com>
Diffstat:
3 files changed, 72 insertions(+), 36 deletions(-)
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
@@ -96,7 +96,6 @@ pub fn clone(
}
pub const ARCH = arch_bits.ARCH;
-pub const HWCAP = arch_bits.HWCAP;
pub const SC = arch_bits.SC;
pub const VDSO = arch_bits.VDSO;
pub const user_desc = arch_bits.user_desc;
@@ -524,6 +523,53 @@ pub const O = switch (native_arch) {
else => @compileError("missing std.os.linux.O constants for this architecture"),
};
+pub const HWCAP = switch (native_arch) {
+ .arm, .armeb, .thumb, .thumbeb => struct {
+ pub const SWP = 1 << 0;
+ pub const HALF = 1 << 1;
+ pub const THUMB = 1 << 2;
+ pub const @"26BIT" = 1 << 3;
+ pub const FAST_MULT = 1 << 4;
+ pub const FPA = 1 << 5;
+ pub const VFP = 1 << 6;
+ pub const EDSP = 1 << 7;
+ pub const JAVA = 1 << 8;
+ pub const IWMMXT = 1 << 9;
+ pub const CRUNCH = 1 << 10;
+ pub const THUMBEE = 1 << 11;
+ pub const NEON = 1 << 12;
+ pub const VFPv3 = 1 << 13;
+ pub const VFPv3D16 = 1 << 14;
+ pub const TLS = 1 << 15;
+ pub const VFPv4 = 1 << 16;
+ pub const IDIVA = 1 << 17;
+ pub const IDIVT = 1 << 18;
+ pub const VFPD32 = 1 << 19;
+ pub const IDIV = IDIVA | IDIVT;
+ pub const LPAE = 1 << 20;
+ pub const EVTSTRM = 1 << 21;
+ },
+ .loongarch32, .loongarch64 => struct {
+ pub const CPUCFG = 1 << 0;
+ pub const LAM = 1 << 1;
+ pub const UAL = 1 << 2;
+ pub const FPU = 1 << 3;
+ pub const LSX = 1 << 4;
+ pub const LASX = 1 << 5;
+ pub const CRC32 = 1 << 6;
+ pub const COMPLEX = 1 << 7;
+ pub const CRYPTO = 1 << 8;
+ pub const LVZ = 1 << 9;
+ pub const LBT_X86 = 1 << 10;
+ pub const LBT_ARM = 1 << 11;
+ pub const LBT_MIPS = 1 << 12;
+ pub const PTW = 1 << 13;
+ pub const LSPW = 1 << 14;
+ pub const SCQ = 1 << 15;
+ },
+ else => struct {},
+};
+
pub const RENAME = packed struct(u32) {
/// Cannot be set together with `EXCHANGE`.
NOREPLACE: bool = false,
diff --git a/lib/std/os/linux/arm.zig b/lib/std/os/linux/arm.zig
@@ -182,30 +182,4 @@ pub const VDSO = struct {
pub const CGT_VER = "LINUX_2.6";
};
-pub const HWCAP = struct {
- pub const SWP = 1 << 0;
- pub const HALF = 1 << 1;
- pub const THUMB = 1 << 2;
- pub const @"26BIT" = 1 << 3;
- pub const FAST_MULT = 1 << 4;
- pub const FPA = 1 << 5;
- pub const VFP = 1 << 6;
- pub const EDSP = 1 << 7;
- pub const JAVA = 1 << 8;
- pub const IWMMXT = 1 << 9;
- pub const CRUNCH = 1 << 10;
- pub const THUMBEE = 1 << 11;
- pub const NEON = 1 << 12;
- pub const VFPv3 = 1 << 13;
- pub const VFPv3D16 = 1 << 14;
- pub const TLS = 1 << 15;
- pub const VFPv4 = 1 << 16;
- pub const IDIVA = 1 << 17;
- pub const IDIVT = 1 << 18;
- pub const VFPD32 = 1 << 19;
- pub const IDIV = IDIVA | IDIVT;
- pub const LPAE = 1 << 20;
- pub const EVTSTRM = 1 << 21;
-};
-
pub const time_t = i32;
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));