This patch can obtain the cpucfg value at runtime and extract the
flag bits of features for function selection.
libgcc/ChangeLog:
* config/loongarch/t-loongarch64: Add cpuinfo.c to LIB2ADD.
* config/loongarch/cpuinfo.c: New file.
---
libgcc/config/loongarch/cpuinfo.c | 77 +++++++++++++++++++++++++++
libgcc/config/loongarch/t-loongarch64 | 2 +
2 files changed, 79 insertions(+)
create mode 100644 libgcc/config/loongarch/cpuinfo.c
diff --git a/libgcc/config/loongarch/cpuinfo.c
b/libgcc/config/loongarch/cpuinfo.c
new file mode 100644
index 00000000000..bec602459b1
--- /dev/null
+++ b/libgcc/config/loongarch/cpuinfo.c
@@ -0,0 +1,77 @@
+/* CPU feature detection for LoongArch architecture.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "common/config/loongarch/cpu-features.h"
+
+#define CPUCFG1_LA64 2ULL << 0
+#define CPUCFG1_UAL 1ULL << 20
+#define CPUCFG2_LSX 1ULL << 6
+#define CPUCFG2_LASX 1ULL << 7
+#define CPUCFG2_FRECIPE 1ULL << 25
+#define CPUCFG2_DIV32 1ULL << 26
+#define CPUCFG2_LAM_BH 1ULL << 27
+#define CPUCFG2_LAMCAS 1ULL << 28
+#define CPUCFG2_SCQ 1ULL << 30
+#define CPUCFG3_LD_SEQ_SA 1ULL << 23
+
+struct {
+ loongarch_fmv_feature_mask features;
+} __loongarch_feature_bits __attribute__ ((visibility ("hidden"), nocommon));
+
+void __init_loongarch_features_resolver (void);
+void
+__init_loongarch_features_resolver (void)
+{
+ if (__atomic_load_n (&__loongarch_feature_bits.features, __ATOMIC_RELAXED))
+ return;
+
+ loongarch_fmv_feature_mask feat = 0ULL;
+#define setCPUFeature(F) feat |= 1ULL << F;
+ unsigned int CPUCFG1 = __builtin_loongarch_cpucfg (1);
+ unsigned int CPUCFG2 = __builtin_loongarch_cpucfg (2);
+ unsigned int CPUCFG3 = __builtin_loongarch_cpucfg (3);
+
+ if (CPUCFG1 & CPUCFG1_LA64)
+ setCPUFeature (FEAT_LA64);
+ if (CPUCFG1 & CPUCFG1_UAL)
+ setCPUFeature (FEAT_UAL);
+ if (CPUCFG2 & CPUCFG2_LSX)
+ setCPUFeature (FEAT_LSX);
+ if (CPUCFG2 & CPUCFG2_LASX)
+ setCPUFeature (FEAT_LASX);
+ if (CPUCFG2 & CPUCFG2_FRECIPE)
+ setCPUFeature (FEAT_FRECIPE);
+ if (CPUCFG2 & CPUCFG2_DIV32)
+ setCPUFeature (FEAT_DIV32);
+ if (CPUCFG2 & CPUCFG2_LAM_BH)
+ setCPUFeature (FEAT_LAM_BH);
+ if (CPUCFG2 & CPUCFG2_LAMCAS)
+ setCPUFeature (FEAT_LAMCAS);
+ if (CPUCFG2 & CPUCFG2_SCQ)
+ setCPUFeature (FEAT_SCQ);
+ if (CPUCFG3 & CPUCFG3_LD_SEQ_SA)
+ setCPUFeature (FEAT_LD_SEQ_SA);
+#undef setCPUFeature
+ __atomic_store_n (&__loongarch_feature_bits.features, feat,
__ATOMIC_RELAXED);
+}
diff --git a/libgcc/config/loongarch/t-loongarch64
b/libgcc/config/loongarch/t-loongarch64
index a1e3513e288..20d15207515 100644
--- a/libgcc/config/loongarch/t-loongarch64
+++ b/libgcc/config/loongarch/t-loongarch64
@@ -1 +1,3 @@
+LIB2ADD += $(srcdir)/config/loongarch/cpuinfo.c
+
softfp_int_modes += ti
--
2.34.1