[RFC,3/5] RISC-V: Save and restore VCSR when doing user context switch
Checks
Context |
Check |
Description |
dj/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
Commit Message
According to the RISC-V V extension specification, all vector registers
except VCSR are caller-saved registers. The VCSR (vxrm + vxsat) has thread
storage duration. Therefore, only VCSR needs to be added to the user
context operation.
---
sysdeps/riscv/Makefile | 5 ++++
sysdeps/riscv/rtld-global-offsets.sym | 7 +++++
sysdeps/unix/sysv/linux/riscv/bits/hwcap.h | 31 +++++++++++++++++++++
sysdeps/unix/sysv/linux/riscv/getcontext.S | 22 ++++++++++++++-
sysdeps/unix/sysv/linux/riscv/setcontext.S | 22 +++++++++++++++
sysdeps/unix/sysv/linux/riscv/swapcontext.S | 41 ++++++++++++++++++++++++++++
sysdeps/unix/sysv/linux/riscv/sysdep.h | 1 +
sysdeps/unix/sysv/linux/riscv/ucontext_i.sym | 6 ++++
8 files changed, 134 insertions(+), 1 deletion(-)
create mode 100644 sysdeps/riscv/rtld-global-offsets.sym
create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/hwcap.h
Comments
On Mon, 13 Sep 2021, Vincent Chen wrote:
> According to the RISC-V V extension specification, all vector registers
> except VCSR are caller-saved registers. The VCSR (vxrm + vxsat) has thread
> storage duration. Therefore, only VCSR needs to be added to the user
> context operation.
What is the intended programming model for using vxrm and vxsat?
The expectation for the floating-point rounding modes and flags is that
they work just like user-defined _Thread_local variables - that is, they
are *not* saved or restored by setjmp/longjmp or *context functions. It
would be natural to expect fixed-point rounding modes and flags to work
similarly.
On Tue, Sep 14, 2021 at 4:48 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Mon, 13 Sep 2021, Vincent Chen wrote:
>
> > According to the RISC-V V extension specification, all vector registers
> > except VCSR are caller-saved registers. The VCSR (vxrm + vxsat) has thread
> > storage duration. Therefore, only VCSR needs to be added to the user
> > context operation.
>
> What is the intended programming model for using vxrm and vxsat?
>
> The expectation for the floating-point rounding modes and flags is that
> they work just like user-defined _Thread_local variables - that is, they
> are *not* saved or restored by setjmp/longjmp or *context functions. It
> would be natural to expect fixed-point rounding modes and flags to work
> similarly.
Indeed, Joseph, vxsat and vxrm should be treated analogously to the FP
flags and rounding mode, respectively.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
On Wed, Sep 15, 2021 at 8:13 AM Andrew Waterman <andrew@sifive.com> wrote:
>
> On Tue, Sep 14, 2021 at 4:48 PM Joseph Myers <joseph@codesourcery.com> wrote:
> >
> > On Mon, 13 Sep 2021, Vincent Chen wrote:
> >
> > > According to the RISC-V V extension specification, all vector registers
> > > except VCSR are caller-saved registers. The VCSR (vxrm + vxsat) has thread
> > > storage duration. Therefore, only VCSR needs to be added to the user
> > > context operation.
> >
> > What is the intended programming model for using vxrm and vxsat?
> >
> > The expectation for the floating-point rounding modes and flags is that
> > they work just like user-defined _Thread_local variables - that is, they
> > are *not* saved or restored by setjmp/longjmp or *context functions. It
> > would be natural to expect fixed-point rounding modes and flags to work
> > similarly.
>
> Indeed, Joseph, vxsat and vxrm should be treated analogously to the FP
> flags and rounding mode, respectively.
>
OK, I understood. As Andrew mentioned, the vxsat and vxrm should be
treated analogously to the FP flags and rounding mode. Therefore, the
VCSR should not be saved and restored in *context functions. I think
this patch can be dropped in the next version patch. Thank Joseph and
Andrew for the kind reply.
Thanks,
Vincent
> >
> > --
> > Joseph S. Myers
> > joseph@codesourcery.com
On 12/09/2021 22:41, Vincent Chen wrote:
> According to the RISC-V V extension specification, all vector registers
> except VCSR are caller-saved registers. The VCSR (vxrm + vxsat) has thread
> storage duration. Therefore, only VCSR needs to be added to the user
> context operation.
> ---
> sysdeps/riscv/Makefile | 5 ++++
> sysdeps/riscv/rtld-global-offsets.sym | 7 +++++
> sysdeps/unix/sysv/linux/riscv/bits/hwcap.h | 31 +++++++++++++++++++++
> sysdeps/unix/sysv/linux/riscv/getcontext.S | 22 ++++++++++++++-
> sysdeps/unix/sysv/linux/riscv/setcontext.S | 22 +++++++++++++++
> sysdeps/unix/sysv/linux/riscv/swapcontext.S | 41 ++++++++++++++++++++++++++++
> sysdeps/unix/sysv/linux/riscv/sysdep.h | 1 +
> sysdeps/unix/sysv/linux/riscv/ucontext_i.sym | 6 ++++
> 8 files changed, 134 insertions(+), 1 deletion(-)
> create mode 100644 sysdeps/riscv/rtld-global-offsets.sym
> create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/hwcap.h
>
> diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile
> index 20a9968..cda3ded 100644
> --- a/sysdeps/riscv/Makefile
> +++ b/sysdeps/riscv/Makefile
> @@ -2,6 +2,11 @@ ifeq ($(subdir),misc)
> sysdep_headers += sys/asm.h
> endif
>
> +ifeq ($(subdir),csu)
> +# get offset to rtld_global._dl_hwcap and rtld_global._dl_hwcap2.
> +gen-as-const-headers += rtld-global-offsets.sym
> +endif
> +
> # RISC-V's assembler also needs to know about PIC as it changes the definition
> # of some assembler macros.
> ASFLAGS-.os += $(pic-ccflag)
> diff --git a/sysdeps/riscv/rtld-global-offsets.sym b/sysdeps/riscv/rtld-global-offsets.sym
> new file mode 100644
> index 0000000..ff4e97f
> --- /dev/null
> +++ b/sysdeps/riscv/rtld-global-offsets.sym
> @@ -0,0 +1,7 @@
> +#define SHARED 1
> +
> +#include <ldsodefs.h>
> +
> +#define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem)
> +
> +RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtld_global_ro_offsetof (_dl_hwcap)
> diff --git a/sysdeps/unix/sysv/linux/riscv/bits/hwcap.h b/sysdeps/unix/sysv/linux/riscv/bits/hwcap.h
> new file mode 100644
> index 0000000..e6c5ef5
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/bits/hwcap.h
> @@ -0,0 +1,31 @@
> +/* Defines for bits in AT_HWCAP. RISC-V Linux version.
> + Copyright (C) 2021 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#if !defined (_SYS_AUXV_H) && !defined (_LINUX_RISCV_SYSDEP_H)
_LINUX_RISCV_SYSDEP_H is defined by an internal header only, so I
think it should no be referenced by an exported one.
> +# error "Never include <bits/hwcap.h> directly; use <sys/auxv.h> instead."
> +#endif
> +
> +/* The following must match the kernel's <asm/hwcap.h>. */
> +#define HWCAP_ISA_I 0x100 //(1 << ('I' - 'A'))
> +#define HWCAP_ISA_M 0x1000 //(1 << ('M' - 'A'))
> +#define HWCAP_ISA_A 0x1 //(1 << ('A' - 'A'))
> +#define HWCAP_ISA_F 0x20 //(1 << ('F' - 'A'))
> +#define HWCAP_ISA_D 0x8 //(1 << ('D' - 'A'))
> +#define HWCAP_ISA_C 0x4 //(1 << ('C' - 'A'))
> +#define HWCAP_ISA_V 0x200000 //(1 << ('V' - 'A'))
> +
> diff --git a/sysdeps/unix/sysv/linux/riscv/getcontext.S b/sysdeps/unix/sysv/linux/riscv/getcontext.S
> index d6a9bbc..840d8fe 100644
> --- a/sysdeps/unix/sysv/linux/riscv/getcontext.S
> +++ b/sysdeps/unix/sysv/linux/riscv/getcontext.S
> @@ -16,6 +16,8 @@
> License along with the GNU C Library. If not, see
> <https://www.gnu.org/licenses/>. */
>
> +#include <sysdep.h>
> +#include <rtld-global-offsets.h>
> #include "ucontext-macros.h"
>
> /* int getcontext (ucontext_t *ucp) */
> @@ -39,6 +41,25 @@ LEAF (__getcontext)
> SAVE_INT_REG (s10, 26, a0)
> SAVE_INT_REG (s11, 27, a0)
>
> +#ifdef __riscv_vector
I take '__riscv_vector' would be defined by the compiler (although there is
no gcc support yet). Why do you need to build iff vector extension is being
use if you are checking the hwcap?
For __riscv_float_abi_soft it does make sense since 'frsr' will be issue
regardless.
> +# ifdef SHARED
> + la t1, _rtld_global_ro
> + REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1)
> +# else
> + la t1, _dl_hwcap
> + REG_L t1, (t1)
> +# endif
> + li t2, HWCAP_ISA_V
> + and t2, t1, t2
> + beqz t2, 1f
> + addi t2, a0, MCONTEXT_EXTENSION
> + li t1, RVV_MAGIC
> + sw t1, (t2)
> + csrr t1, vcsr
> + REG_S t1, VCSR_OFFSET(t2)
> +1:
> +#endif
> +
> #ifndef __riscv_float_abi_soft
> frsr a1
>
> @@ -73,5 +94,4 @@ LEAF (__getcontext)
> 99: j __syscall_error
>
> PSEUDO_END (__getcontext)
> -
> weak_alias (__getcontext, getcontext)
> diff --git a/sysdeps/unix/sysv/linux/riscv/setcontext.S b/sysdeps/unix/sysv/linux/riscv/setcontext.S
> index 9510518..d2404fb 100644
> --- a/sysdeps/unix/sysv/linux/riscv/setcontext.S
> +++ b/sysdeps/unix/sysv/linux/riscv/setcontext.S
> @@ -16,6 +16,8 @@
> License along with the GNU C Library. If not, see
> <https://www.gnu.org/licenses/>. */
>
> +#include <sysdep.h>
> +#include <rtld-global-offsets.h>
> #include "ucontext-macros.h"
>
> /* int __setcontext (const ucontext_t *ucp)
> @@ -64,6 +66,26 @@ LEAF (__setcontext)
> fssr t1
> #endif /* __riscv_float_abi_soft */
>
> +#ifdef __riscv_vector
> +#ifdef SHARED
> + la t1, _rtld_global_ro
> + REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1)
> +#else
> + la t1, _dl_hwcap
> + REG_L t1, (t1)
> +#endif
> + li t2, HWCAP_ISA_V
> + and t2, t1, t2
> + beqz t2, 1f
> + li t1, RVV_MAGIC
> + addi t2, t0, MCONTEXT_EXTENSION
> + lw a1, (t2)
> + bne a1, t1, 1f
> + REG_L t1, VCSR_OFFSET(t2)
> + csrw vcsr, t1
> +1:
> +#endif
> +
> /* Note the contents of argument registers will be random
> unless makecontext() has been called. */
> RESTORE_INT_REG (t1, 0, t0)
> diff --git a/sysdeps/unix/sysv/linux/riscv/swapcontext.S b/sysdeps/unix/sysv/linux/riscv/swapcontext.S
> index df0f699..94ae8e4 100644
> --- a/sysdeps/unix/sysv/linux/riscv/swapcontext.S
> +++ b/sysdeps/unix/sysv/linux/riscv/swapcontext.S
> @@ -16,6 +16,8 @@
> License along with the GNU C Library. If not, see
> <https://www.gnu.org/licenses/>. */
>
> +#include <sysdep.h>
> +#include <rtld-global-offsets.h>
> #include "ucontext-macros.h"
>
> /* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
> @@ -40,6 +42,25 @@ LEAF (__swapcontext)
> SAVE_INT_REG (s10, 26, a0)
> SAVE_INT_REG (s11, 27, a0)
>
> +#ifdef __riscv_vector
> +#ifdef SHARED
> + la t1, _rtld_global_ro
> + REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1)
> +#else
> + la t1, _dl_hwcap
> + REG_L t1, (t1)
> +#endif
> + li t2, HWCAP_ISA_V
> + and t2, t1, t2
> + beqz t2, 1f
> + addi t2, a0, MCONTEXT_EXTENSION
> + li t1, RVV_MAGIC
> + sw t1, (t2)
> + csrr t1, vcsr
> + REG_S t1, VCSR_OFFSET(t2)
> +1:
> +#endif
> +
> #ifndef __riscv_float_abi_soft
> frsr a1
>
> @@ -89,6 +110,26 @@ LEAF (__swapcontext)
> fssr t1
> #endif /* __riscv_float_abi_soft */
>
> +#ifdef __riscv_vector
> +#ifdef SHARED
> + la t1, _rtld_global_ro
> + REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1)
> +#else
> + la t1, _dl_hwcap
> + REG_L t1, (t1)
> +#endif
> + li t2, HWCAP_ISA_V
> + and t2, t1, t2
> + beqz t2, 1f
> + li t1, RVV_MAGIC
> + addi t2, t0, MCONTEXT_EXTENSION
> + lw a1, (t2)
> + bne a1, t1, 1f
> + REG_L t1, VCSR_OFFSET(t2)
> + csrw vcsr, t1
> +1:
> +#endif
> +
> /* Note the contents of argument registers will be random
> unless makecontext() has been called. */
> RESTORE_INT_REG (t1, 0, t0)
> diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h
> index 37ff07a..c9f8fd8 100644
> --- a/sysdeps/unix/sysv/linux/riscv/sysdep.h
> +++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
> @@ -50,6 +50,7 @@
>
> #ifdef __ASSEMBLER__
>
> +# include <bits/hwcap.h>
> # include <sys/asm.h>
>
> # define ENTRY(name) LEAF(name)
> diff --git a/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym
> index be55b26..4037473 100644
> --- a/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym
> +++ b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym
> @@ -2,6 +2,7 @@
> #include <signal.h>
> #include <stddef.h>
> #include <sys/ucontext.h>
> +#include <asm/sigcontext.h>
>
> -- Constants used by the rt_sigprocmask call.
>
> @@ -27,5 +28,10 @@ STACK_FLAGS stack (ss_flags)
>
> MCONTEXT_GREGS mcontext (__gregs)
> MCONTEXT_FPREGS mcontext (__fpregs)
> +MCONTEXT_EXTENSION mcontext (__reserved)
>
> UCONTEXT_SIZE sizeof (ucontext_t)
> +
> +VCSR_OFFSET offsetof (struct __riscv_v_state, vcsr)
> +
> +RVV_MAGIC
>
@@ -2,6 +2,11 @@ ifeq ($(subdir),misc)
sysdep_headers += sys/asm.h
endif
+ifeq ($(subdir),csu)
+# get offset to rtld_global._dl_hwcap and rtld_global._dl_hwcap2.
+gen-as-const-headers += rtld-global-offsets.sym
+endif
+
# RISC-V's assembler also needs to know about PIC as it changes the definition
# of some assembler macros.
ASFLAGS-.os += $(pic-ccflag)
new file mode 100644
@@ -0,0 +1,7 @@
+#define SHARED 1
+
+#include <ldsodefs.h>
+
+#define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem)
+
+RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtld_global_ro_offsetof (_dl_hwcap)
new file mode 100644
@@ -0,0 +1,31 @@
+/* Defines for bits in AT_HWCAP. RISC-V Linux version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#if !defined (_SYS_AUXV_H) && !defined (_LINUX_RISCV_SYSDEP_H)
+# error "Never include <bits/hwcap.h> directly; use <sys/auxv.h> instead."
+#endif
+
+/* The following must match the kernel's <asm/hwcap.h>. */
+#define HWCAP_ISA_I 0x100 //(1 << ('I' - 'A'))
+#define HWCAP_ISA_M 0x1000 //(1 << ('M' - 'A'))
+#define HWCAP_ISA_A 0x1 //(1 << ('A' - 'A'))
+#define HWCAP_ISA_F 0x20 //(1 << ('F' - 'A'))
+#define HWCAP_ISA_D 0x8 //(1 << ('D' - 'A'))
+#define HWCAP_ISA_C 0x4 //(1 << ('C' - 'A'))
+#define HWCAP_ISA_V 0x200000 //(1 << ('V' - 'A'))
+
@@ -16,6 +16,8 @@
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
#include "ucontext-macros.h"
/* int getcontext (ucontext_t *ucp) */
@@ -39,6 +41,25 @@ LEAF (__getcontext)
SAVE_INT_REG (s10, 26, a0)
SAVE_INT_REG (s11, 27, a0)
+#ifdef __riscv_vector
+# ifdef SHARED
+ la t1, _rtld_global_ro
+ REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1)
+# else
+ la t1, _dl_hwcap
+ REG_L t1, (t1)
+# endif
+ li t2, HWCAP_ISA_V
+ and t2, t1, t2
+ beqz t2, 1f
+ addi t2, a0, MCONTEXT_EXTENSION
+ li t1, RVV_MAGIC
+ sw t1, (t2)
+ csrr t1, vcsr
+ REG_S t1, VCSR_OFFSET(t2)
+1:
+#endif
+
#ifndef __riscv_float_abi_soft
frsr a1
@@ -73,5 +94,4 @@ LEAF (__getcontext)
99: j __syscall_error
PSEUDO_END (__getcontext)
-
weak_alias (__getcontext, getcontext)
@@ -16,6 +16,8 @@
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
#include "ucontext-macros.h"
/* int __setcontext (const ucontext_t *ucp)
@@ -64,6 +66,26 @@ LEAF (__setcontext)
fssr t1
#endif /* __riscv_float_abi_soft */
+#ifdef __riscv_vector
+#ifdef SHARED
+ la t1, _rtld_global_ro
+ REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1)
+#else
+ la t1, _dl_hwcap
+ REG_L t1, (t1)
+#endif
+ li t2, HWCAP_ISA_V
+ and t2, t1, t2
+ beqz t2, 1f
+ li t1, RVV_MAGIC
+ addi t2, t0, MCONTEXT_EXTENSION
+ lw a1, (t2)
+ bne a1, t1, 1f
+ REG_L t1, VCSR_OFFSET(t2)
+ csrw vcsr, t1
+1:
+#endif
+
/* Note the contents of argument registers will be random
unless makecontext() has been called. */
RESTORE_INT_REG (t1, 0, t0)
@@ -16,6 +16,8 @@
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
#include "ucontext-macros.h"
/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
@@ -40,6 +42,25 @@ LEAF (__swapcontext)
SAVE_INT_REG (s10, 26, a0)
SAVE_INT_REG (s11, 27, a0)
+#ifdef __riscv_vector
+#ifdef SHARED
+ la t1, _rtld_global_ro
+ REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1)
+#else
+ la t1, _dl_hwcap
+ REG_L t1, (t1)
+#endif
+ li t2, HWCAP_ISA_V
+ and t2, t1, t2
+ beqz t2, 1f
+ addi t2, a0, MCONTEXT_EXTENSION
+ li t1, RVV_MAGIC
+ sw t1, (t2)
+ csrr t1, vcsr
+ REG_S t1, VCSR_OFFSET(t2)
+1:
+#endif
+
#ifndef __riscv_float_abi_soft
frsr a1
@@ -89,6 +110,26 @@ LEAF (__swapcontext)
fssr t1
#endif /* __riscv_float_abi_soft */
+#ifdef __riscv_vector
+#ifdef SHARED
+ la t1, _rtld_global_ro
+ REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1)
+#else
+ la t1, _dl_hwcap
+ REG_L t1, (t1)
+#endif
+ li t2, HWCAP_ISA_V
+ and t2, t1, t2
+ beqz t2, 1f
+ li t1, RVV_MAGIC
+ addi t2, t0, MCONTEXT_EXTENSION
+ lw a1, (t2)
+ bne a1, t1, 1f
+ REG_L t1, VCSR_OFFSET(t2)
+ csrw vcsr, t1
+1:
+#endif
+
/* Note the contents of argument registers will be random
unless makecontext() has been called. */
RESTORE_INT_REG (t1, 0, t0)
@@ -50,6 +50,7 @@
#ifdef __ASSEMBLER__
+# include <bits/hwcap.h>
# include <sys/asm.h>
# define ENTRY(name) LEAF(name)
@@ -2,6 +2,7 @@
#include <signal.h>
#include <stddef.h>
#include <sys/ucontext.h>
+#include <asm/sigcontext.h>
-- Constants used by the rt_sigprocmask call.
@@ -27,5 +28,10 @@ STACK_FLAGS stack (ss_flags)
MCONTEXT_GREGS mcontext (__gregs)
MCONTEXT_FPREGS mcontext (__fpregs)
+MCONTEXT_EXTENSION mcontext (__reserved)
UCONTEXT_SIZE sizeof (ucontext_t)
+
+VCSR_OFFSET offsetof (struct __riscv_v_state, vcsr)
+
+RVV_MAGIC