diff mbox series

[v4,16/17] RISC-V: Build Infastructure

Message ID 20180113103816.4861-17-palmer@dabbelt.com
State New
Headers show
Series [v4,01/17] Skeleton documentation for the RISC-V port | expand

Commit Message

Palmer Dabbelt Jan. 13, 2018, 10:38 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.
---
 sysdeps/riscv/Implies                        |   6 +
 sysdeps/riscv/Makefile                       |   7 +
 sysdeps/riscv/configure                      |   4 +
 sysdeps/riscv/configure.ac                   |   4 +
 sysdeps/riscv/nptl/Makefile                  |  26 +++
 sysdeps/riscv/preconfigure                   |  60 +++++++
 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       |  27 +++
 sysdeps/unix/sysv/linux/riscv/Versions       |   5 +
 sysdeps/unix/sysv/linux/riscv/configure      | 256 +++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/configure.ac   |  44 +++++
 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 |  13 ++
 21 files changed, 472 insertions(+)
 create mode 100644 sysdeps/riscv/Implies
 create mode 100644 sysdeps/riscv/Makefile
 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

Joseph Myers Jan. 15, 2018, 5:44 p.m. UTC | #1
On Sat, 13 Jan 2018, Palmer Dabbelt wrote:

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

> +    case "$flen" in
> +    64)
> +    	float_machine=rvd
> +	with_fp_cond=1
> +    	;;
> +    "")
> +    	float_machine=
> +	with_fp_cond=0
> +    	;;
> +    *)
> +    	echo "Unable to determine FLEN" >&2
> +    	exit 1
> +    	;;
> +    esac

It's deliberate that you don't support the "f" ABI.  Is it also deliberate 
that here you don't support the case of "f" hardware (float but not double 
supported in hardware) with the soft-float ABI, despite having sysdeps 
directories structured to distinguish rvf and rvd?
Palmer Dabbelt Jan. 23, 2018, 12:40 a.m. UTC | #2
On Mon, 15 Jan 2018 09:44:44 PST (-0800), joseph@codesourcery.com wrote:
> On Sat, 13 Jan 2018, Palmer Dabbelt wrote:
>
>> diff --git a/sysdeps/riscv/preconfigure b/sysdeps/riscv/preconfigure
>
>> +    case "$flen" in
>> +    64)
>> +    	float_machine=rvd
>> +	with_fp_cond=1
>> +    	;;
>> +    "")
>> +    	float_machine=
>> +	with_fp_cond=0
>> +    	;;
>> +    *)
>> +    	echo "Unable to determine FLEN" >&2
>> +    	exit 1
>> +    	;;
>> +    esac
>
> It's deliberate that you don't support the "f" ABI.  Is it also deliberate
> that here you don't support the case of "f" hardware (float but not double
> supported in hardware) with the soft-float ABI, despite having sysdeps
> directories structured to distinguish rvf and rvd?

Yes: the idea here was to reduce the amount of targets that the RISC-V port 
needed to support right now.  We originally supported all these targets in 
glibc so the code is still organized that way.  I'd prefer to leave the 
organization as it is in case we want to add support for the F ISAs and ABIs, 
as I have a feeling we might want to extend this in the future.
Joseph Myers Jan. 23, 2018, 12:55 a.m. UTC | #3
On Mon, 22 Jan 2018, Palmer Dabbelt wrote:

> Yes: the idea here was to reduce the amount of targets that the RISC-V port
> needed to support right now.  We originally supported all these targets in
> glibc so the code is still organized that way.  I'd prefer to leave the
> organization as it is in case we want to add support for the F ISAs and ABIs,
> as I have a feeling we might want to extend this in the future.

That's fine (given that the NEWS entry accurately lists what cases are 
supported, which it appears to - it doesn't mention any cases with "f" but 
not "d").
diff mbox series

Patch

