From patchwork Wed Dec 20 07:20:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851276 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88408-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="kCUPg3Hi"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mVn45fJz9s82 for ; Wed, 20 Dec 2017 18:24:33 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=FspuHAyU1TAaZq0G7lgMA+z4MWvudYM r1kPOf+nX58eanQpDJGR7ClGi8xWIASkqB2N1MsZYty0KzE3gQY3rzxQ48Q1Wdm2 31g9lVJA0QOPAa8SmM42peJQhhyf+YqWBAeanG+j4PD2bhg5Ril0/T2LXp2Agfnm AWz2QMfhngx4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=0iwjtVSxUiS3/oOFaDPWca6H5jY=; b=kCUPg 3HipgaSueXyFFoq6yONBSbzCZJRpoVH3+/9EVsvGLCJSmuO1gjdLJs64AjjW4MoX +53zGcGa30T6UGaSY0aYrVinJZuYzFfPsufUbUwfhNe9GW+TIPFL2cLDhBbi/ku9 AGl+36JHD8uBODeWCFpjiAI0pbSBviIjaeJ2Pw= Received: (qmail 9756 invoked by alias); 20 Dec 2017 07:23:55 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 9516 invoked by uid 89); 20 Dec 2017 07:23:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=H*MI:sk:2017122, (unknown) X-HELO: mail-pl0-f48.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=yYlfEep23FY4C8qEEJwNO1HaLugLZLXX1Vve7LZ5QR0=; b=jvKvzN2UFtAw7I/rHVAhJEB+e5LeoQuOqsQGT1fU0IV5iFmziibtAP8XJHE3g5jRHK qgzeAt+XeLF+IRPIKkzZCgVC9jFCZhrK55RFSGpafKuqz30LbChWB2dojcykYGTdFGVc fq6ViUg7apWSvH/tFPWeF5f1jsiOxDSIiDeVWIW+ZPBcVxVubxfMOF9H1gC0AAENvzka SWdLuFFmumvlS+VlmeY1Zv8z6FaxscBjbRi2MyxMXyZ/GGcjDSZqSFGVMpu4a/FkIsFX PwqIn1+t/hW+2pal4V7aw188jlHvHjpKIOSJ1SfJhPqwv8VHZBxnMjVlkNYhlvYrFuEp fiVQ== X-Gm-Message-State: AKGB3mLaNWWh3MPwEHwax4iVmmZa2nce162M+XzyZQUw0t+bFfqqO7yI ZH3WauBaerDL8uI4nvcph9KXhw== X-Google-Smtp-Source: ACJfBou3N4uzFcJsKKPoE+c/YRm9WAWgoVld1QtHeKSv/KkijqGYo9vHJyqmKCz4tP343zaI/33byg== X-Received: by 10.159.253.149 with SMTP id q21mr5887525pls.195.1513754625409; Tue, 19 Dec 2017 23:23:45 -0800 (PST) Subject: [PATCH v2 01/15] RISC-V: Build Infastructure Date: Tue, 19 Dec 2017 23:20:08 -0800 Message-Id: <20171220072022.26909-2-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 +# . + +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 From patchwork Wed Dec 20 07:20:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851275 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88407-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="PXFfTFR8"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mVL56mvz9s7m for ; Wed, 20 Dec 2017 18:24:10 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=vtGvmwFowDN18QOZyncgqh7Sy9IlJED Pv5xVMw9hXl/RrSOb6GYG/IwbGnJujzf16YXPcMi1AzXfy3/+eDlEuyZJP2Fx0VQ Z3L6SGGPiW7BCsh+0K3tfztb/kNbv8iyt6H/ywHXdS1Yzmpge2VKLv+eKQx1hOZl PGcmv2JjM5XA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=6wfjNQ9CpsI8pd0p2hcb77HNpYg=; b=PXFfT FR8prp2lrvJcgUhw0S5ogTty/gOj6h8quphG7428gdVRQtx+f6DjEz8eoDNU/mKP 9m6eaih6dri3NizkHxn9gM9JHfUkHLwAQaPZWRZMmG7qh6UM7+qTnqxFhuShBgbM zTO4HualbVc9A0oL1HzSSmrgnx7SlJv9+Mituo= Received: (qmail 9259 invoked by alias); 20 Dec 2017 07:23:54 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 8960 invoked by uid 89); 20 Dec 2017 07:23:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=H*MI:sk:2017122, UD:ie, sk:double- X-HELO: mail-pg0-f65.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=f18F+HcouDAgTgIHVAKjPY3KDhmo4V9VGmzfZ7fWcUg=; b=IQZ80GmKzawf2yv1eJXgR7rs+ClwhJJ1Al1NxGmBP7zAx1IUgaQRYpCIe/eY3Yax8v iv86Y//WeD5Pr3JJbI0IPOcXNDK9RGdz/ZSp6voF0X53ewg9DGrmwGN4OTtBPf+R4/b7 mX0b5fDheMMAUnz2Rxd6CYUhB4zAvwhXt8Rr7YH+uzAXvopvInI7+C4xOo0gl9u9osle 534YSNRYTwHLLB8PMZ79nWKr2o1Y/ZyzLrPfLwEaf+UWgM/urwjhEI7o7nhkoG8CRtKM uqH6jTyh8zGw8Hw3KjXeH7Ikw0jZq5onEBm/51f6ZlXR0j6cNBBnhxwfF6nQsxWtYl0u Nx0Q== X-Gm-Message-State: AKGB3mK8aOiVFJ1XfdaH8vGgSHQzU+R+M5wqTjC6eDKmQ5fYcZlyoZdS 6bbPMIlbfCG12HDm+p3ODdKwBD1cJng= X-Google-Smtp-Source: ACJfBotXdO2K0XlZZ6Mh9tYgHFXyd6HVhQ5h0o+2Fh45hG1PriK3X2Y6W36mmrCHXKgD6bkFOLA77A== X-Received: by 10.99.149.19 with SMTP id p19mr5227729pgd.381.1513754627293; Tue, 19 Dec 2017 23:23:47 -0800 (PST) Subject: [PATCH v2 02/15] RISC-V: ABI Implementation Date: Tue, 19 Dec 2017 23:20:09 -0800 Message-Id: <20171220072022.26909-3-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + +#include +#include + +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 directly; include 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 + . */ + +#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 + . */ + +#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 + . */ + +#include +#include + +/* 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 + . */ + +#define FIRST_PSEUDO_REGISTER 66 + +#include 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 + . */ + +#include +#include +#include +#include + +/* 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 + . */ + +/* Accept 'frompc' address as argument from the function that calls + _mcount for profiling. Use __builtin_return_address (0) + for the 'selfpc' address. */ + +#include + +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 + . */ + +#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; }) + +#include 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 + . */ + +#include +#include + +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 + . */ + +#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 + . */ + + +#include +#include +#include + +#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); }) From patchwork Wed Dec 20 07:20:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851278 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88410-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="xHkVsU+z"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mWL5hSPz9s7m for ; Wed, 20 Dec 2017 18:25:02 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=Tv/qMPL9CyTkw20pChxVfEDET24176L Illz9SV80eijf/xToAOhsnpaQU/BOZD8rEFrRvl8N7GjFWY2RP/pIyFKMpvRxlpF 5IVZ78kCQUgLIB2yZvRdSSBFS6W1Qz6vowV0ivb/HE80bbBFz5l1/q0SZMyyj8rq gethbJPssWQ8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=99+Ln5qfgW4f+eSpRwcA/2t03mY=; b=xHkVs U+zSLy1nGuhnjLF02/WilJeaVm4bv6Xe+HCO7GloxrLXPOGMw/UYbMZXntHBFnwb YWR6rpdXFsWuybimgOQ9cOz3MOPQKjqoZW+wMZjpT3dvE1kixT5hCpONWEFCSBVd uZdYHWI92efLAEAMLp/OOTlvbf0H/30JOXOMFY= Received: (qmail 10520 invoked by alias); 20 Dec 2017 07:23:56 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 10334 invoked by uid 89); 20 Dec 2017 07:23:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=H*MI:sk:2017122, nowhere, ondemand, 20122017 X-HELO: mail-pl0-f46.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=KaFRcpqHv1nFewsindBfY2+nhvxHWoXTpwQWC0WIxAM=; b=C262r6jFkVdG4+F73eXrv2qkGF6hBr7XWgVQFqQ9QCX+xaYlo8Mxou2aLp0OHwvEkA WpLnBZVDzmSbKcFBXt1ZoTo+r23b+z7WYKbBMhJjI0GkagAZIiooIc9s4A9ZABkoiG5Z ZOJUJGUm7m71DPMeQ3g6Htnb1+DiHcNbLvri8tyXZFH9u6bXyriH4eOcDvh7bVZbPCG1 ewriGqBKTizK8SaVYR+CMzgW4+QK3oYrQZVtDaybgAOoNi5WjoWVLypcCK8Xq1ujaZkw wdm2mvtGV585ylzbE4rBr5knlnKGokNd89/rnU1sm3i5LulcwjL1PDl6up9PjS0pk6Ix +Mrw== X-Gm-Message-State: AKGB3mKbTRdaBER2qUd51Ac8G/H5vSd4TPNzDk4etST7uq39UNnkcxVx bZzFumLKaFSGI0GnBVMoek9cEg== X-Google-Smtp-Source: ACJfBotPiKpwC7QY+kGPbbFTg8+UDajIBRHpjrnktjQILRbvlDp0MCbDDyAOWowFQqfcSqel776coQ== X-Received: by 10.84.141.3 with SMTP id 3mr5838841plu.367.1513754629090; Tue, 19 Dec 2017 23:23:49 -0800 (PST) Subject: [PATCH v2 03/15] RISC-V: Startup and Dynamic Loading Code Date: Tue, 19 Dec 2017 23:20:10 -0800 Message-Id: <20171220072022.26909-4-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + +#ifndef _LINK_H +# error "Never include directly; use 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 + . */ + + +#include + +#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 + . */ + +#ifndef dl_machine_h +#define dl_machine_h + +#define ELF_MACHINE_NAME "RISC-V" + +#include +#include +#include +#include + +#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 ?: "", + 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 + . */ + +#ifndef _RISCV_LDSODEFS_H +#define _RISCV_LDSODEFS_H 1 + +#include + +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 + +#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 + . */ + +#define HAVE_ARCH_PLTENTER +#define HAVE_ARCH_PLTEXIT + +#include + +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 + . */ + +#define __ASSEMBLY__ 1 +#include +#include +#include + +/* 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 + . */ + +#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 From patchwork Wed Dec 20 07:20:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851277 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88409-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="Waph5qzt"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mVz6y40z9s7v for ; Wed, 20 Dec 2017 18:24:43 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=pqmOMylkNwvpOD/L6I4naaGxtS1Jr58 cZQQ7csBN7g5P8Drr8S4u2RMWumGlgZfOQgL9HD4YmJj8nHd3tmk2x1bFfZsEmyB w969vpg0+EuOsPYgRlt7GvnM8ylG+wpMImNnM8/LgHFn+fOzSJtU39K3estDy5C8 A8P6ynuxBQrE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=XwRmEwSdvCyKDU+bZ3oQZZ/ualA=; b=Waph5 qztkPQBpDne81+FbNuuu8MLLztusALxWZq4XHb0di33O5DMnh2dBItbFboQ3ldiQ ktu+g6ZfyNG2RPkMkuOZAv/P6nKDeeY4SOxu4RXE3SZOeZSJ5daD8X5wxcRlg2Sh ACh0RnmoN2SR2j999x3MDBQ3fTpMjg05XOWd2E= Received: (qmail 10130 invoked by alias); 20 Dec 2017 07:23:56 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 9928 invoked by uid 89); 20 Dec 2017 07:23:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=H*MI:sk:2017122, H*RU:209.85.192.196, Hx-spam-relays-external:209.85.192.196 X-HELO: mail-pf0-f196.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=ISixlIK0gPk5xlT3dCVgEe89bj0zN4vXhSTNlWl7eC0=; b=kWR2QydzHYXQc8w1oA2o07xvfxzR18l+j4fX22LFImDGSyBmRGNZDvEG+eVMWWJJ/Q 1xjd03EzT5q4Puu+BWTLhyGOlSnsuSnDxh023V503hUxgHHxcU8wpN5ahWvsHvfemd9Q HeXaDYMVBEp7I+GFmE/YKcrJCyJTtwSL1Y0XVzMJc0h6HPxQNlUMIbzGHE18/B+/YH6j oHwTzwTedCWdR06RzSpdDx144zX9ifg2foaVKTk12SsffuTjYR3YCAzElI0pHrzUpz8A xhYdw1vBdgoq+dW0c/d4/FlCAYKPjR74hH5CpzlDxkt3OJG7DTSjtEomR7Q57gMJJfq2 NXWw== X-Gm-Message-State: AKGB3mIIDJnHDEsJdWuxDBdulVOZUpaLqo5jEJj7R2xJAQhfOpHW+GtI Tg3NDj7ij46eODS4jNfT6YH0aRqI678= X-Google-Smtp-Source: ACJfBotil84q+eKsBK66U+0F2uSODZTRu2KMhF2VvEmeLXYt8gsIXIfvu29KQGhOxbz0qH7ACZG6/g== X-Received: by 10.99.174.73 with SMTP id e9mr5283082pgp.297.1513754630717; Tue, 19 Dec 2017 23:23:50 -0800 (PST) Subject: [PATCH v2 04/15] RISC-V: Thread-Local Storage Support Date: Tue, 19 Dec 2017 23:20:11 -0800 Message-Id: <20171220072022.26909-5-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + + +/* 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 + . */ + +#include +#include + +/* 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 +#include + +#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 + . */ + +#ifndef _RISCV_TLS_H +#define _RISCV_TLS_H 1 + +#include + +#ifndef __ASSEMBLER__ +# include +# include +# include +# include + +register void* __thread_self asm("tp"); +# define READ_THREAD_POINTER() ({ __thread_self; }) + +/* Get system call information. */ +# include + +/* 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 + +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 + . */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +#include + +/* 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 */ From patchwork Wed Dec 20 07:20:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851279 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88411-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="KRCV+f9z"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mWj3njsz9s82 for ; Wed, 20 Dec 2017 18:25:21 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=FoFwrXCJGTZHvxK3tGYHIQBcHWHl9nw 4c8HVc9KzDbAO8v3OuXdVesbLwO0Vy2ute4B9B3imk1M8DVAxIWbgefjn5XsXTVe enE6bvFgdIEFH2aNnAs057v6Op6yGeTRPQ3Dpl1c/pnGwLQwaF0CkDsDm1YX9Csb TmVGVbwtV7Qo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=pUqmrUcZmyVBKHcbZutL3e4pbig=; b=KRCV+ f9zAOqkWZQHPbymV08kH4MHPgLJXd+il0DC/q/SBJTJXXabszR0G9VYJJLkcNCMP EDwML2wCR59AbrlnRTojUk1zYDV5vqoLyNumnc3RxpNqlslWZDibbgCRYDZ9Mvlx mvT5ZcoIRBpoMeVaHijhahmEp3wriwQHGvXeME= Received: (qmail 11031 invoked by alias); 20 Dec 2017 07:23:57 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 10875 invoked by uid 89); 20 Dec 2017 07:23:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=mutual, msk, HX-Received:10.99.49.215 X-HELO: mail-pg0-f53.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=oBe8Ev8ARjPX4xDrvzFmwwIXeEVMXLq/Kaz6FYaNe1I=; b=bR0WoDK/Xpz8NyJhEaMRY539RRWf0bgwa7PBpW1vCVqLBYI15m+y91w0IIv49MerY3 1+NsslGkfa2Xf/qg69QUqptdy+HLjtRaDGbIwWeRUhiUqizlvwI5dWVOhnrTOMdIB5Ek 98BLGFEwBLraWZWKps1BuiC1YcHLa79lRQKl8Nu0uXcNe/WE9Syirsiu+TP13S1UIkqw lQQpm7WelWLD9WI3fl4LU0kJwGpaPBw+yClku0v6SYY85umz7vhtMd/N6o1x8CR84P9g OUlFTjEIImUEcrbKEkxbACX8RZeVaKnI6JabxpKAE/OxLBE1ZPgbUwBCJSmznV+wpGI6 9wPw== X-Gm-Message-State: AKGB3mI+DTa8knBMXyjxgSfdwwUK4NUExWvs4uCoJmVTPDS0YgfHMdO9 QU92N0ASrtIzglCeAEnWGtZgBg== X-Google-Smtp-Source: ACJfBotgvATn6rQLBVK4hrY6LjHcLV6AyIjOl6hJu1SSmzmzPKsVgrkMYO0giPd3k+RVqkVp3HcMwg== X-Received: by 10.99.49.215 with SMTP id x206mr5433993pgx.372.1513754632402; Tue, 19 Dec 2017 23:23:52 -0800 (PST) Subject: [PATCH v2 05/15] RISC-V: Generic Routines Date: Tue, 19 Dec 2017 23:20:12 -0800 Message-Id: <20171220072022.26909-6-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + +#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 + . */ + +#include +#include + +#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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +#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 + . */ + +#include +#include +#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 + . */ + +#include +#include +#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) From patchwork Wed Dec 20 07:20:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88412-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="gOdkNTAP"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mWv1cwTz9s7v for ; Wed, 20 Dec 2017 18:25:30 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=JTaJK/qXF/mYXo90Ycu9ipxLE+knJHo zqMhcCz12RavZ8pvfhsEmp8avRF81YBwiRmRm5hDdX1zGFRjFrPN0BKwy0FPUs0V /tCRwaOUsHFnan5F9a2Na4eLlhzAKmyjrozYR7jgIZLIRW0Fk+58H5dNvk8HIR9f sJJI3qpCNzd0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=q7JTp/BNRG6FJmj4bLWNUhyUETk=; b=gOdkN TAPNXDTr4H/JMoIrZ+XanLlMEmkyMRa4Q2HZmmC0nzngeWHRRV3r/uOGuSeO3GVt 0SBy+hqDkE5YGnAkKG7Xam5MquOXjMB4RZwlA4KbKMwtnBjkSrlBA4XtU6UKHTn/ AfZA13asJaaSKch1Ulw6oPF2JNyb/ifytaw1kU= Received: (qmail 11595 invoked by alias); 20 Dec 2017 07:23:59 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 11440 invoked by uid 89); 20 Dec 2017 07:23:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-pl0-f68.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=hfrOryYpEdkRVzZcx913Vd5m5QDQhRXUur8UnnExCZg=; b=NAOhPn1agfSLPKFvdyShseOtpRIK8NUf/Xz3pdyJDWv2j6HugA60X781JORH2N9YTg +78mJ9iW1htGaR4UiE6s/oTvkxLa2wwU3/wQzturK0HpPS2pW7g+RnC+1ScfYIX7wKlm lGrlCkhzSV8fM/tbxpt2YO/9VLX9p3qmiF+f+gg48GJF5/u23Y9l5eI03RKaitgD8PW6 55pG95a+xwaI71ltf5wQSMhj4W2Q//68WXURcIC3jwS/D0S449G5BffkLnH/K0RJ+QVk RtdDxP8O5DQXrDVr/lFovnGc3bthBT41foT+khp0FF0j+r1woq3OOVgu6QYQ6MQcmwjE kI/Q== X-Gm-Message-State: AKGB3mJGspYOUjH1QYhJm1ahlcIbBP6mP1mXtQKWTZhQjkiXYjk0BWTt u5zV1v3L2bXLFQ1yUDImsMDqkA== X-Google-Smtp-Source: ACJfBosvjuZZBctyx6YWsGJ2abxfsywY2SUum0iSsBKYVSUSY4mcSAcYYNjJgcSDl+htVeEzAbQDPQ== X-Received: by 10.84.129.37 with SMTP id 34mr5783165plb.86.1513754634134; Tue, 19 Dec 2017 23:23:54 -0800 (PST) Subject: [PATCH v2 06/15] RISC-V: Generic and soft-fp Routines Date: Tue, 19 Dec 2017 23:20:13 -0800 Message-Id: <20171220072022.26909-7-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org This patch contains the miscellaneous math routines and headers we have implemented for RISC-V. This includes things from 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 + . */ + +#ifndef _FENV_H +# error "Never use directly; include 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 + . */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +#include + +#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 + . */ + +#include +#include + +#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 From patchwork Wed Dec 20 07:20:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851285 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88417-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="ELQwOmev"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mYG58ynz9s7m for ; Wed, 20 Dec 2017 18:26:42 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=buwHDlVRIaSbj27aXUr1CBKJPMqXIv1 /kDh6jeRmZDfz8J0u0DCE8oOvsopCsbmc/FtRU/cFqJg5gUl63Jh8hF7ZwfJQyeh XkjyEpsh+FJbmx3KA6B/AeWnsO2XWosaKgpDTka8fgpgdRfhcaA0D7GDqvqIGiIe Q43r460E4718= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=/p/mTUM8n9TWtGqvhvHTX4QZtt0=; b=ELQwO mevuiLfZXotXOqTLxNyz/Mx6F8RrMaZG4TTvnp8zEWcl+qy/hGbf1Ayrh9mVLUKr Pq+izCnx8bp7+XAe1ckk5uFGDRYIh9AnexT2xxT/wucryEgv32PNcNein9Geh5eU sRLllNtBRv7eglvwLthBN89m1XFUCayCqPm1/w= Received: (qmail 25144 invoked by alias); 20 Dec 2017 07:24:24 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 15559 invoked by uid 89); 20 Dec 2017 07:24:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=20152017, HX-Received:10.159.247.196, halfway, 2014-2017 X-HELO: mail-pl0-f46.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=cFu15McWw8Et/JHCTKHO5qpvEpBK4yDmhUE/COMlf8U=; b=C0nPWH4srfWAd6Q6dN42c/55d//ZuihtHHBp89AAfaMYuMSf5gI9kBFtENuKUuZ+pE r7YQEf0F2qv0repnUxiQkFWbAYcQJxCsorkazTO4RR/R9bKnonwo619h539EvkpgVuTv BiIced7OGHD6Ex+SQjeIOEzrsNKTfqVighsqiWnrkoT1YAwf/daV39O8kMkxf6Hpfngb aFafKiaMxlMwAT7p5QHSAPFjQRY1L2/uWl8xRY18OliDmTevJG7egloITvT+TN0wCq2/ Yk1Pt8m6nvxaTLf7XC35PpyeuF8QBbKssqITpS6rXwQilEGZkfWnrUkzizIbrEKZHJTU MwDg== X-Gm-Message-State: AKGB3mLeqatRoKxdIMPzz4KeLbTrOUKMJ1wEQEI39jjrSt/mgChjuyLu 1HqbwsvBeAwOlfC5PzDA54sAHg== X-Google-Smtp-Source: ACJfBotshSlRXrczRBuOQ/RjoB4EtYjxMQirp/Bxn+wDt6WF340G+2R0UYb/5Y6HFzw9SXmW5GPoig== X-Received: by 10.159.247.196 with SMTP id v4mr5992407plz.62.1513754635817; Tue, 19 Dec 2017 23:23:55 -0800 (PST) Subject: [PATCH v2 07/15] RISC-V: RV32F Support Date: Tue, 19 Dec 2017 23:20:14 -0800 Message-Id: <20171220072022.26909-8-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#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 + . */ + +#ifndef RISCV_MATH_PRIVATE_H +#define RISCV_MATH_PRIVATE_H 1 + +#include +#include +#include + +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 + +#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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include +#include + +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) From patchwork Wed Dec 20 07:20:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851287 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88419-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="MtE0lL8f"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mYg4F2Wz9s7m for ; Wed, 20 Dec 2017 18:27:03 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=viPDWuYMVWzCvIp6soqQRqfX6glgZzE X9V9pSkIs4PvyjnP0TwO5A20nk4hcEjzt+TE4IJGthtvnk08FwQK8M0PrDa2uf8D CBx/01caP8vOpZ4GLofWKjjpExMmkqq0VHJSus44aORZyGHQPbKLgLRbGIxdQvvE o74g7XVcwTGk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=rwdy8MCPgU0aKPdkHEVBFmg/ZDw=; b=MtE0l L8fvDPYhVh52IgSkfZQrdT3VXu8H4k6gCqV/iWn/VSbOYjs0G0t5A+cV8W0cUSww gfqCRgJ0FyjjV9vlJR62Va6chVqhy3GwF26YBXfbLbZIim3W9ug6mU9qYFLUs0LG JbWZanOTSCz2TUjJuenPl+2ZLxefql/oC528pE= Received: (qmail 26663 invoked by alias); 20 Dec 2017 07:24:25 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 15521 invoked by uid 89); 20 Dec 2017 07:24:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=halfway X-HELO: mail-pl0-f65.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=4R1STDYxWf7V6FJtZstQPxebi1KXmwQGAmcGKOloRBY=; b=TSSCW2Cv3jdeWWurbJ1+7c7DqZgmAfstU5cHHbr8UxNpu9nyBWyYIdsv+FnDd19eai wjJYigkMoSW+CjuQi1P7IxigvFnz+K2eKcjLITeozE0hRcwZKgY7xO24n2gu1skH4fG7 X8XVeAqatWNdiZF8b/KW0BJcc23/iid/AilDzyviTJp3ZGb7TTYfZLzjHialSFIs3+UE 2BTgKShBz1942oBRQFePurfnYW9FD5p47QjLvAE8VfLH5awAOZ7GiJvbakqdYfDHZPFE LPHugSfj99e/bAeMlLUYyYopu00CGcmq4nJN4s7rFsQ0V/upPx9LK1S1XTUAFs4aOUAJ rzcQ== X-Gm-Message-State: AKGB3mKZPEjZqw65dFqIIhilMGIdGV6Nne+F1maa9Liqs6qz//Sscb6Y iMwAY8Qiz4FSZhZDLUV8NIwxiA== X-Google-Smtp-Source: ACJfBosYbmn6Iuuzzxik/DpPLttNx3j/au3GxM5X1NnTW+XHyAIY2qtdNE00CHLD5xaYyR0cG8oLww== X-Received: by 10.159.207.131 with SMTP id z3mr6042401plo.259.1513754637484; Tue, 19 Dec 2017 23:23:57 -0800 (PST) Subject: [PATCH v2 08/15] RISC-V: RV32D, RV64F, and RV64D Support Date: Tue, 19 Dec 2017 23:20:15 -0800 Message-Id: <20171220072022.26909-9-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include + +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 + . */ + +#include + +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 + . */ + +#include + +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 + . */ + +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + + +#include +#include +#include + +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 + . */ + +#include +#include +#include + +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 + . */ + +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +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 + . */ + +#include +#include + +int +__issignaling (double x) +{ + return _FCLASS (x) & _FCLASS_SNAN; +} +libm_hidden_def (__issignaling) From patchwork Wed Dec 20 07:20:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851281 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88413-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="db0rAOB1"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mX71BDSz9s7m for ; Wed, 20 Dec 2017 18:25:42 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=gWMYlheVdxEO/Ve4Q5ZBsUpApQoSd22 2pWjJBiAysNityL7uYvF3Mord0/dOzhGUMptE6EsNeI/jto2c9VrcNoKDZPuv2gR EEddE3t6z7lsCur3Ny4s2kZLWRtHjvl7glMeXnVdlhb6JMFwfDT4ZGhuavA1+t3U 77HQZ2cozZe0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=hVHRsCz1oOo6zvwuD4NnV/2Vct0=; b=db0rA OB1eCAZDQ28/4jO10lUlmPDGo86dHfd59/BVH0OLiZ4RfaYny6hcWFrCsLKW3aJs A675FGdve0TPXCvcYW2dXBWIvoiULqd46VVWLM3ohL575OVLz9HeYJ4cdPCSX7B8 STadO4fVYp0iURX1++aJalll1h72adytp+WDjk= Received: (qmail 14853 invoked by alias); 20 Dec 2017 07:24:07 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 13672 invoked by uid 89); 20 Dec 2017 07:24:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=halfway, 2014-2017, 20142017 X-HELO: mail-pf0-f196.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=ORUjTexKNXX0zB4OUjdF4rUjPWfWHddV1QEgyMyZYOY=; b=DBn0qkjwIGN6o8HYavpYrEOzeFZmC/3pscox5vAmmm9yL/QaampWyWhSnW6PjCB2D2 CiAdeZMa/rzgIr2rFtjqAujvRFm2juQym0YQYxBmv4m8cV9UdWUpg7taEvFCJCzGl0aK NhoqfP9P/RD8NE1WDrWZ4djm1FTuCeRc5b0ZwYv6Sde5LUtAfOqCwv1tpqq/8ZQ6Qd3l 3W6yVA3Fn0rKg5aC37P3nJ6MQRsVosgA+fybt9cAPQGjL7MRetuvgl1k7ZBYn9tDVlc7 CtdoloEm4fjfitt34JoIhNSI6VAgc2Lsvt8GkCZBQtVkm6GmksvJDm5yHW0/zTTzjIzc cOPA== X-Gm-Message-State: AKGB3mJHDOGHcJVcuiWi17FYC2F5zjk+IXcKxTKuZ5HRH7Lq9VgIxprd ZYweXkBh4ZyM2z9VPfDjcXE8UQ== X-Google-Smtp-Source: ACJfBosmrZPVKx6eQY9TI7SsMFirohxRvsPEggsmUn1IyWl3Q/SnnkWCExrBmZYrrCVFzCl+D1xViw== X-Received: by 10.101.67.203 with SMTP id n11mr5458079pgp.228.1513754639045; Tue, 19 Dec 2017 23:23:59 -0800 (PST) Subject: [PATCH v2 09/15] RISC-V: Atomic and Locking Routines Date: Tue, 19 Dec 2017 23:20:16 -0800 Message-Id: <20171220072022.26909-10-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + +#ifndef _BITS_PTHREADTYPES_ARCH_H +#define _BITS_PTHREADTYPES_ARCH_H 1 + +#include + +#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 + . */ + +#ifndef _SEMAPHORE_H +# error "Never use directly; include 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 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 + . */ + +#ifndef _LINUX_RISCV_BITS_ATOMIC_H +#define _LINUX_RISCV_BITS_ATOMIC_H 1 + +#include + +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 +#include + +#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 */ From patchwork Wed Dec 20 07:20:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851284 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88416-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="iCoFIMFu"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mXs02s1z9ryQ for ; Wed, 20 Dec 2017 18:26:20 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=yysvJtqFsd3xj0qK6Q7Og5By8psNa87 WheTyCGh35BTUGYw8nhgb2xsJKCnyJ+9s2Ub802tK/JM8Z6lkT3iNAiHqwvFLExr CH9OAi7PniZ3Zm6X+T1Fv7CFEPHblV6/uByUbR9RDItg1RYIA33rok6j+FkfeyBO dwNuRVIkG0uY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=hOJsZoP8NvCVvSMuiB+SpbKsD0A=; b=iCoFI MFuat9wwIMRtB3Jp2W+EqB7WtI322C0vNHYgREpBCmx9mNaRrll/ZFAu9cIYtYwA Hm+uXC+P1eO+KeYeLFSokYN07eKg+nsCDTyymofhxjAvscSrrOpZb33RmpvwFZrb t/wSM2Rot7VY9Ceu9CyvwqtEi+yOQuuThW5+M8= Received: (qmail 24181 invoked by alias); 20 Dec 2017 07:24:23 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 15539 invoked by uid 89); 20 Dec 2017 07:24:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Nonstandard, Non-standard X-HELO: mail-pg0-f67.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=FVG/809gIpQfHw6gu1+y6yxH79es9rFtNTXniQgpcJg=; b=hkLNzX5ESBQIss78IEc1AwwE9EcS4QJXf35hnGtrkQO3WjIZLdwUHP0wB6Zv5OUTCa LdwQBlyx8SBT5ybbubyQ0pwHXVXZAzoW48qC5312ke484WNYZtVkl61Qb6rpAyp+qAFd WdeMJsTJBPMSEfE/5j/BHlBylaDNDWjCOthZXCqpboPeVhgFPiRBrJ3gbSfsXVQNnqrm qB5biV7mJVI1BRGmCzknxh7lsS9FbJgbwC+FfFprdsfKUtCeyi9nL0QLasGbUzZTsNKI HiS3rarR2ZDiOK8LgRGdGlexVBXONUOznWPvldEHLz8PIlolSDKXNcqwVJ5fcyyUXhfN cE+g== X-Gm-Message-State: AKGB3mLUanf3xKD2Om7brvHdFXoylgl6/mMSA4YNBs5B3sqQ06cPj/MA syNmJVjw5wI+bp45v40FmoMRnw== X-Google-Smtp-Source: ACJfBouTjaXfB7u8cIh2Mlikau5QuTgrM7kmayeqKQ4f3+ihe6z861Dn8mdKn/KpIQuS+YRz+kDfFg== X-Received: by 10.98.17.72 with SMTP id z69mr5896858pfi.86.1513754640704; Tue, 19 Dec 2017 23:24:00 -0800 (PST) Subject: [PATCH v2 10/15] RISC-V: Linux Syscall Interface Date: Tue, 19 Dec 2017 23:20:17 -0800 Message-Id: <20171220072022.26909-11-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 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 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 + . */ + +/* 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 +#include +#define _ERRNO_H 1 +#include +#include +#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 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 + . */ + +#define __ASSUME_ACCEPT4_SYSCALL 1 +#define __ASSUME_RECVMMSG_SYSCALL 1 +#define __ASSUME_SENDMMSG_SYSCALL 1 + +#include_next 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 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 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 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 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 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 + . */ + +#include + +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 + . */ + +#include + +#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 + . */ + +#ifndef _LINUX_RISCV_SYSDEP_H +#define _LINUX_RISCV_SYSDEP_H 1 + +#include +#include + +#ifdef __ASSEMBLER__ + +#include + +#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 +#endif + +#include + +#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 + . */ + +/* vfork() is just a special case of clone(). */ + +#include +#include +#define __ASSEMBLY__ +#include +#include + + .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) From patchwork Wed Dec 20 07:20:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851286 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88418-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="jbKoHb3Y"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mYS32ckz9s7m for ; Wed, 20 Dec 2017 18:26:52 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=VmTvmP9ANM/vU+XnHOBVautlMVpcdTT 1ZPr/iEfWeBKX6XXl4GCrxAhmC2WzGtLjE1qBHyRS46NtzkcN30GN42wsQkQEedy CS7OvfYD+O59xWiF11H58i1EYCcpJZg0YGY1GdyhZF+ENEECNzcibOAES/+jAXyE PczKsnFkX2qI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=NfGSFNjo1biuewbV2GCdKJSlHDo=; b=jbKoH b3Yl3kxo8QG29FdLYzUEQHB//LPE4HZoJvHWb/P0C3dG48fLBWaB9TBIQTvHAJ75 THQ/+i4s46jwisBxHFMjxtfBBF1mnyTw/uJhcA5OxR7Rc4EPaOaMLQAiRU3dKhZg miLSXlqQoDKQpNZXQLVH8Lpj0R02wgi9HvW9bI= Received: (qmail 25830 invoked by alias); 20 Dec 2017 07:24:25 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 21751 invoked by uid 89); 20 Dec 2017 07:24:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Gas X-HELO: mail-pl0-f53.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=EyJhRLwFy5FG9ZgUEqt1hTYumQogejtHfrLuSpTHNa0=; b=ITe5V++DJAjbeZfaQGoUQdKSyvy5VW7POaA2NJMuBcapW0lqwnpimatd8O1cR5BNB2 Mjd8ImXL56277ce9O3xQLARqyXGHDml7upiEhqyUVBOOWETVepsDnvk424tHQO/acV/U vR4yXktq0RRQLCikKOnPnrcXkRgvC/eHsgto90nimyEy/2C0opf37KdE72fk2hp7ac9Y 5X/1fyJAZsdSbKNsJ/1mKuyJ8OZwxQsHnq8nXREBc/5L3QsEvGD811CtqdoL00+j/YuF E/12p7AFtjy7iJX+QzjOFiPPk9mzNncwZII96XvYdDbT7rTiqZjrLzqnD4YMRFwUKERW elhg== X-Gm-Message-State: AKGB3mKz2UM9BhiPg/qMZkqyEri3uznXh8uGWzVfFCEWIi5KNT7O4VOI V4170aZF9Lsm9m7fyRKU0iHsdg== X-Google-Smtp-Source: ACJfBovE66qUw3yomZcMGMKTcGQ3IPPbhS35RlP08MTIPN/lBiig6xrjl5nCIHfs/9CXkAkJXWQPMQ== X-Received: by 10.159.218.152 with SMTP id w24mr6099897plp.43.1513754642491; Tue, 19 Dec 2017 23:24:02 -0800 (PST) Subject: [PATCH v2 11/15] RISC-V: Linux ABI Date: Tue, 19 Dec 2017 23:20:18 -0800 Message-Id: <20171220072022.26909-12-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + +#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 + . */ + +/* 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 + . */ + +#ifndef _FCNTL_H +# error "Never use directly; include instead." +#endif + +#include + +/* 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 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 + . */ + +#ifndef _SYS_MMAN_H +# error "Never use directly; include 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 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 + . */ + +#ifndef _BITS_SIGCONTEXT_H +#define _BITS_SIGCONTEXT_H 1 + +#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H +# error "Never use directly; include 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 + . */ + +#include +#include +#include +#include + +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 + . */ + +#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 + . */ + +#ifdef SHARED +# include +# include + +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 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 + . */ + +#ifndef _LIBC_VDSO_H +#define _LIBC_VDSO_H + +#ifdef SHARED + +# include + +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 + . */ + +#include +#include +#include +#include +#include + +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 + . */ + +#include +#include +#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 + . */ + +/* Produced by this program: + + #include + #include + #include + #include + + 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 + . */ + +/* Produced by this program: + + #include + #include + #include + #include + + 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 + . */ + +#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 + . */ + +#include + +#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 + . */ + +#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 + . */ + +#ifndef _SYS_CACHECTL_H +#define _SYS_CACHECTL_H 1 + +#include + +__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 + . */ + +#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 +#include +#include +#include +#include + +/* 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 + . */ + +/* 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 + +#include +#include +#include + +#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 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 + . */ + +#include +#include +#include +#ifndef __ASSEMBLER__ +# include +#endif +#include + +/* 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 + . */ + +#ifndef _LINUX_RISCV_UCONTEXT_MACROS_H +#define _LINUX_RISCV_UCONTEXT_MACROS_H + +#include +#include + +#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 +#include +#include +#include + +-- 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) From patchwork Wed Dec 20 07:20:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851282 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88414-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="S0EKfHiR"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mXM6LVSz9ryQ for ; Wed, 20 Dec 2017 18:25:55 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=Z9sqOj5EOeuJzDYcim1nzi0VE0lN78m FrIPkrz1sFVdIccVawnKvoNno9PlWt/ttRUbGFnVJMWshaOGincJr3bWyXIi2tkI 1dFXHLw1RGAs+kW7+rDjKZyo7H1fDS+etBa/zJ+mMcGwCIDAEqLZ87pQMBCnIeqs mB7v5CBwLAtQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=iN1fcXbkFA7OTvbkuo+v+3c8fvo=; b=S0EKf HiRfsl+8cAFFZMBS+ff3lXkc64l0y91cBd9Pa0+vWkdujhEBy7fwbvBdZArFH2Be oAELEPbARb4bVLatPAVCMXgRKBZ4jiFPEbH666swvJ/sRBV8bEoASETNpf6Vxr8V z7IpgYc+fzE5dCIPNXOVMWT6w3GwJ0bU8thNKY= Received: (qmail 22958 invoked by alias); 20 Dec 2017 07:24:22 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 15544 invoked by uid 89); 20 Dec 2017 07:24:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-pl0-f68.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=JfC6eRMTN7dVWtR1SBqMKcwFSi/GIbjsyg+8tUGiJpg=; b=SxZlPGiEzAj67q675KFm61Mz+LiAQkhG2rGuHswOGyIcaC0x6bClO8P497z9WajKcQ rFoPt530izBPMdERh7Xxs0PZgbvYJXKUBx8LnsMRa6S7AkpcIJelbS/pGt3X3lxppa36 mq50k+zSqDyONhTDm+QsoTJ1ByKSVcNEZySFGKfC0T22Qj+CHd30wHQIh6GZMeZRAQXI Qt7DaydZbYPFQBrIrT/YQCXJ5eBP4O3NM2R6sBnzAQeeDd5b7jssRwB5MRc5AOXTmnOu KCAz8iOTbaOuITe/q5O36M09s8KitHyQ1t2LeDsJz+b1Heuz3wgu4b3w9oQAyYMIjWu5 HMxg== X-Gm-Message-State: AKGB3mK3Et1de/oHP084t0w6uWrhCoAC/gRQDKV6VuusgF1qav07o4GL 3ubloEhdCX+Cklf4j7n8gs2RgAbMx9Q= X-Google-Smtp-Source: ACJfBotg/zqyDsvyjuCStkKnLSiDHmxC08aC/Q7wuJLcXJmQ2CgCnHyBxqSQXLYgu+XD8F3swY+1sg== X-Received: by 10.159.241.1 with SMTP id q1mr6042782plr.383.1513754644013; Tue, 19 Dec 2017 23:24:04 -0800 (PST) Subject: [PATCH v2 12/15] RISC-V: Linux Startup and Dynamic Loading Code Date: Tue, 19 Dec 2017 23:20:19 -0800 Message-Id: <20171220072022.26909-13-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 + . */ + +#include + +#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 + . */ + +#include + +#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 + . */ + +#ifndef _LDSODEFS_H + +/* Get the real definitions. */ +#include_next + +/* 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 */ From patchwork Wed Dec 20 07:20:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851283 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88415-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="KEifI7M6"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mXb3dvvz9ryQ for ; Wed, 20 Dec 2017 18:26:07 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=jpiqfpX3FktblGVKmORlp1otBD6oKjX TEwnwbsfNuDgyLIxtUzU6hT2/dbShJZKwRrXL9CZz5EBezV2mOeepVgV049hV05e iuJYpE6lZVXTQFl5lR3lEA7h+RJHh4NrD1JQ60HkON4Qr9SiR9FlpPcX3WMHwLBS xnLoVyobvM4k= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=3DZkfNhjKE2qbZFj2gR6LadOu9I=; b=KEifI 7M6igxD2GRij2zjBh1p7czxMjT38o70lzo6oAzrO6b36sIDfidxCMUQ6+AHrtcCP e7UDloZArLLFfbwD6xJMeyl8+0w+sRrQCHvO8Rx3iVImjZ5Yvmd8f/n2IZIipcdR r6LoAgYmSQgliUiuIOb90ckLUm6ienqMI+j1zc= Received: (qmail 23427 invoked by alias); 20 Dec 2017 07:24:23 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 15803 invoked by uid 89); 20 Dec 2017 07:24:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=HX-Received:10.84.237.2 X-HELO: mail-pl0-f48.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=yJJiwJdHAlp7YPJlPHsQ4yHxu71OirLN9ryYXqTZO1o=; b=BGh8OSlj31UQ+F5ZjkeN2EbwGXrOEy2rkJj2sAHxtM1XcUiE6zt0UBAN+IW9syl+3J AI8vNz25gj1y8Wh3hdSZSJ9CrxN61IhWp08DrUq8mFrrVUn1mlTYjW/WAeBrvY6j6Nd4 2WuWwvMtBxlQrSrstDhY+Jd/9Pn87rM0Y2O0kmnfA1odLLPmVHc3VLBUQwSYaHuFpFDS TwPaIsc0RcCIfDrHH4KTPVFP0isbe3OJJdWFY0NlW/QBo/QjTFchvDE1C9ZVyt/tqzRW RBf4hJkBsQWJCEHcvyMkogyDrLwhU7ql2mX5MhaFA7MjroX23QeWmMCVlRloDgTWvaK6 I2Lg== X-Gm-Message-State: AKGB3mJ48blwmyKj9RxI1Pe5rVyYY1iTzY4tl8zhNeFQ4MLZwfo8B6a2 uONKRWQbjeCQheiDOIcltTGEEQ== X-Google-Smtp-Source: ACJfBov34uEZnY/V6gWU6PLWgn2KoT6nU2OMi1LEV7gFR2coGDjbtMTQsuxSGqeGubbrCqRotKMY4Q== X-Received: by 10.84.237.2 with SMTP id s2mr5937025plk.415.1513754645501; Tue, 19 Dec 2017 23:24:05 -0800 (PST) Subject: [PATCH v2 13/15] Add RISC-V dynamic relocations to elf.h Date: Tue, 19 Dec 2017 23:20:20 -0800 Message-Id: <20171220072022.26909-14-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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 */ From patchwork Wed Dec 20 07:20:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851289 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88421-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="qdZfd2Vn"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mZ40lLDz9s7m for ; Wed, 20 Dec 2017 18:27:23 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=qChGgskacicGeoHiGtBA8X21EfR5WXt gJ1waLLlaYTgaCpeVW3wmHjhluoJ35/PIRinEN6Vu7FOhLMNB9S27K75KLb/Fj42 EkoS6oAA4iHCZjeqwhFeNJTl6IY56Jad/+x8qIfZ1uJv01E7Lt9erqHAcPs5wwV9 5XVn9bAh23lQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=E/aw40i60+NNRFkkZNqlDi5KiCg=; b=qdZfd 2Vn+66RI9bxVp1c+FeJyDt9xFt3klTwmGcLNGs7CgTyGsQyg8acYkTTgWWJlkNy3 zMjIrul4jCG2McuFKgQRS+HRnFtgZNqL0YL3uVxj3zg/BdzmjRVQTGGn7pDQFnGQ Mgwuf60kCNB/o3BlZf9OLmOrFFvxxClJy+6bD8= Received: (qmail 27413 invoked by alias); 20 Dec 2017 07:24:27 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 17015 invoked by uid 89); 20 Dec 2017 07:24:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-pg0-f42.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=AuYtfffduMd4tdO9LVacJ5E9wtb7GNOxagLliqQtC2s=; b=YdsLswEuMKMlOJHj4HMCPUCWUyW3CmlpXXfjOHLnoBdS98srrUkUuK/2Ey0vyZOw+u qgnvg2xE2cJOief22orV5ekV+ToiLo8E4gafuBNbqPRHvabENuR+G13GY3jB5d41VKM3 4Z2J1iyPvaGzNguQY+6X+adh2hDawqphIMLXhZwjGsIAhBHWmzG9WomeyKZYW1W6ZBWh lvOuSqAldXGAa1MSZ3hdeaM0OW3o7A7H+IbNfcJEZbhFZ1KeBWJG+0Kc/+0WITWAirwc 5X/MTTt72zGskoJauPxgbDjiRjmxhgUJz+1wmMIAxxueTsroP9txrt6jdQoCgYiyeD6d 3sLw== X-Gm-Message-State: AKGB3mKv1OsUzDURKAW2WFwQGJkpSmUVkfmnWdqqJZhcp7XlBFgpjVBV syEE1bMVyPwnbeR6AcNsegmoBw== X-Google-Smtp-Source: ACJfBos9oyZSIQnN25ksePhd4aLTSrJdYAZH3zv4G06qtcvtATXBRYgMhRwZicLT13peXf9b7R+aQQ== X-Received: by 10.99.98.198 with SMTP id w189mr5456955pgb.328.1513754647494; Tue, 19 Dec 2017 23:24:07 -0800 (PST) Subject: [PATCH v2 14/15] Add linux-4.15 VDSO hash for RISC-V Date: Tue, 19 Dec 2017 23:20:21 -0800 Message-Id: <20171220072022.26909-15-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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, From patchwork Wed Dec 20 07:20:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 851288 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88420-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="pHcp5QCi"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z1mYv2CgRz9s7m for ; Wed, 20 Dec 2017 18:27:15 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=fC/wi1QM/RES//lcrTWUGpC9bpk13A3 yZrKlBkbKj4ne9M8LL+u1zQO/UN8GDF0+/qY2VaWiJx8QZybxS9M1o3gOnUqGudW RIfI8/s5khDiqK/gbfeZHW4zNqc+PucPKSKWkdt9ypqQNNmfiC84KDbnKrHIEq+I qZDP+8U6Cajs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=UrNIR0L8ok2TCfSA2xxmQWNpNng=; b=pHcp5 QCidOaacJCwv6r/FLTLxiXwecdcK3dHgVIQO9WlyRFp9hmujqXukFvwmRm5G1SJn /IYL3AoCk3+HBbNzNdSCUJP1gt5W0MO28J6HP+a7k2QTZGDooTPT5CK2OyPCJyvr cte66zDBQ/N0AHvkrQ1SGf06gqcQjkXya1BEZY= Received: (qmail 26981 invoked by alias); 20 Dec 2017 07:24:26 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 21343 invoked by uid 89); 20 Dec 2017 07:24:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-pf0-f182.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=5khUMqYFSAWfLXo9qLx9id267t39wUDIhFMO1bGgroE=; b=UuwO1erjilF841T2XNHPrRjF0XBPY0Lw9Y4fgCasSbif9q3vUIYlBqxWq/xfKJ4Ilr ihe8jd3Vs6f9V5ZK4KjpXdvzqAbzNCnIcOPs9ymCk5JjkexX/ZKCLfURjFmE+3MUmQ58 tSs8wPZH4LBIgGRpckG0LGEUVLe5tJepV4QVStTMdzA8zv4yiAuINo8BQSkY8/nMtvEt xtE7a1teZYduVegmgN9ArFQ49VG5FZsKJ1KN4DFJF4Yd6+hauFkijUQoJvcoadkcUh+d yWJ62Gm8/ALQtQYW4ZX3G4veEGaVyaV1fmoKzu2E2v0R5S+ScYag+b2Na9VMSAJ/58EL 2LlA== X-Gm-Message-State: AKGB3mLxhkQx4gWK6joeGHN8YMR4EFZ+67Xfo15T79XIkW71kXJ7O3T1 4To5b4AoLW0xgZw2+os+m6eVyQ== X-Google-Smtp-Source: ACJfBosOtsddzLYcVr0iNjIGjl9w27DCYOB/5hJNjs5YmJNjYTUG2vDLTEJD7P2CklguEKA88HjVVw== X-Received: by 10.101.66.66 with SMTP id d2mr5429223pgq.244.1513754648955; Tue, 19 Dec 2017 23:24:08 -0800 (PST) Subject: [PATCH v2 15/15] Add RISC-V to build-many-glibcs.py Date: Tue, 19 Dec 2017 23:20:22 -0800 Message-Id: <20171220072022.26909-16-palmer@dabbelt.com> In-Reply-To: <20171220072022.26909-1-palmer@dabbelt.com> References: <20171220072022.26909-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org 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=[{},