{"id":2220811,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2220811/?format=json","web_url":"http://patchwork.ozlabs.org/project/uclibc-ng/patch/20260408053507.2640564-4-cmirabil@redhat.com/","project":{"id":55,"url":"http://patchwork.ozlabs.org/api/1.1/projects/55/?format=json","name":"uClibc NG development","link_name":"uclibc-ng","list_id":"devel.uclibc-ng.org","list_email":"devel@uclibc-ng.org","web_url":"http://www.uclibc-ng.org","scm_url":"","webscm_url":"http://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git"},"msgid":"<20260408053507.2640564-4-cmirabil@redhat.com>","date":"2026-04-08T05:35:07","name":"[uclibc-ng-devel,v1,3/3] riscv: add support for ucontext functions","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"b226fadfad9071b262a29452ab31a5a1eb305a57","submitter":{"id":82370,"url":"http://patchwork.ozlabs.org/api/1.1/people/82370/?format=json","name":"Charles Mirabile","email":"cmirabil@redhat.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/uclibc-ng/patch/20260408053507.2640564-4-cmirabil@redhat.com/mbox/","series":[{"id":499072,"url":"http://patchwork.ozlabs.org/api/1.1/series/499072/?format=json","web_url":"http://patchwork.ozlabs.org/project/uclibc-ng/list/?series=499072","date":"2026-04-08T05:35:05","name":"Misc Additions for RISC-V","version":1,"mbox":"http://patchwork.ozlabs.org/series/499072/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2220811/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2220811/checks/","tags":{},"headers":{"Return-Path":"<devel-bounces@uclibc-ng.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=JyxrJyhf;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=uclibc-ng.org\n (client-ip=89.238.66.15; helo=helium.openadk.org;\n envelope-from=devel-bounces@uclibc-ng.org; receiver=patchwork.ozlabs.org)","helium.openadk.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=JyxrJyhf;\n\tdkim-atps=neutral"],"X-Greylist":"delayed 430 seconds by postgrey-1.37 at legolas;\n Wed, 08 Apr 2026 15:43:04 AEST","Received":["from helium.openadk.org (helium.openadk.org [89.238.66.15])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4frBmm5FJtz1xv0\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 08 Apr 2026 15:43:04 +1000 (AEST)","from helium.openadk.org (localhost [127.0.0.1])\n\tby helium.openadk.org (Postfix) with ESMTP id 919BE31E0CF8;\n\tWed, 08 Apr 2026 07:35:52 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby helium.openadk.org (Postfix) with ESMTPS id 90ED931E0B9B\n\tfor <devel@uclibc-ng.org>; Wed, 08 Apr 2026 07:35:18 +0200 (CEST)","from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-214--BZFu9W0OWefjcUCBzT9gg-1; Wed,\n 08 Apr 2026 01:35:16 -0400","from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 1DA0819560B4\n\tfor <devel@uclibc-ng.org>; Wed,  8 Apr 2026 05:35:15 +0000 (UTC)","from cmirabil.redhat.com (unknown [10.2.16.11])\n\tby mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 3FB9A300019F;\n\tWed,  8 Apr 2026 05:35:14 +0000 (UTC)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1775626517;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\t to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\t content-transfer-encoding:content-transfer-encoding:\n\t in-reply-to:in-reply-to:references:references;\n\tbh=uJNFkFSgdJ/QCM7MtMLvujdbrGK6L6GYy74ACs4HqQc=;\n\tb=JyxrJyhfbuHx/n7bHDmwmrNCDmnQ7Tmo44NX9rI/wAH0RchAeAv7iXFoyKhbUcQM4xPrB2\n\tQDsEipTMTO7wUQUiuLF+5aZLnAPXSydb4tMa6nbBYszU/G4OzDIkdAxAJd7VRUeM5iJC4C\n\tFV3D2cZp/8kscSAzdJ9rrFnUsaYNnTU=","X-MC-Unique":"-BZFu9W0OWefjcUCBzT9gg-1","X-Mimecast-MFC-AGG-ID":"-BZFu9W0OWefjcUCBzT9gg_1775626515","From":"Charles Mirabile <cmirabil@redhat.com>","To":"devel@uclibc-ng.org","Date":"Wed,  8 Apr 2026 01:35:07 -0400","Message-ID":"<20260408053507.2640564-4-cmirabil@redhat.com>","In-Reply-To":"<20260408053507.2640564-1-cmirabil@redhat.com>","References":"<20260408053507.2640564-1-cmirabil@redhat.com>","MIME-Version":"1.0","X-Scanned-By":"MIMEDefang 3.4.1 on 10.30.177.4","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"0YJ83c4ehfPSrFrNl-OPvUWMh4cddkWNpvc04Wa2c_E_1775626515","X-Mimecast-Originator":"redhat.com","Message-ID-Hash":"AUOTACUGMSDEQGEEKADIZ4HSIQG2OAZZ","X-Message-ID-Hash":"AUOTACUGMSDEQGEEKADIZ4HSIQG2OAZZ","X-MailFrom":"cmirabil@redhat.com","X-Mailman-Rule-Misses":"dmarc-mitigation; no-senders; approved; loop;\n banned-address; emergency; member-moderation; nonmember-moderation;\n administrivia; implicit-dest; max-recipients; max-size; news-moderation;\n no-subject; digests; suspicious-header","CC":"Charles Mirabile <cmirabil@redhat.com>","X-Mailman-Version":"3.3.10","Precedence":"list","Subject":"[uclibc-ng-devel] [PATCH v1 3/3] riscv: add support for ucontext\n functions","List-Id":"uClibc-ng Development <devel.uclibc-ng.org>","Archived-At":"\n <https://uclibc-ng.org/mailman3/hyperkitty/list/devel@uclibc-ng.org/message/AUOTACUGMSDEQGEEKADIZ4HSIQG2OAZZ/>","List-Archive":"\n <https://uclibc-ng.org/mailman3/hyperkitty/list/devel@uclibc-ng.org/>","List-Help":"<mailto:devel-request@uclibc-ng.org?subject=help>","List-Owner":"<mailto:devel-owner@uclibc-ng.org>","List-Post":"<mailto:devel@uclibc-ng.org>","List-Subscribe":"<mailto:devel-join@uclibc-ng.org>","List-Unsubscribe":"<mailto:devel-leave@uclibc-ng.org>","Content-Type":"text/plain; charset=\"us-ascii\"; x-default=\"true\"","Content-Transfer-Encoding":"7bit"},"content":"These functions (largely obsolescent) are from SUSv3 and allow\ncontex switching within userspace (\"green threading\").\n\nPorted over from the patch where they were added to glibc\n7f33b09c65e3fdb6 (\"RISC-V: Linux ABI\").\nOnly minimal change was __glibc_unlikely => unlikely\n\nSigned-off-by: Charles Mirabile <cmirabil@redhat.com>\n---\n extra/Configs/Config.riscv32                 |   1 +\n extra/Configs/Config.riscv64                 |   1 +\n libc/sysdeps/linux/riscv32/Makefile.arch     |   2 +\n libc/sysdeps/linux/riscv32/getcontext.S      |  77 ++++++++++++\n libc/sysdeps/linux/riscv32/makecontext.c     |  78 ++++++++++++\n libc/sysdeps/linux/riscv32/setcontext.S      | 114 +++++++++++++++++\n libc/sysdeps/linux/riscv32/swapcontext.S     | 125 +++++++++++++++++++\n libc/sysdeps/linux/riscv32/ucontext-macros.h |  49 ++++++++\n libc/sysdeps/linux/riscv32/ucontext_i.sym    |  31 +++++\n libc/sysdeps/linux/riscv64/Makefile.arch     |   2 +\n libc/sysdeps/linux/riscv64/getcontext.S      |  77 ++++++++++++\n libc/sysdeps/linux/riscv64/makecontext.c     |  78 ++++++++++++\n libc/sysdeps/linux/riscv64/setcontext.S      | 114 +++++++++++++++++\n libc/sysdeps/linux/riscv64/swapcontext.S     | 125 +++++++++++++++++++\n libc/sysdeps/linux/riscv64/ucontext-macros.h |  49 ++++++++\n libc/sysdeps/linux/riscv64/ucontext_i.sym    |  31 +++++\n 16 files changed, 954 insertions(+)\n create mode 100644 libc/sysdeps/linux/riscv32/getcontext.S\n create mode 100644 libc/sysdeps/linux/riscv32/makecontext.c\n create mode 100644 libc/sysdeps/linux/riscv32/setcontext.S\n create mode 100644 libc/sysdeps/linux/riscv32/swapcontext.S\n create mode 100644 libc/sysdeps/linux/riscv32/ucontext-macros.h\n create mode 100644 libc/sysdeps/linux/riscv32/ucontext_i.sym\n create mode 100644 libc/sysdeps/linux/riscv64/getcontext.S\n create mode 100644 libc/sysdeps/linux/riscv64/makecontext.c\n create mode 100644 libc/sysdeps/linux/riscv64/setcontext.S\n create mode 100644 libc/sysdeps/linux/riscv64/swapcontext.S\n create mode 100644 libc/sysdeps/linux/riscv64/ucontext-macros.h\n create mode 100644 libc/sysdeps/linux/riscv64/ucontext_i.sym","diff":"diff --git a/extra/Configs/Config.riscv32 b/extra/Configs/Config.riscv32\nindex 304d30f70..e0ffcc11d 100644\n--- a/extra/Configs/Config.riscv32\n+++ b/extra/Configs/Config.riscv32\n@@ -12,3 +12,4 @@ config FORCE_OPTIONS_FOR_ARCH\n \tdefault y\n \tselect ARCH_LITTLE_ENDIAN\n \tselect ARCH_HAS_MMU\n+\tselect ARCH_HAS_UCONTEXT\ndiff --git a/extra/Configs/Config.riscv64 b/extra/Configs/Config.riscv64\nindex f1e8511ee..9b8490f4a 100644\n--- a/extra/Configs/Config.riscv64\n+++ b/extra/Configs/Config.riscv64\n@@ -12,3 +12,4 @@ config FORCE_OPTIONS_FOR_ARCH\n \tdefault y\n \tselect ARCH_LITTLE_ENDIAN\n \tselect ARCH_HAS_MMU\n+\tselect ARCH_HAS_UCONTEXT\ndiff --git a/libc/sysdeps/linux/riscv32/Makefile.arch b/libc/sysdeps/linux/riscv32/Makefile.arch\nindex 21ecaa65b..33f4008be 100644\n--- a/libc/sysdeps/linux/riscv32/Makefile.arch\n+++ b/libc/sysdeps/linux/riscv32/Makefile.arch\n@@ -1,2 +1,4 @@\n CSRC-y := __syscall_error.c cache.c\n SSRC-y := __longjmp.S setjmp.S vfork.S clone.S\n+CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c\n+SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S swapcontext.S\ndiff --git a/libc/sysdeps/linux/riscv32/getcontext.S b/libc/sysdeps/linux/riscv32/getcontext.S\nnew file mode 100644\nindex 000000000..bde350f72\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv32/getcontext.S\n@@ -0,0 +1,77 @@\n+/* Save current context.\n+   Copyright (C) 2009-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"ucontext-macros.h\"\n+\n+/* int getcontext (ucontext_t *ucp) */\n+\n+\t.text\n+LEAF (__getcontext)\n+\tSAVE_INT_REG (ra,   0, a0)\n+\tSAVE_INT_REG (ra,   1, a0)\n+\tSAVE_INT_REG (sp,   2, a0)\n+\tSAVE_INT_REG (s0,   8, a0)\n+\tSAVE_INT_REG (s1,   9, a0)\n+\tSAVE_INT_REG (x0,  10, a0)\t/* return 0 by overwriting a0.  */\n+\tSAVE_INT_REG (s2,  18, a0)\n+\tSAVE_INT_REG (s3,  19, a0)\n+\tSAVE_INT_REG (s4,  20, a0)\n+\tSAVE_INT_REG (s5,  21, a0)\n+\tSAVE_INT_REG (s6,  22, a0)\n+\tSAVE_INT_REG (s7,  23, a0)\n+\tSAVE_INT_REG (s8,  24, a0)\n+\tSAVE_INT_REG (s9,  25, a0)\n+\tSAVE_INT_REG (s10, 26, a0)\n+\tSAVE_INT_REG (s11, 27, a0)\n+\n+#ifndef __riscv_float_abi_soft\n+\tfrsr\ta1\n+\n+\tSAVE_FP_REG (fs0,   8, a0)\n+\tSAVE_FP_REG (fs1,   9, a0)\n+\tSAVE_FP_REG (fs2,  18, a0)\n+\tSAVE_FP_REG (fs3,  19, a0)\n+\tSAVE_FP_REG (fs4,  20, a0)\n+\tSAVE_FP_REG (fs5,  21, a0)\n+\tSAVE_FP_REG (fs6,  22, a0)\n+\tSAVE_FP_REG (fs7,  23, a0)\n+\tSAVE_FP_REG (fs8,  24, a0)\n+\tSAVE_FP_REG (fs9,  25, a0)\n+\tSAVE_FP_REG (fs10, 26, a0)\n+\tSAVE_FP_REG (fs11, 27, a0)\n+\n+\tsw\ta1, MCONTEXT_FSR(a0)\n+#endif /* __riscv_float_abi_soft */\n+\n+/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */\n+\tli\ta3, _NSIG8\n+\tadd     a2, a0, UCONTEXT_SIGMASK\n+\tmv\ta1, zero\n+\tli\ta0, SIG_BLOCK\n+\n+\tli\ta7, SYS_ify (rt_sigprocmask)\n+\tscall\n+\tbltz\ta0, 99f\n+\n+\tret\n+\n+99:\tj\t__syscall_error\n+\n+PSEUDO_END (__getcontext)\n+\n+weak_alias (__getcontext, getcontext)\ndiff --git a/libc/sysdeps/linux/riscv32/makecontext.c b/libc/sysdeps/linux/riscv32/makecontext.c\nnew file mode 100644\nindex 000000000..9bd73cc67\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv32/makecontext.c\n@@ -0,0 +1,78 @@\n+/* Create new context.  RISC-V version.\n+   Copyright (C) 2001-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include <sysdep.h>\n+#include <sys/asm.h>\n+#include <sys/ucontext.h>\n+#include <stdarg.h>\n+#include <assert.h>\n+\n+void\n+__makecontext (ucontext_t *ucp, void (*func) (void), int argc,\n+\t       long int a0, long int a1, long int a2, long int a3, long int a4,\n+\t       ...)\n+{\n+  extern void __start_context (void) attribute_hidden;\n+  long int i, sp;\n+\n+  _Static_assert (REG_NARGS == 8, \"__makecontext assumes 8 argument registers\");\n+\n+  /* Set up the stack.  */\n+  sp = ((long int) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ALMASK;\n+\n+  /* Set up the register context.\n+     ra = s0 = 0, terminating the stack for backtracing purposes.\n+     s1 = the function we must call.\n+     s2 = the subsequent context to run.  */\n+  ucp->uc_mcontext.__gregs[REG_RA] = 0;\n+  ucp->uc_mcontext.__gregs[REG_S0] = 0;\n+  ucp->uc_mcontext.__gregs[REG_S1] = (long int) func;\n+  ucp->uc_mcontext.__gregs[REG_S2] = (long int) ucp->uc_link;\n+  ucp->uc_mcontext.__gregs[REG_SP] = sp;\n+  ucp->uc_mcontext.__gregs[REG_PC] = (long int) &__start_context;\n+\n+  /* Put args in a0-a7, then put any remaining args on the stack.  */\n+  ucp->uc_mcontext.__gregs[REG_A0 + 0] = a0;\n+  ucp->uc_mcontext.__gregs[REG_A0 + 1] = a1;\n+  ucp->uc_mcontext.__gregs[REG_A0 + 2] = a2;\n+  ucp->uc_mcontext.__gregs[REG_A0 + 3] = a3;\n+  ucp->uc_mcontext.__gregs[REG_A0 + 4] = a4;\n+\n+  if (unlikely(argc > 5))\n+    {\n+      va_list vl;\n+      va_start (vl, a4);\n+\n+      long reg_args = argc < REG_NARGS ? argc : REG_NARGS;\n+      for (i = 5; i < reg_args; i++)\n+        ucp->uc_mcontext.__gregs[REG_A0 + i] = va_arg (vl, long);\n+\n+      long int stack_args = argc - reg_args;\n+      if (stack_args > 0)\n+\t{\n+\t  sp = (sp - stack_args * sizeof (long int)) & ALMASK;\n+\t  ucp->uc_mcontext.__gregs[REG_SP] = sp;\n+\t  for (i = 0; i < stack_args; i++)\n+\t    ((long int *) sp)[i] = va_arg (vl, long int);\n+\t}\n+\n+      va_end (vl);\n+    }\n+}\n+\n+weak_alias (__makecontext, makecontext)\ndiff --git a/libc/sysdeps/linux/riscv32/setcontext.S b/libc/sysdeps/linux/riscv32/setcontext.S\nnew file mode 100644\nindex 000000000..9f1c7b41f\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv32/setcontext.S\n@@ -0,0 +1,114 @@\n+/* Set current context.\n+   Copyright (C) 2009-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"ucontext-macros.h\"\n+\n+/*  int __setcontext (const ucontext_t *ucp)\n+\n+  Restores the machine context in UCP and thereby resumes execution\n+  in that context.\n+\n+  This implementation is intended to be used for *synchronous* context\n+  switches only.  Therefore, it does not have to restore anything\n+  other than the PRESERVED state.  */\n+\n+\t.text\n+LEAF (__setcontext)\n+\n+\tmv\tt0, a0\t/* Save ucp into t0.  */\n+\n+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */\n+\tli\ta3, _NSIG8\n+\tmv\ta2, zero\n+\tadd     a1, a0, UCONTEXT_SIGMASK\n+\tli\ta0, SIG_SETMASK\n+\n+\tli\ta7, SYS_ify (rt_sigprocmask)\n+\tscall\n+\n+\tbltz\ta0, 99f\n+\n+\tcfi_def_cfa (t0, 0)\n+\n+#ifndef __riscv_float_abi_soft\n+\tlw\tt1, MCONTEXT_FSR(t0)\n+\n+\tRESTORE_FP_REG_CFI (fs0,   8, t0)\n+\tRESTORE_FP_REG_CFI (fs1,   9, t0)\n+\tRESTORE_FP_REG_CFI (fs2,  18, t0)\n+\tRESTORE_FP_REG_CFI (fs3,  19, t0)\n+\tRESTORE_FP_REG_CFI (fs4,  20, t0)\n+\tRESTORE_FP_REG_CFI (fs5,  21, t0)\n+\tRESTORE_FP_REG_CFI (fs6,  22, t0)\n+\tRESTORE_FP_REG_CFI (fs7,  23, t0)\n+\tRESTORE_FP_REG_CFI (fs8,  24, t0)\n+\tRESTORE_FP_REG_CFI (fs9,  25, t0)\n+\tRESTORE_FP_REG_CFI (fs10, 26, t0)\n+\tRESTORE_FP_REG_CFI (fs11, 27, t0)\n+\n+\tfssr\tt1\n+#endif /* __riscv_float_abi_soft */\n+\n+\t/* Note the contents of argument registers will be random\n+\t   unless makecontext() has been called.  */\n+\tRESTORE_INT_REG     (t1,   0, t0)\n+\tRESTORE_INT_REG_CFI (ra,   1, t0)\n+\tRESTORE_INT_REG     (sp,   2, t0)\n+\tRESTORE_INT_REG_CFI (s0,   8, t0)\n+\tRESTORE_INT_REG_CFI (s1,   9, t0)\n+\tRESTORE_INT_REG     (a0,  10, t0)\n+\tRESTORE_INT_REG     (a1,  11, t0)\n+\tRESTORE_INT_REG     (a2,  12, t0)\n+\tRESTORE_INT_REG     (a3,  13, t0)\n+\tRESTORE_INT_REG     (a4,  14, t0)\n+\tRESTORE_INT_REG     (a5,  15, t0)\n+\tRESTORE_INT_REG     (a6,  16, t0)\n+\tRESTORE_INT_REG     (a7,  17, t0)\n+\tRESTORE_INT_REG_CFI (s2,  18, t0)\n+\tRESTORE_INT_REG_CFI (s3,  19, t0)\n+\tRESTORE_INT_REG_CFI (s4,  20, t0)\n+\tRESTORE_INT_REG_CFI (s5,  21, t0)\n+\tRESTORE_INT_REG_CFI (s6,  22, t0)\n+\tRESTORE_INT_REG_CFI (s7,  23, t0)\n+\tRESTORE_INT_REG_CFI (s8,  24, t0)\n+\tRESTORE_INT_REG_CFI (s9,  25, t0)\n+\tRESTORE_INT_REG_CFI (s10, 26, t0)\n+\tRESTORE_INT_REG_CFI (s11, 27, t0)\n+\n+\tjr\tt1\n+\n+99:\tj\t__syscall_error\n+\n+PSEUDO_END (__setcontext)\n+weak_alias (__setcontext, setcontext)\n+\n+LEAF (__start_context)\n+\n+\t/* Terminate call stack by noting ra == 0.  Happily, s0 == 0 here.  */\n+\tcfi_register (ra, s0)\n+\n+\t/* Call the function passed to makecontext.  */\n+\tjalr\ts1\n+\n+\t/* Invoke subsequent context if present, else exit(0).  */\n+\tmv\ta0, s2\n+\tbeqz\ts2, 1f\n+\tjal\t__setcontext\n+1:\tj\texit\n+\n+PSEUDO_END (__start_context)\ndiff --git a/libc/sysdeps/linux/riscv32/swapcontext.S b/libc/sysdeps/linux/riscv32/swapcontext.S\nnew file mode 100644\nindex 000000000..75b58dc66\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv32/swapcontext.S\n@@ -0,0 +1,125 @@\n+/* Save and set current context.\n+   Copyright (C) 2009-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"ucontext-macros.h\"\n+\n+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */\n+\n+LEAF (__swapcontext)\n+\tmv\tt0, a1\t\t\t/* Save ucp into t0.  */\n+\n+\tSAVE_INT_REG (ra,   0, a0)\n+\tSAVE_INT_REG (ra,   1, a0)\n+\tSAVE_INT_REG (sp,   2, a0)\n+\tSAVE_INT_REG (s0,   8, a0)\n+\tSAVE_INT_REG (s1,   9, a0)\n+\tSAVE_INT_REG (x0,  10, a0)\t/* return 0 by overwriting a0.  */\n+\tSAVE_INT_REG (s2,  18, a0)\n+\tSAVE_INT_REG (s3,  19, a0)\n+\tSAVE_INT_REG (s4,  20, a0)\n+\tSAVE_INT_REG (s5,  21, a0)\n+\tSAVE_INT_REG (s6,  22, a0)\n+\tSAVE_INT_REG (s7,  23, a0)\n+\tSAVE_INT_REG (s8,  24, a0)\n+\tSAVE_INT_REG (s9,  25, a0)\n+\tSAVE_INT_REG (s10, 26, a0)\n+\tSAVE_INT_REG (s11, 27, a0)\n+\n+#ifndef __riscv_float_abi_soft\n+\tfrsr a1\n+\n+\tSAVE_FP_REG (fs0,   8, a0)\n+\tSAVE_FP_REG (fs1,   9, a0)\n+\tSAVE_FP_REG (fs2,  18, a0)\n+\tSAVE_FP_REG (fs3,  19, a0)\n+\tSAVE_FP_REG (fs4,  20, a0)\n+\tSAVE_FP_REG (fs5,  21, a0)\n+\tSAVE_FP_REG (fs6,  22, a0)\n+\tSAVE_FP_REG (fs7,  23, a0)\n+\tSAVE_FP_REG (fs8,  24, a0)\n+\tSAVE_FP_REG (fs9,  25, a0)\n+\tSAVE_FP_REG (fs10, 26, a0)\n+\tSAVE_FP_REG (fs11, 27, a0)\n+\n+\tsw\ta1, MCONTEXT_FSR(a0)\n+#endif /* __riscv_float_abi_soft */\n+\n+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */\n+\tli\ta3, _NSIG8\n+\tadd\ta2, a0, UCONTEXT_SIGMASK\n+\tadd     a1, t0, UCONTEXT_SIGMASK\n+\tli\ta0, SIG_SETMASK\n+\n+\tli\ta7, SYS_ify (rt_sigprocmask)\n+\tscall\n+\n+\tbltz\ta0, 99f\n+\n+#ifndef __riscv_float_abi_soft\n+\tlw\tt1, MCONTEXT_FSR(t0)\n+\n+\tRESTORE_FP_REG (fs0,   8, t0)\n+\tRESTORE_FP_REG (fs1,   9, t0)\n+\tRESTORE_FP_REG (fs2,  18, t0)\n+\tRESTORE_FP_REG (fs3,  19, t0)\n+\tRESTORE_FP_REG (fs4,  20, t0)\n+\tRESTORE_FP_REG (fs5,  21, t0)\n+\tRESTORE_FP_REG (fs6,  22, t0)\n+\tRESTORE_FP_REG (fs7,  23, t0)\n+\tRESTORE_FP_REG (fs8,  24, t0)\n+\tRESTORE_FP_REG (fs9,  25, t0)\n+\tRESTORE_FP_REG (fs10, 26, t0)\n+\tRESTORE_FP_REG (fs11, 27, t0)\n+\n+\tfssr\tt1\n+#endif /* __riscv_float_abi_soft */\n+\n+\t/* Note the contents of argument registers will be random\n+\t   unless makecontext() has been called.  */\n+\tRESTORE_INT_REG (t1,   0, t0)\n+\tRESTORE_INT_REG (ra,   1, t0)\n+\tRESTORE_INT_REG (sp,   2, t0)\n+\tRESTORE_INT_REG (s0,   8, t0)\n+\tRESTORE_INT_REG (s1,   9, t0)\n+\tRESTORE_INT_REG (a0,  10, t0)\n+\tRESTORE_INT_REG (a1,  11, t0)\n+\tRESTORE_INT_REG (a2,  12, t0)\n+\tRESTORE_INT_REG (a3,  13, t0)\n+\tRESTORE_INT_REG (a4,  14, t0)\n+\tRESTORE_INT_REG (a5,  15, t0)\n+\tRESTORE_INT_REG (a6,  16, t0)\n+\tRESTORE_INT_REG (a7,  17, t0)\n+\tRESTORE_INT_REG (s2,  18, t0)\n+\tRESTORE_INT_REG (s3,  19, t0)\n+\tRESTORE_INT_REG (s4,  20, t0)\n+\tRESTORE_INT_REG (s5,  21, t0)\n+\tRESTORE_INT_REG (s6,  22, t0)\n+\tRESTORE_INT_REG (s7,  23, t0)\n+\tRESTORE_INT_REG (s8,  24, t0)\n+\tRESTORE_INT_REG (s9,  25, t0)\n+\tRESTORE_INT_REG (s10, 26, t0)\n+\tRESTORE_INT_REG (s11, 27, t0)\n+\n+\tjr\tt1\n+\n+\n+99:\tj\t__syscall_error\n+\n+PSEUDO_END (__swapcontext)\n+\n+weak_alias (__swapcontext, swapcontext)\ndiff --git a/libc/sysdeps/linux/riscv32/ucontext-macros.h b/libc/sysdeps/linux/riscv32/ucontext-macros.h\nnew file mode 100644\nindex 000000000..a73c3a9b0\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv32/ucontext-macros.h\n@@ -0,0 +1,49 @@\n+/* Macros for ucontext routines.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#ifndef _LINUX_RISCV_UCONTEXT_MACROS_H\n+#define _LINUX_RISCV_UCONTEXT_MACROS_H\n+\n+#include <sysdep.h>\n+#include <sys/asm.h>\n+\n+#include \"ucontext_i.h\"\n+\n+#define MCONTEXT_FSR (32 * SZFREG + MCONTEXT_FPREGS)\n+\n+#define SAVE_FP_REG(name, num, base)\t\t\t\\\n+  FREG_S name, ((num) * SZFREG + MCONTEXT_FPREGS)(base)\n+\n+#define RESTORE_FP_REG(name, num, base)\t\t\t\\\n+  FREG_L name, ((num) * SZFREG + MCONTEXT_FPREGS)(base)\n+\n+#define RESTORE_FP_REG_CFI(name, num, base)\t\t\\\n+  RESTORE_FP_REG (name, num, base);\t\t\t\\\n+  cfi_offset (name, (num) * SZFREG + MCONTEXT_FPREGS)\n+\n+#define SAVE_INT_REG(name, num, base)\t\t\t\\\n+  REG_S name, ((num) * SZREG + MCONTEXT_GREGS)(base)\n+\n+#define RESTORE_INT_REG(name, num, base)\t\t\\\n+  REG_L name, ((num) * SZREG + MCONTEXT_GREGS)(base)\n+\n+#define RESTORE_INT_REG_CFI(name, num, base)\t\t\\\n+  RESTORE_INT_REG (name, num, base);\t\t\t\\\n+  cfi_offset (name, (num) * SZREG + MCONTEXT_GREGS)\n+\n+#endif /* _LINUX_RISCV_UCONTEXT_MACROS_H */\ndiff --git a/libc/sysdeps/linux/riscv32/ucontext_i.sym b/libc/sysdeps/linux/riscv32/ucontext_i.sym\nnew file mode 100644\nindex 000000000..be55b2631\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv32/ucontext_i.sym\n@@ -0,0 +1,31 @@\n+#include <inttypes.h>\n+#include <signal.h>\n+#include <stddef.h>\n+#include <sys/ucontext.h>\n+\n+-- Constants used by the rt_sigprocmask call.\n+\n+SIG_BLOCK\n+SIG_SETMASK\n+\n+_NSIG8\t\t\t\t(_NSIG / 8)\n+\n+-- Offsets of the fields in the ucontext_t structure.\n+#define ucontext(member)\toffsetof (ucontext_t, member)\n+#define stack(member)\t\tucontext (uc_stack.member)\n+#define mcontext(member)\tucontext (uc_mcontext.member)\n+\n+UCONTEXT_FLAGS\t\t\tucontext (__uc_flags)\n+UCONTEXT_LINK\t\t\tucontext (uc_link)\n+UCONTEXT_STACK\t\t\tucontext (uc_stack)\n+UCONTEXT_MCONTEXT\t\tucontext (uc_mcontext)\n+UCONTEXT_SIGMASK\t\tucontext (uc_sigmask)\n+\n+STACK_SP\t\t\tstack (ss_sp)\n+STACK_SIZE\t\t\tstack (ss_size)\n+STACK_FLAGS\t\t\tstack (ss_flags)\n+\n+MCONTEXT_GREGS\t\t\tmcontext (__gregs)\n+MCONTEXT_FPREGS\t\t\tmcontext (__fpregs)\n+\n+UCONTEXT_SIZE\t\t\tsizeof (ucontext_t)\ndiff --git a/libc/sysdeps/linux/riscv64/Makefile.arch b/libc/sysdeps/linux/riscv64/Makefile.arch\nindex 21ecaa65b..33f4008be 100644\n--- a/libc/sysdeps/linux/riscv64/Makefile.arch\n+++ b/libc/sysdeps/linux/riscv64/Makefile.arch\n@@ -1,2 +1,4 @@\n CSRC-y := __syscall_error.c cache.c\n SSRC-y := __longjmp.S setjmp.S vfork.S clone.S\n+CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c\n+SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S swapcontext.S\ndiff --git a/libc/sysdeps/linux/riscv64/getcontext.S b/libc/sysdeps/linux/riscv64/getcontext.S\nnew file mode 100644\nindex 000000000..bde350f72\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv64/getcontext.S\n@@ -0,0 +1,77 @@\n+/* Save current context.\n+   Copyright (C) 2009-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"ucontext-macros.h\"\n+\n+/* int getcontext (ucontext_t *ucp) */\n+\n+\t.text\n+LEAF (__getcontext)\n+\tSAVE_INT_REG (ra,   0, a0)\n+\tSAVE_INT_REG (ra,   1, a0)\n+\tSAVE_INT_REG (sp,   2, a0)\n+\tSAVE_INT_REG (s0,   8, a0)\n+\tSAVE_INT_REG (s1,   9, a0)\n+\tSAVE_INT_REG (x0,  10, a0)\t/* return 0 by overwriting a0.  */\n+\tSAVE_INT_REG (s2,  18, a0)\n+\tSAVE_INT_REG (s3,  19, a0)\n+\tSAVE_INT_REG (s4,  20, a0)\n+\tSAVE_INT_REG (s5,  21, a0)\n+\tSAVE_INT_REG (s6,  22, a0)\n+\tSAVE_INT_REG (s7,  23, a0)\n+\tSAVE_INT_REG (s8,  24, a0)\n+\tSAVE_INT_REG (s9,  25, a0)\n+\tSAVE_INT_REG (s10, 26, a0)\n+\tSAVE_INT_REG (s11, 27, a0)\n+\n+#ifndef __riscv_float_abi_soft\n+\tfrsr\ta1\n+\n+\tSAVE_FP_REG (fs0,   8, a0)\n+\tSAVE_FP_REG (fs1,   9, a0)\n+\tSAVE_FP_REG (fs2,  18, a0)\n+\tSAVE_FP_REG (fs3,  19, a0)\n+\tSAVE_FP_REG (fs4,  20, a0)\n+\tSAVE_FP_REG (fs5,  21, a0)\n+\tSAVE_FP_REG (fs6,  22, a0)\n+\tSAVE_FP_REG (fs7,  23, a0)\n+\tSAVE_FP_REG (fs8,  24, a0)\n+\tSAVE_FP_REG (fs9,  25, a0)\n+\tSAVE_FP_REG (fs10, 26, a0)\n+\tSAVE_FP_REG (fs11, 27, a0)\n+\n+\tsw\ta1, MCONTEXT_FSR(a0)\n+#endif /* __riscv_float_abi_soft */\n+\n+/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */\n+\tli\ta3, _NSIG8\n+\tadd     a2, a0, UCONTEXT_SIGMASK\n+\tmv\ta1, zero\n+\tli\ta0, SIG_BLOCK\n+\n+\tli\ta7, SYS_ify (rt_sigprocmask)\n+\tscall\n+\tbltz\ta0, 99f\n+\n+\tret\n+\n+99:\tj\t__syscall_error\n+\n+PSEUDO_END (__getcontext)\n+\n+weak_alias (__getcontext, getcontext)\ndiff --git a/libc/sysdeps/linux/riscv64/makecontext.c b/libc/sysdeps/linux/riscv64/makecontext.c\nnew file mode 100644\nindex 000000000..9bd73cc67\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv64/makecontext.c\n@@ -0,0 +1,78 @@\n+/* Create new context.  RISC-V version.\n+   Copyright (C) 2001-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include <sysdep.h>\n+#include <sys/asm.h>\n+#include <sys/ucontext.h>\n+#include <stdarg.h>\n+#include <assert.h>\n+\n+void\n+__makecontext (ucontext_t *ucp, void (*func) (void), int argc,\n+\t       long int a0, long int a1, long int a2, long int a3, long int a4,\n+\t       ...)\n+{\n+  extern void __start_context (void) attribute_hidden;\n+  long int i, sp;\n+\n+  _Static_assert (REG_NARGS == 8, \"__makecontext assumes 8 argument registers\");\n+\n+  /* Set up the stack.  */\n+  sp = ((long int) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ALMASK;\n+\n+  /* Set up the register context.\n+     ra = s0 = 0, terminating the stack for backtracing purposes.\n+     s1 = the function we must call.\n+     s2 = the subsequent context to run.  */\n+  ucp->uc_mcontext.__gregs[REG_RA] = 0;\n+  ucp->uc_mcontext.__gregs[REG_S0] = 0;\n+  ucp->uc_mcontext.__gregs[REG_S1] = (long int) func;\n+  ucp->uc_mcontext.__gregs[REG_S2] = (long int) ucp->uc_link;\n+  ucp->uc_mcontext.__gregs[REG_SP] = sp;\n+  ucp->uc_mcontext.__gregs[REG_PC] = (long int) &__start_context;\n+\n+  /* Put args in a0-a7, then put any remaining args on the stack.  */\n+  ucp->uc_mcontext.__gregs[REG_A0 + 0] = a0;\n+  ucp->uc_mcontext.__gregs[REG_A0 + 1] = a1;\n+  ucp->uc_mcontext.__gregs[REG_A0 + 2] = a2;\n+  ucp->uc_mcontext.__gregs[REG_A0 + 3] = a3;\n+  ucp->uc_mcontext.__gregs[REG_A0 + 4] = a4;\n+\n+  if (unlikely(argc > 5))\n+    {\n+      va_list vl;\n+      va_start (vl, a4);\n+\n+      long reg_args = argc < REG_NARGS ? argc : REG_NARGS;\n+      for (i = 5; i < reg_args; i++)\n+        ucp->uc_mcontext.__gregs[REG_A0 + i] = va_arg (vl, long);\n+\n+      long int stack_args = argc - reg_args;\n+      if (stack_args > 0)\n+\t{\n+\t  sp = (sp - stack_args * sizeof (long int)) & ALMASK;\n+\t  ucp->uc_mcontext.__gregs[REG_SP] = sp;\n+\t  for (i = 0; i < stack_args; i++)\n+\t    ((long int *) sp)[i] = va_arg (vl, long int);\n+\t}\n+\n+      va_end (vl);\n+    }\n+}\n+\n+weak_alias (__makecontext, makecontext)\ndiff --git a/libc/sysdeps/linux/riscv64/setcontext.S b/libc/sysdeps/linux/riscv64/setcontext.S\nnew file mode 100644\nindex 000000000..9f1c7b41f\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv64/setcontext.S\n@@ -0,0 +1,114 @@\n+/* Set current context.\n+   Copyright (C) 2009-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"ucontext-macros.h\"\n+\n+/*  int __setcontext (const ucontext_t *ucp)\n+\n+  Restores the machine context in UCP and thereby resumes execution\n+  in that context.\n+\n+  This implementation is intended to be used for *synchronous* context\n+  switches only.  Therefore, it does not have to restore anything\n+  other than the PRESERVED state.  */\n+\n+\t.text\n+LEAF (__setcontext)\n+\n+\tmv\tt0, a0\t/* Save ucp into t0.  */\n+\n+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */\n+\tli\ta3, _NSIG8\n+\tmv\ta2, zero\n+\tadd     a1, a0, UCONTEXT_SIGMASK\n+\tli\ta0, SIG_SETMASK\n+\n+\tli\ta7, SYS_ify (rt_sigprocmask)\n+\tscall\n+\n+\tbltz\ta0, 99f\n+\n+\tcfi_def_cfa (t0, 0)\n+\n+#ifndef __riscv_float_abi_soft\n+\tlw\tt1, MCONTEXT_FSR(t0)\n+\n+\tRESTORE_FP_REG_CFI (fs0,   8, t0)\n+\tRESTORE_FP_REG_CFI (fs1,   9, t0)\n+\tRESTORE_FP_REG_CFI (fs2,  18, t0)\n+\tRESTORE_FP_REG_CFI (fs3,  19, t0)\n+\tRESTORE_FP_REG_CFI (fs4,  20, t0)\n+\tRESTORE_FP_REG_CFI (fs5,  21, t0)\n+\tRESTORE_FP_REG_CFI (fs6,  22, t0)\n+\tRESTORE_FP_REG_CFI (fs7,  23, t0)\n+\tRESTORE_FP_REG_CFI (fs8,  24, t0)\n+\tRESTORE_FP_REG_CFI (fs9,  25, t0)\n+\tRESTORE_FP_REG_CFI (fs10, 26, t0)\n+\tRESTORE_FP_REG_CFI (fs11, 27, t0)\n+\n+\tfssr\tt1\n+#endif /* __riscv_float_abi_soft */\n+\n+\t/* Note the contents of argument registers will be random\n+\t   unless makecontext() has been called.  */\n+\tRESTORE_INT_REG     (t1,   0, t0)\n+\tRESTORE_INT_REG_CFI (ra,   1, t0)\n+\tRESTORE_INT_REG     (sp,   2, t0)\n+\tRESTORE_INT_REG_CFI (s0,   8, t0)\n+\tRESTORE_INT_REG_CFI (s1,   9, t0)\n+\tRESTORE_INT_REG     (a0,  10, t0)\n+\tRESTORE_INT_REG     (a1,  11, t0)\n+\tRESTORE_INT_REG     (a2,  12, t0)\n+\tRESTORE_INT_REG     (a3,  13, t0)\n+\tRESTORE_INT_REG     (a4,  14, t0)\n+\tRESTORE_INT_REG     (a5,  15, t0)\n+\tRESTORE_INT_REG     (a6,  16, t0)\n+\tRESTORE_INT_REG     (a7,  17, t0)\n+\tRESTORE_INT_REG_CFI (s2,  18, t0)\n+\tRESTORE_INT_REG_CFI (s3,  19, t0)\n+\tRESTORE_INT_REG_CFI (s4,  20, t0)\n+\tRESTORE_INT_REG_CFI (s5,  21, t0)\n+\tRESTORE_INT_REG_CFI (s6,  22, t0)\n+\tRESTORE_INT_REG_CFI (s7,  23, t0)\n+\tRESTORE_INT_REG_CFI (s8,  24, t0)\n+\tRESTORE_INT_REG_CFI (s9,  25, t0)\n+\tRESTORE_INT_REG_CFI (s10, 26, t0)\n+\tRESTORE_INT_REG_CFI (s11, 27, t0)\n+\n+\tjr\tt1\n+\n+99:\tj\t__syscall_error\n+\n+PSEUDO_END (__setcontext)\n+weak_alias (__setcontext, setcontext)\n+\n+LEAF (__start_context)\n+\n+\t/* Terminate call stack by noting ra == 0.  Happily, s0 == 0 here.  */\n+\tcfi_register (ra, s0)\n+\n+\t/* Call the function passed to makecontext.  */\n+\tjalr\ts1\n+\n+\t/* Invoke subsequent context if present, else exit(0).  */\n+\tmv\ta0, s2\n+\tbeqz\ts2, 1f\n+\tjal\t__setcontext\n+1:\tj\texit\n+\n+PSEUDO_END (__start_context)\ndiff --git a/libc/sysdeps/linux/riscv64/swapcontext.S b/libc/sysdeps/linux/riscv64/swapcontext.S\nnew file mode 100644\nindex 000000000..75b58dc66\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv64/swapcontext.S\n@@ -0,0 +1,125 @@\n+/* Save and set current context.\n+   Copyright (C) 2009-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"ucontext-macros.h\"\n+\n+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */\n+\n+LEAF (__swapcontext)\n+\tmv\tt0, a1\t\t\t/* Save ucp into t0.  */\n+\n+\tSAVE_INT_REG (ra,   0, a0)\n+\tSAVE_INT_REG (ra,   1, a0)\n+\tSAVE_INT_REG (sp,   2, a0)\n+\tSAVE_INT_REG (s0,   8, a0)\n+\tSAVE_INT_REG (s1,   9, a0)\n+\tSAVE_INT_REG (x0,  10, a0)\t/* return 0 by overwriting a0.  */\n+\tSAVE_INT_REG (s2,  18, a0)\n+\tSAVE_INT_REG (s3,  19, a0)\n+\tSAVE_INT_REG (s4,  20, a0)\n+\tSAVE_INT_REG (s5,  21, a0)\n+\tSAVE_INT_REG (s6,  22, a0)\n+\tSAVE_INT_REG (s7,  23, a0)\n+\tSAVE_INT_REG (s8,  24, a0)\n+\tSAVE_INT_REG (s9,  25, a0)\n+\tSAVE_INT_REG (s10, 26, a0)\n+\tSAVE_INT_REG (s11, 27, a0)\n+\n+#ifndef __riscv_float_abi_soft\n+\tfrsr a1\n+\n+\tSAVE_FP_REG (fs0,   8, a0)\n+\tSAVE_FP_REG (fs1,   9, a0)\n+\tSAVE_FP_REG (fs2,  18, a0)\n+\tSAVE_FP_REG (fs3,  19, a0)\n+\tSAVE_FP_REG (fs4,  20, a0)\n+\tSAVE_FP_REG (fs5,  21, a0)\n+\tSAVE_FP_REG (fs6,  22, a0)\n+\tSAVE_FP_REG (fs7,  23, a0)\n+\tSAVE_FP_REG (fs8,  24, a0)\n+\tSAVE_FP_REG (fs9,  25, a0)\n+\tSAVE_FP_REG (fs10, 26, a0)\n+\tSAVE_FP_REG (fs11, 27, a0)\n+\n+\tsw\ta1, MCONTEXT_FSR(a0)\n+#endif /* __riscv_float_abi_soft */\n+\n+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */\n+\tli\ta3, _NSIG8\n+\tadd\ta2, a0, UCONTEXT_SIGMASK\n+\tadd     a1, t0, UCONTEXT_SIGMASK\n+\tli\ta0, SIG_SETMASK\n+\n+\tli\ta7, SYS_ify (rt_sigprocmask)\n+\tscall\n+\n+\tbltz\ta0, 99f\n+\n+#ifndef __riscv_float_abi_soft\n+\tlw\tt1, MCONTEXT_FSR(t0)\n+\n+\tRESTORE_FP_REG (fs0,   8, t0)\n+\tRESTORE_FP_REG (fs1,   9, t0)\n+\tRESTORE_FP_REG (fs2,  18, t0)\n+\tRESTORE_FP_REG (fs3,  19, t0)\n+\tRESTORE_FP_REG (fs4,  20, t0)\n+\tRESTORE_FP_REG (fs5,  21, t0)\n+\tRESTORE_FP_REG (fs6,  22, t0)\n+\tRESTORE_FP_REG (fs7,  23, t0)\n+\tRESTORE_FP_REG (fs8,  24, t0)\n+\tRESTORE_FP_REG (fs9,  25, t0)\n+\tRESTORE_FP_REG (fs10, 26, t0)\n+\tRESTORE_FP_REG (fs11, 27, t0)\n+\n+\tfssr\tt1\n+#endif /* __riscv_float_abi_soft */\n+\n+\t/* Note the contents of argument registers will be random\n+\t   unless makecontext() has been called.  */\n+\tRESTORE_INT_REG (t1,   0, t0)\n+\tRESTORE_INT_REG (ra,   1, t0)\n+\tRESTORE_INT_REG (sp,   2, t0)\n+\tRESTORE_INT_REG (s0,   8, t0)\n+\tRESTORE_INT_REG (s1,   9, t0)\n+\tRESTORE_INT_REG (a0,  10, t0)\n+\tRESTORE_INT_REG (a1,  11, t0)\n+\tRESTORE_INT_REG (a2,  12, t0)\n+\tRESTORE_INT_REG (a3,  13, t0)\n+\tRESTORE_INT_REG (a4,  14, t0)\n+\tRESTORE_INT_REG (a5,  15, t0)\n+\tRESTORE_INT_REG (a6,  16, t0)\n+\tRESTORE_INT_REG (a7,  17, t0)\n+\tRESTORE_INT_REG (s2,  18, t0)\n+\tRESTORE_INT_REG (s3,  19, t0)\n+\tRESTORE_INT_REG (s4,  20, t0)\n+\tRESTORE_INT_REG (s5,  21, t0)\n+\tRESTORE_INT_REG (s6,  22, t0)\n+\tRESTORE_INT_REG (s7,  23, t0)\n+\tRESTORE_INT_REG (s8,  24, t0)\n+\tRESTORE_INT_REG (s9,  25, t0)\n+\tRESTORE_INT_REG (s10, 26, t0)\n+\tRESTORE_INT_REG (s11, 27, t0)\n+\n+\tjr\tt1\n+\n+\n+99:\tj\t__syscall_error\n+\n+PSEUDO_END (__swapcontext)\n+\n+weak_alias (__swapcontext, swapcontext)\ndiff --git a/libc/sysdeps/linux/riscv64/ucontext-macros.h b/libc/sysdeps/linux/riscv64/ucontext-macros.h\nnew file mode 100644\nindex 000000000..a73c3a9b0\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv64/ucontext-macros.h\n@@ -0,0 +1,49 @@\n+/* Macros for ucontext routines.\n+   Copyright (C) 2017-2018 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library.  If not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#ifndef _LINUX_RISCV_UCONTEXT_MACROS_H\n+#define _LINUX_RISCV_UCONTEXT_MACROS_H\n+\n+#include <sysdep.h>\n+#include <sys/asm.h>\n+\n+#include \"ucontext_i.h\"\n+\n+#define MCONTEXT_FSR (32 * SZFREG + MCONTEXT_FPREGS)\n+\n+#define SAVE_FP_REG(name, num, base)\t\t\t\\\n+  FREG_S name, ((num) * SZFREG + MCONTEXT_FPREGS)(base)\n+\n+#define RESTORE_FP_REG(name, num, base)\t\t\t\\\n+  FREG_L name, ((num) * SZFREG + MCONTEXT_FPREGS)(base)\n+\n+#define RESTORE_FP_REG_CFI(name, num, base)\t\t\\\n+  RESTORE_FP_REG (name, num, base);\t\t\t\\\n+  cfi_offset (name, (num) * SZFREG + MCONTEXT_FPREGS)\n+\n+#define SAVE_INT_REG(name, num, base)\t\t\t\\\n+  REG_S name, ((num) * SZREG + MCONTEXT_GREGS)(base)\n+\n+#define RESTORE_INT_REG(name, num, base)\t\t\\\n+  REG_L name, ((num) * SZREG + MCONTEXT_GREGS)(base)\n+\n+#define RESTORE_INT_REG_CFI(name, num, base)\t\t\\\n+  RESTORE_INT_REG (name, num, base);\t\t\t\\\n+  cfi_offset (name, (num) * SZREG + MCONTEXT_GREGS)\n+\n+#endif /* _LINUX_RISCV_UCONTEXT_MACROS_H */\ndiff --git a/libc/sysdeps/linux/riscv64/ucontext_i.sym b/libc/sysdeps/linux/riscv64/ucontext_i.sym\nnew file mode 100644\nindex 000000000..be55b2631\n--- /dev/null\n+++ b/libc/sysdeps/linux/riscv64/ucontext_i.sym\n@@ -0,0 +1,31 @@\n+#include <inttypes.h>\n+#include <signal.h>\n+#include <stddef.h>\n+#include <sys/ucontext.h>\n+\n+-- Constants used by the rt_sigprocmask call.\n+\n+SIG_BLOCK\n+SIG_SETMASK\n+\n+_NSIG8\t\t\t\t(_NSIG / 8)\n+\n+-- Offsets of the fields in the ucontext_t structure.\n+#define ucontext(member)\toffsetof (ucontext_t, member)\n+#define stack(member)\t\tucontext (uc_stack.member)\n+#define mcontext(member)\tucontext (uc_mcontext.member)\n+\n+UCONTEXT_FLAGS\t\t\tucontext (__uc_flags)\n+UCONTEXT_LINK\t\t\tucontext (uc_link)\n+UCONTEXT_STACK\t\t\tucontext (uc_stack)\n+UCONTEXT_MCONTEXT\t\tucontext (uc_mcontext)\n+UCONTEXT_SIGMASK\t\tucontext (uc_sigmask)\n+\n+STACK_SP\t\t\tstack (ss_sp)\n+STACK_SIZE\t\t\tstack (ss_size)\n+STACK_FLAGS\t\t\tstack (ss_flags)\n+\n+MCONTEXT_GREGS\t\t\tmcontext (__gregs)\n+MCONTEXT_FPREGS\t\t\tmcontext (__fpregs)\n+\n+UCONTEXT_SIZE\t\t\tsizeof (ucontext_t)\n","prefixes":["uclibc-ng-devel","v1","3/3"]}