diff --git a/sysdeps/riscv/Implies b/sysdeps/riscv/Implies
new file mode 100644
index 000000000000..15b9e02448aa
--- /dev/null
+++ b/sysdeps/riscv/Implies
@@ -0,0 +1,6 @@ 
+init_array
+
+ieee754/ldbl-128
+ieee754/dbl-64
+ieee754/flt-32
+riscv/soft-fp
diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile
new file mode 100644
index 000000000000..20a996810611
--- /dev/null
+++ b/sysdeps/riscv/Makefile
@@ -0,0 +1,7 @@ 
+ifeq ($(subdir),misc)
+sysdep_headers += sys/asm.h
+endif
+
+# RISC-V's assembler also needs to know about PIC as it changes the definition
+# of some assembler macros.
+ASFLAGS-.os += $(pic-ccflag)
diff --git a/sysdeps/riscv/configure b/sysdeps/riscv/configure
new file mode 100644
index 000000000000..53f5f1b5f113
--- /dev/null
+++ b/sysdeps/riscv/configure
@@ -0,0 +1,4 @@ 
+# 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..c3cc7f36da7e
--- /dev/null
+++ b/sysdeps/riscv/nptl/Makefile
@@ -0,0 +1,26 @@ 
+# Makefile for sysdeps/riscv/nptl.
+# Copyright (C) 2005-2018 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..a486a271031e
--- /dev/null
+++ b/sysdeps/riscv/preconfigure
@@ -0,0 +1,60 @@ 
+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'`
+    atomic=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | grep '#define __riscv_atomic' | cut -d' ' -f2`
+    
+    case "$xlen" in
+    32 | 64)
+    	;;
+    *)
+    	echo "Unable to determine XLEN" >&2
+    	exit 1
+    	;;
+    esac
+    
+    case "$flen" in
+    64)
+    	float_machine=rvd
+	with_fp_cond=1
+    	;;
+    "")
+    	float_machine=
+	with_fp_cond=0
+    	;;
+    *)
+    	echo "Unable to determine FLEN" >&2
+    	exit 1
+    	;;
+    esac
+    
+    case "$float_abi" in
+    soft)
+    	abi_flen=0
+    	;;
+    double)
+    	abi_flen=64
+    	;;
+    *)
+    	echo "Unable to determine floating-point ABI" >&2
+    	exit 1
+    	;;
+    esac
+
+    case "$atomic" in
+    __riscv_atomic)
+        ;;
+    *)
+        echo "glibc requires the A extension" >&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..bf9c24ad77da
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/Makefile
@@ -0,0 +1,27 @@ 
+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 ilp32d lp64 lp64d
+
+ifeq (,$(filter $(default-abi),$(abi-variants)))
+$(error Unknown ABI $(default-abi), must be one of $(abi-variants))
+endif
+
+abi-ilp32-condition   := !defined __LP64__ && defined __riscv_float_abi_soft
+abi-ilp32d-condition  := !defined __LP64__ && defined __riscv_float_abi_double
+abi-lp64-condition    := defined __LP64__ && defined __riscv_float_abi_soft
+abi-lp64d-condition   := defined __LP64__ && 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..54da0fa4cef2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/configure
@@ -0,0 +1,256 @@ 
+# 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_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"
+
+case $libc_cv_riscv_int_abi$libc_cv_riscv_float_abi-$machine in
+lp64-riscv/rv64/*)
+  test -n "$libc_cv_slibdir" ||
+case "$prefix" in
+/usr | /usr/)
+  libc_cv_slibdir=/lib64/lp64
+  libc_cv_rtlddir=/lib
+  if test "$libdir" = '${exec_prefix}/lib'; then
+    libdir='${exec_prefix}/lib64/lp64';
+    # Locale data can be shared between 32-bit and 64-bit libraries.
+    libc_cv_complocaledir='${exec_prefix}/lib/locale'
+  fi
+  ;;
+esac
+  ;;
+lp64d-riscv/rv64/*)
+  test -n "$libc_cv_slibdir" ||
+case "$prefix" in
+/usr | /usr/)
+  libc_cv_slibdir=/lib64/lp64d
+  libc_cv_rtlddir=/lib
+  if test "$libdir" = '${exec_prefix}/lib'; then
+    libdir='${exec_prefix}/lib64/lp64d';
+    # Locale data can be shared between 32-bit and 64-bit libraries.
+    libc_cv_complocaledir='${exec_prefix}/lib/locale'
+  fi
+  ;;
+esac
+  ;;
+ilp32-riscv/rv32/*)
+  test -n "$libc_cv_slibdir" ||
+case "$prefix" in
+/usr | /usr/)
+  libc_cv_slibdir=/lib32/ilp32
+  libc_cv_rtlddir=/lib
+  if test "$libdir" = '${exec_prefix}/lib'; then
+    libdir='${exec_prefix}/lib32/ilp32';
+    # Locale data can be shared between 32-bit and 64-bit libraries.
+    libc_cv_complocaledir='${exec_prefix}/lib/locale'
+  fi
+  ;;
+esac
+  ;;
+ilp32d-riscv/rv32/*)
+  test -n "$libc_cv_slibdir" ||
+case "$prefix" in
+/usr | /usr/)
+  libc_cv_slibdir=/lib32/ilp32d
+  libc_cv_rtlddir=/lib
+  if test "$libdir" = '${exec_prefix}/lib'; then
+    libdir='${exec_prefix}/lib32/ilp32d';
+    # Locale data can be shared between 32-bit and 64-bit libraries.
+    libc_cv_complocaledir='${exec_prefix}/lib/locale'
+  fi
+  ;;
+esac
+  ;;
+esac
diff --git a/sysdeps/unix/sysv/linux/riscv/configure.ac b/sysdeps/unix/sysv/linux/riscv/configure.ac
new file mode 100644
index 000000000000..0c9bc28249e9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/configure.ac
@@ -0,0 +1,44 @@ 
+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_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])
+
+case $libc_cv_riscv_int_abi$libc_cv_riscv_float_abi-$machine in
+lp64-riscv/rv64/*)
+  LIBC_SLIBDIR_RTLDDIR([lib64/lp64], [lib])
+  ;;
+lp64d-riscv/rv64/*)
+  LIBC_SLIBDIR_RTLDDIR([lib64/lp64d], [lib])
+  ;;
+ilp32-riscv/rv32/*)
+  LIBC_SLIBDIR_RTLDDIR([lib32/ilp32], [lib])
+  ;;
+ilp32d-riscv/rv32/*)
+  LIBC_SLIBDIR_RTLDDIR([lib32/ilp32d], [lib])
+  ;;
+esac
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..1d2561e7a8ec
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/shlib-versions
@@ -0,0 +1,13 @@ 
+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 == 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 == 0
+ld=ld-linux-riscv32-ilp32.so.1
+%else
+%error cannot determine ABI
+%endif