From patchwork Thu Jan 25 04:36:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 865733 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-89483-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="TXZ0PZ52"; 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 3zRq5R5zmrz9t3F for ; Thu, 25 Jan 2018 15:37:31 +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=dlgdpNcqlJaDsmBoxoO6UZsFIml5N73 ZbXuCUb5+Pl7tsaeqzPYgYJh0g5RxQ5RSrH+72yzredmhQHaS7XGRB19wDCw/fgP gSJwjuF5qV2Y17XUITbw7Vxih3+6kId4PZ6Rs6xMncbxxdCXJuGmCN7woNs9Zec+ OOMDAEzm5geI= 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=gD1UoBSzCr+IvFmBsbiY00opMO0=; b=TXZ0P Z52Co0jLeb4ezKR7r5arKmmpoSClNBD7tdlhoQON+QzBLaehb7ABOryRFAjgV1D5 tcAj8u7GYNQaizFQ50ql4uo58aEtXPFs+jXKH0LgMhSdbzPM/S2jR67c4ysRZPzV w2QAake0kmXf33iBH2MlZLtFRZZmOPcndMgZSw= Received: (qmail 20078 invoked by alias); 25 Jan 2018 04:36:50 -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 20004 invoked by uid 89); 25 Jan 2018 04:36:49 -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=20172018, 2017-2018, 20022018, unwinding 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=5qiRF6K/ZWz083fWkM82x7AVbpHVGLn1UH5THI+I4ZM=; b=WbjJ16gRzpnxreBanqkq6Eq7E0PMB8D3FZKeepTVk3nFWS4rsySWG39qhvNT0Ov4W1 +VUjzQUc5rSWyuT6Uxr1Ym5zlgOnOKwZfCZouf+/Ug11+Ok+mjxwYcg8810vzWWZfmIJ lmXTS4fEwo+OXAH9Xp6YYLG+Kn1KbwjU1Gt5Oz/pB/uGWczSNcvN5SqZmIhoJdk/rKCU nPMXYkodI2UdHFI0kiu7C2Oq7VGa6q+AwazroCcwZ0jIm8qIq8jAc76367Rjb35LJxu3 /AubleSmjaB1CxWgu4f787jaLAMTz183JivFnqMu6zRVkxZ/UQD+eAz0OSLd01+okkG6 Lfbg== X-Gm-Message-State: AKwxytchZEHdRhP+EUDP7cyxnGw47Hk6jIxjebMN0yEkDOGJnb4PWbMY gsUS/Uu3gA/C5W6jRD2z/rDUZg== X-Google-Smtp-Source: AH8x224fRWhfsXtB0TvSyMUMFmlOQuHdja/tbz1pYEReUGnE8dzaq1wtgyhczI2RE3vEZgzzETuCFA== X-Received: by 2002:a17:902:42c3:: with SMTP id h61-v6mr10108380pld.269.1516855001406; Wed, 24 Jan 2018 20:36:41 -0800 (PST) Subject: [PATCH 05/17] RISC-V: ABI Implementation Date: Wed, 24 Jan 2018 20:36:09 -0800 Message-Id: <20180125043621.19972-6-palmer@dabbelt.com> In-Reply-To: <20180125043621.19972-1-palmer@dabbelt.com> References: <20180125043621.19972-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, patches@groups.riscv.org, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org, joseph@codesourcery.com 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/backtrace.c | 1 + sysdeps/riscv/bits/endian.h | 5 +++ sysdeps/riscv/bits/setjmp.h | 39 ++++++++++++++++++ sysdeps/riscv/bits/wordsize.h | 31 +++++++++++++++ sysdeps/riscv/bsd-_setjmp.c | 1 + sysdeps/riscv/bsd-setjmp.c | 1 + sysdeps/riscv/dl-trampoline.S | 90 ++++++++++++++++++++++++++++++++++++++++++ sysdeps/riscv/gccframe.h | 21 ++++++++++ sysdeps/riscv/jmpbuf-offsets.h | 23 +++++++++++ sysdeps/riscv/jmpbuf-unwind.h | 46 +++++++++++++++++++++ sysdeps/riscv/machine-gmon.h | 37 +++++++++++++++++ sysdeps/riscv/memusage.h | 21 ++++++++++ sysdeps/riscv/setjmp.S | 74 ++++++++++++++++++++++++++++++++++ sysdeps/riscv/sys/asm.h | 66 +++++++++++++++++++++++++++++++ sysdeps/riscv/tls-macros.h | 61 ++++++++++++++++++++++++++++ 16 files changed, 574 insertions(+) create mode 100644 sysdeps/riscv/__longjmp.S create mode 100644 sysdeps/riscv/backtrace.c 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-offsets.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..0b9e5e10e2c5 --- /dev/null +++ b/sysdeps/riscv/__longjmp.S @@ -0,0 +1,57 @@ +/* longjmp, RISC-V version. + Copyright (C) 1996-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#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/backtrace.c b/sysdeps/riscv/backtrace.c new file mode 100644 index 000000000000..27ce597b3950 --- /dev/null +++ b/sysdeps/riscv/backtrace.c @@ -0,0 +1 @@ +#include 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..988ad6b1d6dd --- /dev/null +++ b/sysdeps/riscv/bits/setjmp.h @@ -0,0 +1,39 @@ +/* Define the machine-dependent type `jmp_buf'. RISC-V version. + Copyright (C) 2011-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _RISCV_BITS_SETJMP_H +#define _RISCV_BITS_SETJMP_H + +typedef struct __jmp_buf_internal_tag + { + /* Program counter. */ + long int __pc; + /* Callee-saved registers. */ + long int __regs[12]; + /* Stack pointer. */ + long int __sp; + + /* Callee-saved floating point registers. */ +#if 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..1cd0ae18b270 --- /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-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#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..cda3be9f4e12 --- /dev/null +++ b/sysdeps/riscv/dl-trampoline.S @@ -0,0 +1,90 @@ +/* RISC-V PLT trampoline + Copyright (C) 2017-2018 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +/* Assembler veneer called from the PLT header code for lazy loading. + The PLT header passes its own args in t0-t2. */ + +#ifdef __riscv_float_abi_soft +# define FRAME_SIZE (-((-10 * SZREG) & ALMASK)) +#else +# define FRAME_SIZE (-((-10 * SZREG - 8 * SZFREG) & ALMASK)) +#endif + +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) + +#ifndef __riscv_float_abi_soft + FREG_S fa0, (10*SZREG + 0*SZFREG)(sp) + FREG_S fa1, (10*SZREG + 1*SZFREG)(sp) + FREG_S fa2, (10*SZREG + 2*SZFREG)(sp) + FREG_S fa3, (10*SZREG + 3*SZFREG)(sp) + FREG_S fa4, (10*SZREG + 4*SZFREG)(sp) + FREG_S fa5, (10*SZREG + 5*SZFREG)(sp) + FREG_S fa6, (10*SZREG + 6*SZFREG)(sp) + FREG_S fa7, (10*SZREG + 7*SZFREG)(sp) +#endif + + # 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) + +#ifndef __riscv_float_abi_soft + FREG_L fa0, (10*SZREG + 0*SZFREG)(sp) + FREG_L fa1, (10*SZREG + 1*SZFREG)(sp) + FREG_L fa2, (10*SZREG + 2*SZFREG)(sp) + FREG_L fa3, (10*SZREG + 3*SZFREG)(sp) + FREG_L fa4, (10*SZREG + 4*SZFREG)(sp) + FREG_L fa5, (10*SZREG + 5*SZFREG)(sp) + FREG_L fa6, (10*SZREG + 6*SZFREG)(sp) + FREG_L fa7, (10*SZREG + 7*SZFREG)(sp) +#endif + + 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..3dc62863afb2 --- /dev/null +++ b/sysdeps/riscv/gccframe.h @@ -0,0 +1,21 @@ +/* Definition of object in frame unwind info. RISC-V version. + Copyright (C) 2001-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define FIRST_PSEUDO_REGISTER 66 + +#include diff --git a/sysdeps/riscv/jmpbuf-offsets.h b/sysdeps/riscv/jmpbuf-offsets.h new file mode 100644 index 000000000000..fff4d0d9c6f9 --- /dev/null +++ b/sysdeps/riscv/jmpbuf-offsets.h @@ -0,0 +1,23 @@ +/* Private macros for accessing __jmp_buf contents. RISC-V version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +/* Helper for generic ____longjmp_chk(). */ +#define JB_FRAME_ADDRESS(buf) \ + ((void *) _jmpbuf_sp (buf)) diff --git a/sysdeps/riscv/jmpbuf-unwind.h b/sysdeps/riscv/jmpbuf-unwind.h new file mode 100644 index 000000000000..2e5f37f10243 --- /dev/null +++ b/sysdeps/riscv/jmpbuf-unwind.h @@ -0,0 +1,46 @@ +/* Examine __jmp_buf for unwinding frames. RISC-V version. + Copyright (C) 2003-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#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..a50d50a2e12d --- /dev/null +++ b/sysdeps/riscv/machine-gmon.h @@ -0,0 +1,37 @@ +/* RISC-V definitions for profiling support. + Copyright (C) 1996-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* 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 (unsigned long int frompc, + unsigned long int selfpc); + +#define _MCOUNT_DECL(frompc, selfpc) \ +static inline void mcount_internal (unsigned long int frompc, \ +unsigned long int selfpc) + +#define MCOUNT \ +void _mcount (void *frompc) \ +{ \ + mcount_internal ((unsigned long int) frompc, \ + (unsigned long int) RETURN_ADDRESS (0)); \ +} diff --git a/sysdeps/riscv/memusage.h b/sysdeps/riscv/memusage.h new file mode 100644 index 000000000000..a29e0d1e03ac --- /dev/null +++ b/sysdeps/riscv/memusage.h @@ -0,0 +1,21 @@ +/* Machine-specific definitions for memory usage profiling, RISC-V version. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#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..cfbd276fc311 --- /dev/null +++ b/sysdeps/riscv/setjmp.S @@ -0,0 +1,74 @@ +/* setjmp for RISC-V. + Copyright (C) 1996-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#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..348baa5f136e --- /dev/null +++ b/sysdeps/riscv/sys/asm.h @@ -0,0 +1,66 @@ +/* Miscellaneous macros. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#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 + +#if !defined __riscv_float_abi_soft +/* For ABI uniformity, reserve 8 bytes for floats, even if double-precision + floating-point is not supported in hardware. */ +# if defined __riscv_float_abi_double +# define FREG_L fld +# define FREG_S fsd +# define SZFREG 8 +# else +# error unsupported FLEN +# endif +#endif + +/* Declare leaf routine. */ +#define LEAF(symbol) \ + .globl symbol; \ + .align 2; \ + .type symbol,@function; \ +symbol: \ + cfi_startproc; + +/* 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..5433ed9d16ce --- /dev/null +++ b/sysdeps/riscv/tls-macros.h @@ -0,0 +1,61 @@ +/* Macros to support TLS testing in times of missing compiler support. + Copyright (C) 2017-2018 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + + +#include +#include +#include +#include "dl-tls.h" + +#define LOAD_GP \ + ".option push\n\t" \ + ".option norelax\n\t" \ + "la gp, __global_pointer$\n\t" \ + ".option pop\n\t" + +#define UNLOAD_GP + +#define TLS_GD(x) \ + ({ void *__result; \ + asm (LOAD_GP \ + "la.tls.gd %0, " #x "\n\t" \ + UNLOAD_GP \ + : "=r" (__result)); \ + __tls_get_addr (__result); }) + +#define TLS_LD(x) TLS_GD(x) + +#define TLS_IE(x) \ + ({ void *__result; \ + asm (LOAD_GP \ + "la.tls.ie %0, " #x "\n\t" \ + "add %0, %0, tp\n\t" \ + UNLOAD_GP \ + : "=r" (__result)); \ + __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" \ + "addi %0, %0, %%tprel_lo(" #x ")\n\t" \ + UNLOAD_GP \ + : "=r" (__result)); \ + __result; })