Index: libc/config/linux/app.h =================================================================== --- libc/config/linux/app.h +++ libc/config/linux/app.h @@ -35,7 +35,9 @@ uintptr_t align; }; -#if defined(LIBC_TARGET_ARCH_IS_X86_64) || defined(LIBC_TARGET_ARCH_IS_AARCH64) +#if defined(LIBC_TARGET_ARCH_IS_X86_64) || \ + defined(LIBC_TARGET_ARCH_IS_AARCH64) || \ + defined(LIBC_TARGET_ARCH_IS_RISCV64) // At the language level, argc is an int. But we use uint64_t as the x86_64 // ABI specifies it as an 8 byte value. Likewise, in the ARM64 ABI, arguments // are usually passed in registers. x0 is a doubleword register, so this is Index: libc/config/linux/riscv64/entrypoints.txt =================================================================== --- libc/config/linux/riscv64/entrypoints.txt +++ libc/config/linux/riscv64/entrypoints.txt @@ -48,11 +48,15 @@ libc.src.string.strcat libc.src.string.strchr libc.src.string.strcmp + libc.src.string.strcoll libc.src.string.strcpy libc.src.string.strcspn libc.src.string.strdup libc.src.string.strerror libc.src.string.strerror_r + libc.src.string.strdup + libc.src.string.strerror + libc.src.string.strerror_r libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen @@ -61,10 +65,12 @@ libc.src.string.strncmp libc.src.string.strncpy libc.src.string.strndup + libc.src.string.strndup libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr libc.src.string.strsignal + libc.src.string.strsignal libc.src.string.strspn libc.src.string.strstr libc.src.string.strtok @@ -75,7 +81,7 @@ libc.src.inttypes.imaxdiv libc.src.inttypes.strtoimax libc.src.inttypes.strtoumax - + # stdlib.h entrypoints libc.src.stdlib.abs libc.src.stdlib.atoi @@ -89,6 +95,8 @@ libc.src.stdlib.llabs libc.src.stdlib.lldiv libc.src.stdlib.qsort + libc.src.stdlib.rand + libc.src.stdlib.srand libc.src.stdlib.strtod libc.src.stdlib.strtof libc.src.stdlib.strtol @@ -106,6 +114,8 @@ # stdio.h entrypoints libc.src.stdio.remove + # libc.src.stdio.sprintf + libc.src.stdio.snprintf # sys/mman.h entrypoints libc.src.sys.mman.madvise @@ -162,6 +172,7 @@ libc.src.unistd.dup libc.src.unistd.dup2 libc.src.unistd.dup3 + libc.src.unistd.execve libc.src.unistd.fchdir libc.src.unistd.fsync libc.src.unistd.ftruncate @@ -170,6 +181,7 @@ libc.src.unistd.getpid libc.src.unistd.getppid libc.src.unistd.getuid + libc.src.unistd.isatty libc.src.unistd.link libc.src.unistd.linkat libc.src.unistd.lseek @@ -189,21 +201,314 @@ ) set(TARGET_LIBM_ENTRYPOINTS + # fenv.h entrypoints + # libc.src.fenv.feclearexcept + # libc.src.fenv.fedisableexcept + # libc.src.fenv.feenableexcept + # libc.src.fenv.fegetenv + # libc.src.fenv.fegetexcept + # libc.src.fenv.fegetexceptflag + # libc.src.fenv.fegetround + # libc.src.fenv.feholdexcept + # libc.src.fenv.fesetenv + # libc.src.fenv.fesetexceptflag + # libc.src.fenv.fesetround + # libc.src.fenv.feraiseexcept + # libc.src.fenv.fetestexcept + # libc.src.fenv.feupdateenv + # math.h entrypoints + # libc.src.math.acosf + # libc.src.math.acoshf + # libc.src.math.asin + # libc.src.math.asinf + # libc.src.math.asinhf + # libc.src.math.atanf + # libc.src.math.atanhf + libc.src.math.copysign + libc.src.math.copysignf + libc.src.math.copysignl + libc.src.math.ceil + libc.src.math.ceilf + libc.src.math.ceill + # libc.src.math.cos + # libc.src.math.coshf + # libc.src.math.cosf + # libc.src.math.expf + # libc.src.math.exp10f + # libc.src.math.exp2f + # libc.src.math.expm1f libc.src.math.fabs libc.src.math.fabsf libc.src.math.fabsl libc.src.math.fdim libc.src.math.fdimf libc.src.math.fdiml - libc.src.math.fmax - libc.src.math.fmaxf - libc.src.math.fmaxl + libc.src.math.floor + libc.src.math.floorf + libc.src.math.floorl + # libc.src.math.fma + libc.src.math.fmaf libc.src.math.fmin libc.src.math.fminf libc.src.math.fminl + libc.src.math.fmax + libc.src.math.fmaxf + libc.src.math.fmaxl + # libc.src.math.fmod + # libc.src.math.fmodf + libc.src.math.frexp + libc.src.math.frexpf + libc.src.math.frexpl + # libc.src.math.hypot + # libc.src.math.hypotf + libc.src.math.ilogb + libc.src.math.ilogbf + libc.src.math.ilogbl + libc.src.math.ldexp + libc.src.math.ldexpf + libc.src.math.ldexpl + # libc.src.math.llrint + # libc.src.math.llrintf + # libc.src.math.llrintl + # libc.src.math.llround + # libc.src.math.llroundf + # libc.src.math.llroundl + # libc.src.math.log10 + # libc.src.math.log10f + # libc.src.math.log1pf + # libc.src.math.log2f + # libc.src.math.logf + libc.src.math.logb + libc.src.math.logbf + libc.src.math.logbl + # libc.src.math.lrint + # libc.src.math.lrintf + # libc.src.math.lrintl + # libc.src.math.lround + # libc.src.math.lroundf + # libc.src.math.lroundl + libc.src.math.modf + libc.src.math.modff + libc.src.math.modfl + libc.src.math.nearbyint + libc.src.math.nearbyintf + libc.src.math.nearbyintl + libc.src.math.nextafter + libc.src.math.nextafterf + libc.src.math.nextafterl + # libc.src.math.pow + libc.src.math.remainderf + libc.src.math.remainder + libc.src.math.remainderl + libc.src.math.remquof + libc.src.math.remquo + libc.src.math.remquol + # libc.src.math.rint + # libc.src.math.rintf + # libc.src.math.rintl + libc.src.math.round + libc.src.math.roundf + libc.src.math.roundl + libc.src.math.scalbn + libc.src.math.scalbnf + libc.src.math.scalbnl + # libc.src.math.sin + # libc.src.math.sincosf + # libc.src.math.sinhf + # libc.src.math.sinf + # libc.src.math.sqrt + # libc.src.math.sqrtf + # libc.src.math.sqrtl + # libc.src.math.tan + # libc.src.math.tanf + # libc.src.math.tanhf + libc.src.math.trunc + libc.src.math.truncf + libc.src.math.truncl ) +if(LLVM_LIBC_FULL_BUILD) + list(APPEND TARGET_LIBC_ENTRYPOINTS + # assert.h entrypoints + # libc.src.assert.__assert_fail + + # dirent.h entrypoints + # libc.src.dirent.closedir + # libc.src.dirent.dirfd + # libc.src.dirent.opendir + # libc.src.dirent.readdir + + # network.h entrypoints + # libc.src.network.htonl + # libc.src.network.htons + # libc.src.network.ntohl + # libc.src.network.ntohs + + # pthread.h entrypoints + # libc.src.pthread.pthread_atfork + # libc.src.pthread.pthread_attr_destroy + # libc.src.pthread.pthread_attr_init + # libc.src.pthread.pthread_attr_getdetachstate + # libc.src.pthread.pthread_attr_getguardsize + # libc.src.pthread.pthread_attr_getstack + # libc.src.pthread.pthread_attr_getstacksize + # libc.src.pthread.pthread_attr_setdetachstate + # libc.src.pthread.pthread_attr_setguardsize + # libc.src.pthread.pthread_attr_setstack + # libc.src.pthread.pthread_attr_setstacksize + # libc.src.pthread.pthread_create + # libc.src.pthread.pthread_detach + # libc.src.pthread.pthread_equal + # libc.src.pthread.pthread_exit + # libc.src.pthread.pthread_getname_np + # libc.src.pthread.pthread_getspecific + # libc.src.pthread.pthread_join + # libc.src.pthread.pthread_key_create + # libc.src.pthread.pthread_key_delete + # libc.src.pthread.pthread_self + # libc.src.pthread.pthread_setname_np + # libc.src.pthread.pthread_mutex_destroy + # libc.src.pthread.pthread_mutex_init + # libc.src.pthread.pthread_mutex_lock + # libc.src.pthread.pthread_mutex_unlock + # libc.src.pthread.pthread_mutexattr_destroy + # libc.src.pthread.pthread_mutexattr_init + # libc.src.pthread.pthread_mutexattr_getpshared + # libc.src.pthread.pthread_mutexattr_getrobust + # libc.src.pthread.pthread_mutexattr_gettype + # libc.src.pthread.pthread_mutexattr_setpshared + # libc.src.pthread.pthread_mutexattr_setrobust + # libc.src.pthread.pthread_mutexattr_settype + # libc.src.pthread.pthread_once + # libc.src.pthread.pthread_setspecific + + # sched.h entrypoints + # libc.src.sched.__sched_getcpucount + + # setjmp.h entrypoints + # libc.src.setjmp.longjmp + # libc.src.setjmp.setjmp + + # stdio.h entrypoints + # libc.src.stdio.clearerr + # libc.src.stdio.clearerr_unlocked + # libc.src.stdio.fclose + # libc.src.stdio.flockfile + # libc.src.stdio.feof + # libc.src.stdio.feof_unlocked + # libc.src.stdio.ferror + # libc.src.stdio.ferror_unlocked + # libc.src.stdio.fgetc + # libc.src.stdio.fgetc_unlocked + # libc.src.stdio.fgets + # libc.src.stdio.fflush + # libc.src.stdio.fopen + # libc.src.stdio.fputc + # libc.src.stdio.fputs + # libc.src.stdio.fopencookie + # libc.src.stdio.fread + # libc.src.stdio.fread_unlocked + # libc.src.stdio.fseek + # libc.src.stdio.ftell + # libc.src.stdio.funlockfile + # libc.src.stdio.fwrite + # libc.src.stdio.fwrite_unlocked + # libc.src.stdio.fprintf + # libc.src.stdio.getc + # libc.src.stdio.getc_unlocked + # libc.src.stdio.printf + # libc.src.stdio.sscanf + # libc.src.stdio.scanf + # libc.src.stdio.fscanf + # libc.src.stdio.putc + # libc.src.stdio.putchar + # libc.src.stdio.puts + # libc.src.stdio.setbuf + # libc.src.stdio.setvbuf + # libc.src.stdio.stderr + # libc.src.stdio.stdin + # libc.src.stdio.stdout + # libc.src.stdio.ungetc + + # stdlib.h entrypoints + # libc.src.stdlib._Exit + # libc.src.stdlib.abort + # libc.src.stdlib.atexit + # libc.src.stdlib.exit + # libc.src.stdlib.getenv + + # signal.h entrypoints + # libc.src.signal.raise + # libc.src.signal.kill + # libc.src.signal.sigaction + # libc.src.signal.sigaltstack + # libc.src.signal.sigdelset + # libc.src.signal.sigaddset + # libc.src.signal.sigemptyset + # libc.src.signal.sigprocmask + # libc.src.signal.sigfillset + # libc.src.signal.signal + + # spawn.h entrypoints + # libc.src.spawn.posix_spawn + # libc.src.spawn.posix_spawn_file_actions_addclose + # libc.src.spawn.posix_spawn_file_actions_adddup2 + # libc.src.spawn.posix_spawn_file_actions_addopen + # libc.src.spawn.posix_spawn_file_actions_destroy + # libc.src.spawn.posix_spawn_file_actions_init + + # threads.h entrypoints + # libc.src.threads.call_once + # libc.src.threads.cnd_broadcast + # libc.src.threads.cnd_destroy + # libc.src.threads.cnd_init + # libc.src.threads.cnd_signal + # libc.src.threads.cnd_wait + # libc.src.threads.mtx_destroy + # libc.src.threads.mtx_init + # libc.src.threads.mtx_lock + # libc.src.threads.mtx_unlock + # libc.src.threads.thrd_create + # libc.src.threads.thrd_current + # libc.src.threads.thrd_detach + # libc.src.threads.thrd_equal + # libc.src.threads.thrd_exit + # libc.src.threads.thrd_join + # libc.src.threads.tss_create + # libc.src.threads.tss_delete + # libc.src.threads.tss_get + # libc.src.threads.tss_set + + # time.h entrypoints + # libc.src.time.asctime + # libc.src.time.asctime_r + # libc.src.time.clock_gettime + # libc.src.time.clock + # libc.src.time.difftime + # libc.src.time.gettimeofday + # libc.src.time.gmtime + # libc.src.time.gmtime_r + # libc.src.time.mktime + # libc.src.time.nanosleep + # libc.src.time.time + + # unistd.h entrypoints + # libc.src.unistd.environ + # libc.src.unistd.execv + # libc.src.unistd.fork + # libc.src.unistd.__llvm_libc_syscall + # libc.src.unistd.getopt + # libc.src.unistd.optarg + # libc.src.unistd.optind + # libc.src.unistd.optopt + # libc.src.unistd.opterr + + # sys/select.h entrypoints + # libc.src.sys.select.select + ) +endif() + set(TARGET_LLVMLIBC_ENTRYPOINTS ${TARGET_LIBC_ENTRYPOINTS} ${TARGET_LIBM_ENTRYPOINTS} Index: libc/config/linux/riscv64/headers.txt =================================================================== --- libc/config/linux/riscv64/headers.txt +++ libc/config/linux/riscv64/headers.txt @@ -1,8 +1,39 @@ set(TARGET_PUBLIC_HEADERS + # libc.include.assert libc.include.ctype + # libc.include.dirent libc.include.errno + libc.include.fcntl + # libc.include.fenv libc.include.inttypes libc.include.math - libc.include.stdlib + # libc.include.pthread + libc.include.sched + # libc.include.signal + # libc.include.spawn + # libc.include.setjmp + # libc.include.stdio + # libc.include.stdlib libc.include.string + libc.include.termios + # libc.include.threads + libc.include.time + libc.include.unistd + + libc.include.arpa_inet + + # libc.include.sys_auxv + # libc.include.sys_ioctl + libc.include.sys_mman + # libc.include.sys_prctl + libc.include.sys_random + libc.include.sys_resource + # libc.include.sys_select + # libc.include.sys_socket + libc.include.sys_stat + # libc.include.sys_syscall + # libc.include.sys_time + # libc.include.sys_types + libc.include.sys_utsname + libc.include.sys_wait ) Index: libc/include/llvm-libc-types/fenv_t.h =================================================================== --- libc/include/llvm-libc-types/fenv_t.h +++ libc/include/llvm-libc-types/fenv_t.h @@ -21,5 +21,8 @@ unsigned char __mxcsr[4]; } fenv_t; #endif +#ifdef __riscv +typedef unsigned int fenv_t; +#endif #endif // __LLVM_LIBC_TYPES_FENV_T_H__ Index: libc/src/__support/FPUtil/FEnvImpl.h =================================================================== --- libc/src/__support/FPUtil/FEnvImpl.h +++ libc/src/__support/FPUtil/FEnvImpl.h @@ -30,6 +30,8 @@ #include "x86_64/FEnvImpl.h" #elif defined(LIBC_TARGET_ARCH_IS_ARM) #include "arm/FEnvImpl.h" +#elif defined(LIBC_TARGET_ARCH_IS_RISCV64) +#include "riscv64/FEnvImpl.h" #else namespace __llvm_libc::fputil { @@ -44,6 +46,10 @@ LIBC_INLINE int raise_except(int) { return 0; } +LIBC_INLINE int enable_except(int) { return 0; } + +LIBC_INLINE int disable_except(int) { return 0; } + LIBC_INLINE int get_round() { return FE_TONEAREST; } LIBC_INLINE int set_round(int) { return 0; } Index: libc/src/__support/FPUtil/FMA.h =================================================================== --- libc/src/__support/FPUtil/FMA.h +++ libc/src/__support/FPUtil/FMA.h @@ -18,6 +18,8 @@ #include "x86_64/FMA.h" #elif defined(LIBC_TARGET_ARCH_IS_AARCH64) #include "aarch64/FMA.h" +#elif defined(LIBC_TARGET_ARCH_IS_RISCV64) +#include "riscv64/FMA.h" #endif #else Index: libc/src/__support/FPUtil/riscv64/FEnvImpl.h =================================================================== --- /dev/null +++ libc/src/__support/FPUtil/riscv64/FEnvImpl.h @@ -0,0 +1,50 @@ +//===-- RISCV64 floating point env manipulation functions --------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_RISCV64_FENVIMPL_H +#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_RISCV64_FENVIMPL_H + +#include "src/__support/macros/attributes.h" // LIBC_INLINE +#include "src/__support/macros/properties/architectures.h" + +#if !defined(LIBC_TARGET_ARCH_IS_RISCV64) +#error "Invalid include" +#endif + +#include +#include + +namespace __llvm_libc { +namespace fputil { + +LIBC_INLINE int clear_except(int) { return 0; } + +LIBC_INLINE int test_except(int) { return 0; } + +LIBC_INLINE int set_except(int) { return 0; } + +LIBC_INLINE int get_except() { return 0; } + +LIBC_INLINE int raise_except(int) { return 0; } + +LIBC_INLINE int enable_except(int) { return 0; } + +LIBC_INLINE int disable_except(int) { return 0; } + +LIBC_INLINE int get_round() { return FE_TONEAREST; } + +LIBC_INLINE int set_round(int) { return 0; } + +LIBC_INLINE int get_env(fenv_t *) { return 0; } + +LIBC_INLINE int set_env(const fenv_t *) { return 0; } + +} // namespace fputil +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_RISCV64_FENVIMPL_H Index: libc/src/__support/FPUtil/riscv64/FMA.h =================================================================== --- /dev/null +++ libc/src/__support/FPUtil/riscv64/FMA.h @@ -0,0 +1,49 @@ +//===-- Aarch64 implementations of the fma function -------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_FMA_H +#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_FMA_H + +#include "src/__support/macros/properties/architectures.h" +#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA + +#if !defined(LIBC_TARGET_ARCH_IS_RISCV64) +#error "Invalid include" +#endif + +#if !defined(LIBC_TARGET_CPU_HAS_FMA) +#error "FMA instructions are not supported" +#endif + +#include "src/__support/CPP/type_traits.h" + +namespace __llvm_libc { +namespace fputil { + +template +cpp::enable_if_t, T> fma(T x, T y, T z) { + float result; + __asm__ __volatile__("fmadd.s %0, %1, %2, %3\n\t" + : "=f"(result) + : "f"(x), "f"(y), "f"(z)); + return result; +} + +template +cpp::enable_if_t, T> fma(T x, T y, T z) { + double result; + __asm__ __volatile__("fmadd.d %0, %1, %2, %3\n\t" + : "=f"(result) + : "f"(x), "f"(y), "f"(z)); + return result; +} + +} // namespace fputil +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_FMA_H Index: libc/src/__support/FPUtil/riscv64/sqrt.h =================================================================== --- /dev/null +++ libc/src/__support/FPUtil/riscv64/sqrt.h @@ -0,0 +1,39 @@ +//===-- Square root of IEEE 754 floating point numbers ----------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_RISCV64_SQRT_H +#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_RISCV64_SQRT_H + +#include "src/__support/common.h" +#include "src/__support/macros/properties/architectures.h" + +#if !defined(LIBC_TARGET_ARCH_IS_RISCV64) +#error "Invalid include" +#endif + +#include "src/__support/FPUtil/generic/sqrt.h" + +namespace __llvm_libc { +namespace fputil { + +template <> LIBC_INLINE float sqrt(float x) { + float result; + __asm__ __volatile__("fsqrt.s %0, %1\n\t" : "=f"(result) : "f"(x)); + return result; +} + +template <> LIBC_INLINE double sqrt(double x) { + double result; + __asm__ __volatile__("fsqrt.d %0, %1\n\t" : "=f"(result) : "f"(x)); + return result; +} + +} // namespace fputil +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_RISCV64_SQRT_H Index: libc/src/__support/FPUtil/sqrt.h =================================================================== --- libc/src/__support/FPUtil/sqrt.h +++ libc/src/__support/FPUtil/sqrt.h @@ -15,6 +15,8 @@ #include "x86_64/sqrt.h" #elif defined(LIBC_TARGET_ARCH_IS_AARCH64) #include "aarch64/sqrt.h" +#elif defined(LIBC_TARGET_ARCH_IS_RISCV64) +#include "riscv64/sqrt.h" #else #include "generic/sqrt.h" Index: libc/src/__support/macros/properties/cpu_features.h =================================================================== --- libc/src/__support/macros/properties/cpu_features.h +++ libc/src/__support/macros/properties/cpu_features.h @@ -36,7 +36,7 @@ #define LIBC_TARGET_CPU_HAS_AVX512BW #endif -#if defined(__ARM_FEATURE_FMA) || defined(__AVX2__) || defined(__FMA__) +#if defined(__ARM_FEATURE_FMA) || defined(__AVX2__) || defined(__FMA__) || defined(__riscv) #define LIBC_TARGET_CPU_HAS_FMA #endif