diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/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/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/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/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/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/compiler-rt/cmake/crt-config-ix.cmake b/compiler-rt/cmake/crt-config-ix.cmake --- a/compiler-rt/cmake/crt-config-ix.cmake +++ b/compiler-rt/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/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/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/compiler-rt/lib/builtins/loongarch/fp_mode.c b/compiler-rt/lib/builtins/loongarch/fp_mode.c new file mode 100644 --- /dev/null +++ b/compiler-rt/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/compiler-rt/test/builtins/Unit/addtf3_test.c b/compiler-rt/test/builtins/Unit/addtf3_test.c --- a/compiler-rt/test/builtins/Unit/addtf3_test.c +++ b/compiler-rt/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/compiler-rt/test/builtins/Unit/subtf3_test.c b/compiler-rt/test/builtins/Unit/subtf3_test.c --- a/compiler-rt/test/builtins/Unit/subtf3_test.c +++ b/compiler-rt/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;