diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index 9f79a9b920db..f567202faa61 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -168,6 +168,7 @@ macro(detect_target_arch) check_symbol_exists(__mips64__ "" __MIPS64) check_symbol_exists(__powerpc64__ "" __PPC64) check_symbol_exists(__powerpc64le__ "" __PPC64LE) + check_symbol_exists(__riscv "" __RISCV) check_symbol_exists(__s390x__ "" __S390X) check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32) check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64) @@ -187,6 +188,14 @@ macro(detect_target_arch) add_default_target_arch(powerpc64) elseif(__PPC64LE) add_default_target_arch(powerpc64le) + elseif(__RISCV) + if(CMAKE_SIZEOF_VOID_P EQUAL "4") + add_default_target_arch(riscv32) + elseif(CMAKE_SIZEOF_VOID_P EQUAL "8") + add_default_target_arch(riscv64) + else() + message(FATAL_ERROR "Unsupport XLEN for RISC-V") + endif() elseif(__S390X) add_default_target_arch(s390x) elseif(__WEBASSEMBLY32) diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index b208f0852408..beb05f6c898d 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -186,6 +186,10 @@ macro(test_targets) test_target_arch(aarch32 "" "-march=armv8-a") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64") test_target_arch(aarch64 "" "-march=armv8-a") + elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "riscv32") + test_target_arch(riscv32 "" "") + elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "riscv64") + test_target_arch(riscv64 "" "") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32") test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64") diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake index bdb2529b5ee2..eda5f46414e3 100644 --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/cmake/builtin-config-ix.cmake @@ -30,6 +30,8 @@ set(X86_64 x86_64) set(MIPS32 mips mipsel) set(MIPS64 mips64 mips64el) set(PPC64 powerpc64 powerpc64le) +set(RISCV32 riscv32) +set(RISCV64 riscv64) set(WASM32 wasm32) set(WASM64 wasm64) @@ -40,7 +42,7 @@ if(APPLE) endif() set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} - ${MIPS32} ${MIPS64} ${PPC64} ${WASM32} ${WASM64}) + ${MIPS32} ${MIPS64} ${PPC64} ${RISCV32} ${RISCV64} ${WASM32} ${WASM64}) include(CompilerRTUtils) include(CompilerRTDarwinUtils) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 9f24b9d50b37..1e04da7bb74d 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -179,6 +179,8 @@ set(X86_64 x86_64) set(MIPS32 mips mipsel) set(MIPS64 mips64 mips64el) set(PPC64 powerpc64 powerpc64le) +set(RISCV32 riscv32) +set(RISCV64 riscv64) set(S390X s390x) set(WASM32 wasm32) set(WASM64 wasm64) diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 13158b903789..6c48a404a181 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -480,6 +480,12 @@ set(powerpc64_SOURCES ${GENERIC_SOURCES}) set(powerpc64le_SOURCES ${powerpc64_SOURCES}) +set(riscv_SOURCES ${GENERIC_SOURCES} ${GENERIC_TF_SOURCES}) +set(riscv32_SOURCES + riscv/mulsi3.S + ${riscv_SOURCES}) +set(riscv64_SOURCES ${riscv_SOURCES}) + set(wasm32_SOURCES ${GENERIC_TF_SOURCES} ${GENERIC_SOURCES}) diff --git a/compiler-rt/lib/builtins/int_types.h b/compiler-rt/lib/builtins/int_types.h index a92238c5b730..f53f343d35d5 100644 --- a/compiler-rt/lib/builtins/int_types.h +++ b/compiler-rt/lib/builtins/int_types.h @@ -60,7 +60,7 @@ typedef union }s; } udwords; -#if (defined(__LP64__) || defined(__wasm__) || defined(__mips64)) +#if (defined(__LP64__) || defined(__wasm__) || defined(__mips64)) || defined(__riscv) #define CRT_HAS_128BIT #endif diff --git a/compiler-rt/lib/builtins/riscv/mulsi3.S b/compiler-rt/lib/builtins/riscv/mulsi3.S new file mode 100644 index 000000000000..a58d237040b6 --- /dev/null +++ b/compiler-rt/lib/builtins/riscv/mulsi3.S @@ -0,0 +1,28 @@ +//===--- mulsi3.S - Integer multiplication routines routines ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#if !defined(__riscv_mul) && __riscv_xlen == 32 + .text + .align 2 + + .globl __mulsi3 + .type __mulsi3, @function +__mulsi3: + mv a2, a0 + mv a0, zero +.L1: + andi a3, a1, 1 + beqz a3, .L2 + add a0, a0, a2 +.L2: + srli a1, a1, 1 + slli a2, a2, 1 + bnez a1, .L1 + ret +#endif diff --git a/compiler-rt/test/builtins/CMakeLists.txt b/compiler-rt/test/builtins/CMakeLists.txt index cabf767223cc..a9199ebf10df 100644 --- a/compiler-rt/test/builtins/CMakeLists.txt +++ b/compiler-rt/test/builtins/CMakeLists.txt @@ -26,6 +26,11 @@ foreach(arch ${BUILTIN_SUPPORTED_ARCH}) string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}") endif() + if (${arch} STREQUAL "riscv32") + list(APPEND BUILTINS_TEST_TARGET_CFLAGS -fforce-enable-int128) + string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}") + endif() + string(TOUPPER ${arch} ARCH_UPPER_CASE) set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) configure_lit_site_cfg( diff --git a/compiler-rt/test/builtins/Unit/riscv/mulsi3_test.c b/compiler-rt/test/builtins/Unit/riscv/mulsi3_test.c new file mode 100644 index 000000000000..9033004f11dd --- /dev/null +++ b/compiler-rt/test/builtins/Unit/riscv/mulsi3_test.c @@ -0,0 +1,119 @@ +// REQUIRES-ANY: riscv32-target-arch +// RUN: %clang_builtins %s %librt -o %t && %run %t +//===-- mulsi3_test.c - Test __mulsi3 -------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __mulsi3 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include "int_lib.h" +#include +#include + +#if !defined(__riscv_mul) && __riscv_xlen == 32 +// Based on mulsi3_test.c + +COMPILER_RT_ABI si_int __mulsi3(si_int a, si_int b); + +int test__mulsi3(si_int a, si_int b, si_int expected) +{ + si_int x = __mulsi3(a, b); + if (x != expected) + printf("error in __mulsi3: %d * %d = %d, expected %d\n", + a, b, __mulsi3(a, b), expected); + return x != expected; +} +#endif + +int main() +{ +#if !defined(__riscv_mul) && __riscv_xlen == 32 + if (test__mulsi3(0, 0, 0)) + return 1; + if (test__mulsi3(0, 1, 0)) + return 1; + if (test__mulsi3(1, 0, 0)) + return 1; + if (test__mulsi3(0, 10, 0)) + return 1; + if (test__mulsi3(10, 0, 0)) + return 1; + if (test__mulsi3(0, INT_MAX, 0)) + return 1; + if (test__mulsi3(INT_MAX, 0, 0)) + return 1; + + if (test__mulsi3(0, -1, 0)) + return 1; + if (test__mulsi3(-1, 0, 0)) + return 1; + if (test__mulsi3(0, -10, 0)) + return 1; + if (test__mulsi3(-10, 0, 0)) + return 1; + if (test__mulsi3(0, INT_MIN, 0)) + return 1; + if (test__mulsi3(INT_MIN, 0, 0)) + return 1; + + if (test__mulsi3(1, 1, 1)) + return 1; + if (test__mulsi3(1, 10, 10)) + return 1; + if (test__mulsi3(10, 1, 10)) + return 1; + if (test__mulsi3(1, INT_MAX, INT_MAX)) + return 1; + if (test__mulsi3(INT_MAX, 1, INT_MAX)) + return 1; + + if (test__mulsi3(1, -1, -1)) + return 1; + if (test__mulsi3(1, -10, -10)) + return 1; + if (test__mulsi3(-10, 1, -10)) + return 1; + if (test__mulsi3(1, INT_MIN, INT_MIN)) + return 1; + if (test__mulsi3(INT_MIN, 1, INT_MIN)) + return 1; + + if (test__mulsi3(46340, 46340, 2147395600)) + return 1; + if (test__mulsi3(-46340, 46340, -2147395600)) + return 1; + if (test__mulsi3(46340, -46340, -2147395600)) + return 1; + if (test__mulsi3(-46340, -46340, 2147395600)) + return 1; + + if (test__mulsi3(4194303, 8192, 34359730176)) + return 1; + if (test__mulsi3(-4194303, 8192, -34359730176)) + return 1; + if (test__mulsi3(4194303, -8192, -34359730176)) + return 1; + if (test__mulsi3(-4194303, -8192, 34359730176)) + return 1; + + if (test__mulsi3(8192, 4194303, 34359730176)) + return 1; + if (test__mulsi3(-8192, 4194303, -34359730176)) + return 1; + if (test__mulsi3(8192, -4194303, -34359730176)) + return 1; + if (test__mulsi3(-8192, -4194303, 34359730176)) + return 1; +#else + printf("skipped\n"); +#endif + + return 0; +}