[v2,01/15] RISC-V: Build Infastructure

Message ID 20171220072022.26909-2-palmer@dabbelt.com
State New, archived
Headers

Commit Message

Palmer Dabbelt Dec. 20, 2017, 7:20 a.m. UTC
  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
  

Comments

Dmitry V. Levin Dec. 20, 2017, 2:05 p.m. UTC | #1
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,
  
Joseph Myers Dec. 20, 2017, 4:21 p.m. UTC | #2
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 Myers Dec. 20, 2017, 4:43 p.m. UTC | #3
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.
  
Adhemerval Zanella Netto Dec. 20, 2017, 4:49 p.m. UTC | #4
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?
  
Palmer Dabbelt Dec. 20, 2017, 8:25 p.m. UTC | #5
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
>> 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.
  

Patch

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