From 6a4f4a9c774608add4b02f95322518bd2f5f51ee Mon Sep 17 00:00:00 2001
From: Aric Belsito <lluixhi@gmail.com>
Date: Tue, 5 Jan 2016 16:12:18 -0800
Subject: [PATCH 1/5] RISC-V: add riscv32 and riscv64 architecture support

Author: Alex Suykov <alex.suykov@gmail.com>
Author: Aric Belsito <lluixhi@gmail.com>
Author: Michael Clark <mjc@sifive.com>
---
 arch/riscv32/atomic_arch.h             |  35 ++++
 arch/riscv32/bits/alltypes.h.in        |  26 +++
 arch/riscv32/bits/endian.h             |   5 +
 arch/riscv32/bits/fcntl.h              |  38 ++++
 arch/riscv32/bits/fenv.h               |  18 ++
 arch/riscv32/bits/float.h              |  16 ++
 arch/riscv32/bits/ipc.h                |  14 ++
 arch/riscv32/bits/limits.h             |   7 +
 arch/riscv32/bits/msg.h                |  13 ++
 arch/riscv32/bits/posix.h              |   2 +
 arch/riscv32/bits/reg.h                |   8 +
 arch/riscv32/bits/sem.h                |   9 +
 arch/riscv32/bits/setjmp.h             |   1 +
 arch/riscv32/bits/shm.h                |  26 +++
 arch/riscv32/bits/signal.h             | 113 ++++++++++
 arch/riscv32/bits/socket.h             |  33 +++
 arch/riscv32/bits/stat.h               |  18 ++
 arch/riscv32/bits/stdint.h             |  20 ++
 arch/riscv32/bits/syscall.h.in         | 278 +++++++++++++++++++++++++
 arch/riscv32/bits/user.h               |  43 ++++
 arch/riscv32/crt_arch.h                |  18 ++
 arch/riscv32/pthread_arch.h            |  12 ++
 arch/riscv32/reloc.h                   |  27 +++
 arch/riscv32/syscall_arch.h            |  78 +++++++
 arch/riscv64/atomic_arch.h             |  66 ++++++
 arch/riscv64/bits/alltypes.h.in        |  29 +++
 arch/riscv64/bits/endian.h             |   5 +
 arch/riscv64/bits/fcntl.h              |  38 ++++
 arch/riscv64/bits/fenv.h               |  17 ++
 arch/riscv64/bits/float.h              |  16 ++
 arch/riscv64/bits/ipc.h                |  14 ++
 arch/riscv64/bits/limits.h             |   7 +
 arch/riscv64/bits/mman.h               |   1 +
 arch/riscv64/bits/msg.h                |  13 ++
 arch/riscv64/bits/posix.h              |   2 +
 arch/riscv64/bits/reg.h                |   8 +
 arch/riscv64/bits/sem.h                |   9 +
 arch/riscv64/bits/setjmp.h             |   1 +
 arch/riscv64/bits/shm.h                |  26 +++
 arch/riscv64/bits/signal.h             | 113 ++++++++++
 arch/riscv64/bits/socket.h             |  33 +++
 arch/riscv64/bits/stat.h               |  18 ++
 arch/riscv64/bits/stdint.h             |  20 ++
 arch/riscv64/bits/syscall.h.in         | 278 +++++++++++++++++++++++++
 arch/riscv64/bits/user.h               |  43 ++++
 arch/riscv64/crt_arch.h                |  18 ++
 arch/riscv64/pthread_arch.h            |  12 ++
 arch/riscv64/reloc.h                   |  27 +++
 arch/riscv64/syscall_arch.h            |  76 +++++++
 configure                              |   7 +
 crt/riscv32/crti.s                     |  11 +
 crt/riscv32/crtn.s                     |   0
 crt/riscv64/crti.s                     |  11 +
 crt/riscv64/crtn.s                     |   0
 include/elf.h                          |  56 +++++
 src/fenv/riscv32/fenv-sf.c             |   3 +
 src/fenv/riscv32/fenv.S                |  53 +++++
 src/fenv/riscv64/fenv-sf.c             |   3 +
 src/fenv/riscv64/fenv.S                |  53 +++++
 src/internal/riscv32/syscall.s         |  15 ++
 src/internal/riscv64/syscall.s         |  15 ++
 src/ldso/riscv32/dlsym.s               |   6 +
 src/ldso/riscv64/dlsym.s               |   6 +
 src/math/riscv32/copysign.s            |   5 +
 src/math/riscv32/copysignf.s           |   5 +
 src/math/riscv32/fabs.s                |   5 +
 src/math/riscv32/fabsf.s               |   5 +
 src/math/riscv32/fma.s                 |   5 +
 src/math/riscv32/fmaf.s                |   5 +
 src/math/riscv32/fmax.s                |   5 +
 src/math/riscv32/fmaxf.s               |   5 +
 src/math/riscv32/fmin.s                |   5 +
 src/math/riscv32/fminf.s               |   5 +
 src/math/riscv32/sqrt.s                |   5 +
 src/math/riscv32/sqrtf.s               |   5 +
 src/math/riscv64/copysign.s            |   5 +
 src/math/riscv64/copysignf.s           |   5 +
 src/math/riscv64/fabs.s                |   5 +
 src/math/riscv64/fabsf.s               |   5 +
 src/math/riscv64/fma.s                 |   5 +
 src/math/riscv64/fmaf.s                |   5 +
 src/math/riscv64/fmax.s                |   5 +
 src/math/riscv64/fmaxf.s               |   5 +
 src/math/riscv64/fmin.s                |   5 +
 src/math/riscv64/fminf.s               |   5 +
 src/math/riscv64/sqrt.s                |   5 +
 src/math/riscv64/sqrtf.s               |   5 +
 src/setjmp/riscv32/longjmp.S           |  44 ++++
 src/setjmp/riscv32/setjmp.S            |  42 ++++
 src/setjmp/riscv64/longjmp.S           |  44 ++++
 src/setjmp/riscv64/setjmp.S            |  42 ++++
 src/signal/riscv32/restore.s           |   8 +
 src/signal/riscv32/sigsetjmp.s         |  21 ++
 src/signal/riscv64/restore.s           |   8 +
 src/signal/riscv64/sigsetjmp.s         |  21 ++
 src/thread/riscv32/__set_thread_area.s |   6 +
 src/thread/riscv32/__unmapself.s       |   7 +
 src/thread/riscv32/clone.s             |  34 +++
 src/thread/riscv32/syscall_cp.s        |  29 +++
 src/thread/riscv64/__set_thread_area.s |   6 +
 src/thread/riscv64/__unmapself.s       |   7 +
 src/thread/riscv64/clone.s             |  34 +++
 src/thread/riscv64/syscall_cp.s        |  29 +++
 103 files changed, 2489 insertions(+)
 create mode 100644 arch/riscv32/atomic_arch.h
 create mode 100644 arch/riscv32/bits/alltypes.h.in
 create mode 100644 arch/riscv32/bits/endian.h
 create mode 100644 arch/riscv32/bits/fcntl.h
 create mode 100644 arch/riscv32/bits/fenv.h
 create mode 100644 arch/riscv32/bits/float.h
 create mode 100644 arch/riscv32/bits/ipc.h
 create mode 100644 arch/riscv32/bits/limits.h
 create mode 100644 arch/riscv32/bits/msg.h
 create mode 100644 arch/riscv32/bits/posix.h
 create mode 100644 arch/riscv32/bits/reg.h
 create mode 100644 arch/riscv32/bits/sem.h
 create mode 100644 arch/riscv32/bits/setjmp.h
 create mode 100644 arch/riscv32/bits/shm.h
 create mode 100644 arch/riscv32/bits/signal.h
 create mode 100644 arch/riscv32/bits/socket.h
 create mode 100644 arch/riscv32/bits/stat.h
 create mode 100644 arch/riscv32/bits/stdint.h
 create mode 100644 arch/riscv32/bits/syscall.h.in
 create mode 100644 arch/riscv32/bits/user.h
 create mode 100644 arch/riscv32/crt_arch.h
 create mode 100644 arch/riscv32/pthread_arch.h
 create mode 100644 arch/riscv32/reloc.h
 create mode 100644 arch/riscv32/syscall_arch.h
 create mode 100644 arch/riscv64/atomic_arch.h
 create mode 100644 arch/riscv64/bits/alltypes.h.in
 create mode 100644 arch/riscv64/bits/endian.h
 create mode 100644 arch/riscv64/bits/fcntl.h
 create mode 100644 arch/riscv64/bits/fenv.h
 create mode 100644 arch/riscv64/bits/float.h
 create mode 100644 arch/riscv64/bits/ipc.h
 create mode 100644 arch/riscv64/bits/limits.h
 create mode 100644 arch/riscv64/bits/mman.h
 create mode 100644 arch/riscv64/bits/msg.h
 create mode 100644 arch/riscv64/bits/posix.h
 create mode 100644 arch/riscv64/bits/reg.h
 create mode 100644 arch/riscv64/bits/sem.h
 create mode 100644 arch/riscv64/bits/setjmp.h
 create mode 100644 arch/riscv64/bits/shm.h
 create mode 100644 arch/riscv64/bits/signal.h
 create mode 100644 arch/riscv64/bits/socket.h
 create mode 100644 arch/riscv64/bits/stat.h
 create mode 100644 arch/riscv64/bits/stdint.h
 create mode 100644 arch/riscv64/bits/syscall.h.in
 create mode 100644 arch/riscv64/bits/user.h
 create mode 100644 arch/riscv64/crt_arch.h
 create mode 100644 arch/riscv64/pthread_arch.h
 create mode 100644 arch/riscv64/reloc.h
 create mode 100644 arch/riscv64/syscall_arch.h
 create mode 100644 crt/riscv32/crti.s
 create mode 100644 crt/riscv32/crtn.s
 create mode 100644 crt/riscv64/crti.s
 create mode 100644 crt/riscv64/crtn.s
 create mode 100644 src/fenv/riscv32/fenv-sf.c
 create mode 100644 src/fenv/riscv32/fenv.S
 create mode 100644 src/fenv/riscv64/fenv-sf.c
 create mode 100644 src/fenv/riscv64/fenv.S
 create mode 100644 src/internal/riscv32/syscall.s
 create mode 100644 src/internal/riscv64/syscall.s
 create mode 100644 src/ldso/riscv32/dlsym.s
 create mode 100644 src/ldso/riscv64/dlsym.s
 create mode 100644 src/math/riscv32/copysign.s
 create mode 100644 src/math/riscv32/copysignf.s
 create mode 100644 src/math/riscv32/fabs.s
 create mode 100644 src/math/riscv32/fabsf.s
 create mode 100644 src/math/riscv32/fma.s
 create mode 100644 src/math/riscv32/fmaf.s
 create mode 100644 src/math/riscv32/fmax.s
 create mode 100644 src/math/riscv32/fmaxf.s
 create mode 100644 src/math/riscv32/fmin.s
 create mode 100644 src/math/riscv32/fminf.s
 create mode 100644 src/math/riscv32/sqrt.s
 create mode 100644 src/math/riscv32/sqrtf.s
 create mode 100644 src/math/riscv64/copysign.s
 create mode 100644 src/math/riscv64/copysignf.s
 create mode 100644 src/math/riscv64/fabs.s
 create mode 100644 src/math/riscv64/fabsf.s
 create mode 100644 src/math/riscv64/fma.s
 create mode 100644 src/math/riscv64/fmaf.s
 create mode 100644 src/math/riscv64/fmax.s
 create mode 100644 src/math/riscv64/fmaxf.s
 create mode 100644 src/math/riscv64/fmin.s
 create mode 100644 src/math/riscv64/fminf.s
 create mode 100644 src/math/riscv64/sqrt.s
 create mode 100644 src/math/riscv64/sqrtf.s
 create mode 100644 src/setjmp/riscv32/longjmp.S
 create mode 100644 src/setjmp/riscv32/setjmp.S
 create mode 100644 src/setjmp/riscv64/longjmp.S
 create mode 100644 src/setjmp/riscv64/setjmp.S
 create mode 100644 src/signal/riscv32/restore.s
 create mode 100644 src/signal/riscv32/sigsetjmp.s
 create mode 100644 src/signal/riscv64/restore.s
 create mode 100644 src/signal/riscv64/sigsetjmp.s
 create mode 100644 src/thread/riscv32/__set_thread_area.s
 create mode 100644 src/thread/riscv32/__unmapself.s
 create mode 100644 src/thread/riscv32/clone.s
 create mode 100644 src/thread/riscv32/syscall_cp.s
 create mode 100644 src/thread/riscv64/__set_thread_area.s
 create mode 100644 src/thread/riscv64/__unmapself.s
 create mode 100644 src/thread/riscv64/clone.s
 create mode 100644 src/thread/riscv64/syscall_cp.s

--- /dev/null
+++ b/arch/riscv32/atomic_arch.h
@@ -0,0 +1,35 @@
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("fence rw,rw" : : : "memory");
+}
+
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ ("lr.w %0, (%1)" : "=&r"(v) : "r"(p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ ("sc.w %0, %2, (%1)" : "=&r"(r) : "r"(p), "r"(v) : "memory");
+	return !r;
+}
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	int old, tmp;
+	__asm__("1:  lr.w    %0, %2      \n"
+		"    bne     %0, %3, 1f  \n"
+		"    sc.w    %1, %4, %2  \n"
+		"    bnez    %1, 1b      \n"
+		"1:                      \n"
+		: "=&r"(old), "+r"(tmp), "+A"(*p)
+		: "r"(t), "r"(s));
+	return old;
+}
--- /dev/null
+++ b/arch/riscv32/bits/alltypes.h.in
@@ -0,0 +1,26 @@
+#define _Addr int
+#define _Int64 long long
+#define _Reg int
+
+TYPEDEF __builtin_va_list va_list;
+TYPEDEF __builtin_va_list __isoc_va_list;
+
+#ifndef __cplusplus
+TYPEDEF int wchar_t;
+#endif
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
+
+TYPEDEF long time_t;
+TYPEDEF long suseconds_t;
+
+TYPEDEF struct { union { int __i[9]; volatile int __vi[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+TYPEDEF struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } cnd_t;
+TYPEDEF struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t;
+TYPEDEF struct { union { int __i[5]; volatile int __vi[5]; void *__p[5]; } __u; } pthread_barrier_t;
--- /dev/null
+++ b/arch/riscv32/bits/endian.h
@@ -0,0 +1,5 @@
+#if __RISCVEB__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
--- /dev/null
+++ b/arch/riscv32/bits/fcntl.h
@@ -0,0 +1,38 @@
+#define O_CREAT        0100
+#define O_EXCL         0200
+#define O_NOCTTY       0400
+#define O_TRUNC       01000
+#define O_APPEND      02000
+#define O_NONBLOCK    04000
+#define O_DSYNC      010000
+#define O_SYNC     04010000
+#define O_RSYNC    04010000
+#define O_DIRECTORY  040000
+#define O_NOFOLLOW  0100000
+#define O_CLOEXEC  02000000
+
+#define O_ASYNC      020000
+#define O_DIRECT    0200000
+#define O_LARGEFILE 0400000
+#define O_NOATIME  01000000
+#define O_PATH    010000000
+#define O_TMPFILE 020040000
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD  0
+#define F_GETFD  1
+#define F_SETFD  2
+#define F_GETFL  3
+#define F_SETFL  4
+#define F_GETLK  5
+#define F_SETLK  6
+#define F_SETLKW 7
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
--- /dev/null
+++ b/arch/riscv32/bits/fenv.h
@@ -0,0 +1,18 @@
+#define FE_INVALID      16
+#define FE_DIVBYZERO    8
+#define FE_OVERFLOW     4
+#define FE_UNDERFLOW    2
+#define FE_INEXACT      1
+
+#define FE_ALL_EXCEPT   31
+
+#define FE_TONEAREST    0
+#define FE_DOWNWARD     2
+#define FE_UPWARD       3
+#define FE_TOWARDZERO   1
+
+typedef unsigned int fexcept_t;
+
+typedef unsigned int fenv_t;
+
+#define FE_DFL_ENV      ((const fenv_t *) -1)
--- /dev/null
+++ b/arch/riscv32/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+
+#define LDBL_MANT_DIG 113
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 33
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 36
--- /dev/null
+++ b/arch/riscv32/bits/ipc.h
@@ -0,0 +1,14 @@
+struct ipc_perm {
+	key_t __ipc_perm_key;
+	uid_t uid;
+	gid_t gid;
+	uid_t cuid;
+	gid_t cgid;
+	mode_t mode;
+	unsigned short __ipc_perm_seq;
+
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
+
+#define IPC_64 0
--- /dev/null
+++ b/arch/riscv32/bits/limits.h
@@ -0,0 +1,7 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define LONG_BIT 32
+#endif
+
+#define LONG_MAX  0x7fffffffL
+#define LLONG_MAX  0x7fffffffffffffffLL
--- /dev/null
+++ b/arch/riscv32/bits/msg.h
@@ -0,0 +1,13 @@
+struct msqid_ds {
+	struct ipc_perm msg_perm;
+	time_t msg_stime;
+	time_t msg_rtime;
+	time_t msg_ctime;
+	unsigned long msg_cbytes;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msg_lrpid;
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
--- /dev/null
+++ b/arch/riscv32/bits/posix.h
@@ -0,0 +1,2 @@
+# define _POSIX_V6_ILP32_OFFBIG 1
+# define _POSIX_V7_ILP32_OFFBIG 1
--- /dev/null
+++ b/arch/riscv32/bits/reg.h
@@ -0,0 +1,8 @@
+#undef __WORDSIZE
+#define __WORDSIZE 32
+#define REG_PC 0
+#define REG_RA 1
+#define REG_SP 2
+#define REG_TP 4
+#define REG_S0 8
+#define REG_A0 10
--- /dev/null
+++ b/arch/riscv32/bits/sem.h
@@ -0,0 +1,9 @@
+struct semid_ds {
+	struct ipc_perm sem_perm;
+	time_t sem_otime;
+	time_t sem_ctime;
+	unsigned short sem_nsems;
+	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
+	time_t __unused3;
+	time_t __unused4;
+};
--- /dev/null
+++ b/arch/riscv32/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long __jmp_buf[40];
--- /dev/null
+++ b/arch/riscv32/bits/shm.h
@@ -0,0 +1,26 @@
+#define SHMLBA 4096
+
+struct shmid_ds
+{
+	struct ipc_perm shm_perm;
+	size_t shm_segsz;
+	time_t shm_atime;
+	time_t shm_dtime;
+	time_t shm_ctime;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
+
+struct shminfo {
+	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+	int __used_ids;
+	unsigned long shm_tot, shm_rss, shm_swp;
+	unsigned long __swap_attempts, __swap_successes;
+};
+
--- /dev/null
+++ b/arch/riscv32/bits/signal.h
@@ -0,0 +1,113 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+# define MINSIGSTKSZ 2048
+# define SIGSTKSZ 8192
+#endif
+
+/* gregs[0] holds the program counter. */
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[32];
+
+struct __riscv_f_ext_state {
+	unsigned int f[32];
+	unsigned int fcsr;
+};
+
+struct __riscv_d_ext_state {
+	unsigned long long f[32];
+	unsigned int fcsr;
+};
+
+struct __riscv_q_ext_state {
+	unsigned long long f[64] __attribute__((aligned(16)));
+	unsigned int fcsr;
+	unsigned int reserved[3];
+};
+
+union __riscv_fp_state {
+	struct __riscv_f_ext_state f;
+	struct __riscv_d_ext_state d;
+	struct __riscv_q_ext_state q;
+};
+
+typedef union __riscv_fp_state fpregset_t;
+
+typedef struct sigcontext {
+	gregset_t gregs;
+	fpregset_t fpregs;
+} mcontext_t;
+
+#else
+typedef struct {
+	unsigned long gregs[32];
+	unsigned long long fpregs[66];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+};
+
+typedef struct __ucontext
+{
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	sigset_t uc_sigmask;
+	char __unused[1024 / 8 - sizeof(sigset_t)];
+	mcontext_t uc_mcontext;
+} ucontext_t;
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO   4
+#define SA_ONSTACK   0x08000000
+#define SA_RESTART   0x10000000
+#define SA_NODEFER   0x40000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTORER  0x04000000
+
+#endif
+
+#define SIGHUP     1
+#define SIGINT     2
+#define SIGQUIT    3
+#define SIGILL     4
+#define SIGTRAP    5
+#define SIGABRT    6
+#define SIGIOT     SIGABRT
+#define SIGBUS     7
+#define SIGFPE     8
+#define SIGKILL    9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   SIGIO
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG     65
--- /dev/null
+++ b/arch/riscv32/bits/socket.h
@@ -0,0 +1,33 @@
+#include <endian.h>
+
+struct msghdr {
+	void *msg_name;
+	socklen_t msg_namelen;
+	struct iovec *msg_iov;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad1, msg_iovlen;
+#else
+	int msg_iovlen, __pad1;
+#endif
+	void *msg_control;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad2;
+	socklen_t msg_controllen;
+#else
+	socklen_t msg_controllen;
+	int __pad2;
+#endif
+	int msg_flags;
+};
+
+struct cmsghdr {
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad1;
+	socklen_t cmsg_len;
+#else
+	socklen_t cmsg_len;
+	int __pad1;
+#endif
+	int cmsg_level;
+	int cmsg_type;
+};
--- /dev/null
+++ b/arch/riscv32/bits/stat.h
@@ -0,0 +1,18 @@
+struct stat {
+	dev_t st_dev;
+	ino_t st_ino;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	unsigned long __pad;
+	off_t st_size;
+	blksize_t st_blksize;
+	int __pad2;
+	blkcnt_t st_blocks;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	unsigned __unused[2];
+};
--- /dev/null
+++ b/arch/riscv32/bits/stdint.h
@@ -0,0 +1,20 @@
+typedef int32_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef uint32_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST32_MIN  INT32_MIN
+
+#define INT_FAST16_MAX  INT32_MAX
+#define INT_FAST32_MAX  INT32_MAX
+
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN      INT32_MIN
+#define INTPTR_MAX      INT32_MAX
+#define UINTPTR_MAX     UINT32_MAX
+#define PTRDIFF_MIN     INT32_MIN
+#define PTRDIFF_MAX     INT32_MAX
+#define SIZE_MAX        UINT32_MAX
--- /dev/null
+++ b/arch/riscv32/bits/syscall.h.in
@@ -0,0 +1,278 @@
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_io_getevents 4
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR_fcntl 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_renameat 38
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR_statfs 43
+#define __NR_fstatfs 44
+#define __NR_truncate 45
+#define __NR_ftruncate 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR_lseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR_sendfile 71
+#define __NR_pselect6 72
+#define __NR_ppoll 73
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_fstatat 79
+#define __NR_fstat 80
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_timerfd_settime 86
+#define __NR_timerfd_gettime 87
+#define __NR_utimensat 88
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_futex 98
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_gettime 108
+#define __NR_timer_getoverrun 109
+#define __NR_timer_settime 110
+#define __NR_timer_delete 111
+#define __NR_clock_settime 112
+#define __NR_clock_gettime 113
+#define __NR_clock_getres 114
+#define __NR_clock_nanosleep 115
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_sched_rr_get_interval 127
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigtimedwait 137
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrlimit 163
+#define __NR_setrlimit 164
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_gettimeofday 169
+#define __NR_settimeofday 170
+#define __NR_adjtimex 171
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_timedsend 182
+#define __NR_mq_timedreceive 183
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semtimedop 192
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR_mmap 222
+#define __NR_fadvise64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_recvmmsg 243
+#define __NR_arch_specific_syscall 244
+#define __NR_wait4 260
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_clock_adjtime 266
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_sysriscv __NR_arch_specific_syscall
+
--- /dev/null
+++ b/arch/riscv32/bits/user.h
@@ -0,0 +1,43 @@
+struct user_regs_struct {
+	unsigned long pc;
+	unsigned long ra;
+	unsigned long sp;
+	unsigned long gp;
+	unsigned long tp;
+	unsigned long t0;
+	unsigned long t1;
+	unsigned long t2;
+	unsigned long s0;
+	unsigned long s1;
+	unsigned long a0;
+	unsigned long a1;
+	unsigned long a2;
+	unsigned long a3;
+	unsigned long a4;
+	unsigned long a5;
+	unsigned long a6;
+	unsigned long a7;
+	unsigned long s2;
+	unsigned long s3;
+	unsigned long s4;
+	unsigned long s5;
+	unsigned long s6;
+	unsigned long s7;
+	unsigned long s8;
+	unsigned long s9;
+	unsigned long s10;
+	unsigned long s11;
+	unsigned long t3;
+	unsigned long t4;
+	unsigned long t5;
+	unsigned long t6;
+};
+
+struct user_fpregs_struct {
+	double f[32];
+	unsigned int fcsr;
+};
+
+#define ELF_NGREG 32
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+typedef struct user_fpregs_struct elf_fpregset_t;
--- /dev/null
+++ b/arch/riscv32/crt_arch.h
@@ -0,0 +1,18 @@
+__asm__(
+".text\n"
+".global " START "\n"
+".type " START ",%function\n"
+START ":\n"
+".weak __global_pointer$\n"
+".hidden __global_pointer$\n\t"
+".option push\n"
+".option norelax\n\t"
+"lla gp, __global_pointer$\n"
+".option pop\n\t"
+"mv a0, sp\n"
+".weak _DYNAMIC\n"
+".hidden _DYNAMIC\n\t"
+"lla a1, _DYNAMIC\n\t"
+"andi sp, sp, -16\n\t"
+"jal " START "_c"
+);
--- /dev/null
+++ b/arch/riscv32/pthread_arch.h
@@ -0,0 +1,12 @@
+static inline struct pthread *__pthread_self()
+{
+	char *tp;
+	__asm__ __volatile__("mv %0, tp" : "=r"(tp));
+	return (void *)(tp - sizeof(struct pthread));
+}
+
+#define TLS_ABOVE_TP
+#define GAP_ABOVE_TP 0
+#define TP_ADJ(p) ((char *)p + sizeof(struct pthread))
+
+#define MC_PC gregs[0]
--- /dev/null
+++ b/arch/riscv32/reloc.h
@@ -0,0 +1,27 @@
+#if defined __riscv_float_abi_soft
+#define RISCV_FP_SUFFIX "-sf"
+#elif defined __riscv_float_abi_single
+#define RISCV_FP_SUFFIX "-sp"
+#elif defined __riscv_float_abi_double
+#define RISCV_FP_SUFFIX ""
+#endif
+
+#define RISCV_LDSO_HELPER(x) "riscv" #x
+#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x)
+
+#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) RISCV_FP_SUFFIX
+
+#define NO_LEGACY_INITFINI
+
+#define TPOFF_K 0
+
+#define REL_SYMBOLIC    R_RISCV_32
+#define REL_PLT         R_RISCV_JUMP_SLOT
+#define REL_RELATIVE    R_RISCV_RELATIVE
+#define REL_COPY        R_RISCV_COPY
+#define REL_DTPMOD      R_RISCV_TLS_DTPMOD32
+#define REL_DTPOFF      R_RISCV_TLS_DTPREL32
+#define REL_TPOFF       R_RISCV_TLS_TPREL32
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"mv sp, %1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" )
--- /dev/null
+++ b/arch/riscv32/syscall_arch.h
@@ -0,0 +1,78 @@
+#define __SYSCALL_LL_E(x) \
+((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
+((union { long long ll; long l[2]; }){ .ll = x }).l[1]
+#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
+
+#define __asm_syscall(...) \
+	__asm__ __volatile__ ("scall\n\t" \
+	: "+r"(a0) : __VA_ARGS__ : "memory"); \
+	return a0; \
+
+static inline long __syscall0(long n)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0");
+	__asm_syscall("r"(a7))
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	__asm_syscall("r"(a7), "0"(a0))
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1))
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	register long a4 __asm__("a4") = e;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	register long a4 __asm__("a4") = e;
+	register long a5 __asm__("a5") = f;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5))
+}
+
+#define VDSO_USEFUL
+/* We don't have a clock_gettime function.
+#define VDSO_CGT_SYM "__vdso_clock_gettime"
+#define VDSO_CGT_VER "LINUX_2.6" */
--- /dev/null
+++ b/arch/riscv64/atomic_arch.h
@@ -0,0 +1,66 @@
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("fence rw,rw" : : : "memory");
+}
+
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ ("lr.w %0, %1" : "=&r"(v), "+A"(*p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ ("sc.w %0, %2, %1" : "=&r"(r), "+A"(*p) : "r"(v) : "memory");
+return !r;
+}
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	int old, tmp;
+	__asm__("1:  lr.w    %0, %2      \n"
+		"    bne     %0, %3, 1f  \n"
+		"    sc.w    %1, %4, %2  \n"
+		"    bnez    %1, 1b      \n"
+		"1:                      \n"
+		: "=&r"(old), "+r"(tmp), "+A"(*p)
+		: "r"(t), "r"(s));
+	return old;
+}
+
+#define a_ll_p a_ll_p
+static inline void *a_ll_p(volatile void *p)
+{
+	void *v;
+	__asm__ __volatile__ ("lr.d %0, %1" : "=&r"(v), "+A"(*(long *)p));
+	return v;
+}
+
+#define a_sc_p a_sc_p
+static inline int a_sc_p(volatile int *p, void *v)
+{
+	int r;
+	__asm__ __volatile__ ("sc.d %0, %2, %1" : "=&r"(r), "+A"(*(long *)p) : "r"(v) : "memory");
+	return !r;
+}
+
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	void *old;
+	int tmp;
+	__asm__("1:  lr.d    %0, %2      \n"
+		"    bne     %0, %3, 1f  \n"
+		"    sc.d    %1, %4, %2  \n"
+		"    bnez    %1, 1b      \n"
+		"1:                      \n"
+		: "=&r"(old), "+r"(tmp), "+A"(*(long *)p)
+		: "r"(t), "r"(s));
+	return old;
+}
--- /dev/null
+++ b/arch/riscv64/bits/alltypes.h.in
@@ -0,0 +1,29 @@
+#define _Addr long
+#define _Int64 long
+#define _Reg long
+
+TYPEDEF __builtin_va_list va_list;
+TYPEDEF __builtin_va_list __isoc_va_list;
+
+#ifndef __cplusplus
+TYPEDEF int wchar_t;
+#endif
+
+TYPEDEF int blksize_t;
+TYPEDEF unsigned int nlink_t;
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
+
+TYPEDEF long time_t;
+TYPEDEF long suseconds_t;
+
+TYPEDEF struct { union { int __i[14]; volatile int __vi[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
+TYPEDEF struct { union { int __i[10]; volatile int __vi[10]; volatile void *volatile __p[5]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[10]; volatile int __vi[10]; volatile void *volatile __p[5]; } __u; } mtx_t;
+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[6]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[6]; } __u; } cnd_t;
+TYPEDEF struct { union { int __i[14]; volatile int __vi[14]; void *__p[7]; } __u; } pthread_rwlock_t;
+TYPEDEF struct { union { int __i[8]; volatile int __vi[8]; void *__p[4]; } __u; } pthread_barrier_t;
--- /dev/null
+++ b/arch/riscv64/bits/endian.h
@@ -0,0 +1,5 @@
+#if __RISCVEB__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
--- /dev/null
+++ b/arch/riscv64/bits/fcntl.h
@@ -0,0 +1,38 @@
+#define O_CREAT        0100
+#define O_EXCL         0200
+#define O_NOCTTY       0400
+#define O_TRUNC       01000
+#define O_APPEND      02000
+#define O_NONBLOCK    04000
+#define O_DSYNC      010000
+#define O_SYNC     04010000
+#define O_RSYNC    04010000
+#define O_DIRECTORY  040000
+#define O_NOFOLLOW  0100000
+#define O_CLOEXEC  02000000
+
+#define O_ASYNC      020000
+#define O_DIRECT    0200000
+#define O_LARGEFILE 0400000
+#define O_NOATIME  01000000
+#define O_PATH    010000000
+#define O_TMPFILE 020040000
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD  0
+#define F_GETFD  1
+#define F_SETFD  2
+#define F_GETFL  3
+#define F_SETFL  4
+#define F_GETLK  5
+#define F_SETLK  6
+#define F_SETLKW 7
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
--- /dev/null
+++ b/arch/riscv64/bits/fenv.h
@@ -0,0 +1,17 @@
+#define FE_INVALID      16
+#define FE_DIVBYZERO    8
+#define FE_OVERFLOW     4
+#define FE_UNDERFLOW    2
+#define FE_INEXACT      1
+
+#define FE_ALL_EXCEPT   31
+
+#define FE_TONEAREST    0
+#define FE_DOWNWARD     2
+#define FE_UPWARD       3
+#define FE_TOWARDZERO   1
+
+typedef unsigned int fexcept_t;
+typedef unsigned int fenv_t;
+
+#define FE_DFL_ENV      ((const fenv_t *) -1)
--- /dev/null
+++ b/arch/riscv64/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+
+#define LDBL_MANT_DIG 113
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 33
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 36
--- /dev/null
+++ b/arch/riscv64/bits/ipc.h
@@ -0,0 +1,14 @@
+struct ipc_perm {
+	key_t __ipc_perm_key;
+	uid_t uid;
+	gid_t gid;
+	uid_t cuid;
+	gid_t cgid;
+	mode_t mode;
+	unsigned short __ipc_perm_seq;
+
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
+
+#define IPC_64 0
--- /dev/null
+++ b/arch/riscv64/bits/limits.h
@@ -0,0 +1,7 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define LONG_BIT 64
+#endif
+
+#define LONG_MAX  0x7fffffffffffffffL
+#define LLONG_MAX  0x7fffffffffffffffLL
--- /dev/null
+++ b/arch/riscv64/bits/mman.h
@@ -0,0 +1 @@
+#define MAP_32BIT       0x40
--- /dev/null
+++ b/arch/riscv64/bits/msg.h
@@ -0,0 +1,13 @@
+struct msqid_ds {
+	struct ipc_perm msg_perm;
+	time_t msg_stime;
+	time_t msg_rtime;
+	time_t msg_ctime;
+	unsigned long msg_cbytes;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msg_lrpid;
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
--- /dev/null
+++ b/arch/riscv64/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_LP64_OFF64 1
+#define _POSIX_V7_LP64_OFF64 1
--- /dev/null
+++ b/arch/riscv64/bits/reg.h
@@ -0,0 +1,8 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
+#define REG_PC 0
+#define REG_RA 1
+#define REG_SP 2
+#define REG_TP 4
+#define REG_S0 8
+#define REG_A0 10
--- /dev/null
+++ b/arch/riscv64/bits/sem.h
@@ -0,0 +1,9 @@
+struct semid_ds {
+	struct ipc_perm sem_perm;
+	time_t sem_otime;
+	time_t sem_ctime;
+	unsigned short sem_nsems;
+	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
+	time_t __unused3;
+	time_t __unused4;
+};
--- /dev/null
+++ b/arch/riscv64/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long __jmp_buf[28];
--- /dev/null
+++ b/arch/riscv64/bits/shm.h
@@ -0,0 +1,26 @@
+#define SHMLBA 4096
+
+struct shmid_ds
+{
+	struct ipc_perm shm_perm;
+	size_t shm_segsz;
+	time_t shm_atime;
+	time_t shm_dtime;
+	time_t shm_ctime;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
+
+struct shminfo {
+	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+	int __used_ids;
+	unsigned long shm_tot, shm_rss, shm_swp;
+	unsigned long __swap_attempts, __swap_successes;
+};
+
--- /dev/null
+++ b/arch/riscv64/bits/signal.h
@@ -0,0 +1,113 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+# define MINSIGSTKSZ 2048
+# define SIGSTKSZ 8192
+#endif
+
+/* gregs[0] holds the program counter. */
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[32];
+
+struct __riscv_f_ext_state {
+	unsigned int f[32];
+	unsigned int fcsr;
+};
+
+struct __riscv_d_ext_state {
+	unsigned long long f[32];
+	unsigned int fcsr;
+};
+
+struct __riscv_q_ext_state {
+	unsigned long long f[64] __attribute__((aligned(16)));
+	unsigned int fcsr;
+	unsigned int reserved[3];
+};
+
+union __riscv_fp_state {
+	struct __riscv_f_ext_state f;
+	struct __riscv_d_ext_state d;
+	struct __riscv_q_ext_state q;
+};
+
+typedef union __riscv_fp_state fpregset_t;
+
+typedef struct sigcontext {
+	gregset_t gregs;
+	fpregset_t fpregs;
+} mcontext_t;
+
+#else
+typedef struct {
+	unsigned long gregs[32];
+	unsigned long long fpregs[66];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+};
+
+typedef struct __ucontext
+{
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	sigset_t uc_sigmask;
+	char __unused[1024 / 8 - sizeof(sigset_t)];
+	mcontext_t uc_mcontext;
+} ucontext_t;
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO   4
+#define SA_ONSTACK   0x08000000
+#define SA_RESTART   0x10000000
+#define SA_NODEFER   0x40000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTORER  0x04000000
+
+#endif
+
+#define SIGHUP     1
+#define SIGINT     2
+#define SIGQUIT    3
+#define SIGILL     4
+#define SIGTRAP    5
+#define SIGABRT    6
+#define SIGIOT     SIGABRT
+#define SIGBUS     7
+#define SIGFPE     8
+#define SIGKILL    9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   SIGIO
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG     65
--- /dev/null
+++ b/arch/riscv64/bits/socket.h
@@ -0,0 +1,33 @@
+#include <endian.h>
+
+struct msghdr {
+	void *msg_name;
+	socklen_t msg_namelen;
+	struct iovec *msg_iov;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad1, msg_iovlen;
+#else
+	int msg_iovlen, __pad1;
+#endif
+	void *msg_control;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad2;
+	socklen_t msg_controllen;
+#else
+	socklen_t msg_controllen;
+	int __pad2;
+#endif
+	int msg_flags;
+};
+
+struct cmsghdr {
+#if __BYTE_ORDER == __BIG_ENDIAN
+	int __pad1;
+	socklen_t cmsg_len;
+#else
+	socklen_t cmsg_len;
+	int __pad1;
+#endif
+	int cmsg_level;
+	int cmsg_type;
+};
--- /dev/null
+++ b/arch/riscv64/bits/stat.h
@@ -0,0 +1,18 @@
+struct stat {
+	dev_t st_dev;
+	ino_t st_ino;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	unsigned long __pad;
+	off_t st_size;
+	blksize_t st_blksize;
+	int __pad2;
+	blkcnt_t st_blocks;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	unsigned __unused[2];
+};
--- /dev/null
+++ b/arch/riscv64/bits/stdint.h
@@ -0,0 +1,20 @@
+typedef int32_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef uint32_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST32_MIN  INT32_MIN
+
+#define INT_FAST16_MAX  INT32_MAX
+#define INT_FAST32_MAX  INT32_MAX
+
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN      INT64_MIN
+#define INTPTR_MAX      INT64_MAX
+#define UINTPTR_MAX     UINT64_MAX
+#define PTRDIFF_MIN     INT64_MIN
+#define PTRDIFF_MAX     INT64_MAX
+#define SIZE_MAX        UINT64_MAX
--- /dev/null
+++ b/arch/riscv64/bits/syscall.h.in
@@ -0,0 +1,278 @@
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_io_getevents 4
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR_fcntl 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_renameat 38
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR_statfs 43
+#define __NR_fstatfs 44
+#define __NR_truncate 45
+#define __NR_ftruncate 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR_lseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR_sendfile 71
+#define __NR_pselect6 72
+#define __NR_ppoll 73
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_fstatat 79
+#define __NR_fstat 80
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_timerfd_settime 86
+#define __NR_timerfd_gettime 87
+#define __NR_utimensat 88
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_futex 98
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_gettime 108
+#define __NR_timer_getoverrun 109
+#define __NR_timer_settime 110
+#define __NR_timer_delete 111
+#define __NR_clock_settime 112
+#define __NR_clock_gettime 113
+#define __NR_clock_getres 114
+#define __NR_clock_nanosleep 115
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_sched_rr_get_interval 127
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigtimedwait 137
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrlimit 163
+#define __NR_setrlimit 164
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_gettimeofday 169
+#define __NR_settimeofday 170
+#define __NR_adjtimex 171
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_timedsend 182
+#define __NR_mq_timedreceive 183
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semtimedop 192
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR_mmap 222
+#define __NR_fadvise64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_recvmmsg 243
+#define __NR_arch_specific_syscall 244
+#define __NR_wait4 260
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_clock_adjtime 266
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_sysriscv __NR_arch_specific_syscall
+
--- /dev/null
+++ b/arch/riscv64/bits/user.h
@@ -0,0 +1,43 @@
+struct user_regs_struct {
+	unsigned long pc;
+	unsigned long ra;
+	unsigned long sp;
+	unsigned long gp;
+	unsigned long tp;
+	unsigned long t0;
+	unsigned long t1;
+	unsigned long t2;
+	unsigned long s0;
+	unsigned long s1;
+	unsigned long a0;
+	unsigned long a1;
+	unsigned long a2;
+	unsigned long a3;
+	unsigned long a4;
+	unsigned long a5;
+	unsigned long a6;
+	unsigned long a7;
+	unsigned long s2;
+	unsigned long s3;
+	unsigned long s4;
+	unsigned long s5;
+	unsigned long s6;
+	unsigned long s7;
+	unsigned long s8;
+	unsigned long s9;
+	unsigned long s10;
+	unsigned long s11;
+	unsigned long t3;
+	unsigned long t4;
+	unsigned long t5;
+	unsigned long t6;
+};
+
+struct user_fpregs_struct {
+	double f[32];
+	unsigned int fcsr;
+};
+
+#define ELF_NGREG 32
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+typedef struct user_fpregs_struct elf_fpregset_t;
--- /dev/null
+++ b/arch/riscv64/crt_arch.h
@@ -0,0 +1,18 @@
+__asm__(
+".text\n"
+".global " START "\n"
+".type " START ",%function\n"
+START ":\n"
+".weak __global_pointer$\n"
+".hidden __global_pointer$\n"
+".option push\n"
+".option norelax\n\t"
+"lla gp, __global_pointer$\n"
+".option pop\n\t"
+"mv a0, sp\n"
+".weak _DYNAMIC\n"
+".hidden _DYNAMIC\n\t"
+"lla a1, _DYNAMIC\n\t"
+"andi sp, sp, -16\n\t"
+"jal " START "_c"
+);
--- /dev/null
+++ b/arch/riscv64/pthread_arch.h
@@ -0,0 +1,12 @@
+static inline struct pthread *__pthread_self()
+{
+	char *tp;
+	__asm__ __volatile__("mv %0, tp" : "=r"(tp));
+	return (void *)(tp - sizeof(struct pthread));
+}
+
+#define TLS_ABOVE_TP
+#define GAP_ABOVE_TP 0
+#define TP_ADJ(p) ((char *)p + sizeof(struct pthread))
+
+#define MC_PC gregs[0]
--- /dev/null
+++ b/arch/riscv64/reloc.h
@@ -0,0 +1,27 @@
+#if defined __riscv_float_abi_soft
+#define RISCV_FP_SUFFIX "-sf"
+#elif defined __riscv_float_abi_single
+#define RISCV_FP_SUFFIX "-sp"
+#elif defined __riscv_float_abi_double
+#define RISCV_FP_SUFFIX ""
+#endif
+
+#define RISCV_LDSO_HELPER(x) "riscv" #x
+#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x)
+
+#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) RISCV_FP_SUFFIX
+
+#define NO_LEGACY_INITFINI
+
+#define TPOFF_K 0
+
+#define REL_SYMBOLIC    R_RISCV_64
+#define REL_PLT         R_RISCV_JUMP_SLOT
+#define REL_RELATIVE    R_RISCV_RELATIVE
+#define REL_COPY        R_RISCV_COPY
+#define REL_DTPMOD      R_RISCV_TLS_DTPMOD64
+#define REL_DTPOFF      R_RISCV_TLS_DTPREL64
+#define REL_TPOFF       R_RISCV_TLS_TPREL64
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"mv sp, %1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" )
--- /dev/null
+++ b/arch/riscv64/syscall_arch.h
@@ -0,0 +1,76 @@
+#define __SYSCALL_LL_E(x) (x)
+#define __SYSCALL_LL_O(x) (x)
+
+#define __asm_syscall(...) \
+	__asm__ __volatile__ ("scall\n\t" \
+	: "+r"(a0) : __VA_ARGS__ : "memory"); \
+	return a0; \
+
+static inline long __syscall0(long n)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0");
+	__asm_syscall("r"(a7))
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	__asm_syscall("r"(a7), "0"(a0))
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1))
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	register long a4 __asm__("a4") = e;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	register long a4 __asm__("a4") = e;
+	register long a5 __asm__("a5") = f;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5))
+}
+
+#define VDSO_USEFUL
+/* We don't have a clock_gettime function.
+#define VDSO_CGT_SYM "__vdso_clock_gettime"
+#define VDSO_CGT_VER "LINUX_2.6" */
--- a/configure
+++ b/configure
@@ -322,6 +322,8 @@ microblaze*) ARCH=microblaze ;;
 or1k*) ARCH=or1k ;;
 powerpc64*|ppc64*) ARCH=powerpc64 ;;
 powerpc*|ppc*) ARCH=powerpc ;;
+riscv64*) ARCH=riscv64 ;;
+riscv*) ARCH=riscv32 ;;
 sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
 s390x*) ARCH=s390x ;;
 unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
@@ -640,6 +642,11 @@ trycppif __LITTLE_ENDIAN__ "$t" && SUBAR
 trycppif _SOFT_FLOAT "$t" && fail "$0: error: soft-float not supported on powerpc64"
 fi
 
+if test "$ARCH" = "riscv" || test "$ARCH" = "riscv64" ; then
+trycppif "RISCVEB || _RISCVEB || __RISCVEB || __RISCVEB__" "$t" && SUBARCH=${SUBARCH}eb
+trycppif __riscv_soft_float "$t" && SUBARCH=${SUBARCH}-sf
+fi
+
 if test "$ARCH" = "sh" ; then
 tryflag CFLAGS_AUTO -Wa,--isa=any
 trycppif __BIG_ENDIAN__ "$t" && SUBARCH=${SUBARCH}eb
--- /dev/null
+++ b/crt/riscv32/crti.s
@@ -0,0 +1,11 @@
+.section .init
+.global _init
+.type _init,%function
+_init:
+        ret
+
+.section .fini
+.global _fini
+.type _fini,%function
+_fini:
+        ret
--- /dev/null
+++ b/crt/riscv64/crti.s
@@ -0,0 +1,11 @@
+.section .init
+.global _init
+.type _init,%function
+_init:
+        ret
+
+.section .fini
+.global _fini
+.type _fini %function
+_fini:
+        ret
--- a/include/elf.h
+++ b/include/elf.h
@@ -3166,6 +3166,62 @@ enum
 #define R_BPF_NONE		0
 #define R_BPF_MAP_FD		1
 
+#define R_RISCV_NONE            0
+#define R_RISCV_32              1
+#define R_RISCV_64              2
+#define R_RISCV_RELATIVE        3
+#define R_RISCV_COPY            4
+#define R_RISCV_JUMP_SLOT       5
+#define R_RISCV_TLS_DTPMOD32    6
+#define R_RISCV_TLS_DTPMOD64    7
+#define R_RISCV_TLS_DTPREL32    8
+#define R_RISCV_TLS_DTPREL64    9
+#define R_RISCV_TLS_TPREL32     10
+#define R_RISCV_TLS_TPREL64     11
+
+#define R_RISCV_BRANCH          16
+#define R_RISCV_JAL             17
+#define R_RISCV_CALL            18
+#define R_RISCV_CALL_PLT        19
+#define R_RISCV_GOT_HI20        20
+#define R_RISCV_TLS_GOT_HI20    21
+#define R_RISCV_TLS_GD_HI20     22
+#define R_RISCV_PCREL_HI20      23
+#define R_RISCV_PCREL_LO12_I    24
+#define R_RISCV_PCREL_LO12_S    25
+#define R_RISCV_HI20            26
+#define R_RISCV_LO12_I          27
+#define R_RISCV_LO12_S          28
+#define R_RISCV_TPREL_HI20      29
+#define R_RISCV_TPREL_LO12_I    30
+#define R_RISCV_TPREL_LO12_S    31
+#define R_RISCV_TPREL_ADD       32
+#define R_RISCV_ADD8            33
+#define R_RISCV_ADD16           34
+#define R_RISCV_ADD32           35
+#define R_RISCV_ADD64           36
+#define R_RISCV_SUB8            37
+#define R_RISCV_SUB16           38
+#define R_RISCV_SUB32           39
+#define R_RISCV_SUB64           40
+#define R_RISCV_GNU_VTINHERIT   41
+#define R_RISCV_GNU_VTENTRY     42
+#define R_RISCV_ALIGN           43
+#define R_RISCV_RVC_BRANCH      44
+#define R_RISCV_RVC_JUMP        45
+#define R_RISCV_RVC_LUI         46
+#define R_RISCV_GPREL_I         47
+#define R_RISCV_GPREL_S         48
+#define R_RISCV_TPREL_I         49
+#define R_RISCV_TPREL_S         50
+#define R_RISCV_RELAX           51
+#define R_RISCV_SUB6            52
+#define R_RISCV_SET6            53
+#define R_RISCV_SET8            54
+#define R_RISCV_SET16           55
+#define R_RISCV_SET32           56
+#define R_RISCV_32_PCREL        57
+
 #ifdef __cplusplus
 }
 #endif
--- /dev/null
+++ b/src/fenv/riscv32/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifdef __riscv_soft_float
+#include "../fenv.c"
+#endif
--- /dev/null
+++ b/src/fenv/riscv32/fenv.S
@@ -0,0 +1,53 @@
+#ifndef __riscv_soft_float
+
+.global feclearexcept
+.type feclearexcept, %function
+feclearexcept:
+        csrc fflags, a0
+        li a0, 0
+        ret
+
+.global feraiseexcept
+.type feraiseexcept, %function
+feraiseexcept:
+        csrs fflags, a0
+        li a0, 0
+        ret
+
+.global fetestexcept
+.type fetestexcept, %function
+fetestexcept:
+        frflags t0
+        and a0, t0, a0
+        ret
+
+.global fegetround
+.type fegetround, %function
+fegetround:
+        frrm a0
+        ret
+
+.global __fesetround
+.type __fesetround, %function
+__fesetround:
+        fsrm t0, a0
+        li a0, 0
+        ret
+
+.global fegetenv
+.type fegetenv, %function
+fegetenv:
+        frcsr t0
+        sw t0, 0(a0)
+        li a0, 0
+        ret
+
+.global fesetenv
+.type fesetenv, %function
+fesetenv:
+        lw t1, 0(a0)
+        fscsr t0, t1
+        li a0, 0
+        ret
+
+#endif
--- /dev/null
+++ b/src/fenv/riscv64/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifdef __riscv_soft_float
+#include "../fenv.c"
+#endif
--- /dev/null
+++ b/src/fenv/riscv64/fenv.S
@@ -0,0 +1,53 @@
+#ifndef __riscv_soft_float
+
+.global feclearexcept
+.type feclearexcept, %function
+feclearexcept:
+        csrc fflags, a0
+        li a0, 0
+        ret
+
+.global feraiseexcept
+.type feraiseexcept, %function
+feraiseexcept:
+        csrs fflags, a0
+        li a0, 0
+        ret
+
+.global fetestexcept
+.type fetestexcept, %function
+fetestexcept:
+        frflags t0
+        and a0, t0, a0
+        ret
+
+.global fegetround
+.type fegetround, %function
+fegetround:
+        frrm a0
+        ret
+
+.global __fesetround
+.type __fesetround, %function
+__fesetround:
+        fsrm t0, a0
+        li a0, 0
+        ret
+
+.global fegetenv
+.type fegetenv, %function
+fegetenv:
+        frcsr t0
+        sw t0, 0(a0)
+        li a0, 0
+        ret
+
+.global fesetenv
+.type fesetenv, %function
+fesetenv:
+        lw t1, 0(a0)
+        fscsr t0, t1
+        li a0, 0
+        ret
+
+#endif
--- /dev/null
+++ b/src/internal/riscv32/syscall.s
@@ -0,0 +1,15 @@
+.global __syscall
+.hidden __syscall
+.type   __syscall,%function
+__syscall:
+        mv t0, a0
+        mv a0, a1
+        mv a1, a2
+        mv a2, a3
+        mv a3, a4
+        mv a4, a5
+        mv a5, a6
+        mv a6, a7
+        mv a7, t0
+        scall
+        ret
--- /dev/null
+++ b/src/internal/riscv64/syscall.s
@@ -0,0 +1,15 @@
+.global __syscall
+.hidden __syscall
+.type   __syscall,%function
+__syscall:
+        mv t0, a0
+        mv a0, a1
+        mv a1, a2
+        mv a2, a3
+        mv a3, a4
+        mv a4, a5
+        mv a5, a6
+        mv a6, a7
+        mv a7, t0
+        scall
+        ret
--- /dev/null
+++ b/src/ldso/riscv32/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym, %function
+dlsym:
+        mv a2, ra
+        j __dlsym
--- /dev/null
+++ b/src/ldso/riscv64/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym, %function
+dlsym:
+        mv a2, ra
+        j __dlsym
--- /dev/null
+++ b/src/math/riscv32/copysign.s
@@ -0,0 +1,5 @@
+.global copysign
+.type   copysign, %function
+copysign:
+        fsgnj.d fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv32/copysignf.s
@@ -0,0 +1,5 @@
+.global copysignf
+.type   copysignf, %function
+copysignf:
+        fsgnj.s fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv32/fabs.s
@@ -0,0 +1,5 @@
+.global fabs
+.type   fabs, %function
+fabs:
+        fabs.d fa0, fa0
+        ret
--- /dev/null
+++ b/src/math/riscv32/fabsf.s
@@ -0,0 +1,5 @@
+.global fabsf
+.type   fabsf, %function
+fabsf:
+        fabs.s fa0, fa0
+        ret
--- /dev/null
+++ b/src/math/riscv32/fma.s
@@ -0,0 +1,5 @@
+.global fma
+.type   fma, %function
+fma:
+        fmadd.d fa0, fa0, fa1, fa2
+        ret
--- /dev/null
+++ b/src/math/riscv32/fmaf.s
@@ -0,0 +1,5 @@
+.global fmaf
+.type   fmaf, %function
+fmaf:
+        fmadd.s fa0, fa0, fa1, fa2
+        ret
--- /dev/null
+++ b/src/math/riscv32/fmax.s
@@ -0,0 +1,5 @@
+.global fmax
+.type   fmax, %function
+fmax:
+        fmax.d fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv32/fmaxf.s
@@ -0,0 +1,5 @@
+.global fmaxf
+.type   fmaxf, %function
+fmaxf:
+        fmax.s fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv32/fmin.s
@@ -0,0 +1,5 @@
+.global fmin
+.type   fmin, %function
+fmin:
+        fmin.d fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv32/fminf.s
@@ -0,0 +1,5 @@
+.global fminf
+.type   fminf, %function
+fminf:
+        fmin.s fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv32/sqrt.s
@@ -0,0 +1,5 @@
+.global sqrt
+.type   sqrt, %function
+sqrt:
+        fsqrt.d fa0, fa0
+        ret
--- /dev/null
+++ b/src/math/riscv32/sqrtf.s
@@ -0,0 +1,5 @@
+.global sqrtf
+.type   sqrtf, %function
+sqrtf:
+        fsqrt.s fa0, fa0
+        ret
--- /dev/null
+++ b/src/math/riscv64/copysign.s
@@ -0,0 +1,5 @@
+.global copysign
+.type   copysign, %function
+copysign:
+        fsgnj.d fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv64/copysignf.s
@@ -0,0 +1,5 @@
+.global copysignf
+.type   copysignf, %function
+copysignf:
+        fsgnj.s fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv64/fabs.s
@@ -0,0 +1,5 @@
+.global fabs
+.type   fabs, %function
+fabs:
+        fabs.d fa0, fa0
+        ret
--- /dev/null
+++ b/src/math/riscv64/fabsf.s
@@ -0,0 +1,5 @@
+.global fabsf
+.type   fabsf, %function
+fabsf:
+        fabs.s fa0, fa0
+        ret
--- /dev/null
+++ b/src/math/riscv64/fma.s
@@ -0,0 +1,5 @@
+.global fma
+.type   fma, %function
+fma:
+        fmadd.d fa0, fa0, fa1, fa2
+        ret
--- /dev/null
+++ b/src/math/riscv64/fmaf.s
@@ -0,0 +1,5 @@
+.global fmaf
+.type   fmaf, %function
+fmaf:
+        fmadd.s fa0, fa0, fa1, fa2
+        ret
--- /dev/null
+++ b/src/math/riscv64/fmax.s
@@ -0,0 +1,5 @@
+.global fmax
+.type   fmax, %function
+fmax:
+        fmax.d fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv64/fmaxf.s
@@ -0,0 +1,5 @@
+.global fmaxf
+.type   fmaxf, %function
+fmaxf:
+        fmax.s fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv64/fmin.s
@@ -0,0 +1,5 @@
+.global fmin
+.type   fmin, %function
+fmin:
+        fmin.d fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv64/fminf.s
@@ -0,0 +1,5 @@
+.global fminf
+.type   fminf, %function
+fminf:
+        fmin.s fa0, fa0, fa1
+        ret
--- /dev/null
+++ b/src/math/riscv64/sqrt.s
@@ -0,0 +1,5 @@
+.global sqrt
+.type   sqrt, %function
+sqrt:
+        fsqrt.d fa0, fa0
+        ret
--- /dev/null
+++ b/src/math/riscv64/sqrtf.s
@@ -0,0 +1,5 @@
+.global sqrtf
+.type   sqrtf, %function
+sqrtf:
+        fsqrt.s fa0, fa0
+        ret
--- /dev/null
+++ b/src/setjmp/riscv32/longjmp.S
@@ -0,0 +1,44 @@
+.global __longjmp
+.global _longjmp
+.global longjmp
+.type __longjmp, %function
+.type _longjmp,  %function
+.type longjmp,   %function
+__longjmp:
+_longjmp:
+longjmp:
+        lw s0,    0(a0)
+        lw s1,    4(a0)
+        lw s2,    8(a0)
+        lw s3,    12(a0)
+        lw s4,    16(a0)
+        lw s5,    20(a0)
+        lw s6,    24(a0)
+        lw s7,    28(a0)
+        lw s8,    32(a0)
+        lw s9,    36(a0)
+        lw s10,   40(a0)
+        lw s11,   44(a0)
+        lw sp,    48(a0)
+        lw ra,    52(a0)
+
+#ifndef __riscv_soft_float
+        fld fs0,  56(a0)
+        fld fs1,  64(a0)
+        fld fs2,  72(a0)
+        fld fs3,  80(a0)
+        fld fs3,  88(a0)
+        fld fs4,  96(a0)
+        fld fs5,  104(a0)
+        fld fs6,  112(a0)
+        fld fs7,  120(a0)
+        fld fs8,  128(a0)
+        fld fs9,  136(a0)
+        fld fs10, 144(a0)
+        fld fs11, 152(a0)
+#endif
+
+        mv a0, a1
+        bnez a1, 1f
+        li a0, 1
+1:      ret
--- /dev/null
+++ b/src/setjmp/riscv32/setjmp.S
@@ -0,0 +1,42 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp, %function
+.type _setjmp,  %function
+.type setjmp,   %function
+__setjmp:
+_setjmp:
+setjmp:
+        sw s0,    0(a0)
+        sw s1,    4(a0)
+        sw s2,    8(a0)
+        sw s3,    12(a0)
+        sw s4,    16(a0)
+        sw s5,    20(a0)
+        sw s6,    24(a0)
+        sw s7,    28(a0)
+        sw s8,    32(a0)
+        sw s9,    36(a0)
+        sw s10,   40(a0)
+        sw s11,   44(a0)
+        sw sp,    48(a0)
+        sw ra,    52(a0)
+
+#ifndef __riscv_soft_float
+        fsd fs0,  56(a0)
+        fsd fs1,  64(a0)
+        fsd fs2,  72(a0)
+        fsd fs3,  80(a0)
+        fsd fs3,  88(a0)
+        fsd fs4,  96(a0)
+        fsd fs5,  104(a0)
+        fsd fs6,  112(a0)
+        fsd fs7,  120(a0)
+        fsd fs8,  128(a0)
+        fsd fs9,  136(a0)
+        fsd fs10, 144(a0)
+        fsd fs11, 152(a0)
+#endif
+
+        li a0, 0
+        ret
--- /dev/null
+++ b/src/setjmp/riscv64/longjmp.S
@@ -0,0 +1,44 @@
+.global __longjmp
+.global _longjmp
+.global longjmp
+.type __longjmp, %function
+.type _longjmp,  %function
+.type longjmp,   %function
+__longjmp:
+_longjmp:
+longjmp:
+        ld s0,    0(a0)
+        ld s1,    8(a0)
+        ld s2,    16(a0)
+        ld s3,    24(a0)
+        ld s4,    32(a0)
+        ld s5,    40(a0)
+        ld s6,    48(a0)
+        ld s7,    56(a0)
+        ld s8,    64(a0)
+        ld s9,    72(a0)
+        ld s10,   80(a0)
+        ld s11,   88(a0)
+        ld sp,    96(a0)
+        ld ra,    104(a0)
+
+#ifndef __riscv_soft_float
+        fld fs0,  112(a0)
+        fld fs1,  120(a0)
+        fld fs2,  128(a0)
+        fld fs3,  136(a0)
+        fld fs3,  144(a0)
+        fld fs4,  152(a0)
+        fld fs5,  160(a0)
+        fld fs6,  168(a0)
+        fld fs7,  176(a0)
+        fld fs8,  184(a0)
+        fld fs9,  192(a0)
+        fld fs10, 200(a0)
+        fld fs11, 208(a0)
+#endif
+
+        mv a0, a1
+        bnez a1, 1f
+        li a0, 1
+1:      ret
--- /dev/null
+++ b/src/setjmp/riscv64/setjmp.S
@@ -0,0 +1,42 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp, %function
+.type _setjmp,  %function
+.type setjmp,   %function
+__setjmp:
+_setjmp:
+setjmp:
+        sd s0,    0(a0)
+        sd s1,    8(a0)
+        sd s2,    16(a0)
+        sd s3,    24(a0)
+        sd s4,    32(a0)
+        sd s5,    40(a0)
+        sd s6,    48(a0)
+        sd s7,    56(a0)
+        sd s8,    64(a0)
+        sd s9,    72(a0)
+        sd s10,   80(a0)
+        sd s11,   88(a0)
+        sd sp,    96(a0)
+        sd ra,    104(a0)
+
+#ifndef __riscv_soft_float
+        fsd fs0,  112(a0)
+        fsd fs1,  120(a0)
+        fsd fs2,  128(a0)
+        fsd fs3,  136(a0)
+        fsd fs3,  144(a0)
+        fsd fs4,  152(a0)
+        fsd fs5,  160(a0)
+        fsd fs6,  168(a0)
+        fsd fs7,  176(a0)
+        fsd fs8,  184(a0)
+        fsd fs9,  192(a0)
+        fsd fs10, 200(a0)
+        fsd fs11, 208(a0)
+#endif
+
+        li a0, 0
+        ret
--- /dev/null
+++ b/src/signal/riscv32/restore.s
@@ -0,0 +1,8 @@
+.global __restore
+.type __restore, %function
+__restore:
+.global __restore_rt
+.type __restore_rt, %function
+__restore_rt:
+	li a7, 139 # SYS_rt_sigreturn
+	scall
--- /dev/null
+++ b/src/signal/riscv32/sigsetjmp.s
@@ -0,0 +1,21 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp, %function
+.type __sigsetjmp, %function
+sigsetjmp:
+__sigsetjmp:
+        beqz a1, setjmp
+
+        sw ra, 160(a0)
+        sw s0, 164(a0)
+        mv s0, a0
+
+        jal setjmp
+
+        mv a1, a0
+        mv a0, s0
+        lw s0, 164(a0)
+        lw ra, 160(a0)
+
+.hidden __sigsetjmp_tail
+        j __sigsetjmp_tail
--- /dev/null
+++ b/src/signal/riscv64/restore.s
@@ -0,0 +1,8 @@
+.global __restore
+.type __restore, %function
+__restore:
+.global __restore_rt
+.type __restore_rt, %function
+__restore_rt:
+	li a7, 139 # SYS_rt_sigreturn
+	scall
--- /dev/null
+++ b/src/signal/riscv64/sigsetjmp.s
@@ -0,0 +1,21 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp, %function
+.type __sigsetjmp, %function
+sigsetjmp:
+__sigsetjmp:
+        beqz a1, setjmp
+
+        sd ra, 216(a0)
+        sd s0, 224(a0)
+        mv s0, a0
+
+        jal setjmp
+
+        mv a1, a0
+        mv a0, s0
+        ld s0, 224(a0)
+        ld ra, 216(a0)
+
+.hidden __sigsetjmp_tail
+        j __sigsetjmp_tail
--- /dev/null
+++ b/src/thread/riscv32/__set_thread_area.s
@@ -0,0 +1,6 @@
+.global __set_thread_area
+.type   __set_thread_area, %function
+__set_thread_area:
+	mv tp, a0
+	li a0, 0
+	ret
--- /dev/null
+++ b/src/thread/riscv32/__unmapself.s
@@ -0,0 +1,7 @@
+.global __unmapself
+.type __unmapself, %function
+__unmapself:
+       li a7, 215 # SYS_munmap
+       scall
+       li a7, 93  # SYS_exit
+       scall
--- /dev/null
+++ b/src/thread/riscv32/clone.s
@@ -0,0 +1,34 @@
+# __clone(func, stack, flags, arg, ptid, tls, ctid)
+#           a0,    a1,    a2,  a3,   a4,  a5,   a6
+
+# syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+#                a7     a0,    a1,   a2,  a3,   a4
+
+.global __clone
+.type  __clone, %function
+__clone:
+        # Save func and arg to stack
+        addi a1, a1, -16
+        sw a0, 0(a1)
+        sw a3, 4(a1)
+
+        # Call SYS_clone
+        mv a0, a2
+        mv a2, a4
+        mv a3, a5
+        mv a4, a6
+        li a7, 220 # SYS_clone
+        scall
+
+        beqz a0, 1f
+        # Parent
+        ret
+
+        # Child
+1:      lw a1, 0(sp)
+        lw a0, 4(sp)
+        jalr a1
+
+        # Exit
+        li a7, 93 # SYS_exit
+        scall
--- /dev/null
+++ b/src/thread/riscv32/syscall_cp.s
@@ -0,0 +1,29 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm, %function
+__syscall_cp_asm:
+__cp_begin:
+        lw t0, 0(a0)
+        bnez t0, __cp_cancel
+
+        mv t0, a1
+        mv a0, a2
+        mv a1, a3
+        mv a2, a4
+        mv a3, a5
+        mv a4, a6
+        mv a5, a7
+        lw a6, 0(sp)
+        mv a7, t0
+        scall
+__cp_cancel:
+        ret
+__cp_end:
+        j __cancel
--- /dev/null
+++ b/src/thread/riscv64/__set_thread_area.s
@@ -0,0 +1,6 @@
+.global __set_thread_area
+.type   __set_thread_area, %function
+__set_thread_area:
+	mv tp, a0
+	li a0, 0
+	ret
--- /dev/null
+++ b/src/thread/riscv64/__unmapself.s
@@ -0,0 +1,7 @@
+.global __unmapself
+.type __unmapself, %function
+__unmapself:
+       li a7, 215 # SYS_munmap
+       scall
+       li a7, 93  # SYS_exit
+       scall
--- /dev/null
+++ b/src/thread/riscv64/clone.s
@@ -0,0 +1,34 @@
+# __clone(func, stack, flags, arg, ptid, tls, ctid)
+#           a0,    a1,    a2,  a3,   a4,  a5,   a6
+
+# syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+#                a7     a0,    a1,   a2,  a3,   a4
+
+.global __clone
+.type  __clone, %function
+__clone:
+        # Save func and arg to stack
+        addi a1, a1, -16
+        sd a0, 0(a1)
+        sd a3, 8(a1)
+
+        # Call SYS_clone
+        mv a0, a2
+        mv a2, a4
+        mv a3, a5
+        mv a4, a6
+        li a7, 220 # SYS_clone
+        scall
+
+        beqz a0, 1f
+        # Parent
+        ret
+
+        # Child
+1:      ld a1, 0(sp)
+        ld a0, 8(sp)
+        jalr a1
+
+        # Exit
+        li a7, 93 # SYS_exit
+        scall
--- /dev/null
+++ b/src/thread/riscv64/syscall_cp.s
@@ -0,0 +1,29 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm, %function
+__syscall_cp_asm:
+__cp_begin:
+        ld t0, 0(a0)
+        bnez t0, __cp_cancel
+
+        mv t0, a1
+        mv a0, a2
+        mv a1, a3
+        mv a2, a4
+        mv a3, a5
+        mv a4, a6
+        mv a5, a7
+        ld a6, 0(sp)
+        mv a7, t0
+        scall
+__cp_cancel:
+        ret
+__cp_end:
+        j __cancel
