[compiler-rt][builtins] Support builtins for LoongArch
Initial builtins for LoongArch.
Add loongarch64 to ALL_CRT_SUPPORTED_ARCH list.
Support fe_getround and fe_raise_inexact in builtins.
Differential Revision: https://reviews.llvm.org/D136338
GitOrigin-RevId: 6e6704b0dc2c8955c6aa3c69535c247ed154eac3
diff --git a/cmake/Modules/CompilerRTUtils.cmake b/cmake/Modules/CompilerRTUtils.cmake
index a4f3a22..7f8e783 100644
--- a/cmake/Modules/CompilerRTUtils.cmake
+++ b/cmake/Modules/CompilerRTUtils.cmake
@@ -151,6 +151,7 @@
check_symbol_exists(__aarch64__ "" __AARCH64)
check_symbol_exists(__x86_64__ "" __X86_64)
check_symbol_exists(__i386__ "" __I386)
+ check_symbol_exists(__loongarch__ "" __LOONGARCH)
check_symbol_exists(__mips__ "" __MIPS)
check_symbol_exists(__mips64__ "" __MIPS64)
check_symbol_exists(__powerpc__ "" __PPC)
@@ -179,6 +180,14 @@
endif()
elseif(__I386)
add_default_target_arch(i386)
+ elseif(__LOONGARCH)
+ if(CMAKE_SIZEOF_VOID_P EQUAL "4")
+ add_default_target_arch(loongarch32)
+ elseif(CMAKE_SIZEOF_VOID_P EQUAL "8")
+ add_default_target_arch(loongarch64)
+ else()
+ message(FATAL_ERROR "Unsupported pointer size for LoongArch")
+ endif()
elseif(__MIPS64) # must be checked before __MIPS
add_default_target_arch(mips64)
elseif(__MIPS)
diff --git a/cmake/base-config-ix.cmake b/cmake/base-config-ix.cmake
index f5d7385..ac97617 100644
--- a/cmake/base-config-ix.cmake
+++ b/cmake/base-config-ix.cmake
@@ -205,6 +205,8 @@
test_target_arch(x86_64 "" "")
endif()
endif()
+ elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "loongarch64")
+ test_target_arch(loongarch64 "" "")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc64le|ppc64le")
test_target_arch(powerpc64le "" "-m64")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc")
diff --git a/cmake/builtin-config-ix.cmake b/cmake/builtin-config-ix.cmake
index 62e8281..0ecf411 100644
--- a/cmake/builtin-config-ix.cmake
+++ b/cmake/builtin-config-ix.cmake
@@ -50,6 +50,7 @@
set(HEXAGON hexagon)
set(X86 i386)
set(X86_64 x86_64)
+set(LOONGARCH64 loongarch64)
set(MIPS32 mips mipsel)
set(MIPS64 mips64 mips64el)
set(PPC32 powerpc powerpcspe)
@@ -72,7 +73,7 @@
${X86} ${X86_64} ${ARM32} ${ARM64} ${AVR}
${HEXAGON} ${MIPS32} ${MIPS64} ${PPC32} ${PPC64}
${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9}
- ${WASM32} ${WASM64} ${VE})
+ ${WASM32} ${WASM64} ${VE} ${LOONGARCH64})
include(CompilerRTUtils)
include(CompilerRTDarwinUtils)
diff --git a/cmake/crt-config-ix.cmake b/cmake/crt-config-ix.cmake
index 78d1a0d..066a0ed 100644
--- a/cmake/crt-config-ix.cmake
+++ b/cmake/crt-config-ix.cmake
@@ -23,6 +23,7 @@
set(HEXAGON hexagon)
set(X86 i386)
set(X86_64 x86_64)
+set(LOONGARCH64 loongarch64)
set(PPC32 powerpc powerpcspe)
set(PPC64 powerpc64 powerpc64le)
set(RISCV32 riscv32)
@@ -30,7 +31,7 @@
set(VE ve)
set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32}
- ${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON})
+ ${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON} ${LOONGARCH64})
include(CompilerRTUtils)
diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt
index 716ecec..fd3d395 100644
--- a/lib/builtins/CMakeLists.txt
+++ b/lib/builtins/CMakeLists.txt
@@ -620,6 +620,14 @@
${GENERIC_TF_SOURCES}
)
+set(loongarch_SOURCES
+ loongarch/fp_mode.c
+ ${GENERIC_SOURCES}
+ ${GENERIC_TF_SOURCES}
+)
+set(loongarch64_SOURCES
+ ${loongarch_SOURCES}
+)
set(mips_SOURCES ${GENERIC_SOURCES})
set(mipsel_SOURCES ${mips_SOURCES})
diff --git a/lib/builtins/loongarch/fp_mode.c b/lib/builtins/loongarch/fp_mode.c
new file mode 100644
index 0000000..0e3d796
--- /dev/null
+++ b/lib/builtins/loongarch/fp_mode.c
@@ -0,0 +1,49 @@
+//=== lib/builtins/loongarch/fp_mode.c - Floaing-point mode utilities -*- C -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "../fp_mode.h"
+
+#define LOONGARCH_TONEAREST 0x0000
+#define LOONGARCH_TOWARDZERO 0x0100
+#define LOONGARCH_UPWARD 0x0200
+#define LOONGARCH_DOWNWARD 0x0300
+
+#define LOONGARCH_RMODE_MASK (LOONGARCH_TONEAREST | LOONGARCH_TOWARDZERO | \
+ LOONGARCH_UPWARD | LOONGARCH_DOWNWARD)
+
+#define LOONGARCH_INEXACT 0x10000
+
+CRT_FE_ROUND_MODE __fe_getround(void) {
+#if __loongarch_frlen != 0
+ int fcsr;
+ __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr));
+ fcsr &= LOONGARCH_RMODE_MASK;
+ switch (fcsr) {
+ case LOONGARCH_TOWARDZERO:
+ return CRT_FE_TOWARDZERO;
+ case LOONGARCH_DOWNWARD:
+ return CRT_FE_DOWNWARD;
+ case LOONGARCH_UPWARD:
+ return CRT_FE_UPWARD;
+ case LOONGARCH_TONEAREST:
+ default:
+ return CRT_FE_TONEAREST;
+ }
+#else
+ return CRT_FE_TONEAREST;
+#endif
+}
+
+int __fe_raise_inexact(void) {
+#if __loongarch_frlen != 0
+ int fcsr;
+ __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr));
+ __asm__ __volatile__(
+ "movgr2fcsr $fcsr0, %0" :: "r" (fcsr | LOONGARCH_INEXACT));
+#endif
+ return 0;
+}
diff --git a/test/builtins/Unit/addtf3_test.c b/test/builtins/Unit/addtf3_test.c
index 82a8020..fe2e2c8 100644
--- a/test/builtins/Unit/addtf3_test.c
+++ b/test/builtins/Unit/addtf3_test.c
@@ -66,7 +66,8 @@
return 1;
#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \
- defined(i386) || defined(__x86_64__)
+ defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && \
+ __loongarch_frlen != 0)
// Rounding mode tests on supported architectures
const long double m = 1234.0L, n = 0.01L;
diff --git a/test/builtins/Unit/subtf3_test.c b/test/builtins/Unit/subtf3_test.c
index c06a0ba..377ae95 100644
--- a/test/builtins/Unit/subtf3_test.c
+++ b/test/builtins/Unit/subtf3_test.c
@@ -59,7 +59,8 @@
return 1;
#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \
- defined(i386) || defined(__x86_64__)
+ defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && \
+ __loongarch_frlen != 0)
// Rounding mode tests on supported architectures
const long double m = 1234.02L, n = 0.01L;