From 5f2b532be56bf39bac3f4b8b9e7947badada3d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 6 Jul 2026 23:26:24 +0200 Subject: [PATCH 1/3] zig.h: fix zig_loongarch_cpucfg() not returning its result correctly --- lib/zig.h | 2 +- stage1/zig.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/zig.h b/lib/zig.h index 34b56286a508b2707f4498f49612d9d625ee7c86..db94ac20445b942586741451f4e02bc7c579aae3 100644 --- a/lib/zig.h +++ b/lib/zig.h @@ -4636,7 +4636,7 @@ static inline void zig_e_zig_loongarch_cpucfg(uint32_t word, uint32_t* result) z static inline void zig_e_zig_loongarch_cpucfg(uint32_t word, uint32_t* result) { #if defined(zig_gnuc_asm) - __asm__("cpucfg %[result], %[word]" : [result] "=r" (result) : [word] "r" (word)); + __asm__("cpucfg %[result], %[word]" : [result] "=r" (*result) : [word] "r" (word)); #else *result = 0; #endif diff --git a/stage1/zig.h b/stage1/zig.h index 34b56286a508b2707f4498f49612d9d625ee7c86..db94ac20445b942586741451f4e02bc7c579aae3 100644 --- a/stage1/zig.h +++ b/stage1/zig.h @@ -4636,7 +4636,7 @@ static inline void zig_e_zig_loongarch_cpucfg(uint32_t word, uint32_t* result) z static inline void zig_e_zig_loongarch_cpucfg(uint32_t word, uint32_t* result) { #if defined(zig_gnuc_asm) - __asm__("cpucfg %[result], %[word]" : [result] "=r" (result) : [word] "r" (word)); + __asm__("cpucfg %[result], %[word]" : [result] "=r" (*result) : [word] "r" (word)); #else *result = 0; #endif -- 2.54.0 From 3e6b2c6b03eacd311de2579b52f5ed9b83e57a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 6 Jul 2026 06:01:23 +0200 Subject: [PATCH 2/3] std.Target: fix definition of generic_la64 CPU model LLVM's generic_la64 model is clearly biased towards Loongson's current offerings rather than actually reflecting a generic model in the architectural sense. So fix it up on our side. --- lib/std/Target/loongarch.zig | 4 +--- tools/update_cpu_features.zig | 8 ++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/std/Target/loongarch.zig b/lib/std/Target/loongarch.zig index 20a02568ccd5a9244923e33c02e6a84ba2fa72de..7158074464942873b3b7e9eb2ecde999bb4c204f 100644 --- a/lib/std/Target/loongarch.zig +++ b/lib/std/Target/loongarch.zig @@ -168,11 +168,9 @@ pub const cpu = struct { }; pub const generic_la64: CpuModel = .{ .name = "generic_la64", - .llvm_name = "generic-la64", + .llvm_name = null, .features = featureSet(&[_]Feature{ .@"64bit", - .lsx, - .ual, }), }; pub const la32rv1_0: CpuModel = .{ diff --git a/tools/update_cpu_features.zig b/tools/update_cpu_features.zig index f7b4de724bedebd4c770ce15b161ef1774c3c4e9..a1f876282a584edb8470c76bcca72a4248c9cb04 100644 --- a/tools/update_cpu_features.zig +++ b/tools/update_cpu_features.zig @@ -1345,6 +1345,13 @@ const targets = [_]ArchTarget{ .td_name = "LoongArch", }, .extra_cpus = &.{ + .{ + .llvm_name = null, + .zig_name = "generic_la64", + .features = &.{ + "64bit", + }, + }, .{ .llvm_name = null, .zig_name = "la32v1_0", @@ -1390,6 +1397,7 @@ const targets = [_]ArchTarget{ }, .omit_cpus = &.{ "generic", + "generic-la64", "loongarch32", "loongarch64", }, -- 2.54.0 From 773a555397684e602fc2a645f221babdfb0a5042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 6 Jul 2026 06:06:41 +0200 Subject: [PATCH 3/3] std.zig.system.loongarch: use generic CPU model if we can't determine the model In principle, there's no reason why we shouldn't be able to proceed with CPU feature detection just because we can't determine the exact CPU model. This is relevant when new silicon appears in the wild and Zig hasn't yet been updated to recognize it. --- lib/std/zig/system/loongarch.zig | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/std/zig/system/loongarch.zig b/lib/std/zig/system/loongarch.zig index c5930340dea96e2aad563e82335030e0b38b61c6..eae8ac31df8f77c5acc66d31752d31ad6bbe3108 100644 --- a/lib/std/zig/system/loongarch.zig +++ b/lib/std/zig/system/loongarch.zig @@ -1,6 +1,13 @@ const builtin = @import("builtin"); const std = @import("std"); +const Variant = enum(u2) { + la32r = 0b00, + la32 = 0b01, + la64 = 0b10, + reserved = 0b11, +}; + inline fn bit(input: u32, offset: u5) bool { return (input >> offset) & 1 != 0; } @@ -19,10 +26,16 @@ pub fn detectNativeCpuAndFeatures( _ = os; _ = query; + const variant: Variant = @enumFromInt(cpucfg(1) & 0b11); + var cpu: std.Target.Cpu = .{ .arch = arch, - .model = switch (cpucfg(0) & 0xf000) { - else => return null, + .model = switch (cpucfg(0) & 0b1111000000000000) { + else => switch (variant) { + .la32r, .la32 => &std.Target.loongarch.cpu.generic_la32, + .la64 => &std.Target.loongarch.cpu.generic_la64, + .reserved => unreachable, + }, 0xc000 => &std.Target.loongarch.cpu.la464, 0xd000 => &std.Target.loongarch.cpu.la664, }, @@ -31,6 +44,8 @@ pub fn detectNativeCpuAndFeatures( cpu.features.addFeatureSet(cpu.model.features); + setFeature(&cpu, .@"32s", variant != .la32r); + const cfg2 = cpucfg(2); const cfg3 = cpucfg(3); -- 2.54.0