public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 04/15] RISC-V: Thread-Local Storage Support
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
  2017-12-20  7:23 ` [PATCH v2 01/15] RISC-V: Build Infastructure Palmer Dabbelt
  2017-12-20  7:23 ` [PATCH v2 05/15] RISC-V: Generic <string.h> Routines Palmer Dabbelt
@ 2017-12-20  7:23 ` Palmer Dabbelt
  2017-12-20 16:45   ` Joseph Myers
  2017-12-20  7:23 ` [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code Palmer Dabbelt
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:23 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This patch implements TLS support for RISC-V.  We support all four
standard TLS addressing modes (LE, IE, LD, and GD) when running on
Linux via NPTL.  There is a draft psABI document that defines our TLS
ABI here

  https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#thread-local-storage
---
 sysdeps/riscv/dl-tls.h             |  48 ++++++++++++
 sysdeps/riscv/libc-tls.c           |  32 ++++++++
 sysdeps/riscv/nptl/tcb-offsets.sym |   6 ++
 sysdeps/riscv/nptl/tls.h           | 145 +++++++++++++++++++++++++++++++++++++
 sysdeps/riscv/stackinfo.h          |  33 +++++++++
 5 files changed, 264 insertions(+)
 create mode 100644 sysdeps/riscv/dl-tls.h
 create mode 100644 sysdeps/riscv/libc-tls.c
 create mode 100644 sysdeps/riscv/nptl/tcb-offsets.sym
 create mode 100644 sysdeps/riscv/nptl/tls.h
 create mode 100644 sysdeps/riscv/stackinfo.h

diff --git a/sysdeps/riscv/dl-tls.h b/sysdeps/riscv/dl-tls.h
new file mode 100644
index 000000000000..34005b226421
--- /dev/null
+++ b/sysdeps/riscv/dl-tls.h
@@ -0,0 +1,48 @@
+/* Thread-local storage handling in the ELF dynamic linker.  RISC-V version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Type used for the representation of TLS information in the GOT.  */
+typedef struct
+{
+  unsigned long int ti_module;
+  unsigned long int ti_offset;
+} tls_index;
+
+/* The thread pointer points to the first static TLS block.  */
+#define TLS_TP_OFFSET		0
+
+/* Dynamic thread vector pointers point 0x800 past the start of each
+   TLS block.  */
+#define TLS_DTV_OFFSET		0x800
+
+/* Compute the value for a GOTTPREL reloc.  */
+#define TLS_TPREL_VALUE(sym_map, sym) \
+  ((sym_map)->l_tls_offset + (sym)->st_value - TLS_TP_OFFSET)
+
+/* Compute the value for a DTPREL reloc.  */
+#define TLS_DTPREL_VALUE(sym) \
+  ((sym)->st_value - TLS_DTV_OFFSET)
+
+extern void *__tls_get_addr (tls_index *ti);
+
+# define GET_ADDR_OFFSET	(ti->ti_offset + TLS_DTV_OFFSET)
+# define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/riscv/libc-tls.c b/sysdeps/riscv/libc-tls.c
new file mode 100644
index 000000000000..415d6d0ab0c5
--- /dev/null
+++ b/sysdeps/riscv/libc-tls.c
@@ -0,0 +1,32 @@
+/* Thread-local storage handling in the ELF dynamic linker.  RISC-V version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <csu/libc-tls.c>
+#include <dl-tls.h>
+
+/* On RISC-V, linker optimizations are not required, so __tls_get_addr
+   can be called even in statically linked binaries.  In this case module
+   must be always 1 and PT_TLS segment exist in the binary, otherwise it
+   would not link.  */
+
+void *
+__tls_get_addr (tls_index *ti)
+{
+  dtv_t *dtv = THREAD_DTV ();
+  return (char *) dtv[1].pointer.val + GET_ADDR_OFFSET;
+}
diff --git a/sysdeps/riscv/nptl/tcb-offsets.sym b/sysdeps/riscv/nptl/tcb-offsets.sym
new file mode 100644
index 000000000000..a989031aad7a
--- /dev/null
+++ b/sysdeps/riscv/nptl/tcb-offsets.sym
@@ -0,0 +1,6 @@
+#include <sysdep.h>
+#include <tls.h>
+
+#define thread_offsetof(mem)	(long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
+
+MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h
new file mode 100644
index 000000000000..0ddf68af49ba
--- /dev/null
+++ b/sysdeps/riscv/nptl/tls.h
@@ -0,0 +1,145 @@
+/* Definition for thread-local data handling.  NPTL/RISC-V version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _RISCV_TLS_H
+#define _RISCV_TLS_H	1
+
+#include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+# include <dl-dtv.h>
+
+register void* __thread_self asm("tp");
+# define READ_THREAD_POINTER() ({ __thread_self; })
+
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* The TP points to the start of the thread blocks.  */
+# define TLS_DTV_AT_TP	1
+# define TLS_TCB_AT_TP	0
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  Because our TCB is before the thread
+   pointer, we don't need this.  */
+# define TLS_INIT_TCB_SIZE	0
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN	__alignof__ (struct pthread)
+
+/* This is the size of the TCB.  Because our TCB is before the thread
+   pointer, we don't need this.  */
+# define TLS_TCB_SIZE		0
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN		__alignof__ (struct pthread)
+
+/* This is the size we need before TCB - actually, it includes the TCB.  */
+# define TLS_PRE_TCB_SIZE \
+  (sizeof (struct pthread)						      \
+   + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+
+/* The thread pointer tp points to the end of the TCB.
+   The pthread_descr structure is immediately in front of the TCB. */
+# define TLS_TCB_OFFSET	0
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+# define INSTALL_DTV(tcbp, dtvp) \
+  (((tcbhead_t *) (tcbp))[-1].dtv = (dtvp) + 1)
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) \
+  (THREAD_DTV() = (dtv))
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(tcbp) \
+  (((tcbhead_t *) (tcbp))[-1].dtv)
+
+/* Code to initially initialize the thread pointer. */
+# define TLS_INIT_TP(tcbp) \
+  ({ __thread_self = (char*)tcbp + TLS_TCB_OFFSET; NULL; })
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  (((tcbhead_t *) (READ_THREAD_POINTER () - TLS_TCB_OFFSET))[-1].dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+ ((struct pthread *) (READ_THREAD_POINTER ()			     \
+		      - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
+
+/* Value passed to 'clone' for initialization of the thread register.  */
+# define TLS_DEFINE_INIT_TP(tp, pd) \
+  void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
+
+/* Access to data in the thread descriptor is easy.  */
+# define THREAD_GETMEM(descr, member) \
+  descr->member
+# define THREAD_GETMEM_NC(descr, member, idx) \
+  descr->member[idx]
+# define THREAD_SETMEM(descr, member, value) \
+  descr->member = (value)
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+  descr->member[idx] = (value)
+
+/* l_tls_offset == 0 is perfectly valid, so we have to use some different
+   value to mean unset l_tls_offset.  */
+# define NO_TLS_OFFSET		-1
+
+/* Get and set the global scope generation counter in struct pthread.  */
+# define THREAD_GSCOPE_FLAG_UNUSED 0
+# define THREAD_GSCOPE_FLAG_USED   1
+# define THREAD_GSCOPE_FLAG_WAIT   2
+# define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
+    }									     \
+  while (0)
+# define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+# define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
+#endif /* __ASSEMBLER__ */
+
+#endif	/* tls.h */
diff --git a/sysdeps/riscv/stackinfo.h b/sysdeps/riscv/stackinfo.h
new file mode 100644
index 000000000000..19c40c72bb12
--- /dev/null
+++ b/sysdeps/riscv/stackinfo.h
@@ -0,0 +1,33 @@
+/* Stack environment definitions for RISC-V.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This file contains a bit of information about the stack allocation
+   of the processor.  */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H	1
+
+#include <elf.h>
+
+/* On RISC-V the stack grows down.  */
+#define _STACK_GROWS_DOWN	1
+
+/* Default to a non-executable stack.  */
+#define DEFAULT_STACK_PERMS (PF_R|PF_W)
+
+#endif	/* stackinfo.h */
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (2 preceding siblings ...)
  2017-12-20  7:23 ` [PATCH v2 04/15] RISC-V: Thread-Local Storage Support Palmer Dabbelt
@ 2017-12-20  7:23 ` Palmer Dabbelt
  2017-12-20 16:38   ` Joseph Myers
  2017-12-20  7:23 ` [PATCH v2 02/15] RISC-V: ABI Implementation Palmer Dabbelt
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:23 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This patch contains the various bits of support used by the C startup
code and the dynamic loader when running on a RISC-V system.  This
contains the implementation of our PLT entries, various ld.so hooks, and
_start.  This does not contain any Linux-specific code.
---
 sysdeps/riscv/bits/link.h   |  56 ++++++++
 sysdeps/riscv/crti.S        |  32 +++++
 sysdeps/riscv/dl-machine.h  | 308 ++++++++++++++++++++++++++++++++++++++++++++
 sysdeps/riscv/ldsodefs.h    |  47 +++++++
 sysdeps/riscv/linkmap.h     |   4 +
 sysdeps/riscv/sotruss-lib.c |  51 ++++++++
 sysdeps/riscv/start.S       |  80 ++++++++++++
 sysdeps/riscv/tst-audit.h   |  23 ++++
 8 files changed, 601 insertions(+)
 create mode 100644 sysdeps/riscv/bits/link.h
 create mode 100644 sysdeps/riscv/crti.S
 create mode 100644 sysdeps/riscv/dl-machine.h
 create mode 100644 sysdeps/riscv/ldsodefs.h
 create mode 100644 sysdeps/riscv/linkmap.h
 create mode 100644 sysdeps/riscv/sotruss-lib.c
 create mode 100644 sysdeps/riscv/start.S
 create mode 100644 sysdeps/riscv/tst-audit.h

diff --git a/sysdeps/riscv/bits/link.h b/sysdeps/riscv/bits/link.h
new file mode 100644
index 000000000000..067f2298e115
--- /dev/null
+++ b/sysdeps/riscv/bits/link.h
@@ -0,0 +1,56 @@
+/* Machine-specific declarations for dynamic linker interface.  RISC-V version.
+   Copyright (C) 2005-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+typedef struct La_riscv_regs
+{
+  unsigned long lr_reg[8]; /* a0 - a7 */
+  double lr_fpreg[8]; /* fa0 - fa7 */
+  unsigned long lr_ra;
+  unsigned long lr_sp;
+} La_riscv_regs;
+
+/* Return values for calls from PLT on RISC-V.  */
+typedef struct La_riscv_retval
+{
+  unsigned long lrv_a0;
+  unsigned long lrv_a1;
+  double lrv_fa0;
+  double lrv_fa1;
+} La_riscv_retval;
+
+__BEGIN_DECLS
+
+extern ElfW(Addr) la_riscv_gnu_pltenter (ElfW(Sym) *__sym, unsigned int __ndx,
+					 uintptr_t *__refcook,
+					 uintptr_t *__defcook,
+					 La_riscv_regs *__regs,
+					 unsigned int *__flags,
+					 const char *__symname,
+					 long int *__framesizep);
+extern unsigned int la_riscv_gnu_pltexit (ElfW(Sym) *__sym, unsigned int __ndx,
+					  uintptr_t *__refcook,
+					  uintptr_t *__defcook,
+					  const La_riscv_regs *__inregs,
+					  La_riscv_retval *__outregs,
+					  const char *__symname);
+
+__END_DECLS
diff --git a/sysdeps/riscv/crti.S b/sysdeps/riscv/crti.S
new file mode 100644
index 000000000000..c28222578ef0
--- /dev/null
+++ b/sysdeps/riscv/crti.S
@@ -0,0 +1,32 @@
+/* Facilitate pthread initialization using init_array.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+#include <sys/asm.h>
+
+#ifdef PREINIT_FUNCTION
+
+#if PREINIT_FUNCTION_WEAK
+# error PREINIT_FUNCTION_WEAK is unsupported
+#endif
+
+	.section .init_array, "aw"
+	.dc.a PREINIT_FUNCTION
+
+#endif
diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
new file mode 100644
index 000000000000..520882159783
--- /dev/null
+++ b/sysdeps/riscv/dl-machine.h
@@ -0,0 +1,308 @@
+/* Machine-dependent ELF dynamic relocation inline functions.  RISC-V version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "RISC-V"
+
+#include <entry.h>
+#include <elf/elf.h>
+#include <sys/asm.h>
+#include <dl-tls.h>
+
+#ifndef _RTLD_PROLOGUE
+# define _RTLD_PROLOGUE(entry)						\
+	".globl\t" __STRING(entry) "\n\t"				\
+	".type\t" __STRING(entry) ", @function\n"			\
+	__STRING(entry) ":\n\t"
+#endif
+
+#ifndef _RTLD_EPILOGUE
+# define _RTLD_EPILOGUE(entry)						\
+	".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t"
+#endif
+
+#define ELF_MACHINE_JMP_SLOT R_RISCV_JUMP_SLOT
+
+#define elf_machine_type_class(type)				\
+  ((ELF_RTYPE_CLASS_PLT * ((type) == ELF_MACHINE_JMP_SLOT	\
+     || (__WORDSIZE == 32 && (type) == R_RISCV_TLS_DTPREL32)	\
+     || (__WORDSIZE == 32 && (type) == R_RISCV_TLS_DTPMOD32)	\
+     || (__WORDSIZE == 32 && (type) == R_RISCV_TLS_TPREL32)	\
+     || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_DTPREL64)	\
+     || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_DTPMOD64)	\
+     || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_TPREL64)))	\
+   | (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY)))
+
+#define ELF_MACHINE_NO_REL 1
+#define ELF_MACHINE_NO_RELA 0
+
+/* Return nonzero iff ELF header is compatible with the running host.  */
+static inline int __attribute_used__
+elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
+{
+  return ehdr->e_machine == EM_RISCV;
+}
+
+/* Return the link-time address of _DYNAMIC.  */
+static inline ElfW(Addr)
+elf_machine_dynamic (void)
+{
+  extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_ __attribute__((visibility("hidden")));
+  return _GLOBAL_OFFSET_TABLE_;
+}
+
+#define STRINGXP(X) __STRING(X)
+#define STRINGXV(X) STRINGV_(X)
+#define STRINGV_(...) # __VA_ARGS__
+
+/* Return the run-time load address of the shared object.  */
+static inline ElfW(Addr)
+elf_machine_load_address (void)
+{
+  ElfW(Addr) load_addr;
+  asm ("lla %0, _DYNAMIC" : "=r"(load_addr));
+  return load_addr - elf_machine_dynamic ();
+}
+
+/* Initial entry point code for the dynamic linker.
+   The C function `_dl_start' is the real entry point;
+   its return value is the user program's entry point. */
+
+#define RTLD_START asm (\
+	".text\n\
+	" _RTLD_PROLOGUE(ENTRY_POINT) "\
+	mv a0, sp\n\
+	jal _dl_start\n\
+	# Stash user entry point in s0.\n\
+	mv s0, a0\n\
+	# See if we were run as a command with the executable file\n\
+	# name as an extra leading argument.\n\
+	lw a0, _dl_skip_args\n\
+	# Load the original argument count.\n\
+	" STRINGXP(REG_L) " a1, 0(sp)\n\
+	# Subtract _dl_skip_args from it.\n\
+	sub a1, a1, a0\n\
+	# Adjust the stack pointer to skip _dl_skip_args words.\n\
+	sll a0, a0, " STRINGXP (PTRLOG) "\n\
+	add sp, sp, a0\n\
+	# Save back the modified argument count.\n\
+	" STRINGXP(REG_S) " a1, 0(sp)\n\
+	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
+	" STRINGXP(REG_L) " a0, _rtld_local\n\
+	add a2, sp, " STRINGXP (SZREG) "\n\
+	sll a3, a1, " STRINGXP (PTRLOG) "\n\
+	add a3, a3, a2\n\
+	add a3, a3, " STRINGXP (SZREG) "\n\
+	# Call the function to run the initializers.\n\
+	jal _dl_init\n\
+	# Pass our finalizer function to _start.\n\
+	lla a0, _dl_fini\n\
+	# Jump to the user entry point.\n\
+	jr s0\n\
+	" _RTLD_EPILOGUE(ENTRY_POINT) "\
+	.previous" \
+);
+
+/* Names of the architecture-specific auditing callback functions.  */
+#define ARCH_LA_PLTENTER riscv_gnu_pltenter
+#define ARCH_LA_PLTEXIT riscv_gnu_pltexit
+
+/* Bias .got.plt entry by the offset requested by the PLT header. */
+#define elf_machine_plt_value(map, reloc, value) (value)
+
+static inline ElfW(Addr)
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
+		       const ElfW(Rela) *reloc,
+		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
+{
+  return *reloc_addr = value;
+}
+
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE_MAP
+
+/* Perform a relocation described by R_INFO at the location pointed to
+   by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
+   MAP is the object containing the reloc.  */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
+		  const ElfW(Sym) *sym, const struct r_found_version *version,
+		  void *const reloc_addr, int skip_ifunc)
+{
+  ElfW(Addr) r_info = reloc->r_info;
+  const unsigned long int r_type = ELFW(R_TYPE) (r_info);
+  ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
+  const ElfW(Sym) *const __attribute__((unused)) refsym = sym;
+  struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+  ElfW(Addr) value = 0;
+  if (sym_map != NULL)
+    value = sym_map->l_addr + sym->st_value + reloc->r_addend;
+
+  switch (r_type)
+    {
+#ifndef RTLD_BOOTSTRAP
+    case __WORDSIZE == 64 ? R_RISCV_TLS_DTPMOD64 : R_RISCV_TLS_DTPMOD32:
+      if (sym_map)
+	*addr_field = sym_map->l_tls_modid;
+      break;
+
+    case __WORDSIZE == 64 ? R_RISCV_TLS_DTPREL64 : R_RISCV_TLS_DTPREL32:
+      if (sym != NULL)
+	*addr_field = TLS_DTPREL_VALUE (sym) + reloc->r_addend;
+      break;
+
+    case __WORDSIZE == 64 ? R_RISCV_TLS_TPREL64 : R_RISCV_TLS_TPREL32:
+      if (sym != NULL)
+	{
+	  CHECK_STATIC_TLS (map, sym_map);
+	  *addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend;
+	}
+      break;
+
+    case R_RISCV_COPY:
+      {
+	if (__builtin_expect (sym == NULL, 0))
+	  /* This can happen in trace mode if an object could not be
+	     found.  */
+	  break;
+
+	/* Handle TLS copy relocations.  */
+	if (__glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_TLS))
+	  {
+	    /* There's nothing to do if the symbol is in .tbss.  */
+	    if (__glibc_likely (sym->st_value >= sym_map->l_tls_initimage_size))
+	      break;
+	    value += (ElfW(Addr)) sym_map->l_tls_initimage - sym_map->l_addr;
+	  }
+
+	size_t size = sym->st_size;
+	if (__builtin_expect (sym->st_size != refsym->st_size, 0))
+	  {
+	    const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+	    if (sym->st_size > refsym->st_size)
+	      size = refsym->st_size;
+	    if (sym->st_size > refsym->st_size || GLRO(dl_verbose))
+	      _dl_error_printf ("\
+  %s: Symbol `%s' has different size in shared object, consider re-linking\n",
+				rtld_progname ?: "<program name unknown>",
+				strtab + refsym->st_name);
+	  }
+
+	memcpy (reloc_addr, (void *)value, size);
+	break;
+      }
+#endif
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+    case R_RISCV_RELATIVE:
+      {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+	/* This is defined in rtld.c, but nowhere in the static libc.a;
+	   make the reference weak so static programs can still link.
+	   This declaration cannot be done when compiling rtld.c
+	   (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+	   common defn for _dl_rtld_map, which is incompatible with a
+	   weak decl in the same file.  */
+#  ifndef SHARED
+	weak_extern (GL(dl_rtld_map));
+#  endif
+	if (map != &GL(dl_rtld_map)) /* Already done in rtld itself.  */
+# endif
+	  *addr_field = map->l_addr + reloc->r_addend;
+      break;
+    }
+#endif
+
+    case R_RISCV_JUMP_SLOT:
+    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
+      *addr_field = value;
+      break;
+
+    case R_RISCV_NONE:
+      break;
+
+    default:
+      _dl_reloc_bad_type (map, r_type, 0);
+      break;
+    }
+}
+
+auto inline void
+__attribute__((always_inline))
+elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
+			  void *const reloc_addr)
+{
+  *(ElfW(Addr) *)reloc_addr = l_addr + reloc->r_addend;
+}
+
+auto inline void
+__attribute__((always_inline))
+elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
+		      const ElfW(Rela) *reloc, int skip_ifunc)
+{
+  ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+  const unsigned int r_type = ELFW(R_TYPE) (reloc->r_info);
+
+  /* Check for unexpected PLT reloc type.  */
+  if (__builtin_expect (r_type == R_RISCV_JUMP_SLOT, 1))
+    {
+      if (__builtin_expect (map->l_mach.plt, 0) == 0)
+	{
+	  if (l_addr)
+	    *reloc_addr += l_addr;
+	}
+      else
+	*reloc_addr = map->l_mach.plt;
+    }
+  else
+    _dl_reloc_bad_type (map, r_type, 1);
+}
+
+/* Set up the loaded object described by L so its stub function
+   will jump to the on-demand fixup code __dl_runtime_resolve.  */
+
+auto inline int
+__attribute__((always_inline))
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+#ifndef RTLD_BOOTSTRAP
+  /* If using PLTs, fill in the first two entries of .got.plt.  */
+  if (l->l_info[DT_JMPREL])
+    {
+      extern void _dl_runtime_resolve (void) __attribute__((visibility("hidden")));
+      ElfW(Addr) *gotplt = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
+      /* If a library is prelinked but we have to relocate anyway,
+	 we have to be able to undo the prelinking of .got.plt.
+	 The prelinker saved the address of .plt for us here.  */
+      if (gotplt[1])
+	l->l_mach.plt = gotplt[1] + l->l_addr;
+      gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve;
+      gotplt[1] = (ElfW(Addr)) l;
+    }
+#endif
+
+  return lazy;
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/sysdeps/riscv/ldsodefs.h b/sysdeps/riscv/ldsodefs.h
new file mode 100644
index 000000000000..db993df80a9a
--- /dev/null
+++ b/sysdeps/riscv/ldsodefs.h
@@ -0,0 +1,47 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _RISCV_LDSODEFS_H
+#define _RISCV_LDSODEFS_H 1
+
+#include <elf.h>
+
+struct La_riscv_regs;
+struct La_riscv_retval;
+
+#define ARCH_PLTENTER_MEMBERS						\
+    Elf64_Addr (*riscv_gnu_pltenter) (Elf64_Sym *, unsigned int,	\
+				      uintptr_t *, uintptr_t *,		\
+				      const struct La_riscv_regs *,	\
+				      unsigned int *, const char *name,	\
+				      long int *framesizep);
+
+#define ARCH_PLTEXIT_MEMBERS						\
+    unsigned int (*riscv_gnu_pltexit) (Elf64_Sym *, unsigned int,	\
+				       uintptr_t *, uintptr_t *,	\
+				       const struct La_riscv_regs *,	\
+				       struct La_riscv_retval *,	\
+				       const char *);
+
+/* The RISC-V ABI specifies that the dynamic section has to be read-only.  */
+
+#define DL_RO_DYN_SECTION 1
+
+#include_next <ldsodefs.h>
+
+#endif
diff --git a/sysdeps/riscv/linkmap.h b/sysdeps/riscv/linkmap.h
new file mode 100644
index 000000000000..a6df7821e675
--- /dev/null
+++ b/sysdeps/riscv/linkmap.h
@@ -0,0 +1,4 @@
+struct link_map_machine
+  {
+    ElfW(Addr) plt; /* Address of .plt */
+  };
diff --git a/sysdeps/riscv/sotruss-lib.c b/sysdeps/riscv/sotruss-lib.c
new file mode 100644
index 000000000000..ef57f6885a96
--- /dev/null
+++ b/sysdeps/riscv/sotruss-lib.c
@@ -0,0 +1,51 @@
+/* Override generic sotruss-lib.c to define actual functions for RISC-V.
+   Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define HAVE_ARCH_PLTENTER
+#define HAVE_ARCH_PLTEXIT
+
+#include <elf/sotruss-lib.c>
+
+ElfW(Addr)
+la_riscv_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)),
+		       unsigned int ndx __attribute__ ((unused)),
+		       uintptr_t *refcook, uintptr_t *defcook,
+		       La_riscv_regs *regs, unsigned int *flags,
+		       const char *symname, long int *framesizep)
+{
+  print_enter (refcook, defcook, symname,
+	       regs->lr_reg[0], regs->lr_reg[1], regs->lr_reg[2],
+	       *flags);
+
+  /* No need to copy anything, we will not need the parameters in any case.  */
+  *framesizep = 0;
+
+  return sym->st_value;
+}
+
+unsigned int
+la_riscv_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+		      uintptr_t *defcook,
+		      const struct La_riscv_regs *inregs,
+		      struct La_riscv_retval *outregs,
+		      const char *symname)
+{
+  print_exit (refcook, defcook, symname, outregs->lrv_a0);
+
+  return 0;
+}
diff --git a/sysdeps/riscv/start.S b/sysdeps/riscv/start.S
new file mode 100644
index 000000000000..5438ae2886b2
--- /dev/null
+++ b/sysdeps/riscv/start.S
@@ -0,0 +1,80 @@
+/* Startup code compliant to the ELF RISC-V ABI.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define __ASSEMBLY__ 1
+#include <entry.h>
+#include <sysdep.h>
+#include <sys/asm.h>
+
+/* The entry point's job is to call __libc_start_main.  Per the ABI,
+   a0 contains the address of a function to be passed to atexit.
+   __libc_start_main wants this in a5.  */
+
+ENTRY(ENTRY_POINT)
+	call  .Lload_gp
+	mv    a5, a0  /* rtld_fini */
+	lla   a0, main
+	REG_L a1, 0(sp)      /* argc */
+	addi  a2, sp, SZREG  /* argv */
+	andi  sp, sp, ALMASK /* Align stack. */
+	lla   a3, __libc_csu_init
+	lla   a4, __libc_csu_fini
+	mv    a6, sp  /* stack_end */
+
+	tail  __libc_start_main@plt
+END(ENTRY_POINT)
+
+/* Dynamic links need the global pointer to be initialized prior to calling
+   any shared library's initializers, so we use preinit_array to load it.
+   This doesn't cut it for static links, though, since the global pointer
+   needs to be initialized before calling __libc_start_main in that case.
+   So we redundantly initialize it at the beginning of _start.  */
+
+.Lload_gp:
+.option push
+.option norelax
+	lla   gp, __global_pointer$
+.option pop
+	ret
+
+	.section .preinit_array,"aw"
+	.dc.a .Lload_gp
+
+/* Define a symbol for the first piece of initialized data.  */
+	.data
+	.globl __data_start
+__data_start:
+	.weak data_start
+	data_start = __data_start
diff --git a/sysdeps/riscv/tst-audit.h b/sysdeps/riscv/tst-audit.h
new file mode 100644
index 000000000000..d49d577f68a6
--- /dev/null
+++ b/sysdeps/riscv/tst-audit.h
@@ -0,0 +1,23 @@
+/* Definitions for testing PLT entry/exit auditing.  RISC-V version.
+   Copyright (C) 2005-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define pltenter la_riscv_gnu_pltenter
+#define pltexit la_riscv_gnu_pltexit
+#define La_regs La_riscv_regs
+#define La_retval La_riscv_retval
+#define int_retval lrv_a0
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
@ 2017-12-20  7:23 ` Palmer Dabbelt
  2017-12-20 14:05   ` Dmitry V. Levin
                     ` (2 more replies)
  2017-12-20  7:23 ` [PATCH v2 05/15] RISC-V: Generic <string.h> Routines Palmer Dabbelt
                   ` (16 subsequent siblings)
  17 siblings, 3 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:23 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This patch lays out the top-level orginazition of the RISC-V port.  It
contains all the Implies files as well as various other fragments of
build infastructure for the RISC-V port.  This contains the only change
to a shared file: config.h.in.

RISC-V is a family of base ISAs with optional extensions.  The base ISAs
are RV32I and RV64I, which are 32-bit and 64-bit integer-only ISAs.
Support for these live in sysdeps/riscv/rv{32,64}.  In addition to these
ISAs, our glibc port supports most of the currently-defined extensions:
the A extension for atomics, the M extension for multiplication, the C
extension for compressed instructions, and the F/D extensions for
single/double precision IEEE floating-point.  Most of these extensions
are handled by GCC, but glibc defines various floating-point wrappers
(in sysdeps/riscv/rv{32,64}/rv{f,d}) and emulation routines (in
sysdeps/riscv/soft-fp).

We support running glibc-based programs on Linux, the suppor for which
lives in sysdeps/unix/sysv/linux/riscv.
---
 config.h.in                                  |   5 +
 nptl/Makefile                                |   4 +
 sysdeps/riscv/Implies                        |   5 +
 sysdeps/riscv/Makefile                       |  49 +++++++
 sysdeps/riscv/Versions                       |   4 +
 sysdeps/riscv/configure                      |   5 +
 sysdeps/riscv/configure.ac                   |   4 +
 sysdeps/riscv/nptl/Makefile                  |  26 ++++
 sysdeps/riscv/preconfigure                   |  54 +++++++
 sysdeps/riscv/rv32/Implies-after             |   1 +
 sysdeps/riscv/rv32/rvd/Implies               |   2 +
 sysdeps/riscv/rv32/rvf/Implies               |   1 +
 sysdeps/riscv/rv64/Implies-after             |   1 +
 sysdeps/riscv/rv64/rvd/Implies               |   3 +
 sysdeps/riscv/rv64/rvf/Implies               |   1 +
 sysdeps/unix/sysv/linux/riscv/Implies        |   1 +
 sysdeps/unix/sysv/linux/riscv/Makefile       | 100 +++++++++++++
 sysdeps/unix/sysv/linux/riscv/Versions       |   5 +
 sysdeps/unix/sysv/linux/riscv/configure      | 210 +++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/configure.ac   |  33 +++++
 sysdeps/unix/sysv/linux/riscv/rv32/Implies   |   3 +
 sysdeps/unix/sysv/linux/riscv/rv64/Implies   |   3 +
 sysdeps/unix/sysv/linux/riscv/rv64/Makefile  |   4 +
 sysdeps/unix/sysv/linux/riscv/shlib-versions |  17 +++
 24 files changed, 541 insertions(+)
 create mode 100644 sysdeps/riscv/Implies
 create mode 100644 sysdeps/riscv/Makefile
 create mode 100644 sysdeps/riscv/Versions
 create mode 100644 sysdeps/riscv/configure
 create mode 100644 sysdeps/riscv/configure.ac
 create mode 100644 sysdeps/riscv/nptl/Makefile
 create mode 100644 sysdeps/riscv/preconfigure
 create mode 100644 sysdeps/riscv/rv32/Implies-after
 create mode 100644 sysdeps/riscv/rv32/rvd/Implies
 create mode 100644 sysdeps/riscv/rv32/rvf/Implies
 create mode 100644 sysdeps/riscv/rv64/Implies-after
 create mode 100644 sysdeps/riscv/rv64/rvd/Implies
 create mode 100644 sysdeps/riscv/rv64/rvf/Implies
 create mode 100644 sysdeps/unix/sysv/linux/riscv/Implies
 create mode 100644 sysdeps/unix/sysv/linux/riscv/Makefile
 create mode 100644 sysdeps/unix/sysv/linux/riscv/Versions
 create mode 100755 sysdeps/unix/sysv/linux/riscv/configure
 create mode 100644 sysdeps/unix/sysv/linux/riscv/configure.ac
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/Implies
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/Implies
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/Makefile
 create mode 100644 sysdeps/unix/sysv/linux/riscv/shlib-versions

diff --git a/config.h.in b/config.h.in
index d928e7dd867c..b0b7cf26cb4b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -100,6 +100,11 @@
 /* AArch64 big endian ABI */
 #undef HAVE_AARCH64_BE
 
+/* RISC-V integer ABI for ld.so.  */
+#undef RISCV_ABI_XLEN
+
+/* RISC-V floating-point ABI for ld.so.  */
+#undef RISCV_ABI_FLEN
 
 /* Linux specific: minimum supported kernel version.  */
 #undef	__LINUX_KERNEL_VERSION
diff --git a/nptl/Makefile b/nptl/Makefile
index 60d036a1ea42..f62d19febf1d 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -611,6 +611,10 @@ else
 librt = $(common-objpfx)rt/librt.a
 endif
 
+# `make check' sometimes triggers a rebuild of librt.so using this Makefile,
+# which ignores librt's dependence on libpthread
+$(common-objpfx)rt/librt.so: $(shared-thread-library)
+
 $(objpfx)tst-cancel17: $(librt)
 $(objpfx)tst-cancelx17: $(librt)
 $(objpfx)tst-_res1mod2.so: $(objpfx)tst-_res1mod1.so
diff --git a/sysdeps/riscv/Implies b/sysdeps/riscv/Implies
new file mode 100644
index 000000000000..c88325b8be16
--- /dev/null
+++ b/sysdeps/riscv/Implies
@@ -0,0 +1,5 @@
+init_array
+
+ieee754/ldbl-128
+ieee754/dbl-64
+ieee754/flt-32
diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile
new file mode 100644
index 000000000000..64060531a1d5
--- /dev/null
+++ b/sysdeps/riscv/Makefile
@@ -0,0 +1,49 @@
+ifneq ($(all-rtld-routines),)
+CFLAGS-rtld.c += -mno-plt
+CFLAGS-dl-load.c += -mno-plt
+CFLAGS-dl-cache.c += -mno-plt
+CFLAGS-dl-lookup.c += -mno-plt
+CFLAGS-dl-object.c += -mno-plt
+CFLAGS-dl-reloc.c += -mno-plt
+CFLAGS-dl-deps.c += -mno-plt
+CFLAGS-dl-runtime.c += -mno-plt
+CFLAGS-dl-error.c += -mno-plt
+CFLAGS-dl-init.c += -mno-plt
+CFLAGS-dl-fini.c += -mno-plt
+CFLAGS-dl-debug.c += -mno-plt
+CFLAGS-dl-misc.c += -mno-plt
+CFLAGS-dl-version.c += -mno-plt
+CFLAGS-dl-profile.c += -mno-plt
+CFLAGS-dl-conflict.c += -mno-plt
+CFLAGS-dl-tls.c += -mno-plt
+CFLAGS-dl-origin.c += -mno-plt
+CFLAGS-dl-scope.c += -mno-plt
+CFLAGS-dl-execstack.c += -mno-plt
+CFLAGS-dl-caller.c += -mno-plt
+CFLAGS-dl-open.c += -mno-plt
+CFLAGS-dl-close.c += -mno-plt
+CFLAGS-dl-sysdep.c += -mno-plt
+CFLAGS-dl-environ.c += -mno-plt
+CFLAGS-dl-minimal.c += -mno-plt
+CFLAGS-dl-static.c += -mno-plt
+CFLAGS-dl-brk.c += -mno-plt
+CFLAGS-dl-sbrk.c += -mno-plt
+CFLAGS-dl-getcwd.c += -mno-plt
+CFLAGS-dl-openat64.c += -mno-plt
+CFLAGS-dl-opendir.c += -mno-plt
+CFLAGS-dl-fxstatat64.c += -mno-plt
+endif
+
+CFLAGS-closedir.c += -mno-plt
+CFLAGS-exit.c += -mno-plt
+CFLAGS-cxa_atexit.c += -mno-plt
+
+ifeq ($(subdir),misc)
+sysdep_headers += sys/asm.h
+endif
+
+ASFLAGS-.os += $(pic-ccflag)
+
+ifeq ($(subdir),math)
+CPPFLAGS += -I../soft-fp
+endif
diff --git a/sysdeps/riscv/Versions b/sysdeps/riscv/Versions
new file mode 100644
index 000000000000..aafa348a2395
--- /dev/null
+++ b/sysdeps/riscv/Versions
@@ -0,0 +1,4 @@
+libc {
+  GLIBC_2.27 {
+  }
+}
diff --git a/sysdeps/riscv/configure b/sysdeps/riscv/configure
new file mode 100644
index 000000000000..8dc92a2e7920
--- /dev/null
+++ b/sysdeps/riscv/configure
@@ -0,0 +1,5 @@
+# This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/riscv/elf.
+
+$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
diff --git a/sysdeps/riscv/configure.ac b/sysdeps/riscv/configure.ac
new file mode 100644
index 000000000000..34f62d4b4b82
--- /dev/null
+++ b/sysdeps/riscv/configure.ac
@@ -0,0 +1,4 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/riscv/elf.
+
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/sysdeps/riscv/nptl/Makefile b/sysdeps/riscv/nptl/Makefile
new file mode 100644
index 000000000000..5a4be9b00e93
--- /dev/null
+++ b/sysdeps/riscv/nptl/Makefile
@@ -0,0 +1,26 @@
+# Makefile for sysdeps/riscv/nptl.
+# Copyright (C) 2005-2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
+
+ifeq ($(subdir),nptl)
+libpthread-sysdep_routines += nptl-sysdep
+libpthread-shared-only-routines += nptl-sysdep
+endif
diff --git a/sysdeps/riscv/preconfigure b/sysdeps/riscv/preconfigure
new file mode 100644
index 000000000000..e118a5ed28f6
--- /dev/null
+++ b/sysdeps/riscv/preconfigure
@@ -0,0 +1,54 @@
+case "$machine" in
+riscv*)
+    xlen=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_xlen \(.*\)/\1/p'`
+    flen=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_flen \(.*\)/\1/p'`
+    float_abi=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __riscv_float_abi_\([^ ]*\) .*/\1/p'`
+    
+    case "$xlen" in
+    32 | 64)
+    	;;
+    *)
+    	echo "Unable to determine XLEN" >&2
+    	exit 1
+    	;;
+    esac
+    
+    case "$flen" in
+    64)
+    	float_machine=rvd
+    	;;
+    32)
+    	float_machine=rvf
+    	;;
+    "")
+    	float_machine=
+    	;;
+    *)
+    	echo "Unable to determine FLEN" >&2
+    	exit 1
+    	;;
+    esac
+    
+    case "$float_abi" in
+    soft)
+    	abi_flen=0
+    	;;
+    single)
+    	abi_flen=32
+    	;;
+    double)
+    	abi_flen=64
+    	;;
+    *)
+    	echo "Unable to determine floating-point ABI" >&2
+    	exit 1
+    	;;
+    esac
+    
+    base_machine=riscv
+    machine=riscv/rv$xlen/$float_machine
+    
+    $as_echo "#define RISCV_ABI_XLEN $xlen" >>confdefs.h
+    $as_echo "#define RISCV_ABI_FLEN $abi_flen" >>confdefs.h
+    ;;
+esac
diff --git a/sysdeps/riscv/rv32/Implies-after b/sysdeps/riscv/rv32/Implies-after
new file mode 100644
index 000000000000..39a34c5f5743
--- /dev/null
+++ b/sysdeps/riscv/rv32/Implies-after
@@ -0,0 +1 @@
+wordsize-32
diff --git a/sysdeps/riscv/rv32/rvd/Implies b/sysdeps/riscv/rv32/rvd/Implies
new file mode 100644
index 000000000000..9438838e98b9
--- /dev/null
+++ b/sysdeps/riscv/rv32/rvd/Implies
@@ -0,0 +1,2 @@
+riscv/rvd
+riscv/rvf
diff --git a/sysdeps/riscv/rv32/rvf/Implies b/sysdeps/riscv/rv32/rvf/Implies
new file mode 100644
index 000000000000..66c401443b8c
--- /dev/null
+++ b/sysdeps/riscv/rv32/rvf/Implies
@@ -0,0 +1 @@
+riscv/rvf
diff --git a/sysdeps/riscv/rv64/Implies-after b/sysdeps/riscv/rv64/Implies-after
new file mode 100644
index 000000000000..a8cae95f9d46
--- /dev/null
+++ b/sysdeps/riscv/rv64/Implies-after
@@ -0,0 +1 @@
+wordsize-64
diff --git a/sysdeps/riscv/rv64/rvd/Implies b/sysdeps/riscv/rv64/rvd/Implies
new file mode 100644
index 000000000000..42fb132d12ae
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/Implies
@@ -0,0 +1,3 @@
+riscv/rv64/rvf
+riscv/rvd
+riscv/rvf
diff --git a/sysdeps/riscv/rv64/rvf/Implies b/sysdeps/riscv/rv64/rvf/Implies
new file mode 100644
index 000000000000..66c401443b8c
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvf/Implies
@@ -0,0 +1 @@
+riscv/rvf
diff --git a/sysdeps/unix/sysv/linux/riscv/Implies b/sysdeps/unix/sysv/linux/riscv/Implies
new file mode 100644
index 000000000000..6faec7011569
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/Implies
@@ -0,0 +1 @@
+riscv/nptl
diff --git a/sysdeps/unix/sysv/linux/riscv/Makefile b/sysdeps/unix/sysv/linux/riscv/Makefile
new file mode 100644
index 000000000000..0214869e46ab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/Makefile
@@ -0,0 +1,100 @@
+ifeq ($(subdir),elf)
+sysdep_routines	+= dl-vdso
+ifeq ($(build-shared),yes)
+# This is needed for DSO loading from static binaries.
+sysdep-dl-routines += dl-static
+endif
+endif
+
+ifeq ($(subdir),misc)
+sysdep_headers += sys/cachectl.h
+sysdep_routines += flush-icache
+endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
+
+abi-variants := ilp32 ilp32f ilp32d lp64 lp64f lp64d
+
+ifeq (,$(filter $(default-abi),$(abi-variants)))
+$(error Unknown ABI $(default-abi), must be one of $(abi-variants))
+endif
+
+abi-ilp32-options     := -D__SIZEOF_INT__=4
+abi-ilp32-condition   := (__SIZEOF_INT__ == 4)
+abi-ilp32-options     += -D__SIZEOF_LONG__=4
+abi-ilp32-condition   += && (__SIZEOF_LONG__ == 4)
+abi-ilp32-options     += -D__SIZEOF_POINTER__=4
+abi-ilp32-condition   += && (__SIZEOF_POINTER__ == 4)
+abi-ilp32-options     += -D__riscv_float_abi_soft
+abi-ilp32-condition   += && (defined __riscv_float_abi_soft)
+abi-ilp32-options     += -U__riscv_float_abi_single
+abi-ilp32-condition   += && (!defined __riscv_float_abi_single)
+abi-ilp32-options     += -U__riscv_float_abi_double
+abi-ilp32-condition   += && (!defined __riscv_float_abi_double)
+
+abi-ilp32f-options    := -D__SIZEOF_INT__=4
+abi-ilp32f-condition  := (__SIZEOF_INT__ == 4)
+abi-ilp32f-options    += -D__SIZEOF_LONG__=4
+abi-ilp32f-condition  += && (__SIZEOF_LONG__ == 4)
+abi-ilp32f-options    += -D__SIZEOF_POINTER__=4
+abi-ilp32f-condition  += && (__SIZEOF_POINTER__ == 4)
+abi-ilp32f-options    += -U__riscv_float_abi_soft
+abi-ilp32f-condition  += && (!defined __riscv_float_abi_soft)
+abi-ilp32f-options    += -D__riscv_float_abi_single
+abi-ilp32f-condition  += && (defined __riscv_float_abi_single)
+abi-ilp32f-options    += -U__riscv_float_abi_double
+abi-ilp32f-condition  += && (!defined __riscv_float_abi_double)
+
+abi-ilp32d-options    := -D__SIZEOF_INT__=4
+abi-ilp32d-condition  := (__SIZEOF_INT__ == 4)
+abi-ilp32d-options    += -D__SIZEOF_LONG__=4
+abi-ilp32d-condition  += && (__SIZEOF_LONG__ == 4)
+abi-ilp32d-options    += -D__SIZEOF_POINTER__=4
+abi-ilp32d-condition  += && (__SIZEOF_POINTER__ == 4)
+abi-ilp32d-options    += -U__riscv_float_abi_soft
+abi-ilp32d-condition  += && (!defined __riscv_float_abi_soft)
+abi-ilp32d-options    += -U__riscv_float_abi_single
+abi-ilp32d-condition  += && (!defined __riscv_float_abi_single)
+abi-ilp32d-options    += -D__riscv_float_abi_double
+abi-ilp32d-condition  += && (defined __riscv_float_abi_double)
+
+abi-lp64-options      := -D__SIZEOF_INT__=4
+abi-lp64-condition    := (__SIZEOF_INT__ == 4)
+abi-lp64-options      += -D__SIZEOF_LONG__=8
+abi-lp64-condition    += && (__SIZEOF_LONG__ == 8)
+abi-lp64-options      += -D__SIZEOF_POINTER__=8
+abi-lp64-condition    += && (__SIZEOF_POINTER__ == 8)
+abi-lp64-options      += -D__riscv_float_abi_soft
+abi-lp64-condition    += && (defined __riscv_float_abi_soft)
+abi-lp64-options      += -U__riscv_float_abi_single
+abi-lp64-condition    += && (!defined __riscv_float_abi_single)
+abi-lp64-options      += -U__riscv_float_abi_double
+abi-lp64-condition    += && (!defined __riscv_float_abi_double)
+
+abi-lp64f-options     := -D__SIZEOF_INT__=4
+abi-lp64f-condition   := (__SIZEOF_INT__ == 4)
+abi-lp64f-options     += -D__SIZEOF_LONG__=8
+abi-lp64f-condition   += && (__SIZEOF_LONG__ == 8)
+abi-lp64f-options     += -D__SIZEOF_POINTER__=8
+abi-lp64f-condition   += && (__SIZEOF_POINTER__ == 8)
+abi-lp64f-options     += -U__riscv_float_abi_soft
+abi-lp64f-condition   += && (!defined __riscv_float_abi_soft)
+abi-lp64f-options     += -D__riscv_float_abi_single
+abi-lp64f-condition   += && (defined __riscv_float_abi_single)
+abi-lp64f-options     += -U__riscv_float_abi_double
+abi-lp64f-condition   += && (!defined __riscv_float_abi_double)
+
+abi-lp64d-options     := -D__SIZEOF_INT__=4
+abi-lp64d-condition   := (__SIZEOF_INT__ == 4)
+abi-lp64d-options     += -D__SIZEOF_LONG__=8
+abi-lp64d-condition   += && (__SIZEOF_LONG__ == 8)
+abi-lp64d-options     += -D__SIZEOF_POINTER__=8
+abi-lp64d-condition   += && (__SIZEOF_POINTER__ == 8)
+abi-lp64d-options     += -U__riscv_float_abi_soft
+abi-lp64d-condition   += && (!defined __riscv_float_abi_soft)
+abi-lp64d-options     += -U__riscv_float_abi_single
+abi-lp64d-condition   += && (!defined __riscv_float_abi_single)
+abi-lp64d-options     += -D__riscv_float_abi_double
+abi-lp64d-condition   += && (defined __riscv_float_abi_double)
diff --git a/sysdeps/unix/sysv/linux/riscv/Versions b/sysdeps/unix/sysv/linux/riscv/Versions
new file mode 100644
index 000000000000..f61c7e31a0ae
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/Versions
@@ -0,0 +1,5 @@
+libc {
+  GLIBC_2.27 {
+    __riscv_flush_icache;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/riscv/configure b/sysdeps/unix/sysv/linux/riscv/configure
new file mode 100755
index 000000000000..4dd085a7b0b6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/configure
@@ -0,0 +1,210 @@
+# This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/unix/sysv/linux/riscv.
+
+arch_minimum_kernel=4.15.0
+
+libc_cv_riscv_int_abi=no
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "4 8 8" >/dev/null 2>&1; then :
+  libc_cv_riscv_int_abi=lp64
+fi
+rm -f conftest*
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "4 4 4" >/dev/null 2>&1; then :
+  libc_cv_riscv_int_abi=ilp32
+fi
+rm -f conftest*
+
+if test $libc_cv_riscv_int_abi = no; then
+  as_fn_error $? "Unable to determine integer ABI" "$LINENO" 5
+fi
+
+libc_cv_riscv_float_abi=no
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __riscv_float_abi_double
+		   yes
+		   #endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_riscv_float_abi=d
+fi
+rm -f conftest*
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __riscv_float_abi_single
+		   yes
+		   #endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_riscv_float_abi=f
+fi
+rm -f conftest*
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __riscv_float_abi_soft
+		   yes
+		   #endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_riscv_float_abi=
+fi
+rm -f conftest*
+
+if test $libc_cv_riscv_float_abi = no; then
+  as_fn_error $? "Unable to determine floating-point ABI" "$LINENO" 5
+fi
+
+config_vars="$config_vars
+default-abi = $libc_cv_riscv_int_abi$libc_cv_riscv_float_abi"
diff --git a/sysdeps/unix/sysv/linux/riscv/configure.ac b/sysdeps/unix/sysv/linux/riscv/configure.ac
new file mode 100644
index 000000000000..b9a6207d48d6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/configure.ac
@@ -0,0 +1,33 @@
+sinclude(./aclocal.m4)dnl Autoconf lossage
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/unix/sysv/linux/riscv.
+
+arch_minimum_kernel=4.15.0
+
+libc_cv_riscv_int_abi=no
+AC_EGREP_CPP(4 8 8, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__
+  ], libc_cv_riscv_int_abi=lp64)
+AC_EGREP_CPP(4 4 4, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__
+  ], libc_cv_riscv_int_abi=ilp32)
+if test $libc_cv_riscv_int_abi = no; then
+  AC_MSG_ERROR([Unable to determine integer ABI])
+fi
+
+libc_cv_riscv_float_abi=no
+AC_EGREP_CPP(yes, [#ifdef __riscv_float_abi_double
+		   yes
+		   #endif
+  ],libc_cv_riscv_float_abi=d)
+AC_EGREP_CPP(yes, [#ifdef __riscv_float_abi_single
+		   yes
+		   #endif
+  ],libc_cv_riscv_float_abi=f)
+AC_EGREP_CPP(yes, [#ifdef __riscv_float_abi_soft
+		   yes
+		   #endif
+  ],libc_cv_riscv_float_abi=)
+if test $libc_cv_riscv_float_abi = no; then
+  AC_MSG_ERROR([Unable to determine floating-point ABI])
+fi
+
+LIBC_CONFIG_VAR([default-abi], [$libc_cv_riscv_int_abi$libc_cv_riscv_float_abi])
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/Implies b/sysdeps/unix/sysv/linux/riscv/rv32/Implies
new file mode 100644
index 000000000000..8b7deb33cd51
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/Implies
@@ -0,0 +1,3 @@
+unix/sysv/linux/riscv
+unix/sysv/linux/generic/wordsize-32
+unix/sysv/linux/generic
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/Implies b/sysdeps/unix/sysv/linux/riscv/rv64/Implies
new file mode 100644
index 000000000000..f042343bf7b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/Implies
@@ -0,0 +1,3 @@
+unix/sysv/linux/riscv
+unix/sysv/linux/generic
+unix/sysv/linux/wordsize-64
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/Makefile b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
new file mode 100644
index 000000000000..cb60d740476d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),socket)
+CFLAGS-recv.c += -fexceptions
+CFLAGS-send.c += -fexceptions
+endif
diff --git a/sysdeps/unix/sysv/linux/riscv/shlib-versions b/sysdeps/unix/sysv/linux/riscv/shlib-versions
new file mode 100644
index 000000000000..fe7322d23a94
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/shlib-versions
@@ -0,0 +1,17 @@
+DEFAULT		GLIBC_2.27
+
+%if RISCV_ABI_XLEN == 64 && RISCV_ABI_FLEN == 64
+ld=ld-linux-riscv64-lp64d.so.1
+%elif RISCV_ABI_XLEN == 64 && RISCV_ABI_FLEN == 32
+ld=ld-linux-riscv64-lp64f.so.1
+%elif RISCV_ABI_XLEN == 64 && RISCV_ABI_FLEN == 0
+ld=ld-linux-riscv64-lp64.so.1
+%elif RISCV_ABI_XLEN == 32 && RISCV_ABI_FLEN == 64
+ld=ld-linux-riscv32-ilp32d.so.1
+%elif RISCV_ABI_XLEN == 32 && RISCV_ABI_FLEN == 32
+ld=ld-linux-riscv32-ilp32f.so.1
+%elif RISCV_ABI_XLEN == 32 && RISCV_ABI_FLEN == 0
+ld=ld-linux-riscv32-ilp32.so.1
+%else
+%error cannot determine ABI
+%endif
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* RISC-V glibc port v2
@ 2017-12-20  7:23 Palmer Dabbelt
  2017-12-20  7:23 ` [PATCH v2 01/15] RISC-V: Build Infastructure Palmer Dabbelt
                   ` (17 more replies)
  0 siblings, 18 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:23 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj

Sorry it's been a while since the v1 patch set, but things have been busy in
RISC-V land.  The biggest development so far has been our Linux port, which has
been accepted into Linus' tree and will be released as part of 4.15.0.  We have
been in binutils since 2.28 and GCC since 7.1.0, but as we've brought up more
complicated software we've found a handful of bugs so it's best to use the
upcoming releases (2.30 and 7.3.0).  Our QEMU port is not yet upstream (we're
preparing it for submission now), and general availiability of the first
commercial, Linux-capable RISC-V chips is scheduled for Q1 2018.  We've had
preliminary ports of Debian, Fedora, and OpenEmbedded to RISC-V, all of which
are currently waiting on glibc so we can declare the ABI stable.

We're planning on supporting 6 glibc configurations on RISC-V, all of which we
internally run regression tests on:

* -march=rv64imafdc -mabi=lp64d   -- what we expect to be the most used
                                     configuration
* -march=rv64imac   -mabi=lp64    -- soft floating point
* -march=rv64imafdc -mabi=lp64    -- soft float ABI, but allowed to use
				     hardware floating point instruction.  This
				     is like softfp in ARM land.
* -march=rv32imafdc -mabi=ilp32d  -- rv32i is a 32-bit ISA
* -march=rv32imac   -mabi=ilp32
* -march=rv32imafdc -mabi=ilp32

While we anticipate we'll want to add an x32-style ABI on rv64i-based systems,
we haven't implemented that anywhere yet.

There's a few things I know that have to be done:

* I need to go through and sanitize the floating-point routines, which I had to
  refactor as a result of the new FP aliasing mechanism.
* Our test suite results are very bad, but I believe this is because we're
  running on QEMU's user-mode emulation which is known to be both buggy and
  incomplete.  I'm bringing up userspace again to produce a more reasonable
  test suite run, which will hopefully have a much cleaner run.
* Should we have padding in __pthread_rwlock_arch_t?  I assume the padding on
  other architectures is there for ABI reasons and shouldn't be necessary for
  new ports, but the ports I usually rely on all have excatly the same padding
  so I'm worried there's another reason for this.
* I've only added one configuration to build-many-glibcs.py, which I haven't
  actually run yet.  I'll rectify this, but I wanted to at least get something
  out so everyone was on the same page here -- the commit is more of a TODO
  than an actual commit.
* The port was warning-free recently, but I've rebased it a bit so that might
  not be the case any more.
* I'm not sure what the right the to do with VDSO_NAME_LINUX_4_15 is.  It seems
  odd that there's nothing newer than 2.6.29 in there.

I know it's a bit late and that it's a busy time for everyone, but we're really
hoping to get into 2.27 if possible.  We've been maintaing this port out of
tree for years, and I don't think the quality is going to increase
significantly until we get in tree, declare the ABI stable, and users start
really cranking on it.

A (very brief, as it's been 6 months) summary of the changes since the v1 patch
set includes:

* Many copyright cleanups.
* We're using the generic versions of a handful of functions and headers,
  including ieee754.h, mathdef.h mathinline.h, fabs{,f}, and
  fe{disable,enable,get}except.
* Removal of lots of head code, including pthread_lock, atomic_fast.
* A handful of ABI fixes to match our upstreamed Linux port, including
  sigcontext, instruction-cache flushing, and some syscall sanitization.
* We've changed to use libm_alias_{float,double}, like upstream
* Compiler builtins are used for atomics where possible.
* We now mandate the A extension in Linux, support for non-A systems has been
  removed from glibc.

Thanks to everyone who has helped review the patch set!  I believe we've gone
through all the feedback from the first patch set.  Sorry if we've missed
anything, but at this point I think it'd be best to re-submit it -- it's been a
long time since the previous patch set.

Here's the full list of patches v2.  If one gets lost, they'll be availibale on
the riscv-for-submission-v2 branch of http://github.com/riscv/riscv-glibc

[PATCH v2 01/15] RISC-V: Build Infastructure
[PATCH v2 02/15] RISC-V: ABI Implementation
[PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code
[PATCH v2 04/15] RISC-V: Thread-Local Storage Support
[PATCH v2 05/15] RISC-V: Generic <string.h> Routines
[PATCH v2 06/15] RISC-V: Generic <math.h> and soft-fp Routines
[PATCH v2 07/15] RISC-V: RV32F Support
[PATCH v2 08/15] RISC-V: RV32D, RV64F, and RV64D Support
[PATCH v2 09/15] RISC-V: Atomic and Locking Routines
[PATCH v2 10/15] RISC-V: Linux Syscall Interface
[PATCH v2 11/15] RISC-V: Linux ABI
[PATCH v2 12/15] RISC-V: Linux Startup and Dynamic Loading Code
[PATCH v2 13/15] Add RISC-V dynamic relocations to elf.h
[PATCH v2 14/15] Add linux-4.15 VDSO hash for RISC-V
[PATCH v2 15/15] Add RISC-V to build-many-glibcs.py

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 05/15] RISC-V: Generic <string.h> Routines
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
  2017-12-20  7:23 ` [PATCH v2 01/15] RISC-V: Build Infastructure Palmer Dabbelt
@ 2017-12-20  7:23 ` Palmer Dabbelt
  2017-12-20 16:48   ` Joseph Myers
  2017-12-20  7:23 ` [PATCH v2 04/15] RISC-V: Thread-Local Storage Support Palmer Dabbelt
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:23 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This patch contains fast versions of the various routines from string.h
that have been implemented for RISC-V.  Since RISC-V doesn't define any
specific performance characteristics they're not optimized for any
particular microarchitecture, but are designed to be generally good.
---
 sysdeps/riscv/detect_null_byte.h |  31 ++++++++
 sysdeps/riscv/memcpy.c           |  92 ++++++++++++++++++++++
 sysdeps/riscv/memset.S           | 107 ++++++++++++++++++++++++++
 sysdeps/riscv/strcmp.S           | 159 +++++++++++++++++++++++++++++++++++++++
 sysdeps/riscv/strcpy.c           |  73 ++++++++++++++++++
 sysdeps/riscv/strlen.c           |  58 ++++++++++++++
 6 files changed, 520 insertions(+)
 create mode 100644 sysdeps/riscv/detect_null_byte.h
 create mode 100644 sysdeps/riscv/memcpy.c
 create mode 100644 sysdeps/riscv/memset.S
 create mode 100644 sysdeps/riscv/strcmp.S
 create mode 100644 sysdeps/riscv/strcpy.c
 create mode 100644 sysdeps/riscv/strlen.c

diff --git a/sysdeps/riscv/detect_null_byte.h b/sysdeps/riscv/detect_null_byte.h
new file mode 100644
index 000000000000..a888b5d25bf3
--- /dev/null
+++ b/sysdeps/riscv/detect_null_byte.h
@@ -0,0 +1,31 @@
+/* RISC-V null byte detection
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _RISCV_DETECT_NULL_BYTE_H
+#define _RISCV_DETECT_NULL_BYTE_H	1
+
+static __inline__ unsigned long detect_null_byte (unsigned long w)
+{
+  unsigned long mask = 0x7f7f7f7f;
+  if (sizeof (long) == 8)
+    mask = ((mask << 16) << 16) | mask;
+  return ~(((w & mask) + mask) | w | mask);
+}
+
+#endif /* detect_null_byte.h */
diff --git a/sysdeps/riscv/memcpy.c b/sysdeps/riscv/memcpy.c
new file mode 100644
index 000000000000..8be924ac1b56
--- /dev/null
+++ b/sysdeps/riscv/memcpy.c
@@ -0,0 +1,92 @@
+/* Optimized memory copy implementation for RISC-V.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdint.h>
+
+#define MEMCPY_LOOP_BODY(a, b, t) {	\
+    t tt = *b;				\
+    a++, b++;				\
+    *(a - 1) = tt;			\
+  }
+
+void *__memcpy(void *aa, const void *bb, size_t n)
+{
+  uintptr_t msk = sizeof(long) - 1;
+  char *a = (char *)aa, *end = a + n;
+  const char *b = (const char *)bb;
+  long *la, *lend;
+  const long *lb;
+  int same_alignment = ((uintptr_t)a & msk) == ((uintptr_t)b & msk);
+
+  /* Handle small cases, and those without mutual alignment.  */
+  if (__glibc_unlikely(!same_alignment || n < sizeof(long)))
+    {
+small:
+      while (a < end)
+	MEMCPY_LOOP_BODY(a, b, char);
+      return aa;
+    }
+
+  /* Obtain alignment.  */
+  if (__glibc_unlikely(((uintptr_t)a & msk) != 0))
+    while ((uintptr_t)a & msk)
+      MEMCPY_LOOP_BODY(a, b, char);
+
+  la = (long *)a;
+  lb = (const long *)b;
+  lend = (long *)((uintptr_t)end & ~msk);
+
+  /* Handle large, aligned cases.  */
+  if (__glibc_unlikely(la < lend - 8))
+    while (la < lend - 8)
+      {
+	long b0 = *lb++;
+	long b1 = *lb++;
+	long b2 = *lb++;
+	long b3 = *lb++;
+	long b4 = *lb++;
+	long b5 = *lb++;
+	long b6 = *lb++;
+	long b7 = *lb++;
+	long b8 = *lb++;
+	*la++ = b0;
+	*la++ = b1;
+	*la++ = b2;
+	*la++ = b3;
+	*la++ = b4;
+	*la++ = b5;
+	*la++ = b6;
+	*la++ = b7;
+	*la++ = b8;
+      }
+
+  /* Handle aligned, small case.  */
+  while (la < lend)
+    MEMCPY_LOOP_BODY(la, lb, long);
+
+  /* Handle misaligned remainder.  */
+  a = (char *)la;
+  b = (const char *)lb;
+  if (__glibc_unlikely(a < end))
+    goto small;
+
+  return aa;
+}
+weak_alias (__memcpy, memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/sysdeps/riscv/memset.S b/sysdeps/riscv/memset.S
new file mode 100644
index 000000000000..b06eb8312ed1
--- /dev/null
+++ b/sysdeps/riscv/memset.S
@@ -0,0 +1,107 @@
+/* Optimized memset implementation for RISC-V.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+ENTRY(memset)
+  li a6, 15
+  mv a4, a0
+  bleu a2, a6, .Ltiny
+  and a5, a4, 15
+  bnez a5, .Lmisaligned
+
+.Laligned:
+  bnez a1, .Lwordify
+
+.Lwordified:
+  and a3, a2, ~15
+  and a2, a2, 15
+  add a3, a3, a4
+
+#if __riscv_xlen == 64
+1:sd a1, 0(a4)
+  sd a1, 8(a4)
+#else
+1:sw a1, 0(a4)
+  sw a1, 4(a4)
+  sw a1, 8(a4)
+  sw a1, 12(a4)
+#endif
+  add a4, a4, 16
+  bltu a4, a3, 1b
+
+  bnez a2, .Ltiny
+  ret
+
+.Ltiny:
+  sub a3, a6, a2
+  sll a3, a3, 2
+1:auipc t0, %pcrel_hi(.Ltable)
+  add a3, a3, t0
+.option push
+.option norvc
+.Ltable_misaligned:
+  jr a3, %pcrel_lo(1b)
+.Ltable:
+  sb a1,14(a4)
+  sb a1,13(a4)
+  sb a1,12(a4)
+  sb a1,11(a4)
+  sb a1,10(a4)
+  sb a1, 9(a4)
+  sb a1, 8(a4)
+  sb a1, 7(a4)
+  sb a1, 6(a4)
+  sb a1, 5(a4)
+  sb a1, 4(a4)
+  sb a1, 3(a4)
+  sb a1, 2(a4)
+  sb a1, 1(a4)
+  sb a1, 0(a4)
+.option pop
+  ret
+
+.Lwordify:
+  and a1, a1, 0xFF
+  sll a3, a1, 8
+  or  a1, a1, a3
+  sll a3, a1, 16
+  or  a1, a1, a3
+#if __riscv_xlen == 64
+  sll a3, a1, 32
+  or  a1, a1, a3
+#endif
+  j .Lwordified
+
+.Lmisaligned:
+  sll a3, a5, 2
+1:auipc t0, %pcrel_hi(.Ltable_misaligned)
+  add a3, a3, t0
+  mv t0, ra
+  jalr a3, %pcrel_lo(1b)
+  mv ra, t0
+
+  add a5, a5, -16
+  sub a4, a4, a5
+  add a2, a2, a5
+  bleu a2, a6, .Ltiny
+  j .Laligned
+END(memset)
+
+weak_alias(memset, __GI_memset)
diff --git a/sysdeps/riscv/strcmp.S b/sysdeps/riscv/strcmp.S
new file mode 100644
index 000000000000..edc38513cc21
--- /dev/null
+++ b/sysdeps/riscv/strcmp.S
@@ -0,0 +1,159 @@
+/* Optimized string compare implementation for RISC-V.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
+# error
+#endif
+
+ENTRY(strcmp)
+  or    a4, a0, a1
+  li    t2, -1
+  and   a4, a4, SZREG-1
+  bnez  a4, .Lmisaligned
+
+#if SZREG == 4
+  li t3, 0x7f7f7f7f
+#else
+  ld t3, mask
+#endif
+
+  .macro check_one_word i n
+    REG_L a2, \i*SZREG(a0)
+    REG_L a3, \i*SZREG(a1)
+
+    and   t0, a2, t3
+    or    t1, a2, t3
+    add   t0, t0, t3
+    or    t0, t0, t1
+
+    bne   t0, t2, .Lnull\i
+    .if \i+1-\n
+      bne   a2, a3, .Lmismatch
+    .else
+      add   a0, a0, \n*SZREG
+      add   a1, a1, \n*SZREG
+      beq   a2, a3, .Lloop
+      # fall through to .Lmismatch
+    .endif
+  .endm
+
+  .macro foundnull i n
+    .ifne \i
+      .Lnull\i:
+      add   a0, a0, \i*SZREG
+      add   a1, a1, \i*SZREG
+      .ifeq \i-1
+        .Lnull0:
+      .endif
+      bne   a2, a3, .Lmisaligned
+      li    a0, 0
+      ret
+    .endif
+  .endm
+
+.Lloop:
+  # examine full words at a time, favoring strings of a couple dozen chars
+#if __riscv_xlen == 32
+  check_one_word 0 5
+  check_one_word 1 5
+  check_one_word 2 5
+  check_one_word 3 5
+  check_one_word 4 5
+#else
+  check_one_word 0 3
+  check_one_word 1 3
+  check_one_word 2 3
+#endif
+  # backwards branch to .Lloop contained above
+
+.Lmismatch:
+  # words don't match, but a2 has no null byte.
+#if __riscv_xlen == 64
+  sll   a4, a2, 48
+  sll   a5, a3, 48
+  bne   a4, a5, .Lmismatch_upper
+  sll   a4, a2, 32
+  sll   a5, a3, 32
+  bne   a4, a5, .Lmismatch_upper
+#endif
+  sll   a4, a2, 16
+  sll   a5, a3, 16
+  bne   a4, a5, .Lmismatch_upper
+
+  srl   a4, a2, 8*SZREG-16
+  srl   a5, a3, 8*SZREG-16
+  sub   a0, a4, a5
+  and   a1, a0, 0xff
+  bnez  a1, 1f
+  ret
+
+.Lmismatch_upper:
+  srl   a4, a4, 8*SZREG-16
+  srl   a5, a5, 8*SZREG-16
+  sub   a0, a4, a5
+  and   a1, a0, 0xff
+  bnez  a1, 1f
+  ret
+
+1:and   a4, a4, 0xff
+  and   a5, a5, 0xff
+  sub   a0, a4, a5
+  ret
+
+.Lmisaligned:
+  # misaligned
+  lbu   a2, 0(a0)
+  lbu   a3, 0(a1)
+  add   a0, a0, 1
+  add   a1, a1, 1
+  bne   a2, a3, 1f
+  bnez  a2, .Lmisaligned
+
+1:
+  sub   a0, a2, a3
+  ret
+
+  # cases in which a null byte was detected
+#if __riscv_xlen == 32
+  foundnull 0 5
+  foundnull 1 5
+  foundnull 2 5
+  foundnull 3 5
+  foundnull 4 5
+#else
+  foundnull 0 3
+  foundnull 1 3
+  foundnull 2 3
+#endif
+
+END(strcmp)
+
+weak_alias(strcmp, __GI_strcmp)
+
+#if SZREG == 8
+#ifdef __PIC__
+.section .rodata.cst8,"aM",@progbits,8
+#else
+.section .srodata.cst8,"aM",@progbits,8
+#endif
+.align 3
+mask: .8byte 0x7f7f7f7f7f7f7f7f
+#endif
diff --git a/sysdeps/riscv/strcpy.c b/sysdeps/riscv/strcpy.c
new file mode 100644
index 000000000000..9382fb145db9
--- /dev/null
+++ b/sysdeps/riscv/strcpy.c
@@ -0,0 +1,73 @@
+/* Optimized string copy implementation for RISC-V.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "detect_null_byte.h"
+
+#undef strcpy
+
+char* strcpy(char* dst, const char* src)
+{
+  char* dst0 = dst;
+
+  int misaligned = ((uintptr_t)dst | (uintptr_t)src) & (sizeof(long)-1);
+  if (__builtin_expect(!misaligned, 1))
+  {
+    long* ldst = (long*)dst;
+    const long* lsrc = (const long*)src;
+
+    while (!detect_null_byte(*lsrc))
+      *ldst++ = *lsrc++;
+
+    dst = (char*)ldst;
+    src = (const char*)lsrc;
+
+    char c0 = src[0];
+    char c1 = src[1];
+    char c2 = src[2];
+    if (!(*dst++ = c0)) return dst0;
+    if (!(*dst++ = c1)) return dst0;
+    char c3 = src[3];
+    if (!(*dst++ = c2)) return dst0;
+    if (sizeof(long) == 4) goto out;
+    char c4 = src[4];
+    if (!(*dst++ = c3)) return dst0;
+    char c5 = src[5];
+    if (!(*dst++ = c4)) return dst0;
+    char c6 = src[6];
+    if (!(*dst++ = c5)) return dst0;
+    if (!(*dst++ = c6)) return dst0;
+
+out:
+    *dst++ = 0;
+    return dst0;
+  }
+
+  char ch;
+  do
+  {
+    ch = *src;
+    src++;
+    dst++;
+    *(dst-1) = ch;
+  } while(ch);
+
+  return dst0;
+}
+libc_hidden_def(strcpy)
diff --git a/sysdeps/riscv/strlen.c b/sysdeps/riscv/strlen.c
new file mode 100644
index 000000000000..86a76947c3f3
--- /dev/null
+++ b/sysdeps/riscv/strlen.c
@@ -0,0 +1,58 @@
+/* Determine the length of a string.  RISC-V version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <stdint.h>
+#include "detect_null_byte.h"
+
+#undef strlen
+
+size_t strlen(const char* str)
+{
+  const char* start = str;
+
+  if (__builtin_expect((uintptr_t)str & (sizeof(long)-1), 0)) do
+  {
+    char ch = *str;
+    str++;
+    if (!ch)
+      return str - start - 1;
+  } while ((uintptr_t)str & (sizeof(long)-1));
+
+  unsigned long* ls = (unsigned long*)str;
+  while (!detect_null_byte(*ls++))
+    ;
+  asm volatile ("" : "+r"(ls)); /* prevent "optimization" */
+
+  str = (const char*)ls;
+  size_t ret = str - start, sl = sizeof(long);
+
+  char c0 = str[0-sl], c1 = str[1-sl], c2 = str[2-sl], c3 = str[3-sl];
+  if (c0 == 0)            return ret + 0 - sl;
+  if (c1 == 0)            return ret + 1 - sl;
+  if (c2 == 0)            return ret + 2 - sl;
+  if (sl == 4 || c3 == 0) return ret + 3 - sl;
+
+  c0 = str[4-sl], c1 = str[5-sl], c2 = str[6-sl], c3 = str[7-sl];
+  if (c0 == 0)            return ret + 4 - sl;
+  if (c1 == 0)            return ret + 5 - sl;
+  if (c2 == 0)            return ret + 6 - sl;
+
+  return ret + 7 - sl;
+}
+libc_hidden_def(strlen)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 02/15] RISC-V: ABI Implementation
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (3 preceding siblings ...)
  2017-12-20  7:23 ` [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code Palmer Dabbelt
@ 2017-12-20  7:23 ` Palmer Dabbelt
  2017-12-20 16:31   ` Joseph Myers
  2017-12-20  7:24 ` [PATCH v2 06/15] RISC-V: Generic <math.h> and soft-fp Routines Palmer Dabbelt
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:23 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This patch contains code that needs to directly know about the RISC-V
ABI, which is specified in a work-in-progress psABI document:

  https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

This is meant to contain all the RISC-V code that needs to explicitly
name registers or manage in-memory structure layout.  This does not
contain any of the Linux-specific code.
---
 sysdeps/riscv/__longjmp.S     | 57 +++++++++++++++++++++++++++++++
 sysdeps/riscv/bits/endian.h   |  5 +++
 sysdeps/riscv/bits/setjmp.h   | 41 +++++++++++++++++++++++
 sysdeps/riscv/bits/wordsize.h | 31 +++++++++++++++++
 sysdeps/riscv/bsd-_setjmp.c   |  1 +
 sysdeps/riscv/bsd-setjmp.c    |  1 +
 sysdeps/riscv/dl-trampoline.S | 63 ++++++++++++++++++++++++++++++++++
 sysdeps/riscv/gccframe.h      | 21 ++++++++++++
 sysdeps/riscv/jmpbuf-unwind.h | 46 +++++++++++++++++++++++++
 sysdeps/riscv/machine-gmon.h  | 34 +++++++++++++++++++
 sysdeps/riscv/memusage.h      | 21 ++++++++++++
 sysdeps/riscv/setjmp.S        | 74 ++++++++++++++++++++++++++++++++++++++++
 sysdeps/riscv/sys/asm.h       | 78 +++++++++++++++++++++++++++++++++++++++++++
 sysdeps/riscv/tls-macros.h    | 59 ++++++++++++++++++++++++++++++++
 14 files changed, 532 insertions(+)
 create mode 100644 sysdeps/riscv/__longjmp.S
 create mode 100644 sysdeps/riscv/bits/endian.h
 create mode 100644 sysdeps/riscv/bits/setjmp.h
 create mode 100644 sysdeps/riscv/bits/wordsize.h
 create mode 100644 sysdeps/riscv/bsd-_setjmp.c
 create mode 100644 sysdeps/riscv/bsd-setjmp.c
 create mode 100644 sysdeps/riscv/dl-trampoline.S
 create mode 100644 sysdeps/riscv/gccframe.h
 create mode 100644 sysdeps/riscv/jmpbuf-unwind.h
 create mode 100644 sysdeps/riscv/machine-gmon.h
 create mode 100644 sysdeps/riscv/memusage.h
 create mode 100644 sysdeps/riscv/setjmp.S
 create mode 100644 sysdeps/riscv/sys/asm.h
 create mode 100644 sysdeps/riscv/tls-macros.h

diff --git a/sysdeps/riscv/__longjmp.S b/sysdeps/riscv/__longjmp.S
new file mode 100644
index 000000000000..940cff131309
--- /dev/null
+++ b/sysdeps/riscv/__longjmp.S
@@ -0,0 +1,57 @@
+/* longjmp, RISC-V version.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+ENTRY (__longjmp)
+	REG_L ra,  0*SZREG(a0)
+	REG_L s0,  1*SZREG(a0)
+	REG_L s1,  2*SZREG(a0)
+	REG_L s2,  3*SZREG(a0)
+	REG_L s3,  4*SZREG(a0)
+	REG_L s4,  5*SZREG(a0)
+	REG_L s5,  6*SZREG(a0)
+	REG_L s6,  7*SZREG(a0)
+	REG_L s7,  8*SZREG(a0)
+	REG_L s8,  9*SZREG(a0)
+	REG_L s9, 10*SZREG(a0)
+	REG_L s10,11*SZREG(a0)
+	REG_L s11,12*SZREG(a0)
+	REG_L sp, 13*SZREG(a0)
+
+#ifndef __riscv_float_abi_soft
+	FREG_L fs0, 14*SZREG+ 0*SZFREG(a0)
+	FREG_L fs1, 14*SZREG+ 1*SZFREG(a0)
+	FREG_L fs2, 14*SZREG+ 2*SZFREG(a0)
+	FREG_L fs3, 14*SZREG+ 3*SZFREG(a0)
+	FREG_L fs4, 14*SZREG+ 4*SZFREG(a0)
+	FREG_L fs5, 14*SZREG+ 5*SZFREG(a0)
+	FREG_L fs6, 14*SZREG+ 6*SZFREG(a0)
+	FREG_L fs7, 14*SZREG+ 7*SZFREG(a0)
+	FREG_L fs8, 14*SZREG+ 8*SZFREG(a0)
+	FREG_L fs9, 14*SZREG+ 9*SZFREG(a0)
+	FREG_L fs10,14*SZREG+10*SZFREG(a0)
+	FREG_L fs11,14*SZREG+11*SZFREG(a0)
+#endif
+
+	seqz a0, a1
+	add  a0, a0, a1   # a0 = (a1 == 0) ? 1 : a1
+	ret
+
+END(__longjmp)
diff --git a/sysdeps/riscv/bits/endian.h b/sysdeps/riscv/bits/endian.h
new file mode 100644
index 000000000000..4aaf559d4f43
--- /dev/null
+++ b/sysdeps/riscv/bits/endian.h
@@ -0,0 +1,5 @@
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/sysdeps/riscv/bits/setjmp.h b/sysdeps/riscv/bits/setjmp.h
new file mode 100644
index 000000000000..de1df30c7cc0
--- /dev/null
+++ b/sysdeps/riscv/bits/setjmp.h
@@ -0,0 +1,41 @@
+/* Define the machine-dependent type `jmp_buf'.  RISC-V version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _RISCV_BITS_SETJMP_H
+#define _RISCV_BITS_SETJMP_H
+
+typedef struct __jmp_buf_internal_tag
+  {
+    /* Program counter.  */
+    long __pc;
+    /* Callee-saved registers. */
+    long __regs[12];
+    /* Stack pointer.  */
+    long __sp;
+
+    /* Callee-saved floating point registers.  */
+#ifdef __riscv_float_abi_single
+   float __fpregs[12];
+#elif defined (__riscv_float_abi_double)
+   double __fpregs[12];
+#elif !defined (__riscv_float_abi_soft)
+# error unsupported FLEN
+#endif
+  } __jmp_buf[1];
+
+#endif /* _RISCV_BITS_SETJMP_H */
diff --git a/sysdeps/riscv/bits/wordsize.h b/sysdeps/riscv/bits/wordsize.h
new file mode 100644
index 000000000000..4781cc4899a3
--- /dev/null
+++ b/sysdeps/riscv/bits/wordsize.h
@@ -0,0 +1,31 @@
+/* Determine the wordsize from the preprocessor defines.  RISC-V version.
+   Copyright (C) 2002-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if __riscv_xlen == (__SIZEOF_POINTER__ * 8)
+# define __WORDSIZE __riscv_xlen
+#else
+# error unsupported ABI
+#endif
+
+#if __riscv_xlen == 64
+# define __WORDSIZE_TIME64_COMPAT32 1
+#else
+# define __WORDSIZE_TIME64_COMPAT32 0
+# define __WORDSIZE32_SIZE_ULONG    0
+# define __WORDSIZE32_PTRDIFF_LONG  0
+#endif
diff --git a/sysdeps/riscv/bsd-_setjmp.c b/sysdeps/riscv/bsd-_setjmp.c
new file mode 100644
index 000000000000..0d413101ce0d
--- /dev/null
+++ b/sysdeps/riscv/bsd-_setjmp.c
@@ -0,0 +1 @@
+/* _setjmp is implemented in setjmp.S */
diff --git a/sysdeps/riscv/bsd-setjmp.c b/sysdeps/riscv/bsd-setjmp.c
new file mode 100644
index 000000000000..ee7c5e3437d4
--- /dev/null
+++ b/sysdeps/riscv/bsd-setjmp.c
@@ -0,0 +1 @@
+/* setjmp is implemented in setjmp.S */
diff --git a/sysdeps/riscv/dl-trampoline.S b/sysdeps/riscv/dl-trampoline.S
new file mode 100644
index 000000000000..045643f89784
--- /dev/null
+++ b/sysdeps/riscv/dl-trampoline.S
@@ -0,0 +1,63 @@
+/* RISC-V PLT trampoline
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+/* Assembler veneer called from the PLT header code for lazy loading.
+   The PLT header passes its own args in t0-t2.  */
+
+#define FRAME_SIZE (-((-10 * SZREG) & ALMASK))
+
+ENTRY(_dl_runtime_resolve)
+  # Save arguments to stack.
+  addi sp, sp, -FRAME_SIZE
+  REG_S ra, 9*SZREG(sp)
+  REG_S a0, 1*SZREG(sp)
+  REG_S a1, 2*SZREG(sp)
+  REG_S a2, 3*SZREG(sp)
+  REG_S a3, 4*SZREG(sp)
+  REG_S a4, 5*SZREG(sp)
+  REG_S a5, 6*SZREG(sp)
+  REG_S a6, 7*SZREG(sp)
+  REG_S a7, 8*SZREG(sp)
+
+  # Update .got.plt and obtain runtime address of callee.
+  slli a1, t1, 1
+  mv a0, t0       # link map
+  add a1, a1, t1  # reloc offset (== thrice the .got.plt offset)
+  la a2, _dl_fixup
+  jalr a2
+  mv t1, a0
+
+  # Restore arguments from stack.
+  REG_L ra, 9*SZREG(sp)
+  REG_L a0, 1*SZREG(sp)
+  REG_L a1, 2*SZREG(sp)
+  REG_L a2, 3*SZREG(sp)
+  REG_L a3, 4*SZREG(sp)
+  REG_L a4, 5*SZREG(sp)
+  REG_L a5, 6*SZREG(sp)
+  REG_L a6, 7*SZREG(sp)
+  REG_L a7, 8*SZREG(sp)
+  addi sp, sp, FRAME_SIZE
+
+  # Invoke the callee.
+  jr t1
+END(_dl_runtime_resolve)
diff --git a/sysdeps/riscv/gccframe.h b/sysdeps/riscv/gccframe.h
new file mode 100644
index 000000000000..28f6908826e2
--- /dev/null
+++ b/sysdeps/riscv/gccframe.h
@@ -0,0 +1,21 @@
+/* Definition of object in frame unwind info.  RISC-V version.
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define FIRST_PSEUDO_REGISTER 66
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/sysdeps/riscv/jmpbuf-unwind.h b/sysdeps/riscv/jmpbuf-unwind.h
new file mode 100644
index 000000000000..8b4ed8196dec
--- /dev/null
+++ b/sysdeps/riscv/jmpbuf-unwind.h
@@ -0,0 +1,46 @@
+/* Examine __jmp_buf for unwinding frames.  RISC-V version.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+   containing a local variable at ADDRESS.  */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle)		\
+  ((void *) (address) < (void *) demangle ((jmpbuf)[0].__sp))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+  uintptr_t sp = regs[0].__sp;
+#ifdef PTR_DEMANGLE
+  PTR_DEMANGLE (sp);
+#endif
+  return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal longjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/sysdeps/riscv/machine-gmon.h b/sysdeps/riscv/machine-gmon.h
new file mode 100644
index 000000000000..2ec7a34d9bc6
--- /dev/null
+++ b/sysdeps/riscv/machine-gmon.h
@@ -0,0 +1,34 @@
+/* RISC-V definitions for profiling support.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Accept 'frompc' address as argument from the function that calls
+   _mcount for profiling.  Use  __builtin_return_address (0)
+   for the 'selfpc' address.  */
+
+#include <sysdep.h>
+
+static void mcount_internal (u_long frompc, u_long selfpc);
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+static inline void mcount_internal (u_long frompc, u_long selfpc)
+
+#define MCOUNT								\
+void _mcount (void *frompc)						\
+{									\
+  mcount_internal ((u_long) frompc, (u_long) RETURN_ADDRESS (0));	\
+}
diff --git a/sysdeps/riscv/memusage.h b/sysdeps/riscv/memusage.h
new file mode 100644
index 000000000000..eec156b3ec68
--- /dev/null
+++ b/sysdeps/riscv/memusage.h
@@ -0,0 +1,21 @@
+/* Machine-specific definitions for memory usage profiling, RISC-V version.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/sysdeps/riscv/setjmp.S b/sysdeps/riscv/setjmp.S
new file mode 100644
index 000000000000..dc1dd98b2892
--- /dev/null
+++ b/sysdeps/riscv/setjmp.S
@@ -0,0 +1,74 @@
+/* setjmp for RISC-V.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+ENTRY (_setjmp)
+  li	a1, 0
+  j	__sigsetjmp
+END (_setjmp)
+ENTRY (setjmp)
+  li	a1, 1
+  /* Fallthrough */
+END (setjmp)
+ENTRY (__sigsetjmp)
+	REG_S ra,  0*SZREG(a0)
+	REG_S s0,  1*SZREG(a0)
+	REG_S s1,  2*SZREG(a0)
+	REG_S s2,  3*SZREG(a0)
+	REG_S s3,  4*SZREG(a0)
+	REG_S s4,  5*SZREG(a0)
+	REG_S s5,  6*SZREG(a0)
+	REG_S s6,  7*SZREG(a0)
+	REG_S s7,  8*SZREG(a0)
+	REG_S s8,  9*SZREG(a0)
+	REG_S s9, 10*SZREG(a0)
+	REG_S s10,11*SZREG(a0)
+	REG_S s11,12*SZREG(a0)
+	REG_S sp, 13*SZREG(a0)
+
+#ifndef __riscv_float_abi_soft
+	FREG_S fs0, 14*SZREG+ 0*SZFREG(a0)
+	FREG_S fs1, 14*SZREG+ 1*SZFREG(a0)
+	FREG_S fs2, 14*SZREG+ 2*SZFREG(a0)
+	FREG_S fs3, 14*SZREG+ 3*SZFREG(a0)
+	FREG_S fs4, 14*SZREG+ 4*SZFREG(a0)
+	FREG_S fs5, 14*SZREG+ 5*SZFREG(a0)
+	FREG_S fs6, 14*SZREG+ 6*SZFREG(a0)
+	FREG_S fs7, 14*SZREG+ 7*SZFREG(a0)
+	FREG_S fs8, 14*SZREG+ 8*SZFREG(a0)
+	FREG_S fs9, 14*SZREG+ 9*SZFREG(a0)
+	FREG_S fs10,14*SZREG+10*SZFREG(a0)
+	FREG_S fs11,14*SZREG+11*SZFREG(a0)
+#endif
+
+#if !IS_IN (libc) && IS_IN (rtld)
+  /* In ld.so we never save the signal mask.  */
+  li a0, 0
+  ret
+#else
+  /* Make a tail call to __sigjmp_save; it takes the same args.  */
+  j __sigjmp_save
+#endif
+
+
+END(__sigsetjmp)
+
+hidden_def (__sigsetjmp)
+weak_alias(_setjmp, __GI__setjmp)
diff --git a/sysdeps/riscv/sys/asm.h b/sysdeps/riscv/sys/asm.h
new file mode 100644
index 000000000000..992d47b798e7
--- /dev/null
+++ b/sysdeps/riscv/sys/asm.h
@@ -0,0 +1,78 @@
+/* Miscellaneous macros.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_ASM_H
+#define _SYS_ASM_H
+
+/*
+ * Macros to handle different pointer/register sizes for 32/64-bit code
+ */
+#if __riscv_xlen == 64
+# define PTRLOG 3
+# define SZREG	8
+# define REG_S sd
+# define REG_L ld
+#elif __riscv_xlen == 32
+# define PTRLOG 2
+# define SZREG	4
+# define REG_S sw
+# define REG_L lw
+#else
+# error __riscv_xlen must equal 32 or 64
+#endif
+
+#ifndef __riscv_float_abi_soft
+/* For ABI uniformity, reserve 8 bytes for floats, even if double-precision
+   floating-point is not supported in hardware.  */
+# ifdef __riscv_float_abi_single
+#  define FREG_L flw
+#  define FREG_S fsw
+#  define SZFREG 4
+# elif defined(__riscv_float_abi_double)
+#  define FREG_L fld
+#  define FREG_S fsd
+#  define SZFREG 8
+# else
+#  error unsupported FLEN
+# endif
+#endif
+
+/*
+ * LEAF - declare leaf routine
+ */
+#define	LEAF(symbol)				\
+		.globl	symbol;			\
+		.align	2;			\
+		.type	symbol,@function;	\
+symbol:						\
+		cfi_startproc;
+
+/*
+ * END - mark end of function
+ */
+#undef END
+#define END(function)				\
+		cfi_endproc;			\
+		.size	function,.-function
+
+/*
+ * Stack alignment
+ */
+#define ALMASK	~15
+
+#endif /* sys/asm.h */
diff --git a/sysdeps/riscv/tls-macros.h b/sysdeps/riscv/tls-macros.h
new file mode 100644
index 000000000000..b9c3b6e417b5
--- /dev/null
+++ b/sysdeps/riscv/tls-macros.h
@@ -0,0 +1,59 @@
+/* Macros to support TLS testing in times of missing compiler support.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+#include <sys/cdefs.h>
+#include <sys/asm.h>
+#include <sysdep.h>
+
+#define LOAD_GP						\
+	".option push\n\t"				\
+	".option norelax\n\t"				\
+	"la gp, __global_pointer$\n\t"			\
+	".option pop\n\t"
+
+#define UNLOAD_GP
+
+#define TLS_GD(x)					\
+	({ void *__result;				\
+	asm (LOAD_GP					\
+	     "la.tls.gd %0, " #x "\n\t"			\
+	     UNLOAD_GP					\
+	     : "=r"(__result));				\
+	__tls_get_addr(__result); })
+
+#define TLS_LD(x) TLS_GD(x)
+
+#define TLS_IE(x)					\
+	({ void *__result;				\
+	asm (LOAD_GP					\
+	     "la.tls.ie %0, " #x "\n\t"			\
+	     UNLOAD_GP					\
+	     : "=r"(__result));				\
+	__tls_get_addr(__result); })
+
+#define TLS_LE(x)					\
+	({ void *__result;				\
+	asm (LOAD_GP					\
+	     "lui %0, %%tprel_hi(" #x ")\n\t"		\
+	     "add %0, %0, tp, %%tprel_add(" #x ")\n\t"	\
+	     "lw %0, %%tprel_lo(" #x ")(%0)\n\t"	\
+	     UNLOAD_GP					\
+	     : "=r"(__result));				\
+	__tls_get_addr(__result); })
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 11/15] RISC-V: Linux ABI
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (5 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 06/15] RISC-V: Generic <math.h> and soft-fp Routines Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20 17:33   ` Joseph Myers
  2017-12-20  7:24 ` [PATCH v2 10/15] RISC-V: Linux Syscall Interface Palmer Dabbelt
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

Linux-specific code that is required for maintaining ABI compatibility.
This doesn't contain the actual system call interface, that is split out
in order to avoid having a patch that's too big.
---
 sysdeps/riscv/nptl/pthread-offsets.h               |  24 ++++
 sysdeps/riscv/nptl/pthreaddef.h                    |  32 +++++
 sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S    |   2 +
 sysdeps/unix/sysv/linux/riscv/bits/fcntl.h         |  62 ++++++++++
 sysdeps/unix/sysv/linux/riscv/bits/mman.h          |  36 ++++++
 sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h    |  32 +++++
 sysdeps/unix/sysv/linux/riscv/flush-icache.c       |  61 ++++++++++
 sysdeps/unix/sysv/linux/riscv/getcontext.S         |  77 ++++++++++++
 sysdeps/unix/sysv/linux/riscv/init-first.c         |  56 +++++++++
 sysdeps/unix/sysv/linux/riscv/libc-vdso.h          |  38 ++++++
 sysdeps/unix/sysv/linux/riscv/libthread_db.abilist |  41 +++++++
 sysdeps/unix/sysv/linux/riscv/makecontext.c        |  71 ++++++++++++
 sysdeps/unix/sysv/linux/riscv/register-dump.h      |  63 ++++++++++
 .../unix/sysv/linux/riscv/rv32/jmp_buf-macros.h    |  53 +++++++++
 .../unix/sysv/linux/riscv/rv64/jmp_buf-macros.h    |  53 +++++++++
 sysdeps/unix/sysv/linux/riscv/setcontext.S         | 114 ++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h     |  28 +++++
 sysdeps/unix/sysv/linux/riscv/swapcontext.S        | 125 ++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/sys/cachectl.h       |  31 +++++
 sysdeps/unix/sysv/linux/riscv/sys/procfs.h         | 111 ++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/sys/ucontext.h       | 126 ++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/sys/user.h           |   2 +
 sysdeps/unix/sysv/linux/riscv/sysdep-cancel.h      | 129 +++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/ucontext-macros.h    |  49 ++++++++
 sysdeps/unix/sysv/linux/riscv/ucontext_i.sym       |  31 +++++
 25 files changed, 1447 insertions(+)
 create mode 100644 sysdeps/riscv/nptl/pthread-offsets.h
 create mode 100644 sysdeps/riscv/nptl/pthreaddef.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/fcntl.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/mman.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/flush-icache.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/getcontext.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/init-first.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/libc-vdso.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/libthread_db.abilist
 create mode 100644 sysdeps/unix/sysv/linux/riscv/makecontext.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/register-dump.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/jmp_buf-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/setcontext.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/swapcontext.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sys/cachectl.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sys/procfs.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sys/user.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep-cancel.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/ucontext-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/ucontext_i.sym

diff --git a/sysdeps/riscv/nptl/pthread-offsets.h b/sysdeps/riscv/nptl/pthread-offsets.h
new file mode 100644
index 000000000000..940f496b37e2
--- /dev/null
+++ b/sysdeps/riscv/nptl/pthread-offsets.h
@@ -0,0 +1,24 @@
+/* RISC-V pthread offsets
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define __PTHREAD_MUTEX_NUSERS_OFFSET   12
+#define __PTHREAD_MUTEX_KIND_OFFSET     16
+#define __PTHREAD_MUTEX_SPINS_OFFSET    20
+#define __PTHREAD_MUTEX_ELISION_OFFSET  22
+#define __PTHREAD_MUTEX_LIST_OFFSET     24
diff --git a/sysdeps/riscv/nptl/pthreaddef.h b/sysdeps/riscv/nptl/pthreaddef.h
new file mode 100644
index 000000000000..4919be835c63
--- /dev/null
+++ b/sysdeps/riscv/nptl/pthreaddef.h
@@ -0,0 +1,32 @@
+/* pthread machine parameter definitions,  RISC-V version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE	(2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  */
+#define STACK_ALIGN		16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK	2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT		16
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME	__builtin_frame_address (0)
diff --git a/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
new file mode 100644
index 000000000000..e903c7e0df2a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
@@ -0,0 +1,2 @@
+#define __longjmp ____longjmp_chk
+#include <__longjmp.S>
diff --git a/sysdeps/unix/sysv/linux/riscv/bits/fcntl.h b/sysdeps/unix/sysv/linux/riscv/bits/fcntl.h
new file mode 100644
index 000000000000..d8cd045319b1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/bits/fcntl.h
@@ -0,0 +1,62 @@
+/* O_*, F_*, FD_* bit values for Linux / RISC-V.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+/* In 64-bit ISA files are always with 64bit off_t and F_*LK64 are the same as
+ * non-64-bit versions.  It will need to be revised for 128-bit.  */
+#if __WORDSIZE == 64
+# define __O_LARGEFILE	0
+
+# define F_GETLK64	5	/* Get record locking info.  */
+# define F_SETLK64	6	/* Set record locking info (non-blocking).  */
+# define F_SETLKW64	7	/* Set record locking info (blocking).	*/
+#endif
+
+struct flock
+  {
+    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    short int l_whence; /* Where `l_start' is relative to (like `lseek').  */
+#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
+    __off_t l_start;    /* Offset where the lock begins.  */
+    __off_t l_len;      /* Size of the locked area; zero means until EOF.  */
+#else
+    __off64_t l_start;  /* Offset where the lock begins.  */
+    __off64_t l_len;    /* Size of the locked area; zero means until EOF.  */
+#endif
+    __pid_t l_pid;      /* Process holding the lock.  */
+  };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+  {
+    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    short int l_whence; /* Where `l_start' is relative to (like `lseek').  */
+    __off64_t l_start;  /* Offset where the lock begins.  */
+    __off64_t l_len;    /* Size of the locked area; zero means until EOF.  */
+    __pid_t l_pid;      /* Process holding the lock.  */
+  };
+#endif
+
+/* Include generic Linux declarations.  */
+#include <bits/fcntl-linux.h>
diff --git a/sysdeps/unix/sysv/linux/riscv/bits/mman.h b/sysdeps/unix/sysv/linux/riscv/bits/mman.h
new file mode 100644
index 000000000000..92d3e136aaf1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/bits/mman.h
@@ -0,0 +1,36 @@
+/* Definitions for POSIX memory map interface.  Linux/RISC-V version.
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN	0x00100		/* Stack-like segment.  */
+# define MAP_DENYWRITE	0x00800		/* ETXTBSY */
+# define MAP_EXECUTABLE	0x01000		/* Mark it as an executable.  */
+# define MAP_LOCKED	0x02000		/* Lock the mapping.  */
+# define MAP_NORESERVE	0x04000		/* Don't check for reservations.  */
+# define MAP_POPULATE	0x08000		/* Populate (prefault) pagetables.  */
+# define MAP_NONBLOCK	0x10000		/* Do not block on IO.  */
+# define MAP_STACK	0x20000		/* Allocation is for a stack.  */
+# define MAP_HUGETLB	0x40000		/* Create huge page mapping.  */
+#endif
+
+/* Include generic Linux declarations.  */
+#include <bits/mman-linux.h>
diff --git a/sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h b/sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h
new file mode 100644
index 000000000000..0f760244f9fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h
@@ -0,0 +1,32 @@
+/* Machine-dependent signal context structure for Linux.  RISC-V version.
+   Copyright (C) 1996-2017 Free Software
+   Foundation, Inc.  This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_SIGCONTEXT_H
+#define _BITS_SIGCONTEXT_H 1
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+struct sigcontext {
+  /* gregs[0] holds the program counter. */
+  unsigned long gregs[32];
+  unsigned long long fpregs[66] __attribute__((aligned(16)));
+};
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/flush-icache.c b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
new file mode 100644
index 000000000000..de2baa1eb5a5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
@@ -0,0 +1,61 @@
+/* RISC-V instruction cache flushing VDSO calls
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dl-vdso.h>
+#include <stdlib.h>
+#include <atomic.h>
+#include <sys/cachectl.h>
+
+typedef int (*func_type) (void *, void *, unsigned long);
+
+static func_type
+__lookup_riscv_flush_icache (void)
+{
+  PREPARE_VERSION_KNOWN (linux_version, LINUX_4_15);
+
+  func_type func = _dl_vdso_vsym ("__vdso_flush_icache", &linux_version);
+
+  /* The vDSO is required, as there is no exposed system call equivalent.  */
+  if (!func)
+    abort ();
+
+  return func;
+}
+
+#ifdef SHARED
+
+#define INIT_ARCH()
+libc_ifunc (__riscv_flush_icache, __lookup_riscv_flush_icache ())
+
+#else
+
+int
+__riscv_flush_icache (void *start, void *end, unsigned long flags)
+{
+  static volatile func_type cached_func;
+
+  func_type func = cached_func;
+
+  if (!func)
+    cached_func = func = __lookup_riscv_flush_icache ();
+
+  return func (start, end, flags);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/getcontext.S b/sysdeps/unix/sysv/linux/riscv/getcontext.S
new file mode 100644
index 000000000000..0203ce49c2eb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/getcontext.S
@@ -0,0 +1,77 @@
+/* Save current context.
+   Copyright (C) 2009-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "ucontext-macros.h"
+
+/* int getcontext (ucontext_t *ucp) */
+
+	.text
+LEAF (__getcontext)
+	SAVE_INT_REG (ra,   0, a0)
+	SAVE_INT_REG (ra,   1, a0)
+	SAVE_INT_REG (sp,   2, a0)
+	SAVE_INT_REG (s0,   8, a0)
+	SAVE_INT_REG (s1,   9, a0)
+	SAVE_INT_REG (x0,  10, a0)	/* return 0 */
+	SAVE_INT_REG (s2,  18, a0)
+	SAVE_INT_REG (s3,  19, a0)
+	SAVE_INT_REG (s4,  20, a0)
+	SAVE_INT_REG (s5,  21, a0)
+	SAVE_INT_REG (s6,  22, a0)
+	SAVE_INT_REG (s7,  23, a0)
+	SAVE_INT_REG (s8,  24, a0)
+	SAVE_INT_REG (s9,  25, a0)
+	SAVE_INT_REG (s10, 26, a0)
+	SAVE_INT_REG (s11, 27, a0)
+
+#ifndef __riscv_float_abi_soft
+	frsr	a1
+
+	SAVE_FP_REG (fs0,   8, a0)
+	SAVE_FP_REG (fs1,   9, a0)
+	SAVE_FP_REG (fs2,  18, a0)
+	SAVE_FP_REG (fs3,  19, a0)
+	SAVE_FP_REG (fs4,  20, a0)
+	SAVE_FP_REG (fs5,  21, a0)
+	SAVE_FP_REG (fs6,  22, a0)
+	SAVE_FP_REG (fs7,  23, a0)
+	SAVE_FP_REG (fs8,  24, a0)
+	SAVE_FP_REG (fs9,  25, a0)
+	SAVE_FP_REG (fs10, 26, a0)
+	SAVE_FP_REG (fs11, 27, a0)
+
+	sw	a1, MCONTEXT_FSR(a0)
+#endif /* __riscv_float_abi_soft */
+
+/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+	li	a3, _NSIG8
+	add     a2, a0, UCONTEXT_SIGMASK
+	mv	a1, zero
+	li	a0, SIG_BLOCK
+
+	li	a7, SYS_ify (rt_sigprocmask)
+	scall
+	bltz	a0, 99f
+
+	ret
+
+99:	j	__syscall_error
+
+PSEUDO_END (__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/riscv/init-first.c b/sysdeps/unix/sysv/linux/riscv/init-first.c
new file mode 100644
index 000000000000..69deefd030e6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/init-first.c
@@ -0,0 +1,56 @@
+/* RISC-V VDSO initialization
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+long (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *) attribute_hidden;
+long (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
+long (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *)
+    attribute_hidden;
+long (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *)
+    attribute_hidden;
+
+static inline void
+_libc_vdso_platform_setup (void)
+{
+  PREPARE_VERSION_KNOWN (linux_version, LINUX_4_15);
+
+  void *p = _dl_vdso_vsym ("__vdso_getcpu", &linux_version);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL(getcpu) = p;
+
+  p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux_version);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL(gettimeofday) = p;
+
+  p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux_version);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL(clock_gettime) = p;
+
+  p = _dl_vdso_vsym ("__vdso_clock_getres", &linux_version);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL(clock_getres) = p;
+}
+
+# define VDSO_SETUP _libc_vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/libc-vdso.h b/sysdeps/unix/sysv/linux/riscv/libc-vdso.h
new file mode 100644
index 000000000000..dc7f5edb186e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/libc-vdso.h
@@ -0,0 +1,38 @@
+/* RISC-V VDSO function declarations
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#ifdef SHARED
+
+# include <sysdep-vdso.h>
+
+extern long (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *)
+    attribute_hidden;
+extern long (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
+    attribute_hidden;
+extern long (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *)
+    attribute_hidden;
+extern long (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *)
+    attribute_hidden;
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/riscv/libthread_db.abilist b/sysdeps/unix/sysv/linux/riscv/libthread_db.abilist
new file mode 100644
index 000000000000..3d34d7834f15
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/libthread_db.abilist
@@ -0,0 +1,41 @@
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 td_init F
+GLIBC_2.27 td_log F
+GLIBC_2.27 td_symbol_list F
+GLIBC_2.27 td_ta_clear_event F
+GLIBC_2.27 td_ta_delete F
+GLIBC_2.27 td_ta_enable_stats F
+GLIBC_2.27 td_ta_event_addr F
+GLIBC_2.27 td_ta_event_getmsg F
+GLIBC_2.27 td_ta_get_nthreads F
+GLIBC_2.27 td_ta_get_ph F
+GLIBC_2.27 td_ta_get_stats F
+GLIBC_2.27 td_ta_map_id2thr F
+GLIBC_2.27 td_ta_map_lwp2thr F
+GLIBC_2.27 td_ta_new F
+GLIBC_2.27 td_ta_reset_stats F
+GLIBC_2.27 td_ta_set_event F
+GLIBC_2.27 td_ta_setconcurrency F
+GLIBC_2.27 td_ta_thr_iter F
+GLIBC_2.27 td_ta_tsd_iter F
+GLIBC_2.27 td_thr_clear_event F
+GLIBC_2.27 td_thr_dbresume F
+GLIBC_2.27 td_thr_dbsuspend F
+GLIBC_2.27 td_thr_event_enable F
+GLIBC_2.27 td_thr_event_getmsg F
+GLIBC_2.27 td_thr_get_info F
+GLIBC_2.27 td_thr_getfpregs F
+GLIBC_2.27 td_thr_getgregs F
+GLIBC_2.27 td_thr_getxregs F
+GLIBC_2.27 td_thr_getxregsize F
+GLIBC_2.27 td_thr_set_event F
+GLIBC_2.27 td_thr_setfpregs F
+GLIBC_2.27 td_thr_setgregs F
+GLIBC_2.27 td_thr_setprio F
+GLIBC_2.27 td_thr_setsigpending F
+GLIBC_2.27 td_thr_setxregs F
+GLIBC_2.27 td_thr_sigsetmask F
+GLIBC_2.27 td_thr_tls_get_addr F
+GLIBC_2.27 td_thr_tlsbase F
+GLIBC_2.27 td_thr_tsd F
+GLIBC_2.27 td_thr_validate F
diff --git a/sysdeps/unix/sysv/linux/riscv/makecontext.c b/sysdeps/unix/sysv/linux/riscv/makecontext.c
new file mode 100644
index 000000000000..ba393aad3bfe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/makecontext.c
@@ -0,0 +1,71 @@
+/* Create new context.  RISC-V version.
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <sys/ucontext.h>
+#include <stdarg.h>
+#include <assert.h>
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc,
+	       long a0, long a1, long a2, long a3, long a4, ...)
+{
+  extern void __start_context (void) attribute_hidden;
+  long i, sp;
+
+  _Static_assert (REG_NARGS == 8, "__makecontext assumes 8 argument registers");
+
+  /* Set up the stack. */
+  sp = ((long)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ALMASK;
+
+  /* Set up the register context.
+     ra = s0 = 0, terminating the stack for backtracing purposes.
+     s1 = the function we must call.
+     s2 = the subsequent context to run.  */
+  ucp->uc_mcontext.gregs.byindex[REG_RA] = 0;
+  ucp->uc_mcontext.gregs.byindex[REG_S0 + 0] = 0;
+  ucp->uc_mcontext.gregs.byindex[REG_S0 + 1] = (long)func;
+  ucp->uc_mcontext.gregs.byindex[REG_S0 + 2] = (long)ucp->uc_link;
+  ucp->uc_mcontext.gregs.byindex[REG_SP] = sp;
+  ucp->uc_mcontext.gregs.byindex[REG_PC] = (long)&__start_context;
+
+  /* Put args in a0-a7, then put any remaining args on the stack. */
+  ucp->uc_mcontext.gregs.byindex[REG_A0 + 0] = a0;
+  ucp->uc_mcontext.gregs.byindex[REG_A0 + 1] = a1;
+  ucp->uc_mcontext.gregs.byindex[REG_A0 + 2] = a2;
+  ucp->uc_mcontext.gregs.byindex[REG_A0 + 3] = a3;
+  ucp->uc_mcontext.gregs.byindex[REG_A0 + 4] = a4;
+
+  if (__builtin_expect (argc > 5, 0))
+    {
+      va_list vl;
+      va_start (vl, a4);
+
+      long reg_args = argc < REG_NARGS ? argc : REG_NARGS;
+      sp = (sp - (argc - reg_args) * sizeof (long)) & ALMASK;
+      for (i = 5; i < reg_args; i++)
+        ucp->uc_mcontext.gregs.byindex[REG_A0 + i] = va_arg (vl, long);
+      for (i = 0; i < argc - reg_args; i++)
+        ((long*)sp)[i] = va_arg (vl, long);
+
+      va_end (vl);
+    }
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/riscv/register-dump.h b/sysdeps/unix/sysv/linux/riscv/register-dump.h
new file mode 100644
index 000000000000..e5c53f920fba
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/register-dump.h
@@ -0,0 +1,63 @@
+/* Dump registers.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+#include <string.h>
+#include <_itoa.h>
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+  char *cp = _itoa_word (value, buf + len, 16, 0);
+  while (cp > buf)
+    *--cp = '0';
+}
+
+#define REGDUMP_NREGS 32
+#define REGDUMP_PER_LINE (80 / (__WORDSIZE/4 + 4))
+
+static void
+register_dump (int fd, ucontext_t *ctx)
+{
+  int i;
+  char regvalue[__WORDSIZE/4 + 1];
+  char str[82 * ((REGDUMP_NREGS + REGDUMP_PER_LINE - 1) / REGDUMP_PER_LINE)];
+
+  static const char names[REGDUMP_NREGS][4] = {
+    "pc", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
+    "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
+    "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
+    "s8", "s9", "sA", "sB", "t3", "t4", "t5", "t6"
+  };
+
+  str[0] = 0;
+  for (i = 0; i < REGDUMP_NREGS; i++)
+    {
+      strcat (str, names[i]);
+      strcat (str, " ");
+      hexvalue (ctx->uc_mcontext.gregs.byindex[i], regvalue, __WORDSIZE/4);
+      strcat (str, regvalue);
+
+      if ((i + 1) % REGDUMP_PER_LINE == 0)
+	strcat (str, "\n");
+    }
+
+  write (fd, str, strlen (str));
+}
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h
new file mode 100644
index 000000000000..dba7d27c0910
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h
@@ -0,0 +1,53 @@
+/* jump buffer constants for RISC-V
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Produced by this program:
+  
+   #include <stdio.h>
+   #include <unistd.h>
+   #include <setjmp.h>
+   #include <stddef.h>
+   
+   int main(int argc, char **argv)
+   {
+       printf("#define JMP_BUF_SIZE %d\n", sizeof(jmp_buf));
+       printf("#define JMP_BUF_ALIGN %d\n", __alignof__(jmp_buf));
+       printf("#define SIGJMP_BUF_SIZE %d\n", sizeof(sigjmp_buf));
+       printf("#define SIGJMP_BUF_ALIGN %d\n", __alignof__(sigjmp_buf));
+       printf("#define MASK_WAS_SAVED_OFFSET %d\n", offsetof(struct __jmp_buf_tag, __mask_was_saved));
+       printf("#define SAVED_MASK_OFFSET %d\n", offsetof(struct __jmp_buf_tag, __saved_mask));
+   } */
+
+#if defined(__riscv_float_abi_soft)
+# define JMP_BUF_SIZE 188
+# define JMP_BUF_ALIGN 4
+# define SIGJMP_BUF_SIZE 188
+# define SIGJMP_BUF_ALIGN 4
+# define MASK_WAS_SAVED_OFFSET 56
+# define SAVED_MASK_OFFSET 60
+#elif defined(__riscv_float_abi_double)
+# define JMP_BUF_SIZE 288
+# define JMP_BUF_ALIGN 8
+# define SIGJMP_BUF_SIZE 288
+# define SIGJMP_BUF_ALIGN 8
+# define MASK_WAS_SAVED_OFFSET 152
+# define SAVED_MASK_OFFSET 156
+#else
+# error "Unknown RISC-V floating-point ABI"
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/riscv/rv64/jmp_buf-macros.h
new file mode 100644
index 000000000000..67d6ff85803f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/jmp_buf-macros.h
@@ -0,0 +1,53 @@
+/* jump buffer constants for RISC-V
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Produced by this program:
+  
+   #include <stdio.h>
+   #include <unistd.h>
+   #include <setjmp.h>
+   #include <stddef.h>
+   
+   int main(int argc, char **argv)
+   {
+       printf("#define JMP_BUF_SIZE %d\n", sizeof(jmp_buf));
+       printf("#define JMP_BUF_ALIGN %d\n", __alignof__(jmp_buf));
+       printf("#define SIGJMP_BUF_SIZE %d\n", sizeof(sigjmp_buf));
+       printf("#define SIGJMP_BUF_ALIGN %d\n", __alignof__(sigjmp_buf));
+       printf("#define MASK_WAS_SAVED_OFFSET %d\n", offsetof(struct __jmp_buf_tag, __mask_was_saved));
+       printf("#define SAVED_MASK_OFFSET %d\n", offsetof(struct __jmp_buf_tag, __saved_mask));
+   } */
+
+#if defined(__riscv_float_abi_soft)
+# define JMP_BUF_SIZE 248
+# define JMP_BUF_ALIGN 8
+# define SIGJMP_BUF_SIZE 248
+# define SIGJMP_BUF_ALIGN 8
+# define MASK_WAS_SAVED_OFFSET 112
+# define SAVED_MASK_OFFSET 120
+#elif defined(__riscv_float_abi_double)
+# define JMP_BUF_SIZE 344
+# define JMP_BUF_ALIGN 8
+# define SIGJMP_BUF_SIZE 344
+# define SIGJMP_BUF_ALIGN 8
+# define MASK_WAS_SAVED_OFFSET 208
+# define SAVED_MASK_OFFSET 216
+#else
+# error "Unknown RISC-V floating-point ABI"
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/setcontext.S b/sysdeps/unix/sysv/linux/riscv/setcontext.S
new file mode 100644
index 000000000000..27c14dd9da3f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/setcontext.S
@@ -0,0 +1,114 @@
+/* Set current context.
+   Copyright (C) 2009-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "ucontext-macros.h"
+
+/*  int __setcontext (const ucontext_t *ucp)
+
+  Restores the machine context in UCP and thereby resumes execution
+  in that context.
+
+  This implementation is intended to be used for *synchronous* context
+  switches only.  Therefore, it does not have to restore anything
+  other than the PRESERVED state.  */
+
+	.text
+LEAF (__setcontext)
+
+	mv	t0, a0					/* t0 <- ucp */
+
+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
+	li	a3, _NSIG8
+	mv	a2, zero
+	add     a1, a0, UCONTEXT_SIGMASK
+	li	a0, SIG_SETMASK
+
+	li	a7, SYS_ify (rt_sigprocmask)
+	scall
+
+	bltz	a0, 99f
+
+	cfi_def_cfa (t0, 0)
+
+#ifndef __riscv_float_abi_soft
+	lw	t1, MCONTEXT_FSR(t0)
+
+	RESTORE_FP_REG_CFI (fs0,   8, t0)
+	RESTORE_FP_REG_CFI (fs1,   9, t0)
+	RESTORE_FP_REG_CFI (fs2,  18, t0)
+	RESTORE_FP_REG_CFI (fs3,  19, t0)
+	RESTORE_FP_REG_CFI (fs4,  20, t0)
+	RESTORE_FP_REG_CFI (fs5,  21, t0)
+	RESTORE_FP_REG_CFI (fs6,  22, t0)
+	RESTORE_FP_REG_CFI (fs7,  23, t0)
+	RESTORE_FP_REG_CFI (fs8,  24, t0)
+	RESTORE_FP_REG_CFI (fs9,  25, t0)
+	RESTORE_FP_REG_CFI (fs10, 26, t0)
+	RESTORE_FP_REG_CFI (fs11, 27, t0)
+
+	fssr	t1
+#endif /* __riscv_float_abi_soft */
+
+	/* Note the contents of argument registers will be random
+	   unless makecontext() has been called.  */
+	RESTORE_INT_REG     (t1,   0, t0)
+	RESTORE_INT_REG_CFI (ra,   1, t0)
+	RESTORE_INT_REG     (sp,   2, t0)
+	RESTORE_INT_REG_CFI (s0,   8, t0)
+	RESTORE_INT_REG_CFI (s1,   9, t0)
+	RESTORE_INT_REG     (a0,  10, t0)
+	RESTORE_INT_REG     (a1,  11, t0)
+	RESTORE_INT_REG     (a2,  12, t0)
+	RESTORE_INT_REG     (a3,  13, t0)
+	RESTORE_INT_REG     (a4,  14, t0)
+	RESTORE_INT_REG     (a5,  15, t0)
+	RESTORE_INT_REG     (a6,  16, t0)
+	RESTORE_INT_REG     (a7,  17, t0)
+	RESTORE_INT_REG_CFI (s2,  18, t0)
+	RESTORE_INT_REG_CFI (s3,  19, t0)
+	RESTORE_INT_REG_CFI (s4,  20, t0)
+	RESTORE_INT_REG_CFI (s5,  21, t0)
+	RESTORE_INT_REG_CFI (s6,  22, t0)
+	RESTORE_INT_REG_CFI (s7,  23, t0)
+	RESTORE_INT_REG_CFI (s8,  24, t0)
+	RESTORE_INT_REG_CFI (s9,  25, t0)
+	RESTORE_INT_REG_CFI (s10, 26, t0)
+	RESTORE_INT_REG_CFI (s11, 27, t0)
+
+	jr	t1
+
+99:	j	__syscall_error
+
+PSEUDO_END (__setcontext)
+weak_alias (__setcontext, setcontext)
+
+LEAF (__start_context)
+
+	/* Terminate call stack by noting ra == 0.  Happily, s0 == 0 here.  */
+	cfi_register (ra, s0)
+
+	/* Call the function passed to makecontext.  */
+	jalr	s1
+
+	/* Invoke subsequent context if present, else exit(0).  */
+	mv	a0, s2
+	beqz	s2, 1f
+	jal	__setcontext
+1:	j	exit
+
+PSEUDO_END (__start_context)
diff --git a/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
new file mode 100644
index 000000000000..6db65eaa023e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
@@ -0,0 +1,28 @@
+/* RISC-V definitions for signal handling calling conventions.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/ucontext.h>
+
+#define SIGCONTEXT siginfo_t *_si, ucontext_t *
+#define SIGCONTEXT_EXTRA_ARGS _si,
+#define GET_PC(ctx)	((void *) ctx->uc_mcontext.gregs.byindex[REG_PC])
+#define GET_FRAME(ctx)	((void *) ctx->uc_mcontext.gregs.byindex[REG_S0])
+#define GET_STACK(ctx)	((void *) ctx->uc_mcontext.gregs.byindex[REG_SP])
+
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+  (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/sysdeps/unix/sysv/linux/riscv/swapcontext.S b/sysdeps/unix/sysv/linux/riscv/swapcontext.S
new file mode 100644
index 000000000000..1cbb3dcf1bdc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/swapcontext.S
@@ -0,0 +1,125 @@
+/* Save and set current context.
+   Copyright (C) 2009-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "ucontext-macros.h"
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+LEAF (__swapcontext)
+	mv	t0, a1					/* t0 <- ucp */
+
+	SAVE_INT_REG (ra,   0, a0)
+	SAVE_INT_REG (ra,   1, a0)
+	SAVE_INT_REG (sp,   2, a0)
+	SAVE_INT_REG (s0,   8, a0)
+	SAVE_INT_REG (s1,   9, a0)
+	SAVE_INT_REG (x0,  10, a0)	/* return 0 */
+	SAVE_INT_REG (s2,  18, a0)
+	SAVE_INT_REG (s3,  19, a0)
+	SAVE_INT_REG (s4,  20, a0)
+	SAVE_INT_REG (s5,  21, a0)
+	SAVE_INT_REG (s6,  22, a0)
+	SAVE_INT_REG (s7,  23, a0)
+	SAVE_INT_REG (s8,  24, a0)
+	SAVE_INT_REG (s9,  25, a0)
+	SAVE_INT_REG (s10, 26, a0)
+	SAVE_INT_REG (s11, 27, a0)
+
+#ifndef __riscv_float_abi_soft
+	frsr a1
+
+	SAVE_FP_REG (fs0,   8, a0)
+	SAVE_FP_REG (fs1,   9, a0)
+	SAVE_FP_REG (fs2,  18, a0)
+	SAVE_FP_REG (fs3,  19, a0)
+	SAVE_FP_REG (fs4,  20, a0)
+	SAVE_FP_REG (fs5,  21, a0)
+	SAVE_FP_REG (fs6,  22, a0)
+	SAVE_FP_REG (fs7,  23, a0)
+	SAVE_FP_REG (fs8,  24, a0)
+	SAVE_FP_REG (fs9,  25, a0)
+	SAVE_FP_REG (fs10, 26, a0)
+	SAVE_FP_REG (fs11, 27, a0)
+
+	sw	a1, MCONTEXT_FSR(a0)
+#endif /* __riscv_float_abi_soft */
+
+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
+	li	a3, _NSIG8
+	mv	a2, zero
+	add     a1, a0, UCONTEXT_SIGMASK
+	li	a0, SIG_SETMASK
+
+	li	a7, SYS_ify (rt_sigprocmask)
+	scall
+
+	bltz	a0, 99f
+
+#ifndef __riscv_float_abi_soft
+	lw	t1, MCONTEXT_FSR(t0)
+
+	RESTORE_FP_REG (fs0,   8, t0)
+	RESTORE_FP_REG (fs1,   9, t0)
+	RESTORE_FP_REG (fs2,  18, t0)
+	RESTORE_FP_REG (fs3,  19, t0)
+	RESTORE_FP_REG (fs4,  20, t0)
+	RESTORE_FP_REG (fs5,  21, t0)
+	RESTORE_FP_REG (fs6,  22, t0)
+	RESTORE_FP_REG (fs7,  23, t0)
+	RESTORE_FP_REG (fs8,  24, t0)
+	RESTORE_FP_REG (fs9,  25, t0)
+	RESTORE_FP_REG (fs10, 26, t0)
+	RESTORE_FP_REG (fs11, 27, t0)
+
+	fssr	t1
+#endif /* __riscv_float_abi_soft */
+
+	/* Note the contents of argument registers will be random
+	   unless makecontext() has been called.  */
+	RESTORE_INT_REG (t1,   0, t0)
+	RESTORE_INT_REG (ra,   1, t0)
+	RESTORE_INT_REG (sp,   2, t0)
+	RESTORE_INT_REG (s0,   8, t0)
+	RESTORE_INT_REG (s1,   9, t0)
+	RESTORE_INT_REG (a0,  10, t0)
+	RESTORE_INT_REG (a1,  11, t0)
+	RESTORE_INT_REG (a2,  12, t0)
+	RESTORE_INT_REG (a3,  13, t0)
+	RESTORE_INT_REG (a4,  14, t0)
+	RESTORE_INT_REG (a5,  15, t0)
+	RESTORE_INT_REG (a6,  16, t0)
+	RESTORE_INT_REG (a7,  17, t0)
+	RESTORE_INT_REG (s2,  18, t0)
+	RESTORE_INT_REG (s3,  19, t0)
+	RESTORE_INT_REG (s4,  20, t0)
+	RESTORE_INT_REG (s5,  21, t0)
+	RESTORE_INT_REG (s6,  22, t0)
+	RESTORE_INT_REG (s7,  23, t0)
+	RESTORE_INT_REG (s8,  24, t0)
+	RESTORE_INT_REG (s9,  25, t0)
+	RESTORE_INT_REG (s10, 26, t0)
+	RESTORE_INT_REG (s11, 27, t0)
+
+	jr	t1
+
+
+99:	j	__syscall_error
+
+PSEUDO_END (__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/riscv/sys/cachectl.h b/sysdeps/unix/sysv/linux/riscv/sys/cachectl.h
new file mode 100644
index 000000000000..6ba37cf7c93b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/cachectl.h
@@ -0,0 +1,31 @@
+/* RISC-V instruction cache flushing interface
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_CACHECTL_H
+#define _SYS_CACHECTL_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+extern int __riscv_flush_icache (void *start, void *end, unsigned long flags);
+
+__END_DECLS
+
+#endif /* sys/cachectl.h */
diff --git a/sysdeps/unix/sysv/linux/riscv/sys/procfs.h b/sysdeps/unix/sysv/linux/riscv/sys/procfs.h
new file mode 100644
index 000000000000..cf8fec0c354e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/procfs.h
@@ -0,0 +1,111 @@
+/* Core image file related definitions, RISC-V version.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H	1
+
+/* This is somehow modelled after the file of the same name on SysVr4
+   systems.  It provides a definition of the core file format for ELF
+   used on Linux.  */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/ucontext.h>
+
+/* ELF register definitions */
+#define ELF_NGREG	NGREG
+#define ELF_NFPREG	NFPREG
+
+typedef greg_t elf_greg_t;
+typedef gregset_t elf_gregset_t;
+typedef fpregset_t elf_fpregset_t;
+
+__BEGIN_DECLS
+
+struct elf_siginfo
+  {
+    int si_signo;			/* Signal number.  */
+    int si_code;			/* Extra code.  */
+    int si_errno;			/* Errno.  */
+  };
+
+
+/* Definitions to generate Intel SVR4-like core files.  These mostly
+   have the same names as the SVR4 types with "elf_" tacked on the
+   front to prevent clashes with linux definitions, and the typedef
+   forms have been avoided.  This is mostly like the SVR4 structure,
+   but more Linuxy, with things that Linux does not support and which
+   gdb doesn't really use excluded.  Fields present but not used are
+   marked with "XXX".  */
+struct elf_prstatus
+  {
+    struct elf_siginfo pr_info;		/* Info associated with signal.  */
+    short int pr_cursig;		/* Current signal.  */
+    unsigned long int pr_sigpend;	/* Set of pending signals.  */
+    unsigned long int pr_sighold;	/* Set of held signals.  */
+    __pid_t pr_pid;
+    __pid_t pr_ppid;
+    __pid_t pr_pgrp;
+    __pid_t pr_sid;
+    struct timeval pr_utime;		/* User time.  */
+    struct timeval pr_stime;		/* System time.  */
+    struct timeval pr_cutime;		/* Cumulative user time.  */
+    struct timeval pr_cstime;		/* Cumulative system time.  */
+    elf_gregset_t pr_reg;		/* GP registers.  */
+    int pr_fpvalid;			/* True if math copro being used.  */
+  };
+
+
+#define ELF_PRARGSZ     (80)    /* Number of chars for args */
+
+struct elf_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long int pr_flag;		/* Flags.  */
+    long pr_uid;
+    long pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+
+/* Addresses.  */
+typedef void *psaddr_t;
+
+/* Register sets.  Linux has different names.  */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+   therefore habe only ine PID type.  */
+typedef __pid_t lwpid_t;
+
+
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif	/* sys/procfs.h */
diff --git a/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
new file mode 100644
index 000000000000..0ab62b4c5f5e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
@@ -0,0 +1,126 @@
+/* struct ucontext definition, RISC-V version.
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.  
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Don't rely on this, the interface is currently messed up and may need to
+   be broken to be fixed.  */
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H	1
+
+#include <features.h>
+
+#include <bits/types/sigset_t.h>
+#include <bits/types/stack_t.h>
+#include <asm/ptrace.h>
+
+#ifdef __USE_MISC
+# define __ctx(fld) fld
+#else
+# define __ctx(fld) __ ## fld
+#endif
+
+#ifdef __USE_MISC
+
+#define NGREG	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
+#define REG_NARGS 8
+
+typedef unsigned long greg_t;
+
+/* Container for all general registers.  */
+typedef greg_t gregset_t[NGREG];
+
+/* Container for floating-point state.  */
+typedef union __riscv_fp_state fpregset_t;
+
+#endif
+
+/* These structures all must match what's in Linux.  Some are copied.  */
+struct __riscv_gp_state {
+  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;
+};
+
+typedef struct mcontext_t
+  {
+    union {
+      struct __riscv_gp_state byname;
+      unsigned long byindex[32];
+    } gregs;
+    union  __riscv_fp_state fpregs;
+  } mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext_t
+  {
+    unsigned long     uc_flags;
+    struct ucontext  *uc_link;
+    stack_t           uc_stack;
+    sigset_t          uc_sigmask;
+    /* There's some padding here to allow sigset_t to be expanded in the
+     * future.  Though this is unlikely, other architectures put uc_sigmask
+     * at the end of this structure and explicitly state it can be
+     * expanded, so we didn't want to box ourselves in here. */
+    __u8              __unused[1024 / 8 - sizeof(sigset_t)];
+    /* We can't put uc_sigmask at the end of this structure because we need
+     * to be able to expand sigcontext in the future.  For example, the
+     * vector ISA extension will almost certainly add ISA state.  We want
+     * to ensure all user-visible ISA state can be saved and restored via a
+     * ucontext, so we're putting this at the end in order to allow for
+     * infinite extensibility.  Since we know this will be extended and we
+     * assume sigset_t won't be extended an extreme amount, we're
+     * prioritizing this. */
+    mcontext_t uc_mcontext;
+  } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/sysdeps/unix/sysv/linux/riscv/sys/user.h b/sysdeps/unix/sysv/linux/riscv/sys/user.h
new file mode 100644
index 000000000000..faf307936b1e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/user.h
@@ -0,0 +1,2 @@
+/* x86 puts "struct user_regs_struct" in here, this is just a shim. */
+#include <asm/ptrace.h>
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep-cancel.h b/sysdeps/unix/sysv/linux/riscv/sysdep-cancel.h
new file mode 100644
index 000000000000..a2d4e2d15e15
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep-cancel.h
@@ -0,0 +1,129 @@
+/* Assembler macros with cancellation support, RISC-V version.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sysdeps/generic/sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+#include <sys/asm.h>
+
+/* Gas will put the initial save of $gp into the CIE, because it appears to
+   happen before any instructions.  So we use cfi_same_value instead of
+   cfi_restore.  */
+
+#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+      .align 2;								\
+  L(pseudo_start):							\
+  99: j __syscall_error;						\
+  ENTRY (name)								\
+    SINGLE_THREAD_P(t0);						\
+    bnez t0, L(pseudo_cancel);  					\
+  .type __##syscall_name##_nocancel, @function;				\
+  .globl __##syscall_name##_nocancel;					\
+  __##syscall_name##_nocancel:						\
+    li a7, SYS_ify(syscall_name);					\
+    scall;								\
+    bltz a0, 99b;							\
+    ret;								\
+  .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\
+  L(pseudo_cancel):							\
+    addi sp, sp, -STKSPACE;						\
+    REG_S ra, STKOFF_RA(sp);						\
+    cfi_rel_offset (ra, STKOFF_RA);					\
+    PUSHARGS_##args;			/* save syscall args */		\
+    CENABLE;								\
+    REG_S a0, STKOFF_SVMSK(sp);		/* save mask */			\
+    POPARGS_##args;			/* restore syscall args */	\
+    li a7, SYS_ify (syscall_name);					\
+    scall;								\
+    REG_S a0, STKOFF_A0(sp);		/* save syscall result */	\
+    REG_L a0, STKOFF_SVMSK(sp);		/* pass mask as arg1 */		\
+    CDISABLE;								\
+    REG_L ra, STKOFF_RA(sp);		/* restore return address */	\
+    REG_L a0, STKOFF_A0(sp);		/* restore syscall result */	\
+    addi sp, sp, STKSPACE;						\
+    bltz a0, 99b;							\
+  L(pseudo_end):
+
+
+# define PUSHARGS_0	/* nothing to do */
+# define PUSHARGS_1	PUSHARGS_0 REG_S a0, STKOFF_A0(sp); cfi_rel_offset (a0, STKOFF_A0);
+# define PUSHARGS_2	PUSHARGS_1 REG_S a1, STKOFF_A1(sp); cfi_rel_offset (a1, STKOFF_A1);
+# define PUSHARGS_3	PUSHARGS_2 REG_S a2, STKOFF_A2(sp); cfi_rel_offset (a2, STKOFF_A2);
+# define PUSHARGS_4	PUSHARGS_3 REG_S a3, STKOFF_A3(sp); cfi_rel_offset (a3, STKOFF_A3);
+# define PUSHARGS_5	PUSHARGS_4 REG_S a4, STKOFF_A4(sp); cfi_rel_offset (a4, STKOFF_A4);
+# define PUSHARGS_6	PUSHARGS_5 REG_S a5, STKOFF_A5(sp); cfi_rel_offset (a5, STKOFF_A5);
+
+# define POPARGS_0	/* nothing to do */
+# define POPARGS_1	POPARGS_0 REG_L a0, STKOFF_A0(sp);
+# define POPARGS_2	POPARGS_1 REG_L a1, STKOFF_A1(sp);
+# define POPARGS_3	POPARGS_2 REG_L a2, STKOFF_A2(sp);
+# define POPARGS_4	POPARGS_3 REG_L a3, STKOFF_A3(sp);
+# define POPARGS_5	POPARGS_4 REG_L a4, STKOFF_A4(sp);
+# define POPARGS_6	POPARGS_5 REG_L a5, STKOFF_A5(sp);
+
+/* Avoid D$ misses by keeping less-used arguments further down stack.  */
+# define STKOFF_A5	0
+# define STKOFF_A4	(STKOFF_A5 + SZREG)
+# define STKOFF_A3	(STKOFF_A4 + SZREG)
+# define STKOFF_A2	(STKOFF_A3 + SZREG)
+# define STKOFF_A1	(STKOFF_A2 + SZREG)
+# define STKOFF_A0	(STKOFF_A1 + SZREG)
+# define STKOFF_SVMSK	(STKOFF_A0 + SZREG)
+# define STKOFF_RA	(STKOFF_SVMSK + SZREG)
+# define STKSPACE	(STKOFF_RA + SZREG)
+
+# if IS_IN (libpthread)
+#  define CENABLE  call __pthread_enable_asynccancel
+#  define CDISABLE call __pthread_disable_asynccancel
+# elif IS_IN (librt)
+#  define CENABLE  call __librt_enable_asynccancel
+#  define CDISABLE call __librt_disable_asynccancel
+# else
+#  define CENABLE  call __libc_enable_asynccancel
+#  define CDISABLE call __libc_disable_asynccancel
+# endif
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P						\
+	__builtin_expect (THREAD_GETMEM (THREAD_SELF,			\
+					 header.multiple_threads)	\
+			  == 0, 1)
+# else
+#  include "tcb-offsets.h"
+#  define SINGLE_THREAD_P(reg)						\
+	lw reg, MULTIPLE_THREADS_OFFSET(tp)
+#endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P 1
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/ucontext-macros.h b/sysdeps/unix/sysv/linux/riscv/ucontext-macros.h
new file mode 100644
index 000000000000..9d4e8ffcde8f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/ucontext-macros.h
@@ -0,0 +1,49 @@
+/* Macros for ucontext routines.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LINUX_RISCV_UCONTEXT_MACROS_H
+#define _LINUX_RISCV_UCONTEXT_MACROS_H
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#include "ucontext_i.h"
+
+#define MCONTEXT_FSR (32 * SZFREG + MCONTEXT_FPREGS)
+
+#define SAVE_FP_REG(name, num, base)			\
+  FREG_S name, ((num) * SZFREG + MCONTEXT_FPREGS)(base)
+
+#define RESTORE_FP_REG(name, num, base)			\
+  FREG_L name, ((num) * SZFREG + MCONTEXT_FPREGS)(base)
+
+#define RESTORE_FP_REG_CFI(name, num, base)		\
+  RESTORE_FP_REG (name, num, base);			\
+  cfi_offset (name, (num) * SZFREG + MCONTEXT_FPREGS)
+
+#define SAVE_INT_REG(name, num, base)			\
+  REG_S name, ((num) * SZREG + MCONTEXT_GREGS)(base)
+
+#define RESTORE_INT_REG(name, num, base)		\
+  REG_L name, ((num) * SZREG + MCONTEXT_GREGS)(base)
+
+#define RESTORE_INT_REG_CFI(name, num, base)		\
+  RESTORE_INT_REG (name, num, base);			\
+  cfi_offset (name, (num) * SZREG + MCONTEXT_GREGS)
+
+#endif /* _LINUX_RISCV_UCONTEXT_MACROS_H */
diff --git a/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym
new file mode 100644
index 000000000000..f30ba391827c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym
@@ -0,0 +1,31 @@
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+-- Constants used by the rt_sigprocmask call.
+
+SIG_BLOCK
+SIG_SETMASK
+
+_NSIG8				(_NSIG / 8)
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member)	offsetof (ucontext_t, member)
+#define stack(member)		ucontext (uc_stack.member)
+#define mcontext(member)	ucontext (uc_mcontext.member)
+
+UCONTEXT_FLAGS			ucontext (uc_flags)
+UCONTEXT_LINK			ucontext (uc_link)
+UCONTEXT_STACK			ucontext (uc_stack)
+UCONTEXT_MCONTEXT		ucontext (uc_mcontext)
+UCONTEXT_SIGMASK		ucontext (uc_sigmask)
+
+STACK_SP			stack (ss_sp)
+STACK_SIZE			stack (ss_size)
+STACK_FLAGS			stack (ss_flags)
+
+MCONTEXT_GREGS			mcontext (gregs)
+MCONTEXT_FPREGS			mcontext (fpregs)
+
+UCONTEXT_SIZE			sizeof (ucontext_t)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 09/15] RISC-V: Atomic and Locking Routines
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (7 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 10/15] RISC-V: Linux Syscall Interface Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20 17:08   ` Joseph Myers
  2017-12-20  7:24 ` [PATCH v2 12/15] RISC-V: Linux Startup and Dynamic Loading Code Palmer Dabbelt
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This patch implements various atomic and locking routines on RISC-V,
either via the A extension (when present) or via a Linux system call
that does a compare-and-exchange.  This contains both the library
routines and the syscall wrapper.
---
 sysdeps/riscv/nptl/bits/pthreadtypes-arch.h    |  72 ++++++++
 sysdeps/riscv/nptl/bits/semaphore.h            |  33 ++++
 sysdeps/riscv/nptl/libc-lowlevellock.c         |   8 +
 sysdeps/riscv/rv64/rvd/s_roundeven.c           |   1 -
 sysdeps/riscv/rv64/rvf/s_llrintf.c             |   3 +-
 sysdeps/unix/sysv/linux/riscv/atomic-machine.h | 227 +++++++++++++++++++++++++
 6 files changed, 341 insertions(+), 3 deletions(-)
 create mode 100644 sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
 create mode 100644 sysdeps/riscv/nptl/bits/semaphore.h
 create mode 100644 sysdeps/riscv/nptl/libc-lowlevellock.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/atomic-machine.h

diff --git a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
new file mode 100644
index 000000000000..f15e024826ac
--- /dev/null
+++ b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
@@ -0,0 +1,72 @@
+/* Machine-specific pthread type layouts.  RISC-V version.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_PTHREADTYPES_ARCH_H
+#define _BITS_PTHREADTYPES_ARCH_H	1
+
+#include <endian.h>
+
+#if __riscv_xlen == 64
+# define __SIZEOF_PTHREAD_ATTR_T 		56
+# define __SIZEOF_PTHREAD_MUTEX_T 		40
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 		 4
+# define __SIZEOF_PTHREAD_COND_T 		48
+# define __SIZEOF_PTHREAD_CONDATTR_T 		 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 		56
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 		 8
+# define __SIZEOF_PTHREAD_BARRIER_T 		32
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 	 4
+#else
+# define __SIZEOF_PTHREAD_ATTR_T 		32
+# define __SIZEOF_PTHREAD_MUTEX_T 		32
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 		 4
+# define __SIZEOF_PTHREAD_COND_T 		48
+# define __SIZEOF_PTHREAD_CONDATTR_T 		 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 		48
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 		 8
+# define __SIZEOF_PTHREAD_BARRIER_T 		20
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 	 4
+#endif
+
+#define __PTHREAD_COMPAT_PADDING_MID
+#define __PTHREAD_COMPAT_PADDING_END
+#define __PTHREAD_MUTEX_LOCK_ELISION		0
+#define __PTHREAD_MUTEX_USE_UNION	 	0
+#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND	0
+
+#define __LOCK_ALIGNMENT
+#define __ONCE_ALIGNMENT
+
+struct __pthread_rwlock_arch_t
+{
+  unsigned int __readers;
+  unsigned int __writers;
+  unsigned int __wrphase_futex;
+  unsigned int __writers_futex;
+  unsigned int __pad3;
+  unsigned int __pad4;
+  int __cur_writer;
+  int __shared;
+  unsigned long int __pad1;
+  unsigned long int __pad2;
+  unsigned int __flags;
+};
+
+#define __PTHREAD_RWLOCK_ELISION_EXTRA 		0
+
+#endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/riscv/nptl/bits/semaphore.h b/sysdeps/riscv/nptl/bits/semaphore.h
new file mode 100644
index 000000000000..db6bfba34324
--- /dev/null
+++ b/sysdeps/riscv/nptl/bits/semaphore.h
@@ -0,0 +1,33 @@
+/* Machine-specific POSIX semaphore type layouts.  RISC-V version.
+   Copyright (C) 2002-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+#define __SIZEOF_SEM_T	(4 * __SIZEOF_POINTER__)
+
+/* Value returned if `sem_open' failed.  */
+#define SEM_FAILED      ((sem_t *) 0)
+
+
+typedef union
+{
+  char __size[__SIZEOF_SEM_T];
+  long int __align;
+} sem_t;
diff --git a/sysdeps/riscv/nptl/libc-lowlevellock.c b/sysdeps/riscv/nptl/libc-lowlevellock.c
new file mode 100644
index 000000000000..0ecd41e630f3
--- /dev/null
+++ b/sysdeps/riscv/nptl/libc-lowlevellock.c
@@ -0,0 +1,8 @@
+/* This kludge works around a libpthread static linking problem:
+   https://sourceware.org/bugzilla/show_bug.cgi?id=15648 */
+
+#ifndef SHARED
+# define __lll_lock_wait_private weak_function __lll_lock_wait_private
+#endif
+
+#include <lowlevellock.c>
diff --git a/sysdeps/riscv/rv64/rvd/s_roundeven.c b/sysdeps/riscv/rv64/rvd/s_roundeven.c
index 145955c3d6fc..5d857025f2c4 100644
--- a/sysdeps/riscv/rv64/rvd/s_roundeven.c
+++ b/sysdeps/riscv/rv64/rvd/s_roundeven.c
@@ -1,5 +1,4 @@
 /* Round to nearest integer value, rounding halfway cases to even.
-   RISC-V version.
    Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
diff --git a/sysdeps/riscv/rv64/rvf/s_llrintf.c b/sysdeps/riscv/rv64/rvf/s_llrintf.c
index 69f4e8ea9b56..4dc9fbc534f4 100644
--- a/sysdeps/riscv/rv64/rvf/s_llrintf.c
+++ b/sysdeps/riscv/rv64/rvf/s_llrintf.c
@@ -1,5 +1,4 @@
-/* Round argument to nearest integral value according to current rounding
-   direction.  RISC-V version.
+/* Round argument to nearest integral value according to current direction.
    Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
diff --git a/sysdeps/unix/sysv/linux/riscv/atomic-machine.h b/sysdeps/unix/sysv/linux/riscv/atomic-machine.h
new file mode 100644
index 000000000000..29a5599f5319
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/atomic-machine.h
@@ -0,0 +1,227 @@
+/* Low-level functions for atomic operations. RISC-V version.
+   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LINUX_RISCV_BITS_ATOMIC_H
+#define _LINUX_RISCV_BITS_ATOMIC_H 1
+
+#include <inttypes.h>
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+#define atomic_full_barrier() __sync_synchronize()
+
+#ifdef __riscv_atomic
+
+#define __HAVE_64B_ATOMICS (__riscv_xlen >= 64)
+#define USE_ATOMIC_COMPILER_BUILTINS 1
+#define ATOMIC_EXCHANGE_USES_CAS 0
+
+/* Compare and exchange.
+   For all "bool" routines, we return FALSE if exchange succesful.  */
+
+# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+#  define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				  model, __ATOMIC_RELAXED);		\
+  })
+
+# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+#  define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
+  ({									\
+    typeof (*mem) __oldval = (oldval);					\
+    __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0,	\
+				 model, __ATOMIC_RELAXED);		\
+    __oldval;								\
+  })
+
+/* Atomic compare and exchange. */
+
+# define atomic_compare_and_exchange_bool_acq(mem, new, old)	\
+  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,	\
+			mem, new, old, __ATOMIC_ACQUIRE)
+
+# define atomic_compare_and_exchange_val_acq(mem, new, old)	\
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,	\
+		       mem, new, old, __ATOMIC_ACQUIRE)
+
+# define atomic_compare_and_exchange_val_rel(mem, new, old)	 \
+  __atomic_val_bysize (__arch_compare_and_exchange_val, int,    \
+                       mem, new, old, __ATOMIC_RELEASE)
+
+/* Atomic exchange (without compare).  */
+
+# define __arch_exchange_8_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+# define __arch_exchange_16_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+# define __arch_exchange_32_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+#  define __arch_exchange_64_int(mem, newval, model)	\
+  __atomic_exchange_n (mem, newval, model)
+
+# define atomic_exchange_acq(mem, value)				\
+  __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
+
+# define atomic_exchange_rel(mem, value)				\
+  __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
+
+/* Atomically add value and return the previous (unincremented) value.  */
+
+# define __arch_exchange_and_add_8_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+# define __arch_exchange_and_add_16_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+# define __arch_exchange_and_add_32_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+#  define __arch_exchange_and_add_64_int(mem, value, model)	\
+  __atomic_fetch_add (mem, value, model)
+
+# define atomic_exchange_and_add_acq(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       __ATOMIC_ACQUIRE)
+
+# define atomic_exchange_and_add_rel(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       __ATOMIC_RELEASE)
+
+/* Miscellaneous. */
+
+#define asm_amo(which, ordering, mem, value) ({ 		\
+  __atomic_check_size(mem);					\
+  typeof(*mem) __tmp; 						\
+  if (sizeof(__tmp) == 4)					\
+    asm volatile (which ".w" ordering "\t%0, %z2, %1"		\
+		  : "=r"(__tmp), "+A"(*(mem))			\
+		  : "rJ"(value));				\
+  else if (sizeof(__tmp) == 8)					\
+    asm volatile (which ".d" ordering "\t%0, %z2, %1"		\
+		  : "=r"(__tmp), "+A"(*(mem))			\
+		  : "rJ"(value));				\
+  else								\
+    abort();							\
+  __tmp; })
+
+#define atomic_max(mem, value) asm_amo("amomaxu", ".aq", mem, value)
+#define atomic_min(mem, value) asm_amo("amominu", ".aq", mem, value)
+
+#define atomic_bit_test_set(mem, bit)                   \
+  ({ typeof(*mem) __mask = (typeof(*mem))1 << (bit);    \
+     asm_amo("amoor", ".aq", mem, __mask) & __mask; })
+
+#define catomic_exchange_and_add(mem, value)		\
+  atomic_exchange_and_add(mem, value)
+#define catomic_max(mem, value) atomic_max(mem, value)
+
+#else /* __riscv_atomic */
+
+/* If the A (atomic) extension is not present, we need help from the
+   kernel to do atomic accesses.  Linux provides two system calls for
+   this purpose.  RISCV_ATOMIC_CMPXCHG will perform an atomic compare
+   and exchange operation for a 32-bit value.  RISCV_ATOMIC_CMPXCHG64
+   will do the same for a 64-bit value. */
+
+#include <sys/syscall.h>
+#include <sysdep.h>
+
+#define __HAVE_64B_ATOMICS (__riscv_xlen >= 64)
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+  (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+  (abort (), (__typeof (*mem)) 0)
+
+/* The only basic operation needed is compare and exchange.  */
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    (__typeof (*mem)) INTERNAL_SYSCALL (sysriscv, __err, 4,		      \
+		      RISCV_ATOMIC_CMPXCHG, mem, oldval, newval);	      \
+  })
+
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    (__typeof (*mem)) INTERNAL_SYSCALL (sysriscv, __err, 4,		      \
+		      RISCV_ATOMIC_CMPXCHG64, mem, oldval, newval);	      \
+  })
+
+#endif /* !__riscv_atomic */
+
+#endif /* bits/atomic.h */
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 12/15] RISC-V: Linux Startup and Dynamic Loading Code
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (8 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 09/15] RISC-V: Atomic and Locking Routines Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20  7:24 ` [PATCH v2 13/15] Add RISC-V dynamic relocations to elf.h Palmer Dabbelt
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This contains the Linux-specific code for loading programs on RISC-V.
---
 sysdeps/unix/sysv/linux/riscv/dl-static.c | 84 +++++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/ldconfig.h  | 37 ++++++++++++++
 sysdeps/unix/sysv/linux/riscv/ldsodefs.h  | 32 ++++++++++++
 3 files changed, 153 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/riscv/dl-static.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/ldconfig.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/ldsodefs.h

diff --git a/sysdeps/unix/sysv/linux/riscv/dl-static.c b/sysdeps/unix/sysv/linux/riscv/dl-static.c
new file mode 100644
index 000000000000..e5572d1fffe2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/dl-static.c
@@ -0,0 +1,84 @@
+/* Variable initialization.  RISC-V version
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <ldsodefs.h>
+
+#ifdef SHARED
+
+void
+_dl_var_init (void *array[])
+{
+  /* It has to match "variables" below. */
+  enum
+    {
+      DL_PAGESIZE = 0
+    };
+
+  GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]);
+}
+
+#else
+
+static void *variables[] =
+{
+  &GLRO(dl_pagesize)
+};
+
+static void
+_dl_unprotect_relro (struct link_map *l)
+{
+  ElfW(Addr) start = ((l->l_addr + l->l_relro_addr)
+		      & ~(GLRO(dl_pagesize) - 1));
+  ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size)
+		    & ~(GLRO(dl_pagesize) - 1));
+
+  if (start != end)
+    __mprotect ((void *) start, end - start, PROT_READ | PROT_WRITE);
+}
+
+void
+_dl_static_init (struct link_map *l)
+{
+  struct link_map *rtld_map = l;
+  struct r_scope_elem **scope;
+  const ElfW(Sym) *ref = NULL;
+  lookup_t loadbase;
+  void (*f) (void *[]);
+  size_t i;
+
+  loadbase = _dl_lookup_symbol_x ("_dl_var_init", l, &ref, l->l_local_scope,
+				  NULL, 0, 1, NULL);
+
+  for (scope = l->l_local_scope; *scope != NULL; scope++)
+    for (i = 0; i < (*scope)->r_nlist; i++)
+      if ((*scope)->r_list[i] == loadbase)
+	{
+	  rtld_map = (*scope)->r_list[i];
+	  break;
+	}
+
+  if (ref != NULL)
+    {
+      f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref);
+      _dl_unprotect_relro (rtld_map);
+      f (variables);
+      _dl_protect_relro (rtld_map);
+    }
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/ldconfig.h b/sysdeps/unix/sysv/linux/riscv/ldconfig.h
new file mode 100644
index 000000000000..de1f2a8ad811
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/ldconfig.h
@@ -0,0 +1,37 @@
+/* ldconfig default paths and libraries.  Linux/RISC-V version.
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/generic/ldconfig.h>
+
+#define LD_SO_PREFIX "/lib/ld-linux-"
+#define LD_SO_SUFFIX ".so.1"
+
+#if __riscv_xlen == 64
+# define LD_SO_ABI "riscv64-lp64"
+#else
+# define LD_SO_ABI "riscv32-ilp32"
+#endif
+
+#define SYSDEP_KNOWN_INTERPRETER_NAMES				\
+  { LD_SO_PREFIX LD_SO_ABI "d" LD_SO_SUFFIX, FLAG_ELF_LIBC6 },	\
+  { LD_SO_PREFIX LD_SO_ABI "f" LD_SO_SUFFIX, FLAG_ELF_LIBC6 },	\
+  { LD_SO_PREFIX LD_SO_ABI     LD_SO_SUFFIX, FLAG_ELF_LIBC6 },
+
+#define SYSDEP_KNOWN_LIBRARY_NAMES	\
+  { "libc.so.6", FLAG_ELF_LIBC6 },	\
+  { "libm.so.6", FLAG_ELF_LIBC6 },
diff --git a/sysdeps/unix/sysv/linux/riscv/ldsodefs.h b/sysdeps/unix/sysv/linux/riscv/ldsodefs.h
new file mode 100644
index 000000000000..314de0b201d5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/ldsodefs.h
@@ -0,0 +1,32 @@
+/* RISC-V dynamic linker data structures for loaded ELF shared objects.
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_LDSODEFS_H
+
+/* Get the real definitions.  */
+#include_next <ldsodefs.h>
+
+/* Now define our stuff.  */
+
+/* We need special support to initialize DSO loaded for statically linked
+   binaries.  */
+extern void _dl_static_init (struct link_map *map);
+#undef DL_STATIC_INIT
+#define DL_STATIC_INIT(map) _dl_static_init (map)
+
+#endif /* ldsodefs.h */
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 07/15] RISC-V: RV32F Support
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (13 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 08/15] RISC-V: RV32D, RV64F, and RV64D Support Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20 17:01   ` Joseph Myers
  2017-12-20 16:04 ` RISC-V glibc port v2 Joseph Myers
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This contains the base floating-point support for RISC-V, which is
defined by the F extension.  The code in this patch sufficies to
implement RV32F systems only, additional routines are necessary to add
support for RV32D, RV64F, and RV64D.  These additional routines have
been split out to avoid having too large of a patch.
---
 sysdeps/riscv/e_sqrtl.c               |   1 +
 sysdeps/riscv/rvf/e_sqrtf.c           |  27 ++++++
 sysdeps/riscv/rvf/fclrexcpt.c         |  28 ++++++
 sysdeps/riscv/rvf/fegetenv.c          |  32 +++++++
 sysdeps/riscv/rvf/fegetmode.c         |  27 ++++++
 sysdeps/riscv/rvf/fegetround.c        |  29 ++++++
 sysdeps/riscv/rvf/feholdexcpt.c       |  30 +++++++
 sysdeps/riscv/rvf/fesetenv.c          |  30 +++++++
 sysdeps/riscv/rvf/fesetexcept.c       |  26 ++++++
 sysdeps/riscv/rvf/fesetmode.c         |  31 +++++++
 sysdeps/riscv/rvf/fesetround.c        |  39 ++++++++
 sysdeps/riscv/rvf/feupdateenv.c       |  30 +++++++
 sysdeps/riscv/rvf/fgetexcptflg.c      |  30 +++++++
 sysdeps/riscv/rvf/fraiseexcpt.c       |  30 +++++++
 sysdeps/riscv/rvf/fsetexcptflg.c      |  30 +++++++
 sysdeps/riscv/rvf/ftestexcept.c       |  27 ++++++
 sysdeps/riscv/rvf/get-rounding-mode.h |  32 +++++++
 sysdeps/riscv/rvf/math_private.h      | 161 ++++++++++++++++++++++++++++++++++
 sysdeps/riscv/rvf/s_ceilf.c           |  51 +++++++++++
 sysdeps/riscv/rvf/s_copysignf.c       |  28 ++++++
 sysdeps/riscv/rvf/s_finitef.c         |  28 ++++++
 sysdeps/riscv/rvf/s_floorf.c          |  51 +++++++++++
 sysdeps/riscv/rvf/s_fmaf.c            |  30 +++++++
 sysdeps/riscv/rvf/s_fmaxf.c           |  28 ++++++
 sysdeps/riscv/rvf/s_fminf.c           |  28 ++++++
 sysdeps/riscv/rvf/s_fpclassifyf.c     |  36 ++++++++
 sysdeps/riscv/rvf/s_isinff.c          |  29 ++++++
 sysdeps/riscv/rvf/s_isnanf.c          |  28 ++++++
 sysdeps/riscv/rvf/s_issignalingf.c    |  27 ++++++
 sysdeps/riscv/rvf/s_lroundf.c         |  30 +++++++
 sysdeps/riscv/rvf/s_nearbyintf.c      |  51 +++++++++++
 sysdeps/riscv/rvf/s_rintf.c           |  51 +++++++++++
 sysdeps/riscv/rvf/s_roundevenf.c      |  51 +++++++++++
 sysdeps/riscv/rvf/s_roundf.c          |  51 +++++++++++
 sysdeps/riscv/rvf/s_truncf.c          |  51 +++++++++++
 35 files changed, 1289 insertions(+)
 create mode 100644 sysdeps/riscv/e_sqrtl.c
 create mode 100644 sysdeps/riscv/rvf/e_sqrtf.c
 create mode 100644 sysdeps/riscv/rvf/fclrexcpt.c
 create mode 100644 sysdeps/riscv/rvf/fegetenv.c
 create mode 100644 sysdeps/riscv/rvf/fegetmode.c
 create mode 100644 sysdeps/riscv/rvf/fegetround.c
 create mode 100644 sysdeps/riscv/rvf/feholdexcpt.c
 create mode 100644 sysdeps/riscv/rvf/fesetenv.c
 create mode 100644 sysdeps/riscv/rvf/fesetexcept.c
 create mode 100644 sysdeps/riscv/rvf/fesetmode.c
 create mode 100644 sysdeps/riscv/rvf/fesetround.c
 create mode 100644 sysdeps/riscv/rvf/feupdateenv.c
 create mode 100644 sysdeps/riscv/rvf/fgetexcptflg.c
 create mode 100644 sysdeps/riscv/rvf/fraiseexcpt.c
 create mode 100644 sysdeps/riscv/rvf/fsetexcptflg.c
 create mode 100644 sysdeps/riscv/rvf/ftestexcept.c
 create mode 100644 sysdeps/riscv/rvf/get-rounding-mode.h
 create mode 100644 sysdeps/riscv/rvf/math_private.h
 create mode 100644 sysdeps/riscv/rvf/s_ceilf.c
 create mode 100644 sysdeps/riscv/rvf/s_copysignf.c
 create mode 100644 sysdeps/riscv/rvf/s_finitef.c
 create mode 100644 sysdeps/riscv/rvf/s_floorf.c
 create mode 100644 sysdeps/riscv/rvf/s_fmaf.c
 create mode 100644 sysdeps/riscv/rvf/s_fmaxf.c
 create mode 100644 sysdeps/riscv/rvf/s_fminf.c
 create mode 100644 sysdeps/riscv/rvf/s_fpclassifyf.c
 create mode 100644 sysdeps/riscv/rvf/s_isinff.c
 create mode 100644 sysdeps/riscv/rvf/s_isnanf.c
 create mode 100644 sysdeps/riscv/rvf/s_issignalingf.c
 create mode 100644 sysdeps/riscv/rvf/s_lroundf.c
 create mode 100644 sysdeps/riscv/rvf/s_nearbyintf.c
 create mode 100644 sysdeps/riscv/rvf/s_rintf.c
 create mode 100644 sysdeps/riscv/rvf/s_roundevenf.c
 create mode 100644 sysdeps/riscv/rvf/s_roundf.c
 create mode 100644 sysdeps/riscv/rvf/s_truncf.c

diff --git a/sysdeps/riscv/e_sqrtl.c b/sysdeps/riscv/e_sqrtl.c
new file mode 100644
index 000000000000..3241a877ac82
--- /dev/null
+++ b/sysdeps/riscv/e_sqrtl.c
@@ -0,0 +1 @@
+#include "sysdeps/aarch64/soft-fp/e_sqrtl.c"
diff --git a/sysdeps/riscv/rvf/e_sqrtf.c b/sysdeps/riscv/rvf/e_sqrtf.c
new file mode 100644
index 000000000000..b4e440d61556
--- /dev/null
+++ b/sysdeps/riscv/rvf/e_sqrtf.c
@@ -0,0 +1,27 @@
+/* Single precision floating point square root.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+
+float
+__ieee754_sqrtf (float x)
+{
+  asm ("fsqrt.s %0, %1" : "=f" (x) : "f" (x));
+  return x;
+}
+strong_alias (__ieee754_sqrtf, __sqrtf_finite)
diff --git a/sysdeps/riscv/rvf/fclrexcpt.c b/sysdeps/riscv/rvf/fclrexcpt.c
new file mode 100644
index 000000000000..5d395b673a21
--- /dev/null
+++ b/sysdeps/riscv/rvf/fclrexcpt.c
@@ -0,0 +1,28 @@
+/* Clear given exceptions in current floating-point environment.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+  asm volatile ("csrc fflags, %0" : : "r" (excepts));
+  return 0;
+}
+libm_hidden_def (feclearexcept)
diff --git a/sysdeps/riscv/rvf/fegetenv.c b/sysdeps/riscv/rvf/fegetenv.c
new file mode 100644
index 000000000000..100d56268800
--- /dev/null
+++ b/sysdeps/riscv/rvf/fegetenv.c
@@ -0,0 +1,32 @@
+/* Store current floating-point environment.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+__fegetenv (fenv_t *envp)
+{
+  _FPU_GETCW (*envp);
+
+  /* Success.  */
+  return 0;
+}
+libm_hidden_def (__fegetenv)
+weak_alias (__fegetenv, fegetenv)
+libm_hidden_weak (fegetenv)
diff --git a/sysdeps/riscv/rvf/fegetmode.c b/sysdeps/riscv/rvf/fegetmode.c
new file mode 100644
index 000000000000..40a9c2aa5ca3
--- /dev/null
+++ b/sysdeps/riscv/rvf/fegetmode.c
@@ -0,0 +1,27 @@
+/* Store current floating-point control modes.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetmode (femode_t *modep)
+{
+  _FPU_GETCW (*modep);
+  return 0;
+}
diff --git a/sysdeps/riscv/rvf/fegetround.c b/sysdeps/riscv/rvf/fegetround.c
new file mode 100644
index 000000000000..2c6338d432fd
--- /dev/null
+++ b/sysdeps/riscv/rvf/fegetround.c
@@ -0,0 +1,29 @@
+/* Return current rounding direction.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math_private.h>
+
+int
+__fegetround (void)
+{
+  return riscv_getround ();
+}
+libm_hidden_def (__fegetround)
+weak_alias (__fegetround, fegetround)
+libm_hidden_weak (fegetround)
diff --git a/sysdeps/riscv/rvf/feholdexcpt.c b/sysdeps/riscv/rvf/feholdexcpt.c
new file mode 100644
index 000000000000..2fe0168c6d6d
--- /dev/null
+++ b/sysdeps/riscv/rvf/feholdexcpt.c
@@ -0,0 +1,30 @@
+/* Store current floating-point environment and clear exceptions.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math_private.h>
+
+int
+__feholdexcept (fenv_t *envp)
+{
+  libc_feholdexcept_riscv (envp);
+  return 0;
+}
+libm_hidden_def (__feholdexcept)
+weak_alias (__feholdexcept, feholdexcept)
+libm_hidden_weak (feholdexcept)
diff --git a/sysdeps/riscv/rvf/fesetenv.c b/sysdeps/riscv/rvf/fesetenv.c
new file mode 100644
index 000000000000..22cebbedf65d
--- /dev/null
+++ b/sysdeps/riscv/rvf/fesetenv.c
@@ -0,0 +1,30 @@
+/* Install given floating-point environment.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math_private.h>
+
+int
+__fesetenv (const fenv_t *envp)
+{
+  libc_fesetenv_riscv (envp);
+  return 0;
+}
+libm_hidden_def (__fesetenv)
+weak_alias (__fesetenv, fesetenv)
+libm_hidden_weak (fesetenv)
diff --git a/sysdeps/riscv/rvf/fesetexcept.c b/sysdeps/riscv/rvf/fesetexcept.c
new file mode 100644
index 000000000000..0e1d33b392ff
--- /dev/null
+++ b/sysdeps/riscv/rvf/fesetexcept.c
@@ -0,0 +1,26 @@
+/* Set given exception flags.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+
+int
+fesetexcept (int excepts)
+{
+  asm volatile ("csrs fflags, %0" : : "r" (excepts));
+  return 0;
+}
diff --git a/sysdeps/riscv/rvf/fesetmode.c b/sysdeps/riscv/rvf/fesetmode.c
new file mode 100644
index 000000000000..9855cbd7b614
--- /dev/null
+++ b/sysdeps/riscv/rvf/fesetmode.c
@@ -0,0 +1,31 @@
+/* Install given floating-point control modes.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetmode (const femode_t *modep)
+{
+  asm volatile ("csrc fcsr, %0" : : "r" (~FE_ALL_EXCEPT));
+
+  if (modep != FE_DFL_MODE)
+    asm volatile ("csrs fcsr, %0" : : "r" (*modep & ~FE_ALL_EXCEPT));
+
+  return 0;
+}
diff --git a/sysdeps/riscv/rvf/fesetround.c b/sysdeps/riscv/rvf/fesetround.c
new file mode 100644
index 000000000000..b95e7c08d8c0
--- /dev/null
+++ b/sysdeps/riscv/rvf/fesetround.c
@@ -0,0 +1,39 @@
+/* Set current rounding direction.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math_private.h>
+
+int
+__fesetround (int round)
+{
+  switch (round)
+    {
+    case FE_TONEAREST:
+    case FE_TOWARDZERO:
+    case FE_DOWNWARD:
+    case FE_UPWARD:
+      riscv_setround (round);
+      return 0;
+    default:
+      return round; /* a nonzero value */
+    }
+}
+libm_hidden_def (__fesetround)
+weak_alias (__fesetround, fesetround)
+libm_hidden_weak (fesetround)
diff --git a/sysdeps/riscv/rvf/feupdateenv.c b/sysdeps/riscv/rvf/feupdateenv.c
new file mode 100644
index 000000000000..bf3292aaed70
--- /dev/null
+++ b/sysdeps/riscv/rvf/feupdateenv.c
@@ -0,0 +1,30 @@
+/* Install given floating-point environment and raise exceptions.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math_private.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+  libc_feupdateenv_riscv (envp);
+  return 0;
+}
+libm_hidden_def (__feupdateenv)
+weak_alias (__feupdateenv, feupdateenv)
+libm_hidden_weak (feupdateenv)
diff --git a/sysdeps/riscv/rvf/fgetexcptflg.c b/sysdeps/riscv/rvf/fgetexcptflg.c
new file mode 100644
index 000000000000..8b78fbb0c282
--- /dev/null
+++ b/sysdeps/riscv/rvf/fgetexcptflg.c
@@ -0,0 +1,30 @@
+/* Store current representation for exceptions.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math_private.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+  /* Get the current exceptions.  */
+  *flagp = riscv_getflags () & excepts;
+
+  /* Success.  */
+  return 0;
+}
diff --git a/sysdeps/riscv/rvf/fraiseexcpt.c b/sysdeps/riscv/rvf/fraiseexcpt.c
new file mode 100644
index 000000000000..2cdc76213e7f
--- /dev/null
+++ b/sysdeps/riscv/rvf/fraiseexcpt.c
@@ -0,0 +1,30 @@
+/* Raise given exceptions.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+__feraiseexcept (int excepts)
+{
+  asm volatile ("csrs fflags, %0" : : "r" (excepts));
+  return 0;
+}
+libm_hidden_def (__feraiseexcept)
+weak_alias (__feraiseexcept, feraiseexcept)
+libm_hidden_weak (feraiseexcept)
diff --git a/sysdeps/riscv/rvf/fsetexcptflg.c b/sysdeps/riscv/rvf/fsetexcptflg.c
new file mode 100644
index 000000000000..e1399d7d610a
--- /dev/null
+++ b/sysdeps/riscv/rvf/fsetexcptflg.c
@@ -0,0 +1,30 @@
+/* Set floating-point environment exception handling.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+  fexcept_t flags = *flagp;
+  asm volatile ("csrc fflags, %0" : : "r" (excepts));
+  asm volatile ("csrs fflags, %0" : : "r" (flags & excepts));
+
+  return 0;
+}
diff --git a/sysdeps/riscv/rvf/ftestexcept.c b/sysdeps/riscv/rvf/ftestexcept.c
new file mode 100644
index 000000000000..c65f26ca412f
--- /dev/null
+++ b/sysdeps/riscv/rvf/ftestexcept.c
@@ -0,0 +1,27 @@
+/* Test exception in current environment.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math_private.h>
+
+int
+fetestexcept (int excepts)
+{
+  return libc_fetestexcept_riscv (excepts);
+}
+libm_hidden_def (fetestexcept)
diff --git a/sysdeps/riscv/rvf/get-rounding-mode.h b/sysdeps/riscv/rvf/get-rounding-mode.h
new file mode 100644
index 000000000000..dd380fa5b1b8
--- /dev/null
+++ b/sysdeps/riscv/rvf/get-rounding-mode.h
@@ -0,0 +1,32 @@
+/* Determine floating-point rounding mode within libc.  RISC-V version.
+   Copyright (C) 2015-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _RISCV_GET_ROUNDING_MODE_H
+#define _RISCV_GET_ROUNDING_MODE_H
+
+/* Return the floating-point rounding mode.  */
+
+static inline int
+get_rounding_mode (void)
+{
+  int rm;
+  asm volatile ("frrm %0" : "=r" (rm));
+  return rm;
+}
+
+#endif /* get-rounding-mode.h */
diff --git a/sysdeps/riscv/rvf/math_private.h b/sysdeps/riscv/rvf/math_private.h
new file mode 100644
index 000000000000..cbb9a41e4c51
--- /dev/null
+++ b/sysdeps/riscv/rvf/math_private.h
@@ -0,0 +1,161 @@
+/* Private floating point rounding and exceptions handling.  RISC-V version.
+   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef RISCV_MATH_PRIVATE_H
+#define RISCV_MATH_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include <get-rounding-mode.h>
+
+static __always_inline int
+riscv_getround (void)
+{
+  return get_rounding_mode ();
+}
+
+static __always_inline void
+riscv_setround (int rm)
+{
+  asm volatile ("fsrm %z0" : : "rJ" (rm));
+}
+
+static __always_inline int
+riscv_getflags (void)
+{
+  int flags;
+  asm volatile ("frflags %0" : "=r" (flags));
+  return flags;
+}
+
+static __always_inline void
+riscv_setflags (int flags)
+{
+  asm volatile ("fsflags %z0" : : "rJ" (flags));
+}
+
+static __always_inline void
+libc_feholdexcept_riscv (fenv_t *envp)
+{
+  asm volatile ("csrrc %0, fcsr, %1" : "=r" (*envp) : "i" (FE_ALL_EXCEPT));
+}
+
+#define libc_feholdexcept  libc_feholdexcept_riscv
+#define libc_feholdexceptf libc_feholdexcept_riscv
+#define libc_feholdexceptl libc_feholdexcept_riscv
+
+static __always_inline void
+libc_fesetround_riscv (int round)
+{
+  riscv_setround (round);
+}
+
+#define libc_fesetround  libc_fesetround_riscv
+#define libc_fesetroundf libc_fesetround_riscv
+#define libc_fesetroundl libc_fesetround_riscv
+
+static __always_inline void
+libc_feholdexcept_setround_riscv (fenv_t *envp, int round)
+{
+  libc_fesetround_riscv (round);
+  libc_feholdexcept_riscv (envp);
+}
+
+#define libc_feholdexcept_setround  libc_feholdexcept_setround_riscv
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_riscv
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_riscv
+
+static __always_inline int
+libc_fetestexcept_riscv (int ex)
+{
+  return riscv_getflags () & ex;
+}
+
+#define libc_fetestexcept  libc_fetestexcept_riscv
+#define libc_fetestexceptf libc_fetestexcept_riscv
+#define libc_fetestexceptl libc_fetestexcept_riscv
+
+static __always_inline void
+libc_fesetenv_riscv (const fenv_t *envp)
+{
+  long env = (long) envp - (long) FE_DFL_ENV;
+  if (env != 0)
+    env = *envp;
+
+  _FPU_SETCW (env);
+}
+
+#define libc_fesetenv  libc_fesetenv_riscv
+#define libc_fesetenvf libc_fesetenv_riscv
+#define libc_fesetenvl libc_fesetenv_riscv
+#define libc_feresetround_noex  libc_fesetenv_riscv
+#define libc_feresetround_noexf libc_fesetenv_riscv
+#define libc_feresetround_noexl libc_fesetenv_riscv
+
+static __always_inline int
+libc_feupdateenv_test_riscv (const fenv_t *envp, int ex)
+{
+  fenv_t env = *envp;
+  int flags = riscv_getflags ();
+  asm volatile ("csrw fcsr, %z0" : : "rJ" (env | flags));
+  return flags & ex;
+}
+
+#define libc_feupdateenv_test  libc_feupdateenv_test_riscv
+#define libc_feupdateenv_testf libc_feupdateenv_test_riscv
+#define libc_feupdateenv_testl libc_feupdateenv_test_riscv
+
+static __always_inline void
+libc_feupdateenv_riscv (const fenv_t *envp)
+{
+  _FPU_SETCW (*envp | riscv_getflags ());
+}
+
+#define libc_feupdateenv  libc_feupdateenv_riscv
+#define libc_feupdateenvf libc_feupdateenv_riscv
+#define libc_feupdateenvl libc_feupdateenv_riscv
+
+static __always_inline void
+libc_feholdsetround_riscv (fenv_t *envp, int round)
+{
+  /* Note this implementation makes an improperly-formatted fenv_t and
+     so should only be used in conjunction with libc_feresetround.  */
+  int old_round;
+  asm volatile ("csrrw %0, frm, %z1" : "=r" (old_round) : "rJ" (round));
+  *envp = old_round;
+}
+
+#define libc_feholdsetround  libc_feholdsetround_riscv
+#define libc_feholdsetroundf libc_feholdsetround_riscv
+#define libc_feholdsetroundl libc_feholdsetround_riscv
+
+static __always_inline void
+libc_feresetround_riscv (fenv_t *envp)
+{
+  /* Note this implementation takes an improperly-formatted fenv_t and
+     so should only be used in conjunction with libc_feholdsetround.  */
+  riscv_setround (*envp);
+}
+
+#define libc_feresetround  libc_feresetround_riscv
+#define libc_feresetroundf libc_feresetround_riscv
+#define libc_feresetroundl libc_feresetround_riscv
+
+#include_next <math_private.h>
+
+#endif
diff --git a/sysdeps/riscv/rvf/s_ceilf.c b/sysdeps/riscv/rvf/s_ceilf.c
new file mode 100644
index 000000000000..41f6bd9aac0f
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_ceilf.c
@@ -0,0 +1,51 @@
+/* ceilf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-float.h>
+
+float
+__ceilf (float x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnanf (x);
+  float mag = fabsf (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1 << __FLT_MANT_DIG__))
+    {
+      int i;
+      float new_x;
+
+      asm volatile ("fcvt.w.s %0, %1, rup" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.s.w %0, %1, rup" : "=f" (new_x) : "r" (i));
+
+      /* ceil(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysignf (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_float (__ceil, ceil)
diff --git a/sysdeps/riscv/rvf/s_copysignf.c b/sysdeps/riscv/rvf/s_copysignf.c
new file mode 100644
index 000000000000..7628701b9f04
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_copysignf.c
@@ -0,0 +1,28 @@
+/* copysignf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__copysignf (float x, float y)
+{
+  asm ("fsgnj.s %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_float (__copysign, copysign)
diff --git a/sysdeps/riscv/rvf/s_finitef.c b/sysdeps/riscv/rvf/s_finitef.c
new file mode 100644
index 000000000000..16e7de18838e
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_finitef.c
@@ -0,0 +1,28 @@
+/* finitef().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__finitef (float x)
+{
+  return _FCLASS (x) & ~(_FCLASS_INF | _FCLASS_NAN);
+}
+hidden_def (__finitef)
+weak_alias (__finitef, finitef)
diff --git a/sysdeps/riscv/rvf/s_floorf.c b/sysdeps/riscv/rvf/s_floorf.c
new file mode 100644
index 000000000000..27bfc93e8cf2
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_floorf.c
@@ -0,0 +1,51 @@
+/* floorf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-float.h>
+
+float
+__floorf (float x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnanf (x);
+  float mag = fabsf (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1 << __FLT_MANT_DIG__))
+    {
+      int i;
+      float new_x;
+
+      asm volatile ("fcvt.w.s %0, %1, rdn" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.s.w %0, %1, rdn" : "=f" (new_x) : "r" (i));
+
+      /* floor(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysignf (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_float (__floor, floor)
diff --git a/sysdeps/riscv/rvf/s_fmaf.c b/sysdeps/riscv/rvf/s_fmaf.c
new file mode 100644
index 000000000000..13cb4488dcef
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_fmaf.c
@@ -0,0 +1,30 @@
+/* fmaf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv.h>
+#include <ieee754.h>
+#include <libm-alias-float.h>
+
+float
+__fmaf (float x, float y, float z)
+{
+  asm ("fmadd.s %0, %1, %2, %3" : "=f" (x) : "f" (x), "f" (y), "f" (z));
+  return x;
+}
+libm_alias_float (__fma, fma)
diff --git a/sysdeps/riscv/rvf/s_fmaxf.c b/sysdeps/riscv/rvf/s_fmaxf.c
new file mode 100644
index 000000000000..f97ecd87ccaa
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_fmaxf.c
@@ -0,0 +1,28 @@
+/* fmaxf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__fmaxf (float x, float y)
+{
+  asm ("fmax.s %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_float (__fmax, fmax)
diff --git a/sysdeps/riscv/rvf/s_fminf.c b/sysdeps/riscv/rvf/s_fminf.c
new file mode 100644
index 000000000000..eb1197fb20fb
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_fminf.c
@@ -0,0 +1,28 @@
+/* fminf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-float.h>
+
+float
+__fminf (float x, float y)
+{
+  asm ("fmin.s %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_float (__fmin, fmin)
diff --git a/sysdeps/riscv/rvf/s_fpclassifyf.c b/sysdeps/riscv/rvf/s_fpclassifyf.c
new file mode 100644
index 000000000000..015b9de48b4f
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_fpclassifyf.c
@@ -0,0 +1,36 @@
+/* fpclassifyf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__fpclassifyf (float x)
+{
+  int cls = _FCLASS (x);
+  if (__builtin_expect (cls & _FCLASS_NORM, _FCLASS_NORM))
+    return FP_NORMAL;
+  if (__builtin_expect (cls & _FCLASS_ZERO, _FCLASS_ZERO))
+    return FP_ZERO;
+  if (__builtin_expect (cls & _FCLASS_SUBNORM, _FCLASS_SUBNORM))
+    return FP_SUBNORMAL;
+  if (__builtin_expect (cls & _FCLASS_INF, _FCLASS_INF))
+    return FP_INFINITE;
+  return FP_NAN;
+}
+libm_hidden_def (__fpclassifyf)
diff --git a/sysdeps/riscv/rvf/s_isinff.c b/sysdeps/riscv/rvf/s_isinff.c
new file mode 100644
index 000000000000..ecfb15121330
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_isinff.c
@@ -0,0 +1,29 @@
+/* isinff().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__isinff (float x)
+{
+  int cls = _FCLASS (x);
+  return -((cls & _FCLASS_MINF) ? 1 : 0) | ((cls & _FCLASS_PINF) ? 1 : 0);
+}
+hidden_def (__isinff)
+weak_alias (__isinff, isinff)
diff --git a/sysdeps/riscv/rvf/s_isnanf.c b/sysdeps/riscv/rvf/s_isnanf.c
new file mode 100644
index 000000000000..51a9cf3ff3a7
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_isnanf.c
@@ -0,0 +1,28 @@
+/* isnanf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__isnanf (float x)
+{
+  return _FCLASS (x) & _FCLASS_NAN;
+}
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
diff --git a/sysdeps/riscv/rvf/s_issignalingf.c b/sysdeps/riscv/rvf/s_issignalingf.c
new file mode 100644
index 000000000000..a611aa92fa86
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_issignalingf.c
@@ -0,0 +1,27 @@
+/* issignalingf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__issignalingf (float x)
+{
+  return _FCLASS (x) & _FCLASS_SNAN;
+}
+libm_hidden_def (__issignalingf)
diff --git a/sysdeps/riscv/rvf/s_lroundf.c b/sysdeps/riscv/rvf/s_lroundf.c
new file mode 100644
index 000000000000..eeed23c14c95
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_lroundf.c
@@ -0,0 +1,30 @@
+/* lroundf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-float.h>
+
+long
+__lroundf (float x)
+{
+  long res;
+  asm ("fcvt.w.s %0, %1, rmm" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_float (__lround, lround)
diff --git a/sysdeps/riscv/rvf/s_nearbyintf.c b/sysdeps/riscv/rvf/s_nearbyintf.c
new file mode 100644
index 000000000000..bf6c17d72307
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_nearbyintf.c
@@ -0,0 +1,51 @@
+/* Round to int floating-point values.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-float.h>
+
+float
+__nearbyintf (float x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnanf (x);
+  float mag = fabsf (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1 << __FLT_MANT_DIG__))
+    {
+      int i;
+      float new_x;
+
+      asm volatile ("fcvt.w.s %0, %1" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.s.w %0, %1" : "=f" (new_x) : "r" (i));
+
+      /* nearbyint(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysignf (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_float (__nearbyint, nearbyint)
diff --git a/sysdeps/riscv/rvf/s_rintf.c b/sysdeps/riscv/rvf/s_rintf.c
new file mode 100644
index 000000000000..0ed17365e0f3
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_rintf.c
@@ -0,0 +1,51 @@
+/* rintf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-float.h>
+
+float
+__rintf (float x)
+{
+  int nan;
+  float mag;
+
+  nan = isnanf (x);
+  mag = fabsf (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1 << __FLT_MANT_DIG__))
+    {
+      int i;
+      float new_x;
+
+      asm ("fcvt.w.s %0, %1" : "=r" (i) : "f" (x));
+      asm ("fcvt.s.w %0, %1" : "=f" (new_x) : "r" (i));
+
+      /* rint(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysignf (new_x, x);
+    }
+
+  return x;
+}
+
+libm_alias_float (__rint, rint)
diff --git a/sysdeps/riscv/rvf/s_roundevenf.c b/sysdeps/riscv/rvf/s_roundevenf.c
new file mode 100644
index 000000000000..48b3cc5b4ff6
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_roundevenf.c
@@ -0,0 +1,51 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-float.h>
+
+float
+__roundevenf (float x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnanf (x);
+  float mag = fabsf (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1 << __FLT_MANT_DIG__))
+    {
+      int i;
+      float new_x;
+
+      asm volatile ("fcvt.w.s %0, %1, rne" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.s.w %0, %1, rne" : "=f" (new_x) : "r" (i));
+
+      /* roundeven(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysignf (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_float (__roundeven, roundeven)
diff --git a/sysdeps/riscv/rvf/s_roundf.c b/sysdeps/riscv/rvf/s_roundf.c
new file mode 100644
index 000000000000..8820ec28e6bf
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_roundf.c
@@ -0,0 +1,51 @@
+/* roundf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-float.h>
+
+float
+__roundf (float x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnanf (x);
+  float mag = fabsf (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1 << __FLT_MANT_DIG__))
+    {
+      int i;
+      float new_x;
+
+      asm volatile ("fcvt.w.s %0, %1, rmm" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.s.w %0, %1, rmm" : "=f" (new_x) : "r" (i));
+
+      /* round(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysignf (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_float (__round, round)
diff --git a/sysdeps/riscv/rvf/s_truncf.c b/sysdeps/riscv/rvf/s_truncf.c
new file mode 100644
index 000000000000..a9883b77d1ef
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_truncf.c
@@ -0,0 +1,51 @@
+/* truncf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-float.h>
+
+float
+__truncf (float x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnanf (x);
+  float mag = fabsf (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1 << __FLT_MANT_DIG__))
+    {
+      int i;
+      float new_x;
+
+      asm volatile ("fcvt.w.s %0, %1, rtz" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.s.w %0, %1, rtz" : "=f" (new_x) : "r" (i));
+
+      /* trunc(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysignf (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_float (__trunc, trunc)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (6 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 11/15] RISC-V: Linux ABI Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20 16:57   ` Adhemerval Zanella
  2017-12-20 17:24   ` Joseph Myers
  2017-12-20  7:24 ` [PATCH v2 09/15] RISC-V: Atomic and Locking Routines Palmer Dabbelt
                   ` (9 subsequent siblings)
  17 siblings, 2 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

Contains the Linux system call interface, as well as the definitions of
a handful of system calls.
---
 sysdeps/riscv/nptl/nptl-sysdep.S                |   2 +
 sysdeps/unix/sysv/linux/riscv/arch-fork.h       |   1 +
 sysdeps/unix/sysv/linux/riscv/clone.S           |  85 +++++++
 sysdeps/unix/sysv/linux/riscv/getmsg.c          |   1 +
 sysdeps/unix/sysv/linux/riscv/kernel-features.h |  23 ++
 sysdeps/unix/sysv/linux/riscv/profil-counter.h  |   2 +
 sysdeps/unix/sysv/linux/riscv/pt-vfork.S        |   1 +
 sysdeps/unix/sysv/linux/riscv/putmsg.c          |   1 +
 sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c    |   1 +
 sysdeps/unix/sysv/linux/riscv/rv32/readahead.c  |   1 +
 sysdeps/unix/sysv/linux/riscv/syscall.c         |  38 +++
 sysdeps/unix/sysv/linux/riscv/sysdep.S          |  51 ++++
 sysdeps/unix/sysv/linux/riscv/sysdep.h          | 316 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/vfork.S           |  44 ++++
 14 files changed, 567 insertions(+)
 create mode 100644 sysdeps/riscv/nptl/nptl-sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/arch-fork.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/clone.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/getmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/kernel-features.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/profil-counter.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/pt-vfork.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/putmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/syscall.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/vfork.S

diff --git a/sysdeps/riscv/nptl/nptl-sysdep.S b/sysdeps/riscv/nptl/nptl-sysdep.S
new file mode 100644
index 000000000000..3f5c2a364afd
--- /dev/null
+++ b/sysdeps/riscv/nptl/nptl-sysdep.S
@@ -0,0 +1,2 @@
+/* Pull in __syscall_error.  */
+#include <sysdep.S>
diff --git a/sysdeps/unix/sysv/linux/riscv/arch-fork.h b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
new file mode 100644
index 000000000000..5f945378eec0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/arch-fork.h>
diff --git a/sysdeps/unix/sysv/linux/riscv/clone.S b/sysdeps/unix/sysv/linux/riscv/clone.S
new file mode 100644
index 000000000000..4bfdc90702aa
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/clone.S
@@ -0,0 +1,85 @@
+/* Wrapper around clone system call.  RISC-V version.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* clone() is even more special than fork() as it mucks with stacks
+   and invokes a function in the right context after its all over.  */
+
+#include <sys/asm.h>
+#include <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <tls.h>
+#include "tcb-offsets.h"
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+	     void *parent_tidptr, void *tls, void *child_tidptr) */
+
+	.text
+LEAF(__clone)
+
+	/* Sanity check arguments.  */
+	beqz		a0,L(invalid)	/* No NULL function pointers.  */
+	beqz		a1,L(invalid)	/* No NULL stack pointers.  */
+
+	addi		a1,a1,-16	/* Reserve argument save space.  */
+	REG_S		a0,0(a1)	/* Save function pointer.  */
+	REG_S		a3,SZREG(a1)	/* Save argument pointer.  */
+
+	/* The syscall expects the args to be in different slots.  */
+	mv		a0,a2
+	mv		a2,a4
+	mv		a3,a5
+	mv		a4,a6
+
+	/* Do the system call */
+	li		a7,__NR_clone
+	scall
+
+	bltz		a0,L(error)
+	beqz		a0,L(thread_start)
+
+	/* Successful return from the parent */
+	ret
+
+L(invalid):
+	li		a0, -EINVAL
+	/* Something bad happened -- no child created */
+L(error):
+	j		__syscall_error
+	END(__clone)
+
+/* Load up the arguments to the function.  Put this block of code in
+   its own function so that we can terminate the stack trace with our
+   debug info.  */
+
+ENTRY(__thread_start)
+L(thread_start):
+	/* Restore the arg for user's function.  */
+	REG_L		a1,0(sp)	/* Function pointer.  */
+	REG_L		a0,SZREG(sp)	/* Argument pointer.  */
+
+	/* Call the user's function.  */
+	jalr		a1
+
+	/* Call _exit with the function's return value.  */
+	j		_exit
+
+	END(__thread_start)
+
+libc_hidden_def(__clone)
+weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/riscv/getmsg.c b/sysdeps/unix/sysv/linux/riscv/getmsg.c
new file mode 100644
index 000000000000..3a1fa0852504
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/getmsg.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getmsg.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/kernel-features.h b/sysdeps/unix/sysv/linux/riscv/kernel-features.h
new file mode 100644
index 000000000000..21f9600eda73
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/kernel-features.h
@@ -0,0 +1,23 @@
+/* RISC-V kernel features
+   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define __ASSUME_ACCEPT4_SYSCALL	1
+#define __ASSUME_RECVMMSG_SYSCALL	1
+#define __ASSUME_SENDMMSG_SYSCALL	1
+
+#include_next <kernel-features.h>
diff --git a/sysdeps/unix/sysv/linux/riscv/profil-counter.h b/sysdeps/unix/sysv/linux/riscv/profil-counter.h
new file mode 100644
index 000000000000..8a6a0bcf3d59
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/profil-counter.h
@@ -0,0 +1,2 @@
+/* We can use the ix86 version.  */
+#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/sysdeps/unix/sysv/linux/riscv/pt-vfork.S b/sysdeps/unix/sysv/linux/riscv/pt-vfork.S
new file mode 100644
index 000000000000..65cc3823ac87
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/pt-vfork.S
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/alpha/pt-vfork.S>
diff --git a/sysdeps/unix/sysv/linux/riscv/putmsg.c b/sysdeps/unix/sysv/linux/riscv/putmsg.c
new file mode 100644
index 000000000000..ebc1680ca7d1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/putmsg.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/putmsg.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c b/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
new file mode 100644
index 000000000000..a88f5a784a54
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lockf64.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
new file mode 100644
index 000000000000..80170c3e8a4d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/arm/readahead.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/syscall.c b/sysdeps/unix/sysv/linux/riscv/syscall.c
new file mode 100644
index 000000000000..bce62ca06df7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/syscall.c
@@ -0,0 +1,38 @@
+/* system call interface.  Linux/RISC-V version.
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+long
+syscall (long syscall_number, long arg1, long arg2, long arg3, long arg4,
+	 long arg5, long arg6, long arg7)
+{
+  long ret;
+  INTERNAL_SYSCALL_DECL (err);
+
+  ret = INTERNAL_SYSCALL_NCS (syscall_number, err, 7, arg1, arg2, arg3, arg4,
+			      arg5, arg6, arg7);
+
+  if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+    {
+      extern long __syscall_error (long neg_errno);
+      return __syscall_error (ret);
+    }
+
+  return ret;
+}
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.S b/sysdeps/unix/sysv/linux/riscv/sysdep.S
new file mode 100644
index 000000000000..90da2daf7655
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.S
@@ -0,0 +1,51 @@
+/* syscall error handlers
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define errno __libc_errno
+#endif
+
+ENTRY (__syscall_error)
+	mv t0, ra
+	/* Fall through to __syscall_set_errno.  */
+END (__syscall_error)
+
+/* Non-standard calling convention: argument in a0, return address in t0,
+   and clobber only t1.  */
+ENTRY (__syscall_set_errno)
+	/* We got here because a0 < 0, but only codes in the range [-4095, -1]
+	  represent errors.  Otherwise, just return the result normally.  */
+	li t1, -4096
+	bleu a0, t1, 1f
+	neg a0, a0
+#if RTLD_PRIVATE_ERRNO
+	sw a0, rtld_errno, t1
+#elif defined(__PIC__)
+	la.tls.ie t1, errno
+	add t1, t1, tp
+	sw a0, 0(t1)
+#else
+	lui t1, %tprel_hi(errno)
+	add t1, t1, tp, %tprel_add(errno)
+	sw a0, %tprel_lo(errno)(t1)
+#endif
+	li a0, -1
+1:	jr t0
+END (__syscall_set_errno)
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h
new file mode 100644
index 000000000000..56a6053d82a6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -0,0 +1,316 @@
+/* Assembly macros for RISC-V.
+   Copyright (C) 2011-2017
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LINUX_RISCV_SYSDEP_H
+#define _LINUX_RISCV_SYSDEP_H 1
+
+#include <sysdeps/unix/sysv/linux/generic/sysdep.h>
+#include <tls.h>
+
+#ifdef __ASSEMBLER__
+
+#include <sys/asm.h>
+
+#define ENTRY(name) LEAF(name)
+
+#define L(label) .L ## label
+
+/* Performs a system call, handling errors by setting errno.  Linux indicates
+ * errors by setting a0 to a value between -1 and -4095.  */
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args)			\
+  .text;							\
+  .align 2;							\
+  ENTRY (name);							\
+  li a7, SYS_ify(syscall_name);					\
+  scall;							\
+  li a7, -4096;							\
+  bgtu a0, a7, .Lsyscall_error ## name;
+
+#undef PSEUDO_END
+#define PSEUDO_END(sym) 					\
+  SYSCALL_ERROR_HANDLER(sym)					\
+  ret;								\
+  END(sym)
+
+# if !IS_IN (libc)
+#  if RTLD_PRIVATE_ERRNO
+#   define SYSCALL_ERROR_HANDLER(name)				\
+.Lsyscall_error ## name:					\
+	li t1, -4096;						\
+        sw a0, rtld_errno, t1;					\
+        li a0, -1;
+#  elif defined (__PIC__)
+#   define SYSCALL_ERROR_HANDLER(name)				\
+.Lsyscall_error ## name:					\
+        la.tls.ie t1, errno;					\
+	add t1, t1, tp;						\
+	sw a0, 0(t1);						\
+        li a0, -1;
+#  else
+#   define SYSCALL_ERROR_HANDLER(name)				\
+.Lsyscall_error ## name:					\
+        lui t1, %tprel_hi(errno);				\
+        add t1, t1, tp, %tprel_add(errno);			\
+        sw a0, %tprel_lo(errno)(t1);				\
+        li a0, -1;
+#  endif
+# else
+#  define SYSCALL_ERROR_HANDLER(name)				\
+.Lsyscall_error ## name:					\
+        j       __syscall_error;
+# endif
+
+/* Performs a system call, not setting errno.  */
+#undef PSEUDO_NEORRNO
+#define PSEUDO_NOERRNO(name, syscall_name, args)	\
+  .align 2;						\
+  ENTRY(name);						\
+  li a7, SYS_ify(syscall_name);				\
+  scall;
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name)			\
+  END (name)
+
+#undef ret_NOERRNO
+#define ret_NOERRNO ret
+
+/* Perfroms a system call, returning the error code.  */
+#undef PSEUDO_ERRVAL
+#define PSEUDO_ERRVAL(name, syscall_name, args) 	\
+  PSEUDO_NOERRNO(name, syscall_name, args)		\
+  neg a0, a0;
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name)				\
+  END (name)
+
+#undef ret_ERRVAL
+#define ret_ERRVAL ret
+
+#endif /* __ASSEMBLER__ */
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
+#ifndef __ASSEMBLER__
+#include <errno.h>
+#endif
+
+#include <sysdeps/unix/sysdep.h>
+
+#undef SYS_ify
+#define SYS_ify(syscall_name)	__NR_##syscall_name
+
+#ifndef __ASSEMBLER__
+
+/* List of system calls which are supported as vsyscalls.  */
+#define HAVE_CLOCK_GETRES_VSYSCALL	1
+#define HAVE_CLOCK_GETTIME_VSYSCALL	1
+#define HAVE_GETTIMEOFDAY_VSYSCALL	1
+#define HAVE_GETCPU_VSYSCALL		1
+
+/* Define a macro which expands into the inline wrapper code for a system
+   call.  */
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...)				\
+  ({ INTERNAL_SYSCALL_DECL(err);					\
+     long __sys_result = INTERNAL_SYSCALL (name, err, nr, args);	\
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P(__sys_result, ), 0)) \
+       {								\
+         __set_errno (INTERNAL_SYSCALL_ERRNO (__sys_result, ));		\
+	 __sys_result = (unsigned long) -1;				\
+       }								\
+     __sys_result; })
+
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#define INTERNAL_SYSCALL_ERROR_P(val, err)   ((unsigned long) (val) > -4096UL)
+
+#define INTERNAL_SYSCALL_ERRNO(val, err)     (-val)
+
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+	internal_syscall##nr (SYS_ify (name), err, args)
+
+#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
+	internal_syscall##nr (number, err, args)
+
+#define internal_syscall0(number, err, dummy...)			\
+({ 									\
+	long _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0");					\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "=r" (__a0)							\
+	: "r" (__a7)							\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+#define internal_syscall1(number, err, arg0)				\
+({ 									\
+	long _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7)							\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+#define internal_syscall2(number, err, arg0, arg1)	    		\
+({ 									\
+	long _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r"(__a1)						\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+#define internal_syscall3(number, err, arg0, arg1, arg2)      		\
+({ 									\
+	long _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r"(__a1), "r"(__a2)				\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+#define internal_syscall4(number, err, arg0, arg1, arg2, arg3)	  \
+({ 									\
+	long _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	register long __a3 asm("a3") = (long) (arg3);			\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r"(__a1), "r"(__a2), "r"(__a3)			\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+#define internal_syscall5(number, err, arg0, arg1, arg2, arg3, arg4)    \
+({ 									\
+	long _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	register long __a3 asm("a3") = (long) (arg3);			\
+	register long __a4 asm("a4") = (long) (arg4);			\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r"(__a1), "r"(__a2), "r"(__a3), "r"(__a4)	\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+#define internal_syscall6(number, err, arg0, arg1, arg2, arg3, arg4, arg5) \
+({ 									\
+	long _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	register long __a3 asm("a3") = (long) (arg3);			\
+	register long __a4 asm("a4") = (long) (arg4);			\
+	register long __a5 asm("a5") = (long) (arg5);			\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r"(__a1), "r"(__a2), "r"(__a3), "r"(__a4), "r"(__a5)	\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+#define internal_syscall7(number, err, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ 									\
+	long _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	register long __a3 asm("a3") = (long) (arg3);			\
+	register long __a4 asm("a4") = (long) (arg4);			\
+	register long __a5 asm("a5") = (long) (arg5);			\
+	register long __a6 asm("a6") = (long) (arg6);			\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r"(__a1), "r"(__a2), "r"(__a3), "r"(__a4), "r"(__a5), "r"(__a6)	\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+#define __SYSCALL_CLOBBERS "memory"
+#endif /* ! __ASSEMBLER__ */
+
+/* Pointer mangling is not supported.  */
+#define PTR_MANGLE(var) (void) (var)
+#define PTR_DEMANGLE(var) (void) (var)
+
+#endif /* linux/mips/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/riscv/vfork.S b/sysdeps/unix/sysv/linux/riscv/vfork.S
new file mode 100644
index 000000000000..9bddd8d1f4f9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/vfork.S
@@ -0,0 +1,44 @@
+/* vfork for Linux, RISC-V version.
+   Copyright (C) 2005-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* vfork() is just a special case of clone().  */
+
+#include <sys/asm.h>
+#include <sysdep.h>
+#define __ASSEMBLY__
+#include <linux/sched.h>
+#include <asm/signal.h>
+
+	.text
+LEAF(__libc_vfork)
+
+	li	a0, (CLONE_VFORK | CLONE_VM | SIGCHLD)
+	mv	a1, sp
+
+	li	a7, __NR_clone
+	scall
+
+	bltz	a0, 1f
+	ret
+
+1:	j		__syscall_error
+END(__libc_vfork)
+
+weak_alias (__libc_vfork, vfork)
+strong_alias (__libc_vfork, __vfork)
+libc_hidden_def (__vfork)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 06/15] RISC-V: Generic <math.h> and soft-fp Routines
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (4 preceding siblings ...)
  2017-12-20  7:23 ` [PATCH v2 02/15] RISC-V: ABI Implementation Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20 16:50   ` Joseph Myers
  2017-12-20  7:24 ` [PATCH v2 11/15] RISC-V: Linux ABI Palmer Dabbelt
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This patch contains the miscellaneous math routines and headers we have
implemented for RISC-V.  This includes things from <math.h> that aren't
completely ISA-generic, floating-point bit manipulation, and soft-fp
hooks.
---
 sysdeps/riscv/bits/fenv.h   |  74 +++++++++++++++++++++++++++++
 sysdeps/riscv/fpu_control.h |  74 +++++++++++++++++++++++++++++
 sysdeps/riscv/sfp-machine.h | 112 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 260 insertions(+)
 create mode 100644 sysdeps/riscv/bits/fenv.h
 create mode 100644 sysdeps/riscv/fpu_control.h
 create mode 100644 sysdeps/riscv/sfp-machine.h

diff --git a/sysdeps/riscv/bits/fenv.h b/sysdeps/riscv/bits/fenv.h
new file mode 100644
index 000000000000..13569f6d2ca6
--- /dev/null
+++ b/sysdeps/riscv/bits/fenv.h
@@ -0,0 +1,74 @@
+/* Floating point environment, RISC-V version.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+enum
+  {
+    FE_INEXACT   =
+#define FE_INEXACT	(0x01)
+      FE_INEXACT,
+    FE_UNDERFLOW =
+#define FE_UNDERFLOW	(0x02)
+      FE_UNDERFLOW,
+    FE_OVERFLOW  =
+#define FE_OVERFLOW	(0x04)
+      FE_OVERFLOW,
+    FE_DIVBYZERO =
+#define FE_DIVBYZERO	(0x08)
+      FE_DIVBYZERO,
+    FE_INVALID   =
+#define FE_INVALID	(0x10)
+      FE_INVALID,
+  };
+
+#define FE_ALL_EXCEPT \
+	(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+enum
+  {
+    FE_TONEAREST  =
+#define FE_TONEAREST	(0x0)
+      FE_TONEAREST,
+    FE_TOWARDZERO =
+#define FE_TOWARDZERO	(0x1)
+      FE_TOWARDZERO,
+    FE_DOWNWARD   =
+#define FE_DOWNWARD	(0x2)
+      FE_DOWNWARD,
+    FE_UPWARD     =
+#define FE_UPWARD	(0x3)
+      FE_UPWARD,
+  };
+
+
+typedef unsigned int fexcept_t;
+typedef unsigned int fenv_t;
+
+/* If the default argument is used we use this value.  */
+#define FE_DFL_ENV	((__const fenv_t *) -1)
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes.  */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes.  */
+# define FE_DFL_MODE	((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/riscv/fpu_control.h b/sysdeps/riscv/fpu_control.h
new file mode 100644
index 000000000000..f2c59845f8f7
--- /dev/null
+++ b/sysdeps/riscv/fpu_control.h
@@ -0,0 +1,74 @@
+/* FPU control word bits.  RISC-V version.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+#include <features.h>
+
+#ifndef __riscv_flen
+
+#define _FPU_RESERVED 0xffffffff
+#define _FPU_DEFAULT  0x00000000
+typedef unsigned int fpu_control_t;
+#define _FPU_GETCW(cw) (cw) = 0
+#define _FPU_SETCW(cw) do { } while (0)
+extern fpu_control_t __fpu_control;
+
+#else /* __riscv_flen */
+
+#define _FPU_RESERVED 0
+#define _FPU_DEFAULT  0
+#define _FPU_IEEE     _FPU_DEFAULT
+
+/* Type of the control word.  */
+typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
+
+/* Macros for accessing the hardware control word.  */
+#define _FPU_GETCW(cw) __asm__ volatile ("frsr %0" : "=r" (cw))
+#define _FPU_SETCW(cw) __asm__ volatile ("fssr %z0" : : "rJ" (cw))
+
+/* Default control word set at startup.  */
+extern fpu_control_t __fpu_control;
+
+#define _FCLASS(x) ({ int res; \
+  if (sizeof (x) * 8 > __riscv_flen) __builtin_trap (); \
+  if (sizeof (x) == 4) asm ("fclass.s %0, %1" : "=r" (res) : "f" (x)); \
+  else if (sizeof (x) == 8) asm ("fclass.d %0, %1" : "=r" (res) : "f" (x)); \
+  else __builtin_trap (); \
+  res; })
+
+#define _FCLASS_MINF     (1<<0)
+#define _FCLASS_MNORM    (1<<1)
+#define _FCLASS_MSUBNORM (1<<2)
+#define _FCLASS_MZERO    (1<<3)
+#define _FCLASS_PZERO    (1<<4)
+#define _FCLASS_PSUBNORM (1<<5)
+#define _FCLASS_PNORM    (1<<6)
+#define _FCLASS_PINF     (1<<7)
+#define _FCLASS_SNAN     (1<<8)
+#define _FCLASS_QNAN     (1<<9)
+#define _FCLASS_ZERO     (_FCLASS_MZERO | _FCLASS_PZERO)
+#define _FCLASS_SUBNORM  (_FCLASS_MSUBNORM | _FCLASS_PSUBNORM)
+#define _FCLASS_NORM     (_FCLASS_MNORM | _FCLASS_PNORM)
+#define _FCLASS_INF      (_FCLASS_MINF | _FCLASS_PINF)
+#define _FCLASS_NAN      (_FCLASS_SNAN | _FCLASS_QNAN)
+
+#endif /* __riscv_flen */
+
+#endif	/* fpu_control.h */
diff --git a/sysdeps/riscv/sfp-machine.h b/sysdeps/riscv/sfp-machine.h
new file mode 100644
index 000000000000..55949e58b349
--- /dev/null
+++ b/sysdeps/riscv/sfp-machine.h
@@ -0,0 +1,112 @@
+/* RISC-V softfloat definitions
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#if __riscv_xlen == 32
+
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+#define _FP_MUL_MEAT_S(R,X,Y)				\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)				\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)				\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+
+#else
+
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long long
+#define _FP_WS_TYPE		signed long long
+#define _FP_I_TYPE		long long
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+
+#endif
+
+#define _FP_NANSIGN_S		0
+#define _FP_NANSIGN_D		0
+#define _FP_NANSIGN_Q		0
+
+#define _FP_KEEPNANFRACP 0
+#define _FP_QNANNEGATEDP 0
+
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)	\
+  do {						\
+    R##_s = _FP_NANSIGN_##fs;			\
+    _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs);	\
+    R##_c = FP_CLS_NAN;				\
+  } while (0)
+
+#define _FP_DECL_EX		int _frm __attribute__ ((unused));
+#define FP_ROUNDMODE		_frm
+
+#define FP_RND_NEAREST		FE_TONEAREST
+#define FP_RND_ZERO		FE_TOWARDZERO
+#define FP_RND_PINF		FE_UPWARD
+#define FP_RND_MINF		FE_DOWNWARD
+
+#define FP_EX_INVALID		FE_INVALID
+#define FP_EX_OVERFLOW		FE_OVERFLOW
+#define FP_EX_UNDERFLOW		FE_UNDERFLOW
+#define FP_EX_DIVZERO		FE_DIVBYZERO
+#define FP_EX_INEXACT		FE_INEXACT
+
+#define _FP_TININESS_AFTER_ROUNDING 1
+
+#ifdef __riscv_flen
+#define FP_INIT_ROUNDMODE			\
+do {						\
+  __asm__ volatile ("frrm %0" : "=r" (_frm));	\
+} while (0)
+
+#define FP_HANDLE_EXCEPTIONS					\
+do {								\
+  if (__builtin_expect (_fex, 0))				\
+    __asm__ volatile ("csrs fflags, %0" : : "rK" (_fex));	\
+} while (0)
+#else
+#define FP_INIT_ROUNDMODE	_frm = FP_RND_NEAREST
+#endif
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 08/15] RISC-V: RV32D, RV64F, and RV64D Support
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (12 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 15/15] Add RISC-V to build-many-glibcs.py Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20  7:24 ` [PATCH v2 07/15] RISC-V: RV32F Support Palmer Dabbelt
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

This patch adds support for the various other hardware floating point
configurations that RISC-V supports.  This is split from the RV32F patch
to avoid mailing list size restrictions.
---
 sysdeps/riscv/rv32/rvd/s_lrint.c     | 30 ++++++++++++++++++++
 sysdeps/riscv/rv32/rvd/s_lround.c    | 30 ++++++++++++++++++++
 sysdeps/riscv/rv32/rvf/s_llrintf.c   | 30 ++++++++++++++++++++
 sysdeps/riscv/rv32/rvf/s_lrintf.c    | 30 ++++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_ceil.c      | 51 ++++++++++++++++++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_floor.c     | 51 ++++++++++++++++++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_llrint.c    | 29 +++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_llround.c   | 29 +++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_lrint.c     | 29 +++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_lround.c    | 29 +++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_nearbyint.c | 51 ++++++++++++++++++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_rint.c      | 51 ++++++++++++++++++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_round.c     | 51 ++++++++++++++++++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_roundeven.c | 54 ++++++++++++++++++++++++++++++++++++
 sysdeps/riscv/rv64/rvd/s_trunc.c     | 51 ++++++++++++++++++++++++++++++++++
 sysdeps/riscv/rv64/rvf/s_llrintf.c   | 30 ++++++++++++++++++++
 sysdeps/riscv/rv64/rvf/s_llroundf.c  | 30 ++++++++++++++++++++
 sysdeps/riscv/rv64/rvf/s_lrintf.c    | 30 ++++++++++++++++++++
 sysdeps/riscv/rvd/e_sqrt.c           | 27 ++++++++++++++++++
 sysdeps/riscv/rvd/s_copysign.c       | 28 +++++++++++++++++++
 sysdeps/riscv/rvd/s_finite.c         | 28 +++++++++++++++++++
 sysdeps/riscv/rvd/s_fma.c            | 30 ++++++++++++++++++++
 sysdeps/riscv/rvd/s_fmax.c           | 28 +++++++++++++++++++
 sysdeps/riscv/rvd/s_fmin.c           | 28 +++++++++++++++++++
 sysdeps/riscv/rvd/s_fpclassify.c     | 36 ++++++++++++++++++++++++
 sysdeps/riscv/rvd/s_isinf.c          | 29 +++++++++++++++++++
 sysdeps/riscv/rvd/s_isnan.c          | 28 +++++++++++++++++++
 sysdeps/riscv/rvd/s_issignaling.c    | 27 ++++++++++++++++++
 28 files changed, 975 insertions(+)
 create mode 100644 sysdeps/riscv/rv32/rvd/s_lrint.c
 create mode 100644 sysdeps/riscv/rv32/rvd/s_lround.c
 create mode 100644 sysdeps/riscv/rv32/rvf/s_llrintf.c
 create mode 100644 sysdeps/riscv/rv32/rvf/s_lrintf.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_ceil.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_floor.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_llrint.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_llround.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_lrint.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_lround.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_nearbyint.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_rint.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_round.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_roundeven.c
 create mode 100644 sysdeps/riscv/rv64/rvd/s_trunc.c
 create mode 100644 sysdeps/riscv/rv64/rvf/s_llrintf.c
 create mode 100644 sysdeps/riscv/rv64/rvf/s_llroundf.c
 create mode 100644 sysdeps/riscv/rv64/rvf/s_lrintf.c
 create mode 100644 sysdeps/riscv/rvd/e_sqrt.c
 create mode 100644 sysdeps/riscv/rvd/s_copysign.c
 create mode 100644 sysdeps/riscv/rvd/s_finite.c
 create mode 100644 sysdeps/riscv/rvd/s_fma.c
 create mode 100644 sysdeps/riscv/rvd/s_fmax.c
 create mode 100644 sysdeps/riscv/rvd/s_fmin.c
 create mode 100644 sysdeps/riscv/rvd/s_fpclassify.c
 create mode 100644 sysdeps/riscv/rvd/s_isinf.c
 create mode 100644 sysdeps/riscv/rvd/s_isnan.c
 create mode 100644 sysdeps/riscv/rvd/s_issignaling.c

diff --git a/sysdeps/riscv/rv32/rvd/s_lrint.c b/sysdeps/riscv/rv32/rvd/s_lrint.c
new file mode 100644
index 000000000000..7a1fff6ffd27
--- /dev/null
+++ b/sysdeps/riscv/rv32/rvd/s_lrint.c
@@ -0,0 +1,30 @@
+/* lrint().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-double.h>
+
+long
+__lrint (double x)
+{
+  long res;
+  asm ("fcvt.w.d %0, %1" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_double (__lrint, lrint)
diff --git a/sysdeps/riscv/rv32/rvd/s_lround.c b/sysdeps/riscv/rv32/rvd/s_lround.c
new file mode 100644
index 000000000000..7c2e0b81fbe0
--- /dev/null
+++ b/sysdeps/riscv/rv32/rvd/s_lround.c
@@ -0,0 +1,30 @@
+/* lround().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-double.h>
+
+long
+__lround (double x)
+{
+  long res;
+  asm ("fcvt.w.d %0, %1, rmm" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_double (__lround, lround)
diff --git a/sysdeps/riscv/rv32/rvf/s_llrintf.c b/sysdeps/riscv/rv32/rvf/s_llrintf.c
new file mode 100644
index 000000000000..3de8aa99a7f3
--- /dev/null
+++ b/sysdeps/riscv/rv32/rvf/s_llrintf.c
@@ -0,0 +1,30 @@
+/* lrintf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-float.h>
+
+long long
+__llrintf (float x)
+{
+  long res;
+  asm ("fcvt.w.s %0, %1" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_float (__llrint, llrint)
diff --git a/sysdeps/riscv/rv32/rvf/s_lrintf.c b/sysdeps/riscv/rv32/rvf/s_lrintf.c
new file mode 100644
index 000000000000..806a160ce0d7
--- /dev/null
+++ b/sysdeps/riscv/rv32/rvf/s_lrintf.c
@@ -0,0 +1,30 @@
+/* lrintf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-float.h>
+
+long
+__lrintf (float x)
+{
+  long res;
+  asm ("fcvt.w.s %0, %1" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_float (__lrint, lrint)
diff --git a/sysdeps/riscv/rv64/rvd/s_ceil.c b/sysdeps/riscv/rv64/rvd/s_ceil.c
new file mode 100644
index 000000000000..7968148b75a9
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_ceil.c
@@ -0,0 +1,51 @@
+/* ceil().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-double.h>
+
+double
+__ceil (double x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnan (x);
+  double mag = fabs (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1ULL << __DBL_MANT_DIG__))
+    {
+      long i;
+      double new_x;
+
+      asm volatile ("fcvt.l.d %0, %1, rup" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.d.l %0, %1, rup" : "=f" (new_x) : "r" (i));
+
+      /* ceil(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysign (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_double (__ceil, ceil)
diff --git a/sysdeps/riscv/rv64/rvd/s_floor.c b/sysdeps/riscv/rv64/rvd/s_floor.c
new file mode 100644
index 000000000000..01ec0e06e4ce
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_floor.c
@@ -0,0 +1,51 @@
+/* floor().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-double.h>
+
+double
+__floor (double x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnan (x);
+  double mag = fabs (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1ULL << __DBL_MANT_DIG__))
+    {
+      long i;
+      double new_x;
+
+      asm volatile ("fcvt.l.d %0, %1, rdn" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.d.l %0, %1, rdn" : "=f" (new_x) : "r" (i));
+
+      /* floor(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysign (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_double (__floor, floor)
diff --git a/sysdeps/riscv/rv64/rvd/s_llrint.c b/sysdeps/riscv/rv64/rvd/s_llrint.c
new file mode 100644
index 000000000000..77a7b0712f9c
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_llrint.c
@@ -0,0 +1,29 @@
+/* llrint().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libm-alias-double.h>
+
+long long
+__llrint (double x)
+{
+  long long res;
+  asm ("fcvt.l.d %0, %1" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_double(__llrint, llrint)
diff --git a/sysdeps/riscv/rv64/rvd/s_llround.c b/sysdeps/riscv/rv64/rvd/s_llround.c
new file mode 100644
index 000000000000..5df866de7245
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_llround.c
@@ -0,0 +1,29 @@
+/* llround().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libm-alias-double.h>
+
+long long
+__llround (double x)
+{
+  long long res;
+  asm ("fcvt.l.d %0, %1, rmm" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_double (__llround, llround)
diff --git a/sysdeps/riscv/rv64/rvd/s_lrint.c b/sysdeps/riscv/rv64/rvd/s_lrint.c
new file mode 100644
index 000000000000..2d11cc3cd16d
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_lrint.c
@@ -0,0 +1,29 @@
+/* lrint().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libm-alias-double.h>
+
+long
+__lrint (double x)
+{
+  long res;
+  asm ("fcvt.l.d %0, %1" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_double (__lrint, lrint)
diff --git a/sysdeps/riscv/rv64/rvd/s_lround.c b/sysdeps/riscv/rv64/rvd/s_lround.c
new file mode 100644
index 000000000000..b4f37e15bd2e
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_lround.c
@@ -0,0 +1,29 @@
+/* llround().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libm-alias-double.h>
+
+long
+__lround (double x)
+{
+  long res;
+  asm ("fcvt.l.d %0, %1, rmm" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_double (__lround, lround)
diff --git a/sysdeps/riscv/rv64/rvd/s_nearbyint.c b/sysdeps/riscv/rv64/rvd/s_nearbyint.c
new file mode 100644
index 000000000000..aa4399f9c7f3
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_nearbyint.c
@@ -0,0 +1,51 @@
+/* nearbyint().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-double.h>
+
+double
+__nearbyint (double x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnan (x);
+  double mag = fabs (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1ULL << __DBL_MANT_DIG__))
+    {
+      long i;
+      double new_x;
+
+      asm volatile ("fcvt.l.d %0, %1" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.d.l %0, %1" : "=f" (new_x) : "r" (i));
+
+      /* nearbyint(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysign (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_double (__nearbyint, nearbyint)
diff --git a/sysdeps/riscv/rv64/rvd/s_rint.c b/sysdeps/riscv/rv64/rvd/s_rint.c
new file mode 100644
index 000000000000..a44d43373dc6
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_rint.c
@@ -0,0 +1,51 @@
+/* rint().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-double.h>
+
+double
+__rint (double x)
+{
+  int nan;
+  double mag;
+
+  nan = isnan (x);
+  mag = fabs (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1ULL << __DBL_MANT_DIG__))
+    {
+      long i;
+      double new_x;
+
+      asm ("fcvt.l.d %0, %1" : "=r" (i) : "f" (x));
+      asm ("fcvt.d.l %0, %1" : "=f" (new_x) : "r" (i));
+
+      /* rint(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysign (new_x, x);
+    }
+
+  return x;
+}
+
+libm_alias_double (__rint, rint)
diff --git a/sysdeps/riscv/rv64/rvd/s_round.c b/sysdeps/riscv/rv64/rvd/s_round.c
new file mode 100644
index 000000000000..84e4fbfa7997
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_round.c
@@ -0,0 +1,51 @@
+/* round().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-double.h>
+
+double
+__round (double x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnan (x);
+  double mag = fabs (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1ULL << __DBL_MANT_DIG__))
+    {
+      long i;
+      double new_x;
+
+      asm volatile ("fcvt.l.d %0, %1, rmm" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.d.l %0, %1, rmm" : "=f" (new_x) : "r" (i));
+
+      /* round(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysign (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_double (__round, round)
diff --git a/sysdeps/riscv/rv64/rvd/s_roundeven.c b/sysdeps/riscv/rv64/rvd/s_roundeven.c
new file mode 100644
index 000000000000..145955c3d6fc
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_roundeven.c
@@ -0,0 +1,54 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+   RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-double.h>
+
+double
+__roundeven (double x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnan (x);
+  double mag = fabs (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1ULL << __DBL_MANT_DIG__))
+    {
+      long i;
+      double new_x;
+
+      asm volatile ("fcvt.l.d %0, %1, rne" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.d.l %0, %1, rne" : "=f" (new_x) : "r" (i));
+
+      /* roundeven(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysign (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+hidden_def (__roundeven)
+libm_alias_double (__roundeven, roundeven)
diff --git a/sysdeps/riscv/rv64/rvd/s_trunc.c b/sysdeps/riscv/rv64/rvd/s_trunc.c
new file mode 100644
index 000000000000..577e9da50554
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvd/s_trunc.c
@@ -0,0 +1,51 @@
+/* trunc().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <libm-alias-double.h>
+
+double
+__trunc (double x)
+{
+  int flags = riscv_getflags ();
+  int nan = isnan (x);
+  double mag = fabs (x);
+
+  if (nan)
+    return x + x;
+
+  if (mag < (1ULL << __DBL_MANT_DIG__))
+    {
+      long i;
+      double new_x;
+
+      asm volatile ("fcvt.l.d %0, %1, rtz" : "=r" (i) : "f" (x));
+      asm volatile ("fcvt.d.l %0, %1, rtz" : "=f" (new_x) : "r" (i));
+
+      /* trunc(-0) == -0, and in general we'll always have the same
+	 sign as our input.  */
+      x = copysign (new_x, x);
+
+      riscv_setflags (flags);
+    }
+
+  return x;
+}
+
+libm_alias_double (__trunc, trunc)
diff --git a/sysdeps/riscv/rv64/rvf/s_llrintf.c b/sysdeps/riscv/rv64/rvf/s_llrintf.c
new file mode 100644
index 000000000000..69f4e8ea9b56
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvf/s_llrintf.c
@@ -0,0 +1,30 @@
+/* Round argument to nearest integral value according to current rounding
+   direction.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libm-alias-float.h>
+
+long long
+__llrintf (float x)
+{
+  long long res;
+  asm ("fcvt.l.s %0, %1" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_float(__llrint, llrint)
diff --git a/sysdeps/riscv/rv64/rvf/s_llroundf.c b/sysdeps/riscv/rv64/rvf/s_llroundf.c
new file mode 100644
index 000000000000..5b69c01648ec
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvf/s_llroundf.c
@@ -0,0 +1,30 @@
+/* Round float value to long long int.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libm-alias-float.h>
+#include <libm-alias-float.h>
+
+long long
+__llroundf (float x)
+{
+  long long res;
+  asm ("fcvt.l.s %0, %1, rmm" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_float (__llround, llround)
diff --git a/sysdeps/riscv/rv64/rvf/s_lrintf.c b/sysdeps/riscv/rv64/rvf/s_lrintf.c
new file mode 100644
index 000000000000..cb28ffe1b536
--- /dev/null
+++ b/sysdeps/riscv/rv64/rvf/s_lrintf.c
@@ -0,0 +1,30 @@
+/* lrintf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-float.h>
+
+long
+__lrintf (float x)
+{
+  long res;
+  asm ("fcvt.l.s %0, %1" : "=r" (res) : "f" (x));
+  return res;
+}
+
+libm_alias_float (__lrint, lrint)
diff --git a/sysdeps/riscv/rvd/e_sqrt.c b/sysdeps/riscv/rvd/e_sqrt.c
new file mode 100644
index 000000000000..ceac9f4c34a4
--- /dev/null
+++ b/sysdeps/riscv/rvd/e_sqrt.c
@@ -0,0 +1,27 @@
+/* Double precision floating point square root.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+
+double
+__ieee754_sqrt (double x)
+{
+  asm ("fsqrt.d %0, %1" : "=f" (x) : "f" (x));
+  return x;
+}
+strong_alias (__ieee754_sqrt, __sqrt_finite)
diff --git a/sysdeps/riscv/rvd/s_copysign.c b/sysdeps/riscv/rvd/s_copysign.c
new file mode 100644
index 000000000000..d3a5000a6e7b
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_copysign.c
@@ -0,0 +1,28 @@
+/* Copy sign bit between floating-point values.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__copysign (double x, double y)
+{
+  asm ("fsgnj.d %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_double (__copysign, copysign)
diff --git a/sysdeps/riscv/rvd/s_finite.c b/sysdeps/riscv/rvd/s_finite.c
new file mode 100644
index 000000000000..06914e1c1e71
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_finite.c
@@ -0,0 +1,28 @@
+/* finite().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__finite (double x)
+{
+  return _FCLASS (x) & ~(_FCLASS_INF | _FCLASS_NAN);
+}
+hidden_def (__finite)
+weak_alias (__finite, finite)
diff --git a/sysdeps/riscv/rvd/s_fma.c b/sysdeps/riscv/rvd/s_fma.c
new file mode 100644
index 000000000000..ff74857cf578
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_fma.c
@@ -0,0 +1,30 @@
+/* Double precision floating point fused multiply-add.  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fenv.h>
+#include <ieee754.h>
+#include <libm-alias-double.h>
+
+double
+__fma (double x, double y, double z)
+{
+  asm ("fmadd.d %0, %1, %2, %3" : "=f" (x) : "f" (x), "f" (y), "f" (z));
+  return x;
+}
+libm_alias_double (__fma, fma)
diff --git a/sysdeps/riscv/rvd/s_fmax.c b/sysdeps/riscv/rvd/s_fmax.c
new file mode 100644
index 000000000000..b108434cd64b
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_fmax.c
@@ -0,0 +1,28 @@
+/* fmax().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__fmax (double x, double y)
+{
+  asm ("fmax.d %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_double (__fmax, fmax)
diff --git a/sysdeps/riscv/rvd/s_fmin.c b/sysdeps/riscv/rvd/s_fmin.c
new file mode 100644
index 000000000000..4894377602c3
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_fmin.c
@@ -0,0 +1,28 @@
+/* fmin().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <libm-alias-double.h>
+
+double
+__fmin (double x, double y)
+{
+  asm ("fmin.d %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
+  return x;
+}
+libm_alias_double (__fmin, fmin)
diff --git a/sysdeps/riscv/rvd/s_fpclassify.c b/sysdeps/riscv/rvd/s_fpclassify.c
new file mode 100644
index 000000000000..cdfdbdfbc1e2
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_fpclassify.c
@@ -0,0 +1,36 @@
+/* fpclassify().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__fpclassify (double x)
+{
+  int cls = _FCLASS (x);
+  if (__builtin_expect (cls & _FCLASS_NORM, _FCLASS_NORM))
+    return FP_NORMAL;
+  if (__builtin_expect (cls & _FCLASS_ZERO, _FCLASS_ZERO))
+    return FP_ZERO;
+  if (__builtin_expect (cls & _FCLASS_SUBNORM, _FCLASS_SUBNORM))
+    return FP_SUBNORMAL;
+  if (__builtin_expect (cls & _FCLASS_INF, _FCLASS_INF))
+    return FP_INFINITE;
+  return FP_NAN;
+}
+libm_hidden_def (__fpclassify)
diff --git a/sysdeps/riscv/rvd/s_isinf.c b/sysdeps/riscv/rvd/s_isinf.c
new file mode 100644
index 000000000000..92d2f2c261bc
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_isinf.c
@@ -0,0 +1,29 @@
+/* isinf().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__isinf (double x)
+{
+  int cls = _FCLASS (x);
+  return -((cls & _FCLASS_MINF) ? 1 : 0) | ((cls & _FCLASS_PINF) ? 1 : 0);
+}
+hidden_def (__isinf)
+weak_alias (__isinf, isinf)
diff --git a/sysdeps/riscv/rvd/s_isnan.c b/sysdeps/riscv/rvd/s_isnan.c
new file mode 100644
index 000000000000..e88b47287952
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_isnan.c
@@ -0,0 +1,28 @@
+/* isnan().  RISC_V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__isnan (double x)
+{
+  return _FCLASS (x) & _FCLASS_NAN;
+}
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
diff --git a/sysdeps/riscv/rvd/s_issignaling.c b/sysdeps/riscv/rvd/s_issignaling.c
new file mode 100644
index 000000000000..6136d7e7f33f
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_issignaling.c
@@ -0,0 +1,27 @@
+/* issignaling().  RISC-V version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+int
+__issignaling (double x)
+{
+  return _FCLASS (x) & _FCLASS_SNAN;
+}
+libm_hidden_def (__issignaling)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 14/15] Add linux-4.15 VDSO hash for RISC-V
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (10 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 13/15] Add RISC-V dynamic relocations to elf.h Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20  7:24 ` [PATCH v2 15/15] Add RISC-V to build-many-glibcs.py Palmer Dabbelt
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

I'm not actually sure what the right thing to do here is.
---
 sysdeps/unix/sysv/linux/dl-vdso.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sysdeps/unix/sysv/linux/dl-vdso.h b/sysdeps/unix/sysv/linux/dl-vdso.h
index 7d51a33f802d..c72f307eea3b 100644
--- a/sysdeps/unix/sysv/linux/dl-vdso.h
+++ b/sysdeps/unix/sysv/linux/dl-vdso.h
@@ -44,6 +44,8 @@
 #define VDSO_HASH_LINUX_2_6_15	123718565
 #define VDSO_NAME_LINUX_2_6_29	"LINUX_2.6.29"
 #define VDSO_HASH_LINUX_2_6_29	123718585
+#define VDSO_NAME_LINUX_4_15	"LINUX_4.15"
+#define VDSO_HASH_LINUX_4_15	182943605
 
 /* Functions for resolving symbols in the VDSO link map.  */
 extern void *_dl_vdso_vsym (const char *name,
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 15/15] Add RISC-V to build-many-glibcs.py
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (11 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 14/15] Add linux-4.15 VDSO hash for RISC-V Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20  7:24 ` [PATCH v2 08/15] RISC-V: RV32D, RV64F, and RV64D Support Palmer Dabbelt
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

FIXME: I haven't actually run this yet.
---
 scripts/build-many-glibcs.py | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
index b86d6c13877d..31bbf8cba1de 100755
--- a/scripts/build-many-glibcs.py
+++ b/scripts/build-many-glibcs.py
@@ -320,6 +320,11 @@ class Context(object):
                         os_name='linux-gnuspe',
                         variant='e500v1',
                         gcc_cfg=['--disable-multilib', '--enable-secureplt'])
+        self.add_config(arch='riscv',
+                        os_name='linux-gnu',
+                        variant='rv64imafdc-lp64d',
+                        glibcs=[{'variant': 'rv64imafdc-lp64d',
+                                 'ccopts': '-march=rv64imafdc -mabi=lp64d'}])
         self.add_config(arch='s390x',
                         os_name='linux-gnu',
                         glibcs=[{},
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v2 13/15] Add RISC-V dynamic relocations to elf.h
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (9 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 12/15] RISC-V: Linux Startup and Dynamic Loading Code Palmer Dabbelt
@ 2017-12-20  7:24 ` Palmer Dabbelt
  2017-12-20  7:24 ` [PATCH v2 14/15] Add linux-4.15 VDSO hash for RISC-V Palmer Dabbelt
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20  7:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj, Palmer Dabbelt

These relocations can appear in shared objects on RISC-V ELF systems.
---
 elf/elf.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/elf/elf.h b/elf/elf.h
index 01a43ce9ac51..bf10ade6639b 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -3762,6 +3762,20 @@ enum
 
 #define R_TILEGX_NUM		130
 
+/* RISC-V relocations.  */
+#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
+
 /* BPF specific declarations.  */
 
 #define R_BPF_NONE		0	/* No reloc */
-- 
2.13.6

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-20  7:23 ` [PATCH v2 01/15] RISC-V: Build Infastructure Palmer Dabbelt
@ 2017-12-20 14:05   ` Dmitry V. Levin
  2017-12-20 20:25     ` Palmer Dabbelt
  2017-12-20 16:22   ` Joseph Myers
  2017-12-20 16:43   ` Joseph Myers
  2 siblings, 1 reply; 76+ messages in thread
From: Dmitry V. Levin @ 2017-12-20 14:05 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

[-- Attachment #1: Type: text/plain, Size: 1193 bytes --]

On Tue, Dec 19, 2017 at 11:20:08PM -0800, Palmer Dabbelt wrote:
> This patch lays out the top-level orginazition of the RISC-V port.  It
> contains all the Implies files as well as various other fragments of
> build infastructure for the RISC-V port.  This contains the only change
> to a shared file: config.h.in.
[...]
>  config.h.in                                  |   5 +
>  nptl/Makefile                                |   4 +

Well, nptl/Makefile is a shared file, too.

[...]
> diff --git a/nptl/Makefile b/nptl/Makefile
> index 60d036a1ea42..f62d19febf1d 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -611,6 +611,10 @@ else
>  librt = $(common-objpfx)rt/librt.a
>  endif
>  
> +# `make check' sometimes triggers a rebuild of librt.so using this Makefile,
> +# which ignores librt's dependence on libpthread
> +$(common-objpfx)rt/librt.so: $(shared-thread-library)
> +
>  $(objpfx)tst-cancel17: $(librt)
>  $(objpfx)tst-cancelx17: $(librt)
>  $(objpfx)tst-_res1mod2.so: $(objpfx)tst-_res1mod1.so

In fact, this looks like a fix unrelated to the RISC-V port.
If this is really the case, please submit the fix separately.

Thanks,


-- 
ldv

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (14 preceding siblings ...)
  2017-12-20  7:24 ` [PATCH v2 07/15] RISC-V: RV32F Support Palmer Dabbelt
@ 2017-12-20 16:04 ` Joseph Myers
  2017-12-20 20:25   ` Palmer Dabbelt
  2017-12-20 17:40 ` Joseph Myers
  2017-12-20 21:11 ` Joseph Myers
  17 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 16:04 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> We're planning on supporting 6 glibc configurations on RISC-V, all of which we
> internally run regression tests on:
> 
> * -march=rv64imafdc -mabi=lp64d   -- what we expect to be the most used
>                                      configuration
> * -march=rv64imac   -mabi=lp64    -- soft floating point
> * -march=rv64imafdc -mabi=lp64    -- soft float ABI, but allowed to use
> 				     hardware floating point instruction.  This
> 				     is like softfp in ARM land.
> * -march=rv32imafdc -mabi=ilp32d  -- rv32i is a 32-bit ISA
> * -march=rv32imac   -mabi=ilp32
> * -march=rv32imafdc -mabi=ilp32

But you also define dynamic linker names for the "f" ABI variants (lp64f, 
ilp32f), so, as per my previous comments, those should be built by 
build-many-glibcs.py and included in at least some testing.

> * Our test suite results are very bad, but I believe this is because we're
>   running on QEMU's user-mode emulation which is known to be both buggy and
>   incomplete.  I'm bringing up userspace again to produce a more reasonable
>   test suite run, which will hopefully have a much cleaner run.

Full execution test results - meaning on QEMU system-mode emulation or 
hardware, not user-mode emulation - are definitely needed to judge whether 
a port is ready for inclusion (I've suggested < 20 architecture-specific 
FAILs as indicative of a state comparable to other reasonably 
well-maintained ports).

Note that there is no need for the glibc you are testing to be 
ABI-compatible with any glibc in your userspace's root filesystem, so you 
don't need to rebuild userspace (if e.g. it's using older glibc with 
different symbol versions) to test current glibc.  It *does* need to be 
able to find libgcc_s and libstdc++ shared libraries at runtime, but you 
can copy those into the glibc build directory before running tests.

> * I've only added one configuration to build-many-glibcs.py, which I haven't
>   actually run yet.  I'll rectify this, but I wanted to at least get something
>   out so everyone was on the same page here -- the commit is more of a TODO
>   than an actual commit.

There should be at least one per ABI in there.  Additional variants for an 
ABI (e.g. varying whether hard or soft float is used with a soft-float 
ABI) are optional, depending on whether you think they provide useful 
additional coverage of significantly different code in glibc getting 
built.  Such variants should typically only need listing in extra_glibcs 
so they get built in a "glibcs" build but not a "compilers" build.

Depending on the multilib configurations used by GCC you may or may not 
need as many GCC builds as different ABIs (e.g. MIPS has 24 ABIs, so 24 
glibc builds in build-many-glibcs.py, but only 8 separate GCC builds, each 
with multilibs for 3 ABIs).

It's important to make sure that the build is completely clean for the GCC 
/ glibc variants you add, including no failures of compilation tests.  
(That is, clean given that you substitute a checkout of Linus's git tree 
for the default release version of Linux - obviously the builds can't be 
clean from the bots until the Linux 4.15 release comes out.)

> * I'm not sure what the right the to do with VDSO_NAME_LINUX_4_15 is.  It seems
>   odd that there's nothing newer than 2.6.29 in there.

That probably indicates that any more recent vDSOs added to the Linux 
kernel used a version number that reflected when people started developing 
them, rather than the version when they actually got into the kernel.  
Once it gets into the kernel, the symbol version used for the vDSO by the 
kernel becomes part of the kernel/userspace ABI, so fixed even if in some 
sense it's the "wrong" version.

If the RISC-V Linux kernel port uses a LINUX_4.15 symbol version for its 
vDSO, adding VDSO_NAME_LINUX_4_15 seems right to me.

> * Many copyright cleanups.

Of course, if work on the port goes past 31 December before it's ready to 
go in, you'll need to update all copyrights to use <year>-2018 ranges.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-20  7:23 ` [PATCH v2 01/15] RISC-V: Build Infastructure Palmer Dabbelt
  2017-12-20 14:05   ` Dmitry V. Levin
@ 2017-12-20 16:22   ` Joseph Myers
  2017-12-20 16:49     ` Adhemerval Zanella
  2017-12-23  2:22     ` Palmer Dabbelt
  2017-12-20 16:43   ` Joseph Myers
  2 siblings, 2 replies; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 16:22 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile
> new file mode 100644
> index 000000000000..64060531a1d5
> --- /dev/null
> +++ b/sysdeps/riscv/Makefile
> @@ -0,0 +1,49 @@
> +ifneq ($(all-rtld-routines),)
> +CFLAGS-rtld.c += -mno-plt

My previous comments from 
<https://sourceware.org/ml/libc-alpha/2017-06/msg00645.html> still apply: 
this is too fragile (people won't think when making an 
architecture-independent change about whether it needs a RISC-V-specific 
change here) and completely lacking the required detailed explanatory 
comment of what the issue is and the logic for determining what files need 
this option (but really the logic should be implemented to avoid an 
architecture-specific list of architecture-independent files being needed 
at all).

> diff --git a/sysdeps/riscv/Versions b/sysdeps/riscv/Versions
> new file mode 100644
> index 000000000000..aafa348a2395
> --- /dev/null
> +++ b/sysdeps/riscv/Versions
> @@ -0,0 +1,4 @@
> +libc {
> +  GLIBC_2.27 {
> +  }
> +}

You shouldn't need this file at all when there aren't any versions to 
include in it.

> diff --git a/sysdeps/riscv/preconfigure b/sysdeps/riscv/preconfigure

Does your soft-float lack support for exceptions and rounding modes?  If 
so, I'd expect a setting of with_fp_cond, and a corresponding nofpu 
directory or directories with Implies files pointing to ieee754/soft-fp 
(arranged so that always comes before the other ieee754/ directories in 
the sysdeps directory ordering).  That's needed to get the soft-fp 
versions of fmaf/fma/fmal used instead of the default ones relying on 
exceptions and rounding modes, so its absence should show up as test 
failures for soft-float configurations.  In future it will also similarly 
be needed to get soft-fp versions of TS 18661-1 narrowing functions used.

Remark: it makes sense for ieee754/dbl-64/wordsize-64 to be used (before 
ieee754/dbl-64 in the sysdeps directory ordering) in configurations with 
64-bit registers (but that's just an optimization so you may wish to defer 
it).

> +abi-ilp32-options     := -D__SIZEOF_INT__=4

abi-* options variables are no longer used with the current bits/syscall.h 
generation mechanism, so you should remove all settings of such variables 
from the patch.

> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/Makefile b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
> new file mode 100644
> index 000000000000..cb60d740476d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
> @@ -0,0 +1,4 @@
> +ifeq ($(subdir),socket)
> +CFLAGS-recv.c += -fexceptions
> +CFLAGS-send.c += -fexceptions
> +endif

I wonder if this should be made generic for all Linux ports (and removed 
from the mips64 Makefile as well as here).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 02/15] RISC-V: ABI Implementation
  2017-12-20  7:23 ` [PATCH v2 02/15] RISC-V: ABI Implementation Palmer Dabbelt
@ 2017-12-20 16:31   ` Joseph Myers
  2017-12-23  3:25     ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 16:31 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> +END(__longjmp)

Should have space before '(' in such a macro call.

> +ENTRY(_dl_runtime_resolve)

Likewise.

> +END(_dl_runtime_resolve)

Likewise.  Please check and fix this throughout this patch series.

> +/*
> + * Macros to handle different pointer/register sizes for 32/64-bit code
> + */

GNU-style macros should not have the leading '*' on each line; please fix 
throughout this file and anywhere else affected in this patch series.  
Also, comments on macros or functions should generally not name the macro 
or function being described, so e.g. "Declare leaf routine." (or "Declare 
leaf routine SYMBOL.") not "LEAF - declare leaf routine".

> +	     : "=r"(__result));				\

Missing space before '(', and similarly in other TLS macros.

> +	__tls_get_addr(__result); })

Likewise, and similarly in other TLS macros.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code
  2017-12-20  7:23 ` [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code Palmer Dabbelt
@ 2017-12-20 16:38   ` Joseph Myers
  2017-12-23  3:25     ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 16:38 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> +extern ElfW(Addr) la_riscv_gnu_pltenter (ElfW(Sym) *__sym, unsigned int __ndx,

With reference to my previous comments, ElfW is an exception to the rule 
of spaces before '(' in macro and function calls, because it locally 
expands to a single identifier.  So this code is correct not to have a 
space there.

> +  extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_ __attribute__((visibility("hidden")));

However, __attribute__ is *not* an exception.  This should use:
__attribute__ ((visibility ("hidden"))) - and likewise for other 
attributes, elsewhere in this patch or the patch series as a whole.

General question in the area of this patch: static PIE support was 
recently added to glibc.  Do you support it for RISC-V?  It's not so far a 
requirement for adding a port, but if not supported, when the port goes in 
it would need adding to the list at 
<https://sourceware.org/glibc/wiki/PortStatus> of ports for which static 
PIE is not yet known to work.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-20  7:23 ` [PATCH v2 01/15] RISC-V: Build Infastructure Palmer Dabbelt
  2017-12-20 14:05   ` Dmitry V. Levin
  2017-12-20 16:22   ` Joseph Myers
@ 2017-12-20 16:43   ` Joseph Myers
  2017-12-23  3:41     ` Palmer Dabbelt
  2 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 16:43 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

Another observation:

Since you're using ldbl-128, that presumably means _Float128 and _Float64x 
type names are supported with the same format as long double.  So you need 
to add RISC-V to the list in manual/math.texi of ports for which those 
type names and associated interfaces are supported.

I don't think you strictly need to add it to the similar lists for 
_Float128 and _Float64x support in the NEWS section for glibc 2.27, since 
the whole port is new rather than this being a new feature for an existing 
port in the RISC-V case.  However, the patch series needs to include a 
patch adding a NEWS item about the port, and the port also needs to be 
added to the list in the README file of supported glibc configurations 
using the Linux kernel.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 04/15] RISC-V: Thread-Local Storage Support
  2017-12-20  7:23 ` [PATCH v2 04/15] RISC-V: Thread-Local Storage Support Palmer Dabbelt
@ 2017-12-20 16:45   ` Joseph Myers
  2017-12-23 19:10     ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 16:45 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> +#define thread_offsetof(mem)	(long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)

Missing space between offsetof and '('.

> +register void* __thread_self asm("tp");

Missing space after asm.  Also should be "void *__thread_self" not "void* 
__thread_self".

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 05/15] RISC-V: Generic <string.h> Routines
  2017-12-20  7:23 ` [PATCH v2 05/15] RISC-V: Generic <string.h> Routines Palmer Dabbelt
@ 2017-12-20 16:48   ` Joseph Myers
  2017-12-23 22:01     ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 16:48 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> This patch contains fast versions of the various routines from string.h
> that have been implemented for RISC-V.  Since RISC-V doesn't define any
> specific performance characteristics they're not optimized for any
> particular microarchitecture, but are designed to be generally good.

I would again suggest deferring adding such functions, especially the C 
ones, and instead helping with updating / reviewing RTH's optimized 
generic string functions posted a while back, and only adding 
RISC-V-specific ones if there is some clear reason RISC-V needs something 
non-generic for optimal performance.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-20 16:22   ` Joseph Myers
@ 2017-12-20 16:49     ` Adhemerval Zanella
  2017-12-23  2:22     ` Palmer Dabbelt
  1 sibling, 0 replies; 76+ messages in thread
From: Adhemerval Zanella @ 2017-12-20 16:49 UTC (permalink / raw)
  To: Joseph Myers, Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj



On 20/12/2017 14:21, Joseph Myers wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

>> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/Makefile b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
>> new file mode 100644
>> index 000000000000..cb60d740476d
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
>> @@ -0,0 +1,4 @@
>> +ifeq ($(subdir),socket)
>> +CFLAGS-recv.c += -fexceptions
>> +CFLAGS-send.c += -fexceptions
>> +endif
> 
> I wonder if this should be made generic for all Linux ports (and removed 
> from the mips64 Makefile as well as here).
> 

We already a CFLAGS-recv.c with "-fexceptions -fasynchronous-unwind-tables"
for nptl, and I think we should add it for io as well. Could you send a
separately fix along with the mips64 cleanup?

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 06/15] RISC-V: Generic <math.h> and soft-fp Routines
  2017-12-20  7:24 ` [PATCH v2 06/15] RISC-V: Generic <math.h> and soft-fp Routines Palmer Dabbelt
@ 2017-12-20 16:50   ` Joseph Myers
  2017-12-24  0:24     ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 16:50 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> +#ifndef __riscv_flen
> +
> +#define _FPU_RESERVED 0xffffffff

Missing preprocessor indentation, "# define" etc. inside #if (except for 
the #if of a header's multiple-include guard).  Likewise generally in lots 
of places in this patch.

> +#define _FCLASS_MINF     (1<<0)

GNU style would use (1 << 0) with spaces around <<; likewise elsewhere in 
this patch.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2017-12-20  7:24 ` [PATCH v2 10/15] RISC-V: Linux Syscall Interface Palmer Dabbelt
@ 2017-12-20 16:57   ` Adhemerval Zanella
  2017-12-24  0:24     ` Palmer Dabbelt
  2017-12-20 17:24   ` Joseph Myers
  1 sibling, 1 reply; 76+ messages in thread
From: Adhemerval Zanella @ 2017-12-20 16:57 UTC (permalink / raw)
  To: Palmer Dabbelt, libc-alpha; +Cc: Andrew Waterman, Darius Rad, dj



On 20/12/2017 05:20, Palmer Dabbelt wrote:
> Contains the Linux system call interface, as well as the definitions of
> a handful of system calls.
> ---
>  sysdeps/riscv/nptl/nptl-sysdep.S                |   2 +
>  sysdeps/unix/sysv/linux/riscv/arch-fork.h       |   1 +
>  sysdeps/unix/sysv/linux/riscv/clone.S           |  85 +++++++
>  sysdeps/unix/sysv/linux/riscv/getmsg.c          |   1 +
>  sysdeps/unix/sysv/linux/riscv/kernel-features.h |  23 ++
>  sysdeps/unix/sysv/linux/riscv/profil-counter.h  |   2 +
>  sysdeps/unix/sysv/linux/riscv/pt-vfork.S        |   1 +
>  sysdeps/unix/sysv/linux/riscv/putmsg.c          |   1 +
>  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c    |   1 +
>  sysdeps/unix/sysv/linux/riscv/rv32/readahead.c  |   1 +
>  sysdeps/unix/sysv/linux/riscv/syscall.c         |  38 +++
>  sysdeps/unix/sysv/linux/riscv/sysdep.S          |  51 ++++
>  sysdeps/unix/sysv/linux/riscv/sysdep.h          | 316 ++++++++++++++++++++++++
>  sysdeps/unix/sysv/linux/riscv/vfork.S           |  44 ++++
>  14 files changed, 567 insertions(+)
>  create mode 100644 sysdeps/riscv/nptl/nptl-sysdep.S
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/arch-fork.h
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/clone.S
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/getmsg.c
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/kernel-features.h
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/profil-counter.h
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/pt-vfork.S
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/putmsg.c
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/syscall.c
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.S
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.h
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/vfork.S
> 
> diff --git a/sysdeps/riscv/nptl/nptl-sysdep.S b/sysdeps/riscv/nptl/nptl-sysdep.S
> new file mode 100644
> index 000000000000..3f5c2a364afd
> --- /dev/null
> +++ b/sysdeps/riscv/nptl/nptl-sysdep.S
> @@ -0,0 +1,2 @@
> +/* Pull in __syscall_error.  */
> +#include <sysdep.S>
> diff --git a/sysdeps/unix/sysv/linux/riscv/arch-fork.h b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
> new file mode 100644
> index 000000000000..5f945378eec0
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
> @@ -0,0 +1 @@
> +#include <sysdeps/unix/sysv/linux/i386/arch-fork.h>

I would prefer for new ports if we refrain to continue doing this cross arch
code references, it ties implementations that should be independent of each
other and make future cleanups more complex and required to adequate multiple
architecture at once.  

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 07/15] RISC-V: RV32F Support
  2017-12-20  7:24 ` [PATCH v2 07/15] RISC-V: RV32F Support Palmer Dabbelt
@ 2017-12-20 17:01   ` Joseph Myers
  2017-12-20 17:04     ` Joseph Myers
  2017-12-24  0:37     ` Palmer Dabbelt
  0 siblings, 2 replies; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 17:01 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> +  int nan = isnanf (x);

I don't think any libm code should be using the legacy X/Open 
type-specific classification functions such as isnanf.  Use the C99 
type-generic macros such as isnan instead.

> +  int nan = isnanf (x);

Likewise, and again throughout this patch.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 07/15] RISC-V: RV32F Support
  2017-12-20 17:01   ` Joseph Myers
@ 2017-12-20 17:04     ` Joseph Myers
  2017-12-24  1:26       ` Palmer Dabbelt
  2017-12-24  0:37     ` Palmer Dabbelt
  1 sibling, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 17:04 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017, Joseph Myers wrote:

> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
> 
> > +  int nan = isnanf (x);
> 
> I don't think any libm code should be using the legacy X/Open 
> type-specific classification functions such as isnanf.  Use the C99 
> type-generic macros such as isnan instead.

Also, and again in patch 8: I think new code should preferably use bool 
(from <stdbool.h>) for boolean variables like this, instead of int.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 09/15] RISC-V: Atomic and Locking Routines
  2017-12-20  7:24 ` [PATCH v2 09/15] RISC-V: Atomic and Locking Routines Palmer Dabbelt
@ 2017-12-20 17:08   ` Joseph Myers
  2017-12-24  1:26     ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 17:08 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> This patch implements various atomic and locking routines on RISC-V,
> either via the A extension (when present) or via a Linux system call
> that does a compare-and-exchange.  This contains both the library
> routines and the syscall wrapper.

You said in the introduction that the 'A' extension would be required for 
Linux.  I think you need to update the patch description - *and* the patch 
itself - to reflect that.

> diff --git a/sysdeps/riscv/rv64/rvd/s_roundeven.c b/sysdeps/riscv/rv64/rvd/s_roundeven.c

Does not belong in this patch.

> diff --git a/sysdeps/riscv/rv64/rvf/s_llrintf.c b/sysdeps/riscv/rv64/rvf/s_llrintf.c

Likewise.

> +#ifdef __riscv_atomic
> +
> +#define __HAVE_64B_ATOMICS (__riscv_xlen >= 64)
> +#define USE_ATOMIC_COMPILER_BUILTINS 1
> +#define ATOMIC_EXCHANGE_USES_CAS 0

Missing preprocessor indentation.

> +/* Miscellaneous. */
> +
> +#define asm_amo(which, ordering, mem, value) ({ 		\

Likewise, in this part of the file.

> +#else /* __riscv_atomic */

And this part of the file should now just have a #error.  (Giving an error 
for non-A at configure time would be a good idea as well, so the bad 
configuration gets detected as early as possible.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2017-12-20  7:24 ` [PATCH v2 10/15] RISC-V: Linux Syscall Interface Palmer Dabbelt
  2017-12-20 16:57   ` Adhemerval Zanella
@ 2017-12-20 17:24   ` Joseph Myers
  2017-12-25 19:47     ` Palmer Dabbelt
  1 sibling, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 17:24 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> diff --git a/sysdeps/unix/sysv/linux/riscv/getmsg.c b/sysdeps/unix/sysv/linux/riscv/getmsg.c
> new file mode 100644
> index 000000000000..3a1fa0852504
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/getmsg.c
> @@ -0,0 +1 @@
> +#include <sysdeps/unix/sysv/linux/i386/getmsg.c>

Really?  I don't see getpmsg in the generic or RISC-V syscall ABI.

> diff --git a/sysdeps/unix/sysv/linux/riscv/kernel-features.h b/sysdeps/unix/sysv/linux/riscv/kernel-features.h

My comments from 
<https://sourceware.org/ml/libc-alpha/2017-06/msg00661.html> still apply: 
you shouldn't need this file.

> diff --git a/sysdeps/unix/sysv/linux/riscv/putmsg.c b/sysdeps/unix/sysv/linux/riscv/putmsg.c
> new file mode 100644
> index 000000000000..ebc1680ca7d1
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/putmsg.c
> @@ -0,0 +1 @@
> +#include <sysdeps/unix/sysv/linux/i386/putmsg.c>

Same comment as for getmsg.

> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
> new file mode 100644
> index 000000000000..80170c3e8a4d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
> @@ -0,0 +1 @@
> +#include <sysdeps/unix/sysv/linux/arm/readahead.c>

I commented on this before 
<https://sourceware.org/ml/libc-alpha/2017-06/msg00661.html>.  Are you 
sure about it?  The ARM file is dealing with a peculiarity of the syscall 
interface in the case where (a) it follows the C function interface and 
(b) a 32-bit function argument followed by a 64-bit function argument 
requires a one-register gap between them.

Now, RISC-V doesn't seem to do anything special for this syscall in the 
kernel, so I presume it does follow the C function interface.  But 
<https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md> 
says that aligned register pairs are only used for variadic arguments, and 
readahead is not a variadic function.  So I'd expect there not to be a gap 
in the arguments to this syscall, and so use of the ARM function to be 
wrong.  (As the syscall has no errors and no testable semantic effect, as 
long as the fd argument is valid, getting this wrong would not result in 
any test failures.)

> +#ifdef __ASSEMBLER__
> +
> +#include <sys/asm.h>
> +
> +#define ENTRY(name) LEAF(name)

Missing preprocessor indentation here and subsequently (inconsistently) in 
this file.

> +#endif /* linux/mips/sysdep.h */

This comment is clearly wrong here.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 11/15] RISC-V: Linux ABI
  2017-12-20  7:24 ` [PATCH v2 11/15] RISC-V: Linux ABI Palmer Dabbelt
@ 2017-12-20 17:33   ` Joseph Myers
  2017-12-25 19:47     ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 17:33 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> diff --git a/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
> new file mode 100644
> index 000000000000..e903c7e0df2a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
> @@ -0,0 +1,2 @@
> +#define __longjmp ____longjmp_chk
> +#include <__longjmp.S>

I'm not clear how this is meant to achieve the ____longjmp_chk semantics, 
which involve comparing current and saved stack pointers to avoid jumping 
into a frame that has returned.  (See 
sysdeps/unix/sysv/linux/generic/____longjmp_chk.c for a C version of the 
required logic.)

> diff --git a/sysdeps/unix/sysv/linux/riscv/libthread_db.abilist b/sysdeps/unix/sysv/linux/riscv/libthread_db.abilist

You need a full set of abilist baselines, not just this one.

> +extern int __riscv_flush_icache (void *start, void *end, unsigned long flags);

Should use __start, __end, __flags, unless you really intend start, end 
and flags to be part of the public API for this header.

> diff --git a/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h

This header does not look appropriately namespace-clean.  Please make sure 
that all the conform/ tests pass, conditioning contents as necessary.  
It's also missing some preprocessor indentation.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (15 preceding siblings ...)
  2017-12-20 16:04 ` RISC-V glibc port v2 Joseph Myers
@ 2017-12-20 17:40 ` Joseph Myers
  2017-12-25 20:20   ` Palmer Dabbelt
  2017-12-20 21:11 ` Joseph Myers
  17 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 17:40 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> Thanks to everyone who has helped review the patch set!  I believe we've gone
> through all the feedback from the first patch set.  Sorry if we've missed
> anything, but at this point I think it'd be best to re-submit it -- it's been a
> long time since the previous patch set.

Apart from the points I've mentioned in comments on individual patches, as 
previously noted you need a c++-types.data ABI baseline or baselines.  And 
as previously noted a bits/environments.h header may be appropriate though 
not required.  And you're missing libm-test-ulps / libm-test-ulps-name 
files.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-20 14:05   ` Dmitry V. Levin
@ 2017-12-20 20:25     ` Palmer Dabbelt
  0 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20 20:25 UTC (permalink / raw)
  To: ldv; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 06:05:20 PST (-0800), ldv@altlinux.org wrote:
> On Tue, Dec 19, 2017 at 11:20:08PM -0800, Palmer Dabbelt wrote:
>> This patch lays out the top-level orginazition of the RISC-V port.  It
>> contains all the Implies files as well as various other fragments of
>> build infastructure for the RISC-V port.  This contains the only change
>> to a shared file: config.h.in.
> [...]
>>  config.h.in                                  |   5 +
>>  nptl/Makefile                                |   4 +
>
> Well, nptl/Makefile is a shared file, too.
>
> [...]
>> diff --git a/nptl/Makefile b/nptl/Makefile
\f>> index 60d036a1ea42..f62d19febf1d 100644
>> --- a/nptl/Makefile
>> +++ b/nptl/Makefile
>> @@ -611,6 +611,10 @@ else
>>  librt = $(common-objpfx)rt/librt.a
>>  endif
>>  
>> +# `make check' sometimes triggers a rebuild of librt.so using this Makefile,
>> +# which ignores librt's dependence on libpthread
>> +$(common-objpfx)rt/librt.so: $(shared-thread-library)
>> +
>>  $(objpfx)tst-cancel17: $(librt)
>>  $(objpfx)tst-cancelx17: $(librt)
>>  $(objpfx)tst-_res1mod2.so: $(objpfx)tst-_res1mod1.so
>
> In fact, this looks like a fix unrelated to the RISC-V port.
> If this is really the case, please submit the fix separately.
>
> Thanks,

Oh, sorry, that must have snuck in somehow after I wrote the commit message -- 
I did a lot of rebasing.  We noticed this bug when running the test suite, I 
think Andrew must have fixed it because I was still using a workaround.

Thanks for catching this, I'll submit a patch that's pulled out from our port.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-20 16:04 ` RISC-V glibc port v2 Joseph Myers
@ 2017-12-20 20:25   ` Palmer Dabbelt
  2017-12-20 20:42     ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20 20:25 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 08:04:50 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> We're planning on supporting 6 glibc configurations on RISC-V, all of which we
>> internally run regression tests on:
>>
>> * -march=rv64imafdc -mabi=lp64d   -- what we expect to be the most used
>>                                      configuration
>> * -march=rv64imac   -mabi=lp64    -- soft floating point
>> * -march=rv64imafdc -mabi=lp64    -- soft float ABI, but allowed to use
>> 				     hardware floating point instruction.  This
>> 				     is like softfp in ARM land.
>> * -march=rv32imafdc -mabi=ilp32d  -- rv32i is a 32-bit ISA
>> * -march=rv32imac   -mabi=ilp32
>> * -march=rv32imafdc -mabi=ilp32
>
> But you also define dynamic linker names for the "f" ABI variants (lp64f,
> ilp32f), so, as per my previous comments, those should be built by
> build-many-glibcs.py and included in at least some testing.

Oh, sorry -- lp64f and ilp32f aren't going to be supported in glibc/Linux, just 
to reduce the number of ABI combinations.  I'll remove them from the v3.

>> * Our test suite results are very bad, but I believe this is because we're
>>   running on QEMU's user-mode emulation which is known to be both buggy and
>>   incomplete.  I'm bringing up userspace again to produce a more reasonable
>>   test suite run, which will hopefully have a much cleaner run.
>
> Full execution test results - meaning on QEMU system-mode emulation or
> hardware, not user-mode emulation - are definitely needed to judge whether
> a port is ready for inclusion (I've suggested < 20 architecture-specific
> FAILs as indicative of a state comparable to other reasonably
> well-maintained ports).

OK -- the only reason I've been running user-mode emulation is because that's 
how our test scripts are setup.  I'm working getting enough of a userspace 
together to run the test suite natively now.  We've had this before, there's 
just nothing based on the 4.15 RC headers and I want to make sure everything 
absolutely lines up.

> Note that there is no need for the glibc you are testing to be
> ABI-compatible with any glibc in your userspace's root filesystem, so you
> don't need to rebuild userspace (if e.g. it's using older glibc with
> different symbol versions) to test current glibc.  It *does* need to be
> able to find libgcc_s and libstdc++ shared libraries at runtime, but you
> can copy those into the glibc build directory before running tests.
>
>> * I've only added one configuration to build-many-glibcs.py, which I haven't
>>   actually run yet.  I'll rectify this, but I wanted to at least get something
>>   out so everyone was on the same page here -- the commit is more of a TODO
>>   than an actual commit.
>
> There should be at least one per ABI in there.  Additional variants for an
> ABI (e.g. varying whether hard or soft float is used with a soft-float
> ABI) are optional, depending on whether you think they provide useful
> additional coverage of significantly different code in glibc getting
> built.  Such variants should typically only need listing in extra_glibcs
> so they get built in a "glibcs" build but not a "compilers" build.
>
> Depending on the multilib configurations used by GCC you may or may not
> need as many GCC builds as different ABIs (e.g. MIPS has 24 ABIs, so 24
> glibc builds in build-many-glibcs.py, but only 8 separate GCC builds, each
> with multilibs for 3 ABIs).

We currently support all the glibc targets in a single GCC build and we hope to 
keep it that way, so hopefully this says a bit easier for us.  Thanks, though 
-- part of the reason I only put one entry in was because I wasn't sure what to 
do :).

> It's important to make sure that the build is completely clean for the GCC
> / glibc variants you add, including no failures of compilation tests.
> (That is, clean given that you substitute a checkout of Linus's git tree
> for the default release version of Linux - obviously the builds can't be
> clean from the bots until the Linux 4.15 release comes out.)

Makes sense.  I'll be sure this is the case.

>> * I'm not sure what the right the to do with VDSO_NAME_LINUX_4_15 is.  It seems
>>   odd that there's nothing newer than 2.6.29 in there.
>
> That probably indicates that any more recent vDSOs added to the Linux
> kernel used a version number that reflected when people started developing
> them, rather than the version when they actually got into the kernel.
> Once it gets into the kernel, the symbol version used for the vDSO by the
> kernel becomes part of the kernel/userspace ABI, so fixed even if in some
> sense it's the "wrong" version.
>
> If the RISC-V Linux kernel port uses a LINUX_4.15 symbol version for its
> vDSO, adding VDSO_NAME_LINUX_4_15 seems right to me.

OK, that makes sense.  During the Linux submission process it was suggested we 
use 4.15.0, I guess I'm just a bit surprised we're the only ones wo have 
something newer than 2.6.29.

>> * Many copyright cleanups.
>
> Of course, if work on the port goes past 31 December before it's ready to
> go in, you'll need to update all copyrights to use <year>-2018 ranges.

Sounds good.  DJ wrote a copyright checking script, so it should be easy to 
find everything.

Thanks for all the feedback.  I'll go through your messages, and though I 
haven't read them yet I assume we'll be submitting a v3.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-20 20:25   ` Palmer Dabbelt
@ 2017-12-20 20:42     ` Joseph Myers
  0 siblings, 0 replies; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 20:42 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017, Palmer Dabbelt wrote:

> > But you also define dynamic linker names for the "f" ABI variants (lp64f,
> > ilp32f), so, as per my previous comments, those should be built by
> > build-many-glibcs.py and included in at least some testing.
> 
> Oh, sorry -- lp64f and ilp32f aren't going to be supported in glibc/Linux,
> just to reduce the number of ABI combinations.  I'll remove them from the v3.

That's fine, just make sure configure or preconfigure fragments give an 
error if you try to build with such an ABI variant (and then any other 
support for those ABIs can be removed or turn into errors as well).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
                   ` (16 preceding siblings ...)
  2017-12-20 17:40 ` Joseph Myers
@ 2017-12-20 21:11 ` Joseph Myers
  2017-12-20 21:45   ` Palmer Dabbelt
  17 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-20 21:11 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Tue, 19 Dec 2017, Palmer Dabbelt wrote:

> * Should we have padding in __pthread_rwlock_arch_t?  I assume the padding on
>   other architectures is there for ABI reasons and shouldn't be necessary for
>   new ports, but the ports I usually rely on all have excatly the same padding
>   so I'm worried there's another reason for this.

The size was probably originally chosen to be the same as used by 
Linuxthreads.  Since then, there's been at least one rwlock rewrite that 
increased the amount of space that's padding.

On the whole I'd say it's safest to have that padding on RISC-V as well, 
in case there are any more rewrites in future, since it's possible a 
rewrite could increase the amount of space used as well as decreasing it, 
and so if one architecture makes the type smaller than others that could 
complicate any such future change needing more space.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-20 21:11 ` Joseph Myers
@ 2017-12-20 21:45   ` Palmer Dabbelt
  2017-12-25 12:57     ` Adhemerval Zanella
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-20 21:45 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 13:11:02 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> * Should we have padding in __pthread_rwlock_arch_t?  I assume the padding on
>>   other architectures is there for ABI reasons and shouldn't be necessary for
>>   new ports, but the ports I usually rely on all have excatly the same padding
>>   so I'm worried there's another reason for this.
>
> The size was probably originally chosen to be the same as used by
> Linuxthreads.  Since then, there's been at least one rwlock rewrite that
> increased the amount of space that's padding.
>
> On the whole I'd say it's safest to have that padding on RISC-V as well,
> in case there are any more rewrites in future, since it's possible a
> rewrite could increase the amount of space used as well as decreasing it,
> and so if one architecture makes the type smaller than others that could
> complicate any such future change needing more space.

Sounds good.  I'll add a comment

diff --git a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
index f15e024826ac..4fabc4a2cde2 100644
--- a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
@@ -52,6 +52,10 @@
 #define __LOCK_ALIGNMENT
 #define __ONCE_ALIGNMENT

+/* There is a lot of padding in this structure.  While it's not strictly
+   necessary on RISC-V, we're going to leave it in to be on the safe side in
+   case it's needed in the future.  Most other architectures have the padding,
+   so this gives us the same extensibility as everyone else has.  */
 struct __pthread_rwlock_arch_t
 {
   unsigned int __readers;

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-20 16:22   ` Joseph Myers
  2017-12-20 16:49     ` Adhemerval Zanella
@ 2017-12-23  2:22     ` Palmer Dabbelt
  2017-12-23 12:44       ` Joseph Myers
  1 sibling, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-23  2:22 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

Sorry it took a while to get back to you, I've been working through the test 
suite failures.

On Wed, 20 Dec 2017 08:21:55 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile
>> new file mode 100644
>> index 000000000000..64060531a1d5
>> --- /dev/null
>> +++ b/sysdeps/riscv/Makefile
>> @@ -0,0 +1,49 @@
>> +ifneq ($(all-rtld-routines),)
>> +CFLAGS-rtld.c += -mno-plt
>
> My previous comments from
> <https://sourceware.org/ml/libc-alpha/2017-06/msg00645.html> still apply:
> this is too fragile (people won't think when making an
> architecture-independent change about whether it needs a RISC-V-specific
> change here) and completely lacking the required detailed explanatory
> comment of what the issue is and the logic for determining what files need
> this option (but really the logic should be implemented to avoid an
> architecture-specific list of architecture-independent files being needed
> at all).

Ah, sorry, I missed that from last time.  I thought we were doing this because 
we couldn't call via the PLT in ld.so because they hadn't been resolved yet, 
but as far as I can tell there's something else handling this.  I just ran into 
it when looking at the check-localplt stuff (I'm currently going through the 
test suites).

Andrew would know for sure what's going on here -- this has been in our port 
since ~2011 (when he added PLT support) and has never had an explanation.  I 
feel like it's defunct: when I remove it we end up with only the PLT entries 
listed in check-localplt, I'd expect a lot more if everything was really 
emitting PLT calls.  I can't figure out what's actually preventing ld.so from 
using PLT calls on the _dl_fixup codepath.

I assume I'm missing something here?

>
>> diff --git a/sysdeps/riscv/Versions b/sysdeps/riscv/Versions
>> new file mode 100644
>> index 000000000000..aafa348a2395
>> --- /dev/null
>> +++ b/sysdeps/riscv/Versions
>> @@ -0,0 +1,4 @@
>> +libc {
>> +  GLIBC_2.27 {
>> +  }
>> +}
>
> You shouldn't need this file at all when there aren't any versions to
> include in it.

IIRC some test was depending on this.  I've filled all the machines with builds 
right now, but I'll give it another look later tonight.  I've got two small 
patches that touch shared build system stuff already.

>> diff --git a/sysdeps/riscv/preconfigure b/sysdeps/riscv/preconfigure
>
> Does your soft-float lack support for exceptions and rounding modes?  If
> so, I'd expect a setting of with_fp_cond, and a corresponding nofpu
> directory or directories with Implies files pointing to ieee754/soft-fp
> (arranged so that always comes before the other ieee754/ directories in
> the sysdeps directory ordering).  That's needed to get the soft-fp
> versions of fmaf/fma/fmal used instead of the default ones relying on
> exceptions and rounding modes, so its absence should show up as test
> failures for soft-float configurations.  In future it will also similarly
> be needed to get soft-fp versions of TS 18661-1 narrowing functions used.

If I understand what's going on correctly here, we support exceptions in the 
soft float ABI when built with hardware floating point instructions, but 
otherwise we don't (we're always round nearest).  I believe that means we need 
to set "with_fp_cond=1" when building with hardware floating point (regardless 
of ABI), and "with_fp_cond=0" otherwise.

Does this look sane?

diff --git a/sysdeps/riscv/preconfigure b/sysdeps/riscv/preconfigure
index e118a5ed28f6..6f2bc20ecd5b 100644
--- a/sysdeps/riscv/preconfigure
+++ b/sysdeps/riscv/preconfigure
@@ -16,12 +16,15 @@ riscv*)
     case "$flen" in
     64)
        float_machine=rvd
+       with_fp_cond=1
        ;;
     32)
        float_machine=rvf
+       with_fp_cond=1
        ;;
     "")
        float_machine=
+       with_fp_cond=0
        ;;
     *)
        echo "Unable to determine FLEN" >&2


> Remark: it makes sense for ieee754/dbl-64/wordsize-64 to be used (before
> ieee754/dbl-64 in the sysdeps directory ordering) in configurations with
> 64-bit registers (but that's just an optimization so you may wish to defer
> it).
>
>> +abi-ilp32-options     := -D__SIZEOF_INT__=4
>
> abi-* options variables are no longer used with the current bits/syscall.h
> generation mechanism, so you should remove all settings of such variables
> from the patch.

OK, we'll remove them for the v3.

>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/Makefile b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
>> new file mode 100644
>> index 000000000000..cb60d740476d
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
>> @@ -0,0 +1,4 @@
>> +ifeq ($(subdir),socket)
>> +CFLAGS-recv.c += -fexceptions
>> +CFLAGS-send.c += -fexceptions
>> +endif
>
> I wonder if this should be made generic for all Linux ports (and removed
> from the mips64 Makefile as well as here).

I think we got it from MIPS, but it doesn't seem like it should be ISA 
dependent.  I'm afraid this is another thing that's been there since before I 
was around, but I feel like since it's not in anyone else's port it's safe to 
drop it from ours.

Thanks for reviewing our code, and sorry it's a bit of a mess.  I'll try and 
get something a bit more sane out for a v3, but I'm afraid it might take a few 
more days -- luckily with the weekend and Christmas I should have some time to 
actually work on this :).

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code
  2017-12-20 16:38   ` Joseph Myers
@ 2017-12-23  3:25     ` Palmer Dabbelt
  2017-12-23  3:33       ` DJ Delorie
  2017-12-23 12:52       ` Joseph Myers
  0 siblings, 2 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-23  3:25 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 08:38:48 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> +extern ElfW(Addr) la_riscv_gnu_pltenter (ElfW(Sym) *__sym, unsigned int __ndx,
>
> With reference to my previous comments, ElfW is an exception to the rule
> of spaces before '(' in macro and function calls, because it locally
> expands to a single identifier.  So this code is correct not to have a
> space there.
>
>> +  extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_ __attribute__((visibility("hidden")));

Ah, luckily I missed those when going through you last mail :)

>
> However, __attribute__ is *not* an exception.  This should use:
> __attribute__ ((visibility ("hidden"))) - and likewise for other
> attributes, elsewhere in this patch or the patch series as a whole.

Ah, thanks -- I'd missed these too.

> General question in the area of this patch: static PIE support was
> recently added to glibc.  Do you support it for RISC-V?  It's not so far a
> requirement for adding a port, but if not supported, when the port goes in
> it would need adding to the list at
> <https://sourceware.org/glibc/wiki/PortStatus> of ports for which static
> PIE is not yet known to work.

I haven't tried it, so I assume it does not work.  It looks like the static PIE 
section's header is broken on that site, I'm seeing

    == Static PIE ===

in normal text.  I assume it's supposed to look more like "=== Static PIE ===" 
to make the text large?

Based on looking through the requirement list, there's enough things there in 
toolchain land that "should just work" that I'm sure something will end up 
being broken.  I assume it's OK to just add the various RISC-V targets to the 
unsupported list for now?

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 02/15] RISC-V: ABI Implementation
  2017-12-20 16:31   ` Joseph Myers
@ 2017-12-23  3:25     ` Palmer Dabbelt
  2017-12-23  3:30       ` DJ Delorie
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-23  3:25 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 08:31:11 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> +END(__longjmp)
>
> Should have space before '(' in such a macro call.
>
>> +ENTRY(_dl_runtime_resolve)
>
> Likewise.
>
>> +END(_dl_runtime_resolve)
>
> Likewise.  Please check and fix this throughout this patch series.
>
>> +/*
>> + * Macros to handle different pointer/register sizes for 32/64-bit code
>> + */
>
> GNU-style macros should not have the leading '*' on each line; please fix
> throughout this file and anywhere else affected in this patch series.
> Also, comments on macros or functions should generally not name the macro
> or function being described, so e.g. "Declare leaf routine." (or "Declare
> leaf routine SYMBOL.") not "LEAF - declare leaf routine".
>
>> +	     : "=r"(__result));				\
>
> Missing space before '(', and similarly in other TLS macros.
>
>> +	__tls_get_addr(__result); })
>
> Likewise, and similarly in other TLS macros.

Thanks.  I believe I've fixed them all, but I'm not 100% sure.  Is there a 
script I can run to check this?  Something like checkpatch.pl in Linux?  I 
poked around Google a bit and couldn't find anything.

I also have one style question: I noticed that

   #define macro(x) ...
   macro (x)

and 

  void func (int x)
  func (x)

don't appear to be consistent, but a grep through the glibc code base seems to 
indicate that's the way things are going.  Did I miss something?

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 02/15] RISC-V: ABI Implementation
  2017-12-23  3:25     ` Palmer Dabbelt
@ 2017-12-23  3:30       ` DJ Delorie
  0 siblings, 0 replies; 76+ messages in thread
From: DJ Delorie @ 2017-12-23  3:30 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: joseph, libc-alpha, andrew, darius


Palmer Dabbelt <palmer@dabbelt.com> writes:
>    #define macro(x) ...

I don't think the language lets you put a space here, else there'd
probably be one.

> Thanks.  I believe I've fixed them all, but I'm not 100% sure.  Is there a 
> script I can run to check this?  Something like checkpatch.pl in Linux?  I 

#!/bin/perl
while (<>) {
  next if /^\+?#\s*define/;
  print if /[a-zA-Z0-9_]\(/;
}

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code
  2017-12-23  3:25     ` Palmer Dabbelt
@ 2017-12-23  3:33       ` DJ Delorie
  2017-12-23 12:52       ` Joseph Myers
  1 sibling, 0 replies; 76+ messages in thread
From: DJ Delorie @ 2017-12-23  3:33 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: joseph, libc-alpha, andrew, darius

Palmer Dabbelt <palmer@dabbelt.com> writes:
> I haven't tried it, so I assume it does not work.  It looks like the static PIE 
> section's header is broken on that site, I'm seeing
>
>     == Static PIE ===
>
> in normal text.  I assume it's supposed to look more like "=== Static PIE ===" 
> to make the text large?

Fixed.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-20 16:43   ` Joseph Myers
@ 2017-12-23  3:41     ` Palmer Dabbelt
  2017-12-23 12:53       ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-23  3:41 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 08:43:18 PST (-0800), joseph@codesourcery.com wrote:
> Another observation:
>
> Since you're using ldbl-128, that presumably means _Float128 and _Float64x
> type names are supported with the same format as long double.  So you need
> to add RISC-V to the list in manual/math.texi of ports for which those
> type names and associated interfaces are supported.

That's our intent.  How does this look?

diff --git a/manual/math.texi b/manual/math.texi
index a9f2a9813832..d19a14b47dc3 100644
--- a/manual/math.texi
+++ b/manual/math.texi
@@ -70,7 +70,7 @@ provided for @code{_Float32}, @code{_Float64} and @code{_Float32x} on
 all platforms.
 It is also provided for @code{_Float128} and @code{_Float64x} on
 powerpc64le (PowerPC 64-bits little-endian), x86_64, x86, ia64,
-aarch64, alpha, mips64, s390 and sparc.
+aarch64, alpha, mips64, riscv, s390 and sparc.

 @menu
 * Mathematical Constants::      Precise numeric values for often-used

> I don't think you strictly need to add it to the similar lists for
> _Float128 and _Float64x support in the NEWS section for glibc 2.27, since
> the whole port is new rather than this being a new feature for an existing
> port in the RISC-V case.  However, the patch series needs to include a
> patch adding a NEWS item about the port, and the port also needs to be
> added to the list in the README file of supported glibc configurations
> using the Linux kernel.

How does this look?

commit 462ad608e82fa7a4c340f05dc6c300610282d8d9
Author: Palmer Dabbelt <palmer@dabbelt.com>
Date:   Fri Dec 22 19:33:57 2017 -0800

    NEWS and README

diff --git a/NEWS b/NEWS
index a43ff26e83cf..a7476265ca9e 100644
--- a/NEWS
+++ b/NEWS
@@ -40,13 +40,13 @@ Major new features:
   process aborts as the result of assertion failures.

 * On platforms where long double has the IEEE binary128 format (aarch64,
-  alpha, mips64, s390 and sparc), the math library now implements _Float128
-  interfaces for that type, as defined by ISO/IEC TS 18661-3:2015.  These
-  are the same interfaces added in version 2.26 for some platforms where
+  alpha, mips64, riscv, s390 and sparc), the math library now implements
+  _Float128 interfaces for that type, as defined by ISO/IEC TS 18661-3:2015.
+  These are the same interfaces added in version 2.26 for some platforms where
   this format is supported but is not the format of long double.

 * On platforms with support for _Float64x (aarch64, alpha, i386, ia64,
-  mips64, powerpc64le, s390, sparc and x86_64), the math library now
+  mips64, powerpc64le, riscv, s390, sparc and x86_64), the math library now
   implements interfaces for that type, as defined by ISO/IEC TS
   18661-3:2015.  These are corresponding interfaces to those supported for
   _Float128.
@@ -67,6 +67,17 @@ Major new features:
   collation ordering.  Previous glibc versions used locale-specific
   ordering, the change might break systems that relied on that.

+* Support for the RISC-V ISA running on Linux has been added.  This port
+  requires at least binutils-2.30, gcc-7.3.0, and linux-4.15; and is supported
+  for the following ISA and ABI pairs:
+
+    - rv32imac ilp32
+    - rv32imafdc ilp32
+    - rv32imafdc ilp32d
+    - rv64imac lp64
+    - rv64imafdc lp64
+    - rv64imafdc lp64d
+
 Deprecated and removed features, and other changes affecting compatibility:

 * On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer
diff --git a/README b/README
index c3d17d137887..4ab2bfc6f4c4 100644
--- a/README
+++ b/README
@@ -39,6 +39,8 @@ The GNU C Library supports these configurations for using Linux kernels:
 	powerpc64*-*-linux-gnu	Big-endian and little-endian.
 	s390-*-linux-gnu
 	s390x-*-linux-gnu
+	riscv32-*-linux-gnu
+	riscv64-*-linux-gnu
 	sh[34]-*-linux-gnu
 	sparc*-*-linux-gnu
 	sparc64*-*-linux-gnu

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-23  2:22     ` Palmer Dabbelt
@ 2017-12-23 12:44       ` Joseph Myers
  2017-12-25 20:58         ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2017-12-23 12:44 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Fri, 22 Dec 2017, Palmer Dabbelt wrote:

> If I understand what's going on correctly here, we support exceptions in the
> soft float ABI when built with hardware floating point instructions, but
> otherwise we don't (we're always round nearest).  I believe that means we need
> to set "with_fp_cond=1" when building with hardware floating point (regardless
> of ABI), and "with_fp_cond=0" otherwise.
> 
> Does this look sane?

Yes, but it needs to go along with having a nofpu sysdeps directory or 
directories with an Implies file or files pointing to ieee754/soft-fp 
(make sure that the soft-float configurations do end up with 
ieee754/soft-fp before other ieee754 directories in their sysdeps 
directory ordering).

> > > +abi-ilp32-options     := -D__SIZEOF_INT__=4
> > 
> > abi-* options variables are no longer used with the current bits/syscall.h
> > generation mechanism, so you should remove all settings of such variables
> > from the patch.
> 
> OK, we'll remove them for the v3.

To be clear, abi-*-condition variables are still needed (used in 
generating gnu/lib-names.h, for example); it's just abi-*-options that are 
obsolete.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code
  2017-12-23  3:25     ` Palmer Dabbelt
  2017-12-23  3:33       ` DJ Delorie
@ 2017-12-23 12:52       ` Joseph Myers
  1 sibling, 0 replies; 76+ messages in thread
From: Joseph Myers @ 2017-12-23 12:52 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Fri, 22 Dec 2017, Palmer Dabbelt wrote:

> On Wed, 20 Dec 2017 08:38:48 PST (-0800), joseph@codesourcery.com wrote:
> > On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
> > 
> > > +extern ElfW(Addr) la_riscv_gnu_pltenter (ElfW(Sym) *__sym, unsigned int
> > > __ndx,
> > 
> > With reference to my previous comments, ElfW is an exception to the rule
> > of spaces before '(' in macro and function calls, because it locally
> > expands to a single identifier.  So this code is correct not to have a
> > space there.
> > 
> > > +  extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_
> > > __attribute__((visibility("hidden")));
> 
> Ah, luckily I missed those when going through you last mail :)

I advise reading 
<https://sourceware.org/glibc/wiki/Style_and_Conventions>, which discusses 
exceptions such as ElfW and GLRO.

> I haven't tried it, so I assume it does not work.  It looks like the static
> PIE section's header is broken on that site, I'm seeing
> 
>    == Static PIE ===
> 
> in normal text.  I assume it's supposed to look more like "=== Static PIE ==="
> to make the text large?

If you don't already have wiki write access you should create an account 
and ask on libc-alpha for someone to add it to 
<https://sourceware.org/glibc/wiki/EditorGroup>.  Then you can fix typos 
yourself, as well as adding RISC-V entries to wiki pages where 
appropriate.

> Based on looking through the requirement list, there's enough things there in
> toolchain land that "should just work" that I'm sure something will end up
> being broken.  I assume it's OK to just add the various RISC-V targets to the
> unsupported list for now?

Yes (once in glibc).  RISC-V entries will also be needed on the list of 
ABIs and dynamic linker names at 
<https://sourceware.org/glibc/wiki/ABIList> - again, only once actually in 
glibc.

Apart from those wiki pages mentioned just now, every release cycle, 
during the one-month release freeze, architecture maintainers should add 
test results to the per-release wiki page (see 
<https://sourceware.org/glibc/wiki/Release/2.26> for the last release as 
an example, <https://sourceware.org/glibc/wiki/Release/2.27> for the next 
one, <https://sourceware.org/glibc/wiki/Release/X.Y> for the template 
for future releases which RISC-V will need adding to once in glibc).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-23  3:41     ` Palmer Dabbelt
@ 2017-12-23 12:53       ` Joseph Myers
  0 siblings, 0 replies; 76+ messages in thread
From: Joseph Myers @ 2017-12-23 12:53 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Fri, 22 Dec 2017, Palmer Dabbelt wrote:

> On Wed, 20 Dec 2017 08:43:18 PST (-0800), joseph@codesourcery.com wrote:
> > Another observation:
> > 
> > Since you're using ldbl-128, that presumably means _Float128 and _Float64x
> > type names are supported with the same format as long double.  So you need
> > to add RISC-V to the list in manual/math.texi of ports for which those
> > type names and associated interfaces are supported.
> 
> That's our intent.  How does this look?

This seems reasonable.

> How does this look?

Likewise.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 04/15] RISC-V: Thread-Local Storage Support
  2017-12-20 16:45   ` Joseph Myers
@ 2017-12-23 19:10     ` Palmer Dabbelt
  0 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-23 19:10 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 08:45:46 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> +#define thread_offsetof(mem)	(long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
>
> Missing space between offsetof and '('.
>
>> +register void* __thread_self asm("tp");
>
> Missing space after asm.  Also should be "void *__thread_self" not "void*
> __thread_self".

Thanks, these have been fixed.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 05/15] RISC-V: Generic <string.h> Routines
  2017-12-20 16:48   ` Joseph Myers
@ 2017-12-23 22:01     ` Palmer Dabbelt
  2018-01-01  0:52       ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-23 22:01 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 08:48:15 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> This patch contains fast versions of the various routines from string.h
>> that have been implemented for RISC-V.  Since RISC-V doesn't define any
>> specific performance characteristics they're not optimized for any
>> particular microarchitecture, but are designed to be generally good.
>
> I would again suggest deferring adding such functions, especially the C
> ones, and instead helping with updating / reviewing RTH's optimized
> generic string functions posted a while back, and only adding
> RISC-V-specific ones if there is some clear reason RISC-V needs something
> non-generic for optimal performance.

Yes, that makes sense -- I think I forgot last time because they hadn't gone in 
yet.  We'll just use the generic ones for now, I'll add it to my TODO list to 
make sure they're generating good code for RISC-V.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 06/15] RISC-V: Generic <math.h> and soft-fp Routines
  2017-12-20 16:50   ` Joseph Myers
@ 2017-12-24  0:24     ` Palmer Dabbelt
  0 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-24  0:24 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 08:50:48 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> +#ifndef __riscv_flen
>> +
>> +#define _FPU_RESERVED 0xffffffff
>
> Missing preprocessor indentation, "# define" etc. inside #if (except for
> the #if of a header's multiple-include guard).  Likewise generally in lots
> of places in this patch.
>
>> +#define _FCLASS_MINF     (1<<0)
>
> GNU style would use (1 << 0) with spaces around <<; likewise elsewhere in
> this patch.

OK, sorry about that.  I believe I've gotten all of both of these.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2017-12-20 16:57   ` Adhemerval Zanella
@ 2017-12-24  0:24     ` Palmer Dabbelt
  2018-01-01  0:56       ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-24  0:24 UTC (permalink / raw)
  To: adhemerval.zanella; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 08:57:48 PST (-0800), adhemerval.zanella@linaro.org wrote:
>
>
> On 20/12/2017 05:20, Palmer Dabbelt wrote:
>> Contains the Linux system call interface, as well as the definitions of
>> a handful of system calls.
>> ---
>>  sysdeps/riscv/nptl/nptl-sysdep.S                |   2 +
>>  sysdeps/unix/sysv/linux/riscv/arch-fork.h       |   1 +
>>  sysdeps/unix/sysv/linux/riscv/clone.S           |  85 +++++++
>>  sysdeps/unix/sysv/linux/riscv/getmsg.c          |   1 +
>>  sysdeps/unix/sysv/linux/riscv/kernel-features.h |  23 ++
>>  sysdeps/unix/sysv/linux/riscv/profil-counter.h  |   2 +
>>  sysdeps/unix/sysv/linux/riscv/pt-vfork.S        |   1 +
>>  sysdeps/unix/sysv/linux/riscv/putmsg.c          |   1 +
>>  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c    |   1 +
>>  sysdeps/unix/sysv/linux/riscv/rv32/readahead.c  |   1 +
>>  sysdeps/unix/sysv/linux/riscv/syscall.c         |  38 +++
>>  sysdeps/unix/sysv/linux/riscv/sysdep.S          |  51 ++++
>>  sysdeps/unix/sysv/linux/riscv/sysdep.h          | 316 ++++++++++++++++++++++++
>>  sysdeps/unix/sysv/linux/riscv/vfork.S           |  44 ++++
>>  14 files changed, 567 insertions(+)
>>  create mode 100644 sysdeps/riscv/nptl/nptl-sysdep.S
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/arch-fork.h
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/clone.S
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/getmsg.c
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/kernel-features.h
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/profil-counter.h
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/pt-vfork.S
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/putmsg.c
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/syscall.c
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.S
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.h
>>  create mode 100644 sysdeps/unix/sysv/linux/riscv/vfork.S
>>
>> diff --git a/sysdeps/riscv/nptl/nptl-sysdep.S b/sysdeps/riscv/nptl/nptl-sysdep.S
>> new file mode 100644
>> index 000000000000..3f5c2a364afd
>> --- /dev/null
>> +++ b/sysdeps/riscv/nptl/nptl-sysdep.S
>> @@ -0,0 +1,2 @@
>> +/* Pull in __syscall_error.  */
>> +#include <sysdep.S>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/arch-fork.h b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
>> new file mode 100644
>> index 000000000000..5f945378eec0
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
>> @@ -0,0 +1 @@
>> +#include <sysdeps/unix/sysv/linux/i386/arch-fork.h>
>
> I would prefer for new ports if we refrain to continue doing this cross arch
> code references, it ties implementations that should be independent of each
> other and make future cleanups more complex and required to adequate multiple
> architecture at once.

OK, no problem.  I've gone and replaced the #include with the contents of the 
included file for every instance where we were doing this.  I'll include this
as part of a v3 patch set.

Thanks for reviewing our port!

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 07/15] RISC-V: RV32F Support
  2017-12-20 17:01   ` Joseph Myers
  2017-12-20 17:04     ` Joseph Myers
@ 2017-12-24  0:37     ` Palmer Dabbelt
  2018-01-01  0:57       ` Joseph Myers
  1 sibling, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-24  0:37 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 09:01:28 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> +  int nan = isnanf (x);
>
> I don't think any libm code should be using the legacy X/Open
> type-specific classification functions such as isnanf.  Use the C99
> type-generic macros such as isnan instead.
>
>> +  int nan = isnanf (x);
>
> Likewise, and again throughout this patch.

If I understand correctly, these are just

* fpclassify
* isnan
* isfinate
* isinf
* isnormal
* signbit

and there's no macros for

* fabs
* copysign

If so, I believe I've fixed them all.

Thanks!

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 09/15] RISC-V: Atomic and Locking Routines
  2017-12-20 17:08   ` Joseph Myers
@ 2017-12-24  1:26     ` Palmer Dabbelt
  0 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-24  1:26 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 09:08:18 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> This patch implements various atomic and locking routines on RISC-V,
>> either via the A extension (when present) or via a Linux system call
>> that does a compare-and-exchange.  This contains both the library
>> routines and the syscall wrapper.
>
> You said in the introduction that the 'A' extension would be required for
> Linux.  I think you need to update the patch description - *and* the patch
> itself - to reflect that.
>
>> diff --git a/sysdeps/riscv/rv64/rvd/s_roundeven.c b/sysdeps/riscv/rv64/rvd/s_roundeven.c
>
> Does not belong in this patch.
>
>> diff --git a/sysdeps/riscv/rv64/rvf/s_llrintf.c b/sysdeps/riscv/rv64/rvf/s_llrintf.c
>
> Likewise.
>
>> +#ifdef __riscv_atomic
>> +
>> +#define __HAVE_64B_ATOMICS (__riscv_xlen >= 64)
>> +#define USE_ATOMIC_COMPILER_BUILTINS 1
>> +#define ATOMIC_EXCHANGE_USES_CAS 0
>
> Missing preprocessor indentation.
>
>> +/* Miscellaneous. */
>> +
>> +#define asm_amo(which, ordering, mem, value) ({ 		\
>
> Likewise, in this part of the file.
>
>> +#else /* __riscv_atomic */
>
> And this part of the file should now just have a #error.  (Giving an error
> for non-A at configure time would be a good idea as well, so the bad
> configuration gets detected as early as possible.)

I've already made it #error here, and I added a preconfigure check for the 
atomic extension as well.  I'll fix up the commit for the v3.

Thanks!

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 07/15] RISC-V: RV32F Support
  2017-12-20 17:04     ` Joseph Myers
@ 2017-12-24  1:26       ` Palmer Dabbelt
  0 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-24  1:26 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 09:04:04 PST (-0800), joseph@codesourcery.com wrote:
> On Wed, 20 Dec 2017, Joseph Myers wrote:
>
>> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>>
>> > +  int nan = isnanf (x);
>>
>> I don't think any libm code should be using the legacy X/Open
>> type-specific classification functions such as isnanf.  Use the C99
>> type-generic macros such as isnan instead.
>
> Also, and again in patch 8: I think new code should preferably use bool
> (from <stdbool.h>) for boolean variables like this, instead of int.

OK, makes sense.  I think I've fixed them all.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-20 21:45   ` Palmer Dabbelt
@ 2017-12-25 12:57     ` Adhemerval Zanella
  2018-01-01  0:58       ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Adhemerval Zanella @ 2017-12-25 12:57 UTC (permalink / raw)
  To: libc-alpha



On 20/12/2017 19:45, Palmer Dabbelt wrote:
> On Wed, 20 Dec 2017 13:11:02 PST (-0800), joseph@codesourcery.com wrote:
>> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>>
>>> * Should we have padding in __pthread_rwlock_arch_t?  I assume the padding on
>>>   other architectures is there for ABI reasons and shouldn't be necessary for
>>>   new ports, but the ports I usually rely on all have excatly the same padding
>>>   so I'm worried there's another reason for this.
>>
>> The size was probably originally chosen to be the same as used by
>> Linuxthreads.  Since then, there's been at least one rwlock rewrite that
>> increased the amount of space that's padding.
>>
>> On the whole I'd say it's safest to have that padding on RISC-V as well,
>> in case there are any more rewrites in future, since it's possible a
>> rewrite could increase the amount of space used as well as decreasing it,
>> and so if one architecture makes the type smaller than others that could
>> complicate any such future change needing more space.
> 
> Sounds good.  I'll add a comment
> 
> diff --git a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
> index f15e024826ac..4fabc4a2cde2 100644
> --- a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
> +++ b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
> @@ -52,6 +52,10 @@
> #define __LOCK_ALIGNMENT
> #define __ONCE_ALIGNMENT
> 
> +/* There is a lot of padding in this structure.  While it's not strictly
> +   necessary on RISC-V, we're going to leave it in to be on the safe side in
> +   case it's needed in the future.  Most other architectures have the padding,
> +   so this gives us the same extensibility as everyone else has.  */
> struct __pthread_rwlock_arch_t
> {
>   unsigned int __readers;

I have a patchset that should reorganize better the pthread type internal structures
and add default version that will make new ports easier (no need to redefine them
unless the port requires something special). I am planning to send it for reviews
today or tomorrow.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 11/15] RISC-V: Linux ABI
  2017-12-20 17:33   ` Joseph Myers
@ 2017-12-25 19:47     ` Palmer Dabbelt
  2018-01-01  1:04       ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-25 19:47 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 09:33:36 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
>> new file mode 100644
>> index 000000000000..e903c7e0df2a
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
>> @@ -0,0 +1,2 @@
>> +#define __longjmp ____longjmp_chk
>> +#include <__longjmp.S>
>
> I'm not clear how this is meant to achieve the ____longjmp_chk semantics,
> which involve comparing current and saved stack pointers to avoid jumping
> into a frame that has returned.  (See
> sysdeps/unix/sysv/linux/generic/____longjmp_chk.c for a C version of the
> required logic.)
>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/libthread_db.abilist b/sysdeps/unix/sysv/linux/riscv/libthread_db.abilist
>
> You need a full set of abilist baselines, not just this one.

Thanks.  I think I have them all now, they'll be included as part of the v3.

>> +extern int __riscv_flush_icache (void *start, void *end, unsigned long flags);
>
> Should use __start, __end, __flags, unless you really intend start, end
> and flags to be part of the public API for this header.

Sorry, I'm a bit confused by this.  Our intent is that this function (along 
with its arguments) can be called from user code, and will remain part of the 
public ABI forever.  I looked around a bit, would something like

    #ifdef __USE_MISC
    extern int riscv_flush_icache (void *__start, void *__end, unsigned long __flags);
    #endif

be correct?

>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
>
> This header does not look appropriately namespace-clean.  Please make sure
> that all the conform/ tests pass, conditioning contents as necessary.
> It's also missing some preprocessor indentation.

Yep, it's not.  It'll be fixed for the v3.

Thanks!

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2017-12-20 17:24   ` Joseph Myers
@ 2017-12-25 19:47     ` Palmer Dabbelt
  0 siblings, 0 replies; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-25 19:47 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 09:24:21 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/getmsg.c b/sysdeps/unix/sysv/linux/riscv/getmsg.c
>> new file mode 100644
>> index 000000000000..3a1fa0852504
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/riscv/getmsg.c
>> @@ -0,0 +1 @@
>> +#include <sysdeps/unix/sysv/linux/i386/getmsg.c>
>
> Really?  I don't see getpmsg in the generic or RISC-V syscall ABI.
>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/kernel-features.h b/sysdeps/unix/sysv/linux/riscv/kernel-features.h
>
> My comments from
> <https://sourceware.org/ml/libc-alpha/2017-06/msg00661.html> still apply:
> you shouldn't need this file.
>
>> diff --git a/sysdeps/unix/sysv/linux/riscv/putmsg.c b/sysdeps/unix/sysv/linux/riscv/putmsg.c
>> new file mode 100644
>> index 000000000000..ebc1680ca7d1
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/riscv/putmsg.c
>> @@ -0,0 +1 @@
>> +#include <sysdeps/unix/sysv/linux/i386/putmsg.c>
>
> Same comment as for getmsg.

Thanks, we must have gotten our signals crossed on your original messages.  
You're right here, I'll remove the files for the v3.

>> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
>> new file mode 100644
>> index 000000000000..80170c3e8a4d
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
>> @@ -0,0 +1 @@
>> +#include <sysdeps/unix/sysv/linux/arm/readahead.c>
>
> I commented on this before
> <https://sourceware.org/ml/libc-alpha/2017-06/msg00661.html>.  Are you
> sure about it?  The ARM file is dealing with a peculiarity of the syscall
> interface in the case where (a) it follows the C function interface and
> (b) a 32-bit function argument followed by a 64-bit function argument
> requires a one-register gap between them.
>
> Now, RISC-V doesn't seem to do anything special for this syscall in the
> kernel, so I presume it does follow the C function interface.  But
> <https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md>
> says that aligned register pairs are only used for variadic arguments, and
> readahead is not a variadic function.  So I'd expect there not to be a gap
> in the arguments to this syscall, and so use of the ARM function to be
> wrong.  (As the syscall has no errors and no testable semantic effect, as
> long as the fd argument is valid, getting this wrong would not result in
> any test failures.)

Sorry, again, that we missed that.  You're correct here, we'll remove it for 
the v3.

>> +#ifdef __ASSEMBLER__
>> +
>> +#include <sys/asm.h>
>> +
>> +#define ENTRY(name) LEAF(name)
>
> Missing preprocessor indentation here and subsequently (inconsistently) in
> this file.
>
>> +#endif /* linux/mips/sysdep.h */
>
> This comment is clearly wrong here.

These should all be fixed.  Thanks!

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-20 17:40 ` Joseph Myers
@ 2017-12-25 20:20   ` Palmer Dabbelt
  2018-01-01  1:20     ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-25 20:20 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 20 Dec 2017 09:40:43 PST (-0800), joseph@codesourcery.com wrote:
> On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
>
>> Thanks to everyone who has helped review the patch set!  I believe we've gone
>> through all the feedback from the first patch set.  Sorry if we've missed
>> anything, but at this point I think it'd be best to re-submit it -- it's been a
>> long time since the previous patch set.
>
> Apart from the points I've mentioned in comments on individual patches, as
> previously noted you need a c++-types.data ABI baseline or baselines.  And
> as previously noted a bits/environments.h header may be appropriate though
> not required.  And you're missing libm-test-ulps / libm-test-ulps-name
> files.

I don't think we need a bits/environments.h right now, but I think we will need 
one if we're going to support ILP32 on RV64I-based systems.  If I understand 
correctly, it's OK to add this file when we add the new ABI?

I'll add the libm-test-ulps* files, I just need to get the native test suite 
running to generate them.

Thanks for all the help!  My plan is to go through the remaining feedback on 
the v2 and then submit a v3 when build-many-glibcs.py passes all the tests, 
which I think I'm pretty close to having done.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-23 12:44       ` Joseph Myers
@ 2017-12-25 20:58         ` Palmer Dabbelt
  2018-01-01  1:21           ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2017-12-25 20:58 UTC (permalink / raw)
  To: joseph; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Sat, 23 Dec 2017 04:44:28 PST (-0800), joseph@codesourcery.com wrote:
> On Fri, 22 Dec 2017, Palmer Dabbelt wrote:
>
>> If I understand what's going on correctly here, we support exceptions in the
>> soft float ABI when built with hardware floating point instructions, but
>> otherwise we don't (we're always round nearest).  I believe that means we need
>> to set "with_fp_cond=1" when building with hardware floating point (regardless
>> of ABI), and "with_fp_cond=0" otherwise.
>>
>> Does this look sane?
>
> Yes, but it needs to go along with having a nofpu sysdeps directory or
> directories with an Implies file or files pointing to ieee754/soft-fp
> (make sure that the soft-float configurations do end up with
> ieee754/soft-fp before other ieee754 directories in their sysdeps
> directory ordering).

OK.  I think we might need to reorganize our directories a bit to do that, but 
I'll try and figure something sane out.

>> > > +abi-ilp32-options     := -D__SIZEOF_INT__=4
>> >
>> > abi-* options variables are no longer used with the current bits/syscall.h
>> > generation mechanism, so you should remove all settings of such variables
>> > from the patch.
>>
>> OK, we'll remove them for the v3.
>
> To be clear, abi-*-condition variables are still needed (used in
> generating gnu/lib-names.h, for example); it's just abi-*-options that are
> obsolete.

Thanks -- I noticed that when going through the commit history to see what 
other ports had done here.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 05/15] RISC-V: Generic <string.h> Routines
  2017-12-23 22:01     ` Palmer Dabbelt
@ 2018-01-01  0:52       ` Joseph Myers
  2018-01-03 15:46         ` Adhemerval Zanella
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2018-01-01  0:52 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Sat, 23 Dec 2017, Palmer Dabbelt wrote:

> > I would again suggest deferring adding such functions, especially the C
> > ones, and instead helping with updating / reviewing RTH's optimized
> > generic string functions posted a while back, and only adding
> > RISC-V-specific ones if there is some clear reason RISC-V needs something
> > non-generic for optimal performance.
> 
> Yes, that makes sense -- I think I forgot last time because they hadn't gone
> in yet.  We'll just use the generic ones for now, I'll add it to my TODO list
> to make sure they're generating good code for RISC-V.

To be clear, RTH's optimized functions aren't in glibc yet.  So, if you 
find they'd be better for RISC-V than the current generic functions, you 
should join in the process of getting them in glibc - for 2.28 not 2.27 
now, of course (but only if generic functions can't be made good for 
RISC-V would RISC-V-specific ones be desirable).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2017-12-24  0:24     ` Palmer Dabbelt
@ 2018-01-01  0:56       ` Joseph Myers
  2018-01-03 13:43         ` Christoph Hellwig
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2018-01-01  0:56 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: adhemerval.zanella, libc-alpha, Andrew Waterman, Darius Rad, dj

On Sat, 23 Dec 2017, Palmer Dabbelt wrote:

> > > diff --git a/sysdeps/unix/sysv/linux/riscv/arch-fork.h
> > > b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
> > > new file mode 100644
> > > index 000000000000..5f945378eec0
> > > --- /dev/null
> > > +++ b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
> > > @@ -0,0 +1 @@
> > > +#include <sysdeps/unix/sysv/linux/i386/arch-fork.h>
> > 
> > I would prefer for new ports if we refrain to continue doing this cross arch
> > code references, it ties implementations that should be independent of each
> > other and make future cleanups more complex and required to adequate
> > multiple
> > architecture at once.
> 
> OK, no problem.  I've gone and replaced the #include with the contents of the
> included file for every instance where we were doing this.  I'll include this
> as part of a v3 patch set.

Copying the included file isn't particularly good either.  Rather, each 
such case, whether a copy from another architecture or a #include from 
another architecture, indicates a case where refactoring is needed to 
avoid such duplication - if the code can be generic for all new ports it 
should be in a generic location, while if it's generic for ports with a 
particular property things should be factored so a port only needs to 
declare that it has that property.  (Of course such refactoring is risky 
so not typically appropriate during a release freeze.)

Often, the files for i386 are actually generic for *old* ports and so if 
you're copying or including such a file (or one from another old 
architecture) you need to be particularly careful that it actually 
represents the desired way to do things now, rather than compatibility 
with old ABIs or old versions of the syscall interface.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 07/15] RISC-V: RV32F Support
  2017-12-24  0:37     ` Palmer Dabbelt
@ 2018-01-01  0:57       ` Joseph Myers
  0 siblings, 0 replies; 76+ messages in thread
From: Joseph Myers @ 2018-01-01  0:57 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Sat, 23 Dec 2017, Palmer Dabbelt wrote:

> * fpclassify
> * isnan
> * isfinate
> * isinf
> * isnormal
> * signbit
> 
> and there's no macros for
> 
> * fabs
> * copysign

Yes.  The type-generic macros that should be used are the classification 
ones, where the return type is independent of the argument type.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-25 12:57     ` Adhemerval Zanella
@ 2018-01-01  0:58       ` Joseph Myers
  0 siblings, 0 replies; 76+ messages in thread
From: Joseph Myers @ 2018-01-01  0:58 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Mon, 25 Dec 2017, Adhemerval Zanella wrote:

> I have a patchset that should reorganize better the pthread type 
> internal structures and add default version that will make new ports 
> easier (no need to redefine them unless the port requires something 
> special). I am planning to send it for reviews today or tomorrow.

I think such a change is clearly too risky to go in during the release 
freeze, so it's not clear it's of any relevance to a new port being 
considered right now (unless consideration of such a port extends past the 
2.27 release, of course).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 11/15] RISC-V: Linux ABI
  2017-12-25 19:47     ` Palmer Dabbelt
@ 2018-01-01  1:04       ` Joseph Myers
  2018-01-02 20:59         ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2018-01-01  1:04 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Mon, 25 Dec 2017, Palmer Dabbelt wrote:

> On Wed, 20 Dec 2017 09:33:36 PST (-0800), joseph@codesourcery.com wrote:
> > On Tue, 19 Dec 2017, Palmer Dabbelt wrote:
> > 
> > > diff --git a/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
> > > b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
> > > new file mode 100644
> > > index 000000000000..e903c7e0df2a
> > > --- /dev/null
> > > +++ b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S
> > > @@ -0,0 +1,2 @@
> > > +#define __longjmp ____longjmp_chk
> > > +#include <__longjmp.S>
> > 
> > I'm not clear how this is meant to achieve the ____longjmp_chk semantics,
> > which involve comparing current and saved stack pointers to avoid jumping
> > into a frame that has returned.  (See
> > sysdeps/unix/sysv/linux/generic/____longjmp_chk.c for a C version of the
> > required logic.)

You quoted this comment of mine without responding to it.  I don't see any 
sign of it having been addressed in the latest version of the port.

> > > +extern int __riscv_flush_icache (void *start, void *end, unsigned long
> > > flags);
> > 
> > Should use __start, __end, __flags, unless you really intend start, end
> > and flags to be part of the public API for this header.
> 
> Sorry, I'm a bit confused by this.  Our intent is that this function (along
> with its arguments) can be called from user code, and will remain part of the
> public ABI forever.  I looked around a bit, would something like
> 
>    #ifdef __USE_MISC
>    extern int riscv_flush_icache (void *__start, void *__end, unsigned long
> __flags);
>    #endif
> 
> be correct?

There should be no __USE_MISC conditional, since this is in a header not 
defined by any standard.

But the parameter names should start with __, yes, unless it is 
specifically intended and documented that it's invalid for a user to do:

#define start something else
#include <sys/cachectl.h>

(and I don't see any reason why you'd want to define that to be invalid).

I see that in the latest port version you've renamed the function to 
__riscv_flush_icache.  Whether that's appropriate depends on whether this 
function is intended to be used in libraries such as libgcc with namespace 
concerns - normally public APIs do not have the leading __ on the name of 
the public interface, but an __ name is needed in certain cases if the 
function is expected to be called from somewhere like libgcc.

I think this machine-specific interface, whatever the function ends up 
being called, needs documenting in the glibc manual - presumably in 
platform.texi, where sys/platform/ppc.h is already documented.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2017-12-25 20:20   ` Palmer Dabbelt
@ 2018-01-01  1:20     ` Joseph Myers
  2018-01-03 13:37       ` Christoph Hellwig
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2018-01-01  1:20 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Mon, 25 Dec 2017, Palmer Dabbelt wrote:

> > Apart from the points I've mentioned in comments on individual patches, as
> > previously noted you need a c++-types.data ABI baseline or baselines.  And
> > as previously noted a bits/environments.h header may be appropriate though
> > not required.  And you're missing libm-test-ulps / libm-test-ulps-name
> > files.
> 
> I don't think we need a bits/environments.h right now, but I think we will
> need one if we're going to support ILP32 on RV64I-based systems.  If I
> understand correctly, it's OK to add this file when we add the new ABI?

Do I understand correctly from this that RV64I processors cannot execute 
RV32I code (unlike e.g. x86_64 where execution of 32-bit code is always 
supported by the processor, or AArch64 where processors may or may not 
support execution of AArch32 code)?  If so, then indeed 
bits/environments.h is not relevant at present.

However, as I understand it you still support simultaneous presence of 
libraries for two different ABIs on a single system (hard-float and 
soft-float ABIs), with those having separate library directories and 
dynamic linker names.  Which means there is still some multi-ABI support 
that should be included in the port and appears to be missing.

In cases where libraries for multiple ABIs may be present at once, there 
should be flags defined in sysdeps/generic/ldconfig.h to allow such 
libraries to be distinguished in ld.so.cache.  elf/cache.c should include 
support for printing a corresponding description for those flags.  There 
should be a sysdeps ldconfig.h file defining 
SYSDEP_KNOWN_INTERPRETER_NAMES with all the supported dynamic linker 
names.  There should be a sysdeps readelflib.c file that includes code to 
identify the flags to associate with a given shared library.  There should 
be a sysdeps dl-cache.h defining _dl_cache_check_flags and (given that you 
use directories other than plain lib) add_system_dir.  There should be an 
ldd_rewrite_script setting in a sysdeps configure.ac file, pointing to a 
sed script that edits ldd so that ldd installed by glibc build for any ABI 
is able to work properly for binaries of any other ABI that can execute on 
that system.

You have ldconfig.h with SYSDEP_KNOWN_INTERPRETER_NAMES.  The other listed 
pieces of multi-ABI support appear to be missing in the latest version of 
the port.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 01/15] RISC-V: Build Infastructure
  2017-12-25 20:58         ` Palmer Dabbelt
@ 2018-01-01  1:21           ` Joseph Myers
  0 siblings, 0 replies; 76+ messages in thread
From: Joseph Myers @ 2018-01-01  1:21 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Mon, 25 Dec 2017, Palmer Dabbelt wrote:

> > Yes, but it needs to go along with having a nofpu sysdeps directory or
> > directories with an Implies file or files pointing to ieee754/soft-fp
> > (make sure that the soft-float configurations do end up with
> > ieee754/soft-fp before other ieee754 directories in their sysdeps
> > directory ordering).
> 
> OK.  I think we might need to reorganize our directories a bit to do that, but
> I'll try and figure something sane out.

I don't think you need much reorganization.  Possible just adding 
sysdeps/riscv/nofpu/Implies will suffice.  If it doesn't - if the sysdeps 
directory ordering ends up placing ieee754/soft-fp too late - then maybe 
you need a few sysdeps/riscv/<something>/nofpu/Implies files instead (as 
with MIPS, which has three such files).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 11/15] RISC-V: Linux ABI
  2018-01-01  1:04       ` Joseph Myers
@ 2018-01-02 20:59         ` Joseph Myers
  0 siblings, 0 replies; 76+ messages in thread
From: Joseph Myers @ 2018-01-02 20:59 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: libc-alpha, Andrew Waterman, Darius Rad, dj

On Mon, 1 Jan 2018, Joseph Myers wrote:

> I see that in the latest port version you've renamed the function to 
> __riscv_flush_icache.  Whether that's appropriate depends on whether this 
> function is intended to be used in libraries such as libgcc with namespace 
> concerns - normally public APIs do not have the leading __ on the name of 
> the public interface, but an __ name is needed in certain cases if the 
> function is expected to be called from somewhere like libgcc.

I see GCC will now generate calls to __riscv_flush_icache - which, like 
use in libgcc, is a reason that justifies having the leading __.

> I think this machine-specific interface, whatever the function ends up 
> being called, needs documenting in the glibc manual - presumably in 
> platform.texi, where sys/platform/ppc.h is already documented.

Given that you have an installed header declaring the function, and so 
it's presumably intended for users and not *just* for compiler-generated 
use (unlike a few functions in some configurations that really are just 
for compiler use), this still applies - the API should be documented.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2018-01-01  1:20     ` Joseph Myers
@ 2018-01-03 13:37       ` Christoph Hellwig
  2018-01-03 13:42         ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Christoph Hellwig @ 2018-01-03 13:37 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Palmer Dabbelt, libc-alpha, Andrew Waterman, Darius Rad, dj

On Mon, Jan 01, 2018 at 01:19:48AM +0000, Joseph Myers wrote:
> Do I understand correctly from this that RV64I processors cannot execute 
> RV32I code (unlike e.g. x86_64 where execution of 32-bit code is always 
> supported by the processor, or AArch64 where processors may or may not 
> support execution of AArch32 code)?  If so, then indeed 
> bits/environments.h is not relevant at present.

RV64I processors might be able to execute RV32I code (that support
is optional in the architecture by writing to the sstatus register).  But
the Linux port currently does not support that (yet).

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: RISC-V glibc port v2
  2018-01-03 13:37       ` Christoph Hellwig
@ 2018-01-03 13:42         ` Joseph Myers
  0 siblings, 0 replies; 76+ messages in thread
From: Joseph Myers @ 2018-01-03 13:42 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Palmer Dabbelt, libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 3 Jan 2018, Christoph Hellwig wrote:

> On Mon, Jan 01, 2018 at 01:19:48AM +0000, Joseph Myers wrote:
> > Do I understand correctly from this that RV64I processors cannot execute 
> > RV32I code (unlike e.g. x86_64 where execution of 32-bit code is always 
> > supported by the processor, or AArch64 where processors may or may not 
> > support execution of AArch32 code)?  If so, then indeed 
> > bits/environments.h is not relevant at present.
> 
> RV64I processors might be able to execute RV32I code (that support
> is optional in the architecture by writing to the sstatus register).  But
> the Linux port currently does not support that (yet).

If suppported in future, then all the multi-ABI pieces I mentioned 
(ldconfig / ldd support etc.) will become relevant for pieces built with 
glibc for one of RV64I and RV32I working properly in the presence on the 
system of libraries for the other one of those two, as well as 
bits/environments.h.

For now, in the absence of such support, those pieces are only relevant 
for differences in floating-point ABI.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2018-01-01  0:56       ` Joseph Myers
@ 2018-01-03 13:43         ` Christoph Hellwig
  2018-01-03 15:56           ` Adhemerval Zanella
  0 siblings, 1 reply; 76+ messages in thread
From: Christoph Hellwig @ 2018-01-03 13:43 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Palmer Dabbelt, adhemerval.zanella, libc-alpha, Andrew Waterman,
	Darius Rad, dj

On Mon, Jan 01, 2018 at 12:56:14AM +0000, Joseph Myers wrote:
> such case, whether a copy from another architecture or a #include from 
> another architecture, indicates a case where refactoring is needed to 
> avoid such duplication - if the code can be generic for all new ports it 
> should be in a generic location, while if it's generic for ports with a 
> particular property things should be factored so a port only needs to 
> declare that it has that property.  (Of course such refactoring is risky 
> so not typically appropriate during a release freeze.)
> 
> Often, the files for i386 are actually generic for *old* ports and so if 
> you're copying or including such a file (or one from another old 
> architecture) you need to be particularly careful that it actually 
> represents the desired way to do things now, rather than compatibility 
> with old ABIs or old versions of the syscall interface.

clone is a hodegepodge, but the clone(2) manpage documents it well.
There are two major camps, and risv implements on of those.  And then
there are various oddballs.

So for now it might make sense to just duplicate the i386 file for
riscv, or follow the example of various forks to include it.  In the
long run having a generic implementation for the two common versions
might be useful.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 05/15] RISC-V: Generic <string.h> Routines
  2018-01-01  0:52       ` Joseph Myers
@ 2018-01-03 15:46         ` Adhemerval Zanella
  2018-01-03 16:03           ` Joseph Myers
  0 siblings, 1 reply; 76+ messages in thread
From: Adhemerval Zanella @ 2018-01-03 15:46 UTC (permalink / raw)
  To: libc-alpha



On 31/12/2017 22:52, Joseph Myers wrote:
> On Sat, 23 Dec 2017, Palmer Dabbelt wrote:
> 
>>> I would again suggest deferring adding such functions, especially the C
>>> ones, and instead helping with updating / reviewing RTH's optimized
>>> generic string functions posted a while back, and only adding
>>> RISC-V-specific ones if there is some clear reason RISC-V needs something
>>> non-generic for optimal performance.
>>
>> Yes, that makes sense -- I think I forgot last time because they hadn't gone
>> in yet.  We'll just use the generic ones for now, I'll add it to my TODO list
>> to make sure they're generating good code for RISC-V.
> 
> To be clear, RTH's optimized functions aren't in glibc yet.  So, if you 
> find they'd be better for RISC-V than the current generic functions, you 
> should join in the process of getting them in glibc - for 2.28 not 2.27 
> now, of course (but only if generic functions can't be made good for 
> RISC-V would RISC-V-specific ones be desirable).
> 

I have being working sporadically with RTH's optimized generic string function
and I have pushed my branch on azanella/generic-strings. Based on RTH's initial
proposal I expanded:

  - Fixed an issue with strcmp.
  - Added an unaligned implementation for strcpy (which should be faster for
    architecture that define _STRING_ARCH_unaligned).
  - Changed how to check for initial byte in strchr/strlen/memchr by reading
    aligned and masking out the undesirable bits (instead of reading byte
    per byte).  It follows the strategy already used on arch specific
    implementation (alpha, powerpc).
  - Add SH has_{zero,eq,zero_eq} using arch-specific instructions.

Another thing I would like to check before submitting for 2.28 is a way to
add a generic index_last_/index_fist_ without using __builtin_{clzl,ctzl}.
On some architectures it is implemented by a libgcc call and calling a
function call pretty much defeat the optimizations done (I added a generic
one for SH).

On the patch I haven't noticed any arch-specific instructions meant for
string operations (as for cmpb on powerpc for instance), so I think you
might use the generic implementation for riscv.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2018-01-03 13:43         ` Christoph Hellwig
@ 2018-01-03 15:56           ` Adhemerval Zanella
  2018-01-09  1:30             ` Palmer Dabbelt
  0 siblings, 1 reply; 76+ messages in thread
From: Adhemerval Zanella @ 2018-01-03 15:56 UTC (permalink / raw)
  To: Christoph Hellwig, Joseph Myers
  Cc: Palmer Dabbelt, libc-alpha, Andrew Waterman, Darius Rad, dj



On 03/01/2018 11:43, Christoph Hellwig wrote:
> On Mon, Jan 01, 2018 at 12:56:14AM +0000, Joseph Myers wrote:
>> such case, whether a copy from another architecture or a #include from 
>> another architecture, indicates a case where refactoring is needed to 
>> avoid such duplication - if the code can be generic for all new ports it 
>> should be in a generic location, while if it's generic for ports with a 
>> particular property things should be factored so a port only needs to 
>> declare that it has that property.  (Of course such refactoring is risky 
>> so not typically appropriate during a release freeze.)
>>
>> Often, the files for i386 are actually generic for *old* ports and so if 
>> you're copying or including such a file (or one from another old 
>> architecture) you need to be particularly careful that it actually 
>> represents the desired way to do things now, rather than compatibility 
>> with old ABIs or old versions of the syscall interface.
> 
> clone is a hodegepodge, but the clone(2) manpage documents it well.
> There are two major camps, and risv implements on of those.  And then
> there are various oddballs.
> 
> So for now it might make sense to just duplicate the i386 file for
> riscv, or follow the example of various forks to include it.  In the
> long run having a generic implementation for the two common versions
> might be useful.
> 

Sometime ago I tried to check if it was worth to simplify the arch-fork.h
by defining the supported kernel variations and adding a arch-specific
define (maybe on kernel-features.h).  I did not follow up, but I think it
might be feasible: afaik Linux defines 4 variants:

  - CONFIG_CLONE_BACKWARDS
  - CONFIG_CLONE_BACKWARDS2
  - CONFIG_CLONE_BACKWARDS3
  - And the generic one which I assume it is meant for newer ports.

So I think we expand the arch-fork.h generic to issue the clone based on
arch-specific flags with a generic one as default.  It will make unnecessary
for newer ports to add a arch-fork.h implementation.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 05/15] RISC-V: Generic <string.h> Routines
  2018-01-03 15:46         ` Adhemerval Zanella
@ 2018-01-03 16:03           ` Joseph Myers
  2018-01-03 16:08             ` Adhemerval Zanella
  0 siblings, 1 reply; 76+ messages in thread
From: Joseph Myers @ 2018-01-03 16:03 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Wed, 3 Jan 2018, Adhemerval Zanella wrote:

> Another thing I would like to check before submitting for 2.28 is a way to
> add a generic index_last_/index_fist_ without using __builtin_{clzl,ctzl}.
> On some architectures it is implemented by a libgcc call and calling a
> function call pretty much defeat the optimizations done (I added a generic
> one for SH).

Maybe a configure test should check whether those use a libgcc function, 
so the default can be set based on that?

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 05/15] RISC-V: Generic <string.h> Routines
  2018-01-03 16:03           ` Joseph Myers
@ 2018-01-03 16:08             ` Adhemerval Zanella
  0 siblings, 0 replies; 76+ messages in thread
From: Adhemerval Zanella @ 2018-01-03 16:08 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha



On 03/01/2018 14:02, Joseph Myers wrote:
> On Wed, 3 Jan 2018, Adhemerval Zanella wrote:
> 
>> Another thing I would like to check before submitting for 2.28 is a way to
>> add a generic index_last_/index_fist_ without using __builtin_{clzl,ctzl}.
>> On some architectures it is implemented by a libgcc call and calling a
>> function call pretty much defeat the optimizations done (I added a generic
>> one for SH).
> 
> Maybe a configure test should check whether those use a libgcc function, 
> so the default can be set based on that?
> 

Yes that is one option I have in mind.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2018-01-03 15:56           ` Adhemerval Zanella
@ 2018-01-09  1:30             ` Palmer Dabbelt
  2018-01-09 11:16               ` Adhemerval Zanella
  0 siblings, 1 reply; 76+ messages in thread
From: Palmer Dabbelt @ 2018-01-09  1:30 UTC (permalink / raw)
  To: adhemerval.zanella
  Cc: hch, joseph, libc-alpha, Andrew Waterman, Darius Rad, dj

On Wed, 03 Jan 2018 07:56:32 PST (-0800), adhemerval.zanella@linaro.org wrote:
>
>
> On 03/01/2018 11:43, Christoph Hellwig wrote:
>> On Mon, Jan 01, 2018 at 12:56:14AM +0000, Joseph Myers wrote:
>>> such case, whether a copy from another architecture or a #include from
>>> another architecture, indicates a case where refactoring is needed to
>>> avoid such duplication - if the code can be generic for all new ports it
>>> should be in a generic location, while if it's generic for ports with a
>>> particular property things should be factored so a port only needs to
>>> declare that it has that property.  (Of course such refactoring is risky
>>> so not typically appropriate during a release freeze.)
>>>
>>> Often, the files for i386 are actually generic for *old* ports and so if
>>> you're copying or including such a file (or one from another old
>>> architecture) you need to be particularly careful that it actually
>>> represents the desired way to do things now, rather than compatibility
>>> with old ABIs or old versions of the syscall interface.
>>
>> clone is a hodegepodge, but the clone(2) manpage documents it well.
>> There are two major camps, and risv implements on of those.  And then
>> there are various oddballs.
>>
>> So for now it might make sense to just duplicate the i386 file for
>> riscv, or follow the example of various forks to include it.  In the
>> long run having a generic implementation for the two common versions
>> might be useful.
>>
>
> Sometime ago I tried to check if it was worth to simplify the arch-fork.h
> by defining the supported kernel variations and adding a arch-specific
> define (maybe on kernel-features.h).  I did not follow up, but I think it
> might be feasible: afaik Linux defines 4 variants:
>
>   - CONFIG_CLONE_BACKWARDS
>   - CONFIG_CLONE_BACKWARDS2
>   - CONFIG_CLONE_BACKWARDS3
>   - And the generic one which I assume it is meant for newer ports.
>
> So I think we expand the arch-fork.h generic to issue the clone based on
> arch-specific flags with a generic one as default.  It will make unnecessary
> for newer ports to add a arch-fork.h implementation.

I asked on the Linux mailing list what the sane thing to do is here.  Thanks 
for bringing this up, but it might be too late to change anything on our end -- 
there's probably only 1 more Linux RC left, so unless there's a strong reason 
to prefer one argument ordering I think I'm just going to leave it alone.

Sorry we didn't get around to this sooner!

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH v2 10/15] RISC-V: Linux Syscall Interface
  2018-01-09  1:30             ` Palmer Dabbelt
@ 2018-01-09 11:16               ` Adhemerval Zanella
  0 siblings, 0 replies; 76+ messages in thread
From: Adhemerval Zanella @ 2018-01-09 11:16 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: hch, joseph, libc-alpha, Andrew Waterman, Darius Rad, dj



On 08/01/2018 23:30, Palmer Dabbelt wrote:
> On Wed, 03 Jan 2018 07:56:32 PST (-0800), adhemerval.zanella@linaro.org wrote:
>>
>>
>> On 03/01/2018 11:43, Christoph Hellwig wrote:
>>> On Mon, Jan 01, 2018 at 12:56:14AM +0000, Joseph Myers wrote:
>>>> such case, whether a copy from another architecture or a #include from
>>>> another architecture, indicates a case where refactoring is needed to
>>>> avoid such duplication - if the code can be generic for all new ports it
>>>> should be in a generic location, while if it's generic for ports with a
>>>> particular property things should be factored so a port only needs to
>>>> declare that it has that property.  (Of course such refactoring is risky
>>>> so not typically appropriate during a release freeze.)
>>>>
>>>> Often, the files for i386 are actually generic for *old* ports and so if
>>>> you're copying or including such a file (or one from another old
>>>> architecture) you need to be particularly careful that it actually
>>>> represents the desired way to do things now, rather than compatibility
>>>> with old ABIs or old versions of the syscall interface.
>>>
>>> clone is a hodegepodge, but the clone(2) manpage documents it well.
>>> There are two major camps, and risv implements on of those.  And then
>>> there are various oddballs.
>>>
>>> So for now it might make sense to just duplicate the i386 file for
>>> riscv, or follow the example of various forks to include it.  In the
>>> long run having a generic implementation for the two common versions
>>> might be useful.
>>>
>>
>> Sometime ago I tried to check if it was worth to simplify the arch-fork.h
>> by defining the supported kernel variations and adding a arch-specific
>> define (maybe on kernel-features.h).  I did not follow up, but I think it
>> might be feasible: afaik Linux defines 4 variants:
>>
>>   - CONFIG_CLONE_BACKWARDS
>>   - CONFIG_CLONE_BACKWARDS2
>>   - CONFIG_CLONE_BACKWARDS3
>>   - And the generic one which I assume it is meant for newer ports.
>>
>> So I think we expand the arch-fork.h generic to issue the clone based on
>> arch-specific flags with a generic one as default.  It will make unnecessary
>> for newer ports to add a arch-fork.h implementation.
> 
> I asked on the Linux mailing list what the sane thing to do is here.  Thanks for bringing this up, but it might be too late to change anything on our end -- there's probably only 1 more Linux RC left, so unless there's a strong reason to prefer one argument ordering I think I'm just going to leave it alone.
> 
> Sorry we didn't get around to this sooner!

Indeed I also think it is late for this change and my questioning is more for
curiosity. From glibc end, my recent refactor patches are mainly to make glibc
follow what Linux generic api for newer ports intended to do, so new architecture
inclusion would require as less code as possible.

For this refactor in specific riscv will need to define an extra define.

^ permalink raw reply	[flat|nested] 76+ messages in thread

end of thread, other threads:[~2018-01-09 11:16 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-20  7:23 RISC-V glibc port v2 Palmer Dabbelt
2017-12-20  7:23 ` [PATCH v2 01/15] RISC-V: Build Infastructure Palmer Dabbelt
2017-12-20 14:05   ` Dmitry V. Levin
2017-12-20 20:25     ` Palmer Dabbelt
2017-12-20 16:22   ` Joseph Myers
2017-12-20 16:49     ` Adhemerval Zanella
2017-12-23  2:22     ` Palmer Dabbelt
2017-12-23 12:44       ` Joseph Myers
2017-12-25 20:58         ` Palmer Dabbelt
2018-01-01  1:21           ` Joseph Myers
2017-12-20 16:43   ` Joseph Myers
2017-12-23  3:41     ` Palmer Dabbelt
2017-12-23 12:53       ` Joseph Myers
2017-12-20  7:23 ` [PATCH v2 05/15] RISC-V: Generic <string.h> Routines Palmer Dabbelt
2017-12-20 16:48   ` Joseph Myers
2017-12-23 22:01     ` Palmer Dabbelt
2018-01-01  0:52       ` Joseph Myers
2018-01-03 15:46         ` Adhemerval Zanella
2018-01-03 16:03           ` Joseph Myers
2018-01-03 16:08             ` Adhemerval Zanella
2017-12-20  7:23 ` [PATCH v2 04/15] RISC-V: Thread-Local Storage Support Palmer Dabbelt
2017-12-20 16:45   ` Joseph Myers
2017-12-23 19:10     ` Palmer Dabbelt
2017-12-20  7:23 ` [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code Palmer Dabbelt
2017-12-20 16:38   ` Joseph Myers
2017-12-23  3:25     ` Palmer Dabbelt
2017-12-23  3:33       ` DJ Delorie
2017-12-23 12:52       ` Joseph Myers
2017-12-20  7:23 ` [PATCH v2 02/15] RISC-V: ABI Implementation Palmer Dabbelt
2017-12-20 16:31   ` Joseph Myers
2017-12-23  3:25     ` Palmer Dabbelt
2017-12-23  3:30       ` DJ Delorie
2017-12-20  7:24 ` [PATCH v2 06/15] RISC-V: Generic <math.h> and soft-fp Routines Palmer Dabbelt
2017-12-20 16:50   ` Joseph Myers
2017-12-24  0:24     ` Palmer Dabbelt
2017-12-20  7:24 ` [PATCH v2 11/15] RISC-V: Linux ABI Palmer Dabbelt
2017-12-20 17:33   ` Joseph Myers
2017-12-25 19:47     ` Palmer Dabbelt
2018-01-01  1:04       ` Joseph Myers
2018-01-02 20:59         ` Joseph Myers
2017-12-20  7:24 ` [PATCH v2 10/15] RISC-V: Linux Syscall Interface Palmer Dabbelt
2017-12-20 16:57   ` Adhemerval Zanella
2017-12-24  0:24     ` Palmer Dabbelt
2018-01-01  0:56       ` Joseph Myers
2018-01-03 13:43         ` Christoph Hellwig
2018-01-03 15:56           ` Adhemerval Zanella
2018-01-09  1:30             ` Palmer Dabbelt
2018-01-09 11:16               ` Adhemerval Zanella
2017-12-20 17:24   ` Joseph Myers
2017-12-25 19:47     ` Palmer Dabbelt
2017-12-20  7:24 ` [PATCH v2 09/15] RISC-V: Atomic and Locking Routines Palmer Dabbelt
2017-12-20 17:08   ` Joseph Myers
2017-12-24  1:26     ` Palmer Dabbelt
2017-12-20  7:24 ` [PATCH v2 12/15] RISC-V: Linux Startup and Dynamic Loading Code Palmer Dabbelt
2017-12-20  7:24 ` [PATCH v2 13/15] Add RISC-V dynamic relocations to elf.h Palmer Dabbelt
2017-12-20  7:24 ` [PATCH v2 14/15] Add linux-4.15 VDSO hash for RISC-V Palmer Dabbelt
2017-12-20  7:24 ` [PATCH v2 15/15] Add RISC-V to build-many-glibcs.py Palmer Dabbelt
2017-12-20  7:24 ` [PATCH v2 08/15] RISC-V: RV32D, RV64F, and RV64D Support Palmer Dabbelt
2017-12-20  7:24 ` [PATCH v2 07/15] RISC-V: RV32F Support Palmer Dabbelt
2017-12-20 17:01   ` Joseph Myers
2017-12-20 17:04     ` Joseph Myers
2017-12-24  1:26       ` Palmer Dabbelt
2017-12-24  0:37     ` Palmer Dabbelt
2018-01-01  0:57       ` Joseph Myers
2017-12-20 16:04 ` RISC-V glibc port v2 Joseph Myers
2017-12-20 20:25   ` Palmer Dabbelt
2017-12-20 20:42     ` Joseph Myers
2017-12-20 17:40 ` Joseph Myers
2017-12-25 20:20   ` Palmer Dabbelt
2018-01-01  1:20     ` Joseph Myers
2018-01-03 13:37       ` Christoph Hellwig
2018-01-03 13:42         ` Joseph Myers
2017-12-20 21:11 ` Joseph Myers
2017-12-20 21:45   ` Palmer Dabbelt
2017-12-25 12:57     ` Adhemerval Zanella
2018-01-01  0:58       ` Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).