[RFC] riscv: add vectorized sin

Message ID 20260709105138.539304-1-pincheng.plct@isrc.iscas.ac.cn
State New
Headers
Series [RFC] riscv: add vectorized sin |

Commit Message

Pincheng Wang July 9, 2026, 10:51 a.m. UTC
  Hi all,

This revisits the earlier RFC on RVV-based vector math in newlib [1].
Back then one open question was that RISC-V had no vector function ABI
comparable to x86_64 and aarch64, so there was no agreed way to name
these routines. That is now settled: the name mangling rule was merged
into the psABI in June 2026 [2], so I would like to restart the
discussion with a concrete implementation to build on.

This is a first, self-contained patch: a single function, kept optional
and off by default, so we can settle the build integration and confirm
the ABI symbol naming before adding more of the sin/cos/exp/log set.

Add an RVV implementation of sin for double, exported under the vector
function ABI symbol _ZGVr1Nxv_sin (vfloat64m1_t) from the merged psABI
rule. This is the LMUL=1, unmasked, vector-length-agnostic variant a
compiler emits when vectorizing a scalar sin loop over doubles. Existing
scalar sin and the rest of libm are untouched.

The vector implementation does a Cody-Waite argument reduction with a
three-part pi/2 split and double-double error tracking, then evaluates
the fdlibm sin/cos kernel polynomials. Reduction and kernels are built
from discrete vfmul/vfadd/vfsub intrinsics so the compensated terms are
not lost to FMA contraction. Lanes too large for the fast reduction, as
well as Inf/NaN, fall back per-lane to the existing scalar Payne-Hanek
reducer __ieee754_rem_pio2, guarded by a vcpop so the common case stays
fully vectorized. The worst-case error is <= 1 ULP.

The whole thing is guarded by __riscv_vector, so it compiles to an empty
object on non-vector multilibs and relies on each multilib's own -march
otherwise, keeping the build multilib-safe. A new --enable-vecmath
switch (default off) decides whether the vectorized math is built at all;
configure and Makefile.in are regenerated accordingly. test_vec_sin.c is
a standalone check that walks all three paths and fails if any lane
exceeds 1 ULP; its large-argument reference values are precomputed in
test_vec_sin_bigref.h.

Reviews and suggestions are greatly welcomed!

Thanks,
Pincheng Wang

[1] https://sourceware.org/pipermail/newlib/2025/022175.html
[2] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/455

Signed-off-by: Pincheng Wang <pincheng.plct@isrc.iscas.ac.cn>
---
 newlib/Makefile.in                            |  71 +++--
 newlib/configure                              |  28 ++
 newlib/configure.ac                           |  16 +
 newlib/libm/machine/riscv/Makefile.inc        |   8 +
 newlib/libm/machine/riscv/test_vec_sin.c      | 288 ++++++++++++++++++
 .../libm/machine/riscv/test_vec_sin_bigref.h  | 250 +++++++++++++++
 newlib/libm/machine/riscv/vec_sin.c           | 219 +++++++++++++
 7 files changed, 857 insertions(+), 23 deletions(-)
 create mode 100644 newlib/libm/machine/riscv/test_vec_sin.c
 create mode 100644 newlib/libm/machine/riscv/test_vec_sin_bigref.h
 create mode 100644 newlib/libm/machine/riscv/vec_sin.c
  

Comments

Paul Zimmermann July 9, 2026, 12:02 p.m. UTC | #1
Dear Pincheng,

> The worst-case error is <= 1 ULP.

great! Is that observed or do you have a proof of this bound?
Did you try with inputs from [1] and [2]?

Note that it now exists some vector and correctly rounded implementations [3] and [4].

Paul

[1] https://gitlab.inria.fr/zimmerma/math_accuracy/-/blob/master/binary64/trig.wc
[2] https://gitlab.inria.fr/core-math/core-math/-/blob/master/src/binary64/sin/sin.wc
[3] https://www.arith2026.org/papers/Correctly%20rounded%20vector%20implementation%20of%20the%20exponential%20function%20in%20binary64%20arithmetic.pdf
[4] https://arxiv.org/pdf/2605.15547
  
Pincheng Wang July 10, 2026, 2:11 a.m. UTC | #2
Hi Paul,

On 2026/7/9 20:02, Paul Zimmermann wrote:
>> The worst-case error is <= 1 ULP.
> 
> great! Is that observed or do you have a proof of this bound?
> Did you try with inputs from [1] and [2]?
> 
> Note that it now exists some vector and correctly rounded implementations [3] and [4].
Thank you for the insightful questions. To be completely honest, the <= 
1 ULP bound was an observation rather than a proof. I arrived at this 
conclusion by testing the implementation with approximately 770,000 
samples (about 440,000 uniformly distributed random inputs across three 
code paths, plus roughly 300,000 random full-exponent-range bit 
patterns) against a 250-bit MPFR/mpmath reference. In those specific 
tests, no results exceeded 1 ULP.

However, after running the test cases you provided, I realized my 
initial assessment was incomplete. The maximum ULP errors are 0.931 and 
1.0 for trig.wc and sin.wc respectively. Specifically, 17 cases in 
sin.wc show a ULP error of exactly 1.0, and all of these cases fall into 
the slow path (where |x| >= 1e6).

Thank you also for sharing those papers; they serve as excellent 
references for improving my implementation. I have also noticed that 
some open-source libraries, such as SLEEF [1], claim to achieve <= 1 ULP 
accuracy. Before formally submitting the patch, I will continue to study 
these resources and further refine the accuracy of my implementation, 
while ensuring license compatibility.

Thank you very much for your valuable feedback and guidance.

BR,
Pincheng Wang

[1] https://sleef.org/
  

Patch

diff --git a/newlib/Makefile.in b/newlib/Makefile.in
index 5d1b1acb5..ec50acc8e 100644
--- a/newlib/Makefile.in
+++ b/newlib/Makefile.in
@@ -1011,17 +1011,23 @@  check_PROGRAMS =
 @HAVE_LIBM_MACHINE_SPARC_TRUE@am__append_159 = $(libm_machine_sparc_src)
 @HAVE_LIBM_MACHINE_SPU_TRUE@am__append_160 = $(libm_machine_spu_src)
 @HAVE_LIBM_MACHINE_RISCV_TRUE@am__append_161 = $(libm_machine_riscv_src)
-@HAVE_LIBM_MACHINE_RISCV_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__append_162 = $(libm_ld128_lsrc)
-@HAVE_LIBM_MACHINE_RISCV_TRUE@am__append_163 = 
+
+# Vectorized (RVV) math routines.  vec_sin.c is guarded internally on
+# __riscv_vector, so it compiles to an empty object for non-vector
+# multilibs and relies on each multilib's own -march otherwise (no per-file
+# ISA override is applied here, keeping the build multilib-safe).
+@HAVE_LIBM_MACHINE_RISCV_TRUE@@NEWLIB_VECMATH_TRUE@am__append_162 = libm/machine/riscv/vec_sin.c
+@HAVE_LIBM_MACHINE_RISCV_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__append_163 = $(libm_ld128_lsrc)
 @HAVE_LIBM_MACHINE_RISCV_TRUE@am__append_164 = 
-@HAVE_LIBM_MACHINE_X86_64_TRUE@am__append_165 = $(libm_machine_x86_64_src)
-@HAVE_LIBM_MACHINE_X86_64_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__append_166 = $(libm_ld80_lsrc)
-@HAVE_LIBM_MACHINE_X86_64_TRUE@am__append_167 = 
+@HAVE_LIBM_MACHINE_RISCV_TRUE@am__append_165 = 
+@HAVE_LIBM_MACHINE_X86_64_TRUE@am__append_166 = $(libm_machine_x86_64_src)
+@HAVE_LIBM_MACHINE_X86_64_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__append_167 = $(libm_ld80_lsrc)
 @HAVE_LIBM_MACHINE_X86_64_TRUE@am__append_168 = 
-@HAVE_LIBM_MACHINE_XTENSA_TRUE@@XTENSA_XCHAL_HAVE_FP_SQRT_TRUE@am__append_169 = \
+@HAVE_LIBM_MACHINE_X86_64_TRUE@am__append_169 = 
+@HAVE_LIBM_MACHINE_XTENSA_TRUE@@XTENSA_XCHAL_HAVE_FP_SQRT_TRUE@am__append_170 = \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@@XTENSA_XCHAL_HAVE_FP_SQRT_TRUE@	libm/machine/xtensa/ef_sqrt.c
 
-@HAVE_LIBM_MACHINE_XTENSA_TRUE@am__append_170 = $(libm_machine_xtensa_src)
+@HAVE_LIBM_MACHINE_XTENSA_TRUE@am__append_171 = $(libm_machine_xtensa_src)
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
@@ -3752,8 +3758,9 @@  am__objects_159 = libm/fenv/libm_a-feclearexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_RISCV_TRUE@	libm/machine/riscv/libm_a-s_llround.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_RISCV_TRUE@	libm/machine/riscv/libm_a-sf_llround.$(OBJEXT)
 @HAVE_LIBM_MACHINE_RISCV_TRUE@am__objects_187 = $(am__objects_186)
-@HAVE_LIBM_MACHINE_RISCV_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__objects_188 = $(am__objects_162)
-@HAVE_LIBM_MACHINE_X86_64_TRUE@am__objects_189 = libm/machine/x86_64/libm_a-feclearexcept.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_RISCV_TRUE@@NEWLIB_VECMATH_TRUE@am__objects_188 = libm/machine/riscv/libm_a-vec_sin.$(OBJEXT)
+@HAVE_LIBM_MACHINE_RISCV_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__objects_189 = $(am__objects_162)
+@HAVE_LIBM_MACHINE_X86_64_TRUE@am__objects_190 = libm/machine/x86_64/libm_a-feclearexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_X86_64_TRUE@	libm/machine/x86_64/libm_a-fegetenv.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_X86_64_TRUE@	libm/machine/x86_64/libm_a-fegetexceptflag.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_X86_64_TRUE@	libm/machine/x86_64/libm_a-fegetround.$(OBJEXT) \
@@ -3765,10 +3772,10 @@  am__objects_159 = libm/fenv/libm_a-feclearexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_X86_64_TRUE@	libm/machine/x86_64/libm_a-fesetround.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_X86_64_TRUE@	libm/machine/x86_64/libm_a-fetestexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_X86_64_TRUE@	libm/machine/x86_64/libm_a-feupdateenv.$(OBJEXT)
-@HAVE_LIBM_MACHINE_X86_64_TRUE@am__objects_190 = $(am__objects_189)
-@HAVE_LIBM_MACHINE_X86_64_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__objects_191 = $(am__objects_170)
-@HAVE_LIBM_MACHINE_XTENSA_TRUE@@XTENSA_XCHAL_HAVE_FP_SQRT_TRUE@am__objects_192 = libm/machine/xtensa/libm_a-ef_sqrt.$(OBJEXT)
-@HAVE_LIBM_MACHINE_XTENSA_TRUE@am__objects_193 = libm/machine/xtensa/libm_a-feclearexcept.$(OBJEXT) \
+@HAVE_LIBM_MACHINE_X86_64_TRUE@am__objects_191 = $(am__objects_190)
+@HAVE_LIBM_MACHINE_X86_64_TRUE@@HAVE_LONG_DOUBLE_TRUE@am__objects_192 = $(am__objects_170)
+@HAVE_LIBM_MACHINE_XTENSA_TRUE@@XTENSA_XCHAL_HAVE_FP_SQRT_TRUE@am__objects_193 = libm/machine/xtensa/libm_a-ef_sqrt.$(OBJEXT)
+@HAVE_LIBM_MACHINE_XTENSA_TRUE@am__objects_194 = libm/machine/xtensa/libm_a-feclearexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/libm_a-fegetenv.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/libm_a-fegetexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/libm_a-fegetexceptflag.$(OBJEXT) \
@@ -3777,8 +3784,8 @@  am__objects_159 = libm/fenv/libm_a-feclearexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/libm_a-feraiseexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/libm_a-fetestexcept.$(OBJEXT) \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/libm_a-feupdateenv.$(OBJEXT) \
-@HAVE_LIBM_MACHINE_XTENSA_TRUE@	$(am__objects_192)
-@HAVE_LIBM_MACHINE_XTENSA_TRUE@am__objects_194 = $(am__objects_193)
+@HAVE_LIBM_MACHINE_XTENSA_TRUE@	$(am__objects_193)
+@HAVE_LIBM_MACHINE_XTENSA_TRUE@am__objects_195 = $(am__objects_194)
 am_libm_a_OBJECTS = $(am__objects_145) $(am__objects_149) \
 	$(am__objects_150) $(am__objects_151) $(am__objects_153) \
 	$(am__objects_155) $(am__objects_156) $(am__objects_157) \
@@ -3787,8 +3794,8 @@  am_libm_a_OBJECTS = $(am__objects_145) $(am__objects_149) \
 	$(am__objects_169) $(am__objects_171) $(am__objects_173) \
 	$(am__objects_177) $(am__objects_179) $(am__objects_181) \
 	$(am__objects_183) $(am__objects_185) $(am__objects_187) \
-	$(am__objects_188) $(am__objects_190) $(am__objects_191) \
-	$(am__objects_194)
+	$(am__objects_188) $(am__objects_189) $(am__objects_191) \
+	$(am__objects_192) $(am__objects_195)
 libm_a_OBJECTS = $(am_libm_a_OBJECTS)
 am_libm_test_test_OBJECTS = libm/test/test.$(OBJEXT) \
 	libm/test/string.$(OBJEXT) libm/test/convert.$(OBJEXT) \
@@ -4357,8 +4364,8 @@  libm_a_SOURCES = $(am__append_133) $(am__append_136) \
 	$(am__append_149) $(am__append_150) $(am__append_153) \
 	$(am__append_156) $(am__append_157) $(am__append_158) \
 	$(am__append_159) $(am__append_160) $(am__append_161) \
-	$(am__append_162) $(am__append_165) $(am__append_166) \
-	$(am__append_170)
+	$(am__append_162) $(am__append_163) $(am__append_166) \
+	$(am__append_167) $(am__append_171)
 libm_a_CFLAGS = $(AM_CFLAGS) $(libm_a_CFLAGS_$(subst /,_,$(@D))) $(libm_a_CFLAGS_$(subst /,_,$(@D)_$(<F)))
 libm_a_CCASFLAGS = $(AM_CCASFLAGS) $(libm_a_CCASFLAGS_$(subst /,_,$(@D))) $(libm_a_CCASFLAGS_$(subst /,_,$(@D)_$(<F)))
 libm_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/libm/common $(libm_a_CPPFLAGS_$(subst /,_,$(@D))) $(libm_a_CPPFLAGS_$(subst /,_,$(@D)_$(<F)))
@@ -4793,11 +4800,11 @@  LIBM_CHEWOUT_FILES = $(am__append_134) $(am__append_137) \
 	libm/fenv/feraiseexcept.def libm/fenv/fesetenv.def \
 	libm/fenv/fesetexceptflag.def libm/fenv/fesetround.def \
 	libm/fenv/fetestexcept.def libm/fenv/feupdateenv.def \
-	$(am__append_145) $(am__append_151) $(am__append_163) \
-	$(am__append_167)
+	$(am__append_145) $(am__append_151) $(am__append_164) \
+	$(am__append_168)
 LIBM_CHAPTERS = $(am__append_135) $(am__append_138) $(am__append_142) \
 	libm/complex/complex.tex libm/fenv/fenv.tex $(am__append_146) \
-	$(am__append_152) $(am__append_164) $(am__append_168)
+	$(am__append_152) $(am__append_165) $(am__append_169)
 LIBM_DOCBOOK_OUT_FILES = $(LIBM_CHEWOUT_FILES:.def=.xml)
 @NEWLIB_HW_FP_TRUE@libm_mathfp_src = \
 @NEWLIB_HW_FP_TRUE@	libm/mathfp/s_acos.c libm/mathfp/s_frexp.c libm/mathfp/s_mathcnst.c \
@@ -5409,7 +5416,7 @@  libm_test_test_LDADD = $(CRT0) libm.a libc.a
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/feraiseexcept.c \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/fetestexcept.c \
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@	libm/machine/xtensa/feupdateenv.c \
-@HAVE_LIBM_MACHINE_XTENSA_TRUE@	$(am__append_169)
+@HAVE_LIBM_MACHINE_XTENSA_TRUE@	$(am__append_170)
 @HAVE_LIBM_MACHINE_XTENSA_TRUE@libm_a_CFLAGS_libm_machine_xtensa = -D_LIBM
 all: newlib.h _newlib_version.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -12486,6 +12493,9 @@  libm/machine/riscv/libm_a-s_llround.$(OBJEXT):  \
 libm/machine/riscv/libm_a-sf_llround.$(OBJEXT):  \
 	libm/machine/riscv/$(am__dirstamp) \
 	libm/machine/riscv/$(DEPDIR)/$(am__dirstamp)
+libm/machine/riscv/libm_a-vec_sin.$(OBJEXT):  \
+	libm/machine/riscv/$(am__dirstamp) \
+	libm/machine/riscv/$(DEPDIR)/$(am__dirstamp)
 libm/machine/x86_64/$(am__dirstamp):
 	@$(MKDIR_P) libm/machine/x86_64
 	@: > libm/machine/x86_64/$(am__dirstamp)
@@ -14989,6 +14999,7 @@  distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@libm/machine/riscv/$(DEPDIR)/libm_a-sf_llround.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libm/machine/riscv/$(DEPDIR)/libm_a-sf_lrint.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libm/machine/riscv/$(DEPDIR)/libm_a-sf_lround.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@libm/machine/riscv/$(DEPDIR)/libm_a-vec_sin.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libm/machine/sparc/$(DEPDIR)/libm_a-feclearexcept.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libm/machine/sparc/$(DEPDIR)/libm_a-fegetenv.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libm/machine/sparc/$(DEPDIR)/libm_a-fegetexceptflag.Po@am__quote@
@@ -50334,6 +50345,20 @@  libm/machine/riscv/libm_a-sf_llround.obj: libm/machine/riscv/sf_llround.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libm_a_CPPFLAGS) $(CPPFLAGS) $(libm_a_CFLAGS) $(CFLAGS) -c -o libm/machine/riscv/libm_a-sf_llround.obj `if test -f 'libm/machine/riscv/sf_llround.c'; then $(CYGPATH_W) 'libm/machine/riscv/sf_llround.c'; else $(CYGPATH_W) '$(srcdir)/libm/machine/riscv/sf_llround.c'; fi`
 
+libm/machine/riscv/libm_a-vec_sin.o: libm/machine/riscv/vec_sin.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libm_a_CPPFLAGS) $(CPPFLAGS) $(libm_a_CFLAGS) $(CFLAGS) -MT libm/machine/riscv/libm_a-vec_sin.o -MD -MP -MF libm/machine/riscv/$(DEPDIR)/libm_a-vec_sin.Tpo -c -o libm/machine/riscv/libm_a-vec_sin.o `test -f 'libm/machine/riscv/vec_sin.c' || echo '$(srcdir)/'`libm/machine/riscv/vec_sin.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libm/machine/riscv/$(DEPDIR)/libm_a-vec_sin.Tpo libm/machine/riscv/$(DEPDIR)/libm_a-vec_sin.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libm/machine/riscv/vec_sin.c' object='libm/machine/riscv/libm_a-vec_sin.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libm_a_CPPFLAGS) $(CPPFLAGS) $(libm_a_CFLAGS) $(CFLAGS) -c -o libm/machine/riscv/libm_a-vec_sin.o `test -f 'libm/machine/riscv/vec_sin.c' || echo '$(srcdir)/'`libm/machine/riscv/vec_sin.c
+
+libm/machine/riscv/libm_a-vec_sin.obj: libm/machine/riscv/vec_sin.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libm_a_CPPFLAGS) $(CPPFLAGS) $(libm_a_CFLAGS) $(CFLAGS) -MT libm/machine/riscv/libm_a-vec_sin.obj -MD -MP -MF libm/machine/riscv/$(DEPDIR)/libm_a-vec_sin.Tpo -c -o libm/machine/riscv/libm_a-vec_sin.obj `if test -f 'libm/machine/riscv/vec_sin.c'; then $(CYGPATH_W) 'libm/machine/riscv/vec_sin.c'; else $(CYGPATH_W) '$(srcdir)/libm/machine/riscv/vec_sin.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libm/machine/riscv/$(DEPDIR)/libm_a-vec_sin.Tpo libm/machine/riscv/$(DEPDIR)/libm_a-vec_sin.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libm/machine/riscv/vec_sin.c' object='libm/machine/riscv/libm_a-vec_sin.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libm_a_CPPFLAGS) $(CPPFLAGS) $(libm_a_CFLAGS) $(CFLAGS) -c -o libm/machine/riscv/libm_a-vec_sin.obj `if test -f 'libm/machine/riscv/vec_sin.c'; then $(CYGPATH_W) 'libm/machine/riscv/vec_sin.c'; else $(CYGPATH_W) '$(srcdir)/libm/machine/riscv/vec_sin.c'; fi`
+
 libm/machine/x86_64/libm_a-feclearexcept.o: libm/machine/x86_64/feclearexcept.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libm_a_CPPFLAGS) $(CPPFLAGS) $(libm_a_CFLAGS) $(CFLAGS) -MT libm/machine/x86_64/libm_a-feclearexcept.o -MD -MP -MF libm/machine/x86_64/$(DEPDIR)/libm_a-feclearexcept.Tpo -c -o libm/machine/x86_64/libm_a-feclearexcept.o `test -f 'libm/machine/x86_64/feclearexcept.c' || echo '$(srcdir)/'`libm/machine/x86_64/feclearexcept.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libm/machine/x86_64/$(DEPDIR)/libm_a-feclearexcept.Tpo libm/machine/x86_64/$(DEPDIR)/libm_a-feclearexcept.Po
diff --git a/newlib/configure b/newlib/configure
index dd4153173..ef54ba443 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -838,6 +838,8 @@  HAVE_SIGNAL_DIR_TRUE
 CC_FOR_NEWLIB
 NEWLIB_HW_FP_FALSE
 NEWLIB_HW_FP_TRUE
+NEWLIB_VECMATH_FALSE
+NEWLIB_VECMATH_TRUE
 sys_dir
 shared_machine_dir
 machine_dir
@@ -1001,6 +1003,7 @@  enable_newlib_long_time_t
 enable_newlib_use_gdtoa
 enable_newlib_use_malloc_in_execl
 enable_newlib_hw_misaligned_access
+enable_vecmath
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1672,6 +1675,7 @@  Optional Features:
   --enable-newlib-use-gdtoa   Use gdtoa rather than legacy ldtoa
   --enable-newlib-use-malloc-in-execl   use malloc instead of alloca in execl, execle and execlp
   --enable-newlib-hw-misaligned-access   Use hardware word-by-word access instead of byte-by-byte for misaligned memory
+  --enable-vecmath   build vectorized (SIMD) libm math functions
   --enable-multilib       build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2622,6 +2626,17 @@  else
   newlib_hw_misaligned_access=
 fi
 
+# Check whether --enable-vecmath was given.
+if test "${enable_vecmath+set}" = set; then :
+  enableval=$enable_vecmath; case "${enableval}" in
+   yes) vecmath=yes ;;
+   no)  vecmath=no ;;
+   *) as_fn_error $? "bad value ${enableval} for vecmath" "$LINENO" 5 ;;
+ esac
+else
+  vecmath=no
+fi
+
 # Default to --enable-multilib
 # Check whether --enable-multilib was given.
 if test "${enable_multilib+set}" = set; then :
@@ -5301,6 +5316,15 @@  OBJEXT=o
 
 
 
+ if test x$vecmath = xyes; then
+  NEWLIB_VECMATH_TRUE=
+  NEWLIB_VECMATH_FALSE='#'
+else
+  NEWLIB_VECMATH_TRUE='#'
+  NEWLIB_VECMATH_FALSE=
+fi
+
+
 newlib_hw_fp=false
 #AC_ARG_ENABLE(newlib_hw_fp,
 #[  --enable-newlib-hw-fp    Turn on hardware floating point math],
@@ -7657,6 +7681,10 @@  if test -z "${ELIX_LEVEL_4_TRUE}" && test -z "${ELIX_LEVEL_4_FALSE}"; then
   as_fn_error $? "conditional \"ELIX_LEVEL_4\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NEWLIB_VECMATH_TRUE}" && test -z "${NEWLIB_VECMATH_FALSE}"; then
+  as_fn_error $? "conditional \"NEWLIB_VECMATH\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${NEWLIB_HW_FP_TRUE}" && test -z "${NEWLIB_HW_FP_FALSE}"; then
   as_fn_error $? "conditional \"NEWLIB_HW_FP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/newlib/configure.ac b/newlib/configure.ac
index 4640e69c5..50c2246ad 100644
--- a/newlib/configure.ac
+++ b/newlib/configure.ac
@@ -333,9 +333,25 @@  AC_ARG_ENABLE(newlib-hw-misaligned-access,
   esac
  fi], [newlib_hw_misaligned_access=])dnl
 
+dnl Support --enable-vecmath
+dnl Build the SIMD/vector variants of libm math functions (currently the
+dnl RISC-V Vector routines under libm/machine/riscv).  The sources guard
+dnl their bodies on the target ISA, so this is safe to enable for a
+dnl multilib build; multilibs without the vector extension get empty
+dnl objects.
+AC_ARG_ENABLE(vecmath,
+[  --enable-vecmath   build vectorized (SIMD) libm math functions],
+[case "${enableval}" in
+   yes) vecmath=yes ;;
+   no)  vecmath=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for vecmath) ;;
+ esac], [vecmath=no])dnl
+
 AM_ENABLE_MULTILIB(, ..)
 NEWLIB_CONFIGURE(.)
 
+AM_CONDITIONAL(NEWLIB_VECMATH, test x$vecmath = xyes)
+
 dnl The following is being disabled because the mathfp library is
 dnl not up to standard due to inaccuracies caused by some of the
 dnl floating-point algorithms used.  If you wish to work on this,
diff --git a/newlib/libm/machine/riscv/Makefile.inc b/newlib/libm/machine/riscv/Makefile.inc
index 9ce71e7be..03ec32b96 100644
--- a/newlib/libm/machine/riscv/Makefile.inc
+++ b/newlib/libm/machine/riscv/Makefile.inc
@@ -16,3 +16,11 @@ 
 	%D%/s_llround.c %D%/sf_llround.c
 
 libm_a_SOURCES += $(%C%_src)
+
+if NEWLIB_VECMATH
+# Vectorized (RVV) math routines.  vec_sin.c is guarded internally on
+# __riscv_vector, so it compiles to an empty object for non-vector
+# multilibs and relies on each multilib's own -march otherwise (no per-file
+# ISA override is applied here, keeping the build multilib-safe).
+libm_a_SOURCES += %D%/vec_sin.c
+endif
diff --git a/newlib/libm/machine/riscv/test_vec_sin.c b/newlib/libm/machine/riscv/test_vec_sin.c
new file mode 100644
index 000000000..e358d67e1
--- /dev/null
+++ b/newlib/libm/machine/riscv/test_vec_sin.c
@@ -0,0 +1,288 @@ 
+/*
+ * Accuracy test for the RVV vector sin, _ZGVr1Nxv_sin (double).
+ *
+ * The vector result for every lane is compared against a higher-precision
+ * reference computed with sinl() (long double).  On RISC-V long double is
+ * IEEE binary128 in the ABI but the C library evaluates it at whatever the
+ * platform provides; either way it carries strictly more precision than
+ * double here, which is sufficient to measure a <= 1 ULP double result.
+ * The test walks all three code paths (no-reduction, fast Cody-Waite
+ * reduction, and the Payne-Hanek slow path) plus adversarial arguments
+ * close to multiples of pi/2 and pi, and fails (non-zero exit) if any lane
+ * exceeds 1 ULP.
+ *
+ * Build/run (rv64gcv), e.g.:
+ *   riscv64-unknown-elf-gcc -march=rv64gcv -mabi=lp64d -O2 \
+ *       test_vec_sin.c -L<builddir>/newlib -lm -o test_vec_sin
+ *   qemu-riscv64 -cpu rv64,v=true test_vec_sin
+ *
+ * This program is intentionally standalone (not wired into libm.a); it is
+ * the verification companion for vec_sin.c.
+ */
+
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(__riscv_vector)
+#include <riscv_vector.h>
+
+extern vfloat64m1_t _ZGVr1Nxv_sin (vfloat64m1_t x);
+
+/* ulp(x): distance to the next double away from zero at x's magnitude. */
+static double
+ulp_of (double x)
+{
+  if (x == 0.0)
+    return 0x1p-1074;			/* smallest subnormal */
+  if (!isfinite (x))
+    return INFINITY;
+  int e;
+  frexp (x, &e);
+  int ex = e - 1 - 52;
+  if (ex < -1074)
+    ex = -1074;
+  return ldexp (1.0, ex);
+}
+
+/* Error of got in ULP of the reference, using sinl() as a
+ * higher-precision reference.  Only used where sinl() is trustworthy;
+ * large arguments are checked against a precomputed table instead (see
+ * below) because some C libraries have a buggy large-argument long double
+ * reducer.  */
+static double
+ulp_error (double x, double got)
+{
+  long double ref = sinl ((long double) x);
+  long double diff = (long double) got - ref;
+  if (diff < 0)
+    diff = -diff;
+  double u = ulp_of ((double) ref);
+  return (double) (diff / (long double) u);
+}
+
+/* Threshold below which the platform sinl() is used as the live reference.
+ * Above it we rely on the baked-in correctly-rounded reference table.  */
+#define SINL_REFERENCE_LIMIT 1.0e12
+
+/* Reference table for large arguments, generated offline with a 300-bit
+ * reference (mpmath).  Each entry holds the input's bits and the reference
+ * sin value as a double-double (hi + lo), which carries ~106 bits, plenty
+ * to measure a 1 ULP double error.  */
+struct ref_entry { uint64_t x, sin_hi, sin_lo; };
+static const struct ref_entry big_ref[] = {
+#include "test_vec_sin_bigref.h"
+};
+
+static double
+as_double (uint64_t b)
+{
+  double d;
+  memcpy (&d, &b, sizeof d);
+  return d;
+}
+
+/* A small xorshift PRNG so the test is deterministic and self-contained. */
+static uint64_t rng_state = 0x123456789abcdef0ULL;
+static uint64_t
+rng_next (void)
+{
+  uint64_t x = rng_state;
+  x ^= x << 13;
+  x ^= x >> 7;
+  x ^= x << 17;
+  rng_state = x;
+  return x;
+}
+static double
+rng_uniform (double lo, double hi)
+{
+  double u = (double) (rng_next () >> 11) * 0x1p-53; /* [0,1) */
+  return lo + u * (hi - lo);
+}
+
+/* Run one lane-wide batch through _ZGVr1Nxv_sin, updating the worst error.
+ * Returns the number of lanes that exceeded 1 ULP. */
+static long
+check_batch (const double *xs, size_t n, double *worst, double *worst_x)
+{
+  size_t vl = __riscv_vsetvlmax_e64m1 ();
+  long fails = 0;
+  double lanes[64];
+  for (size_t off = 0; off < n; off += vl)
+    {
+      size_t cnt = (off + vl <= n) ? vl : (n - off);
+      for (size_t k = 0; k < vl; k++)
+	lanes[k] = (k < cnt) ? xs[off + k] : 0.0;
+      vfloat64m1_t xv = __riscv_vle64_v_f64m1 (lanes, vl);
+      vfloat64m1_t rv = _ZGVr1Nxv_sin (xv);
+      __riscv_vse64_v_f64m1 (lanes, rv, vl);
+      for (size_t k = 0; k < cnt; k++)
+	{
+	  double x = xs[off + k];
+	  double e = ulp_error (x, lanes[k]);
+	  if (e > *worst)
+	    {
+	      *worst = e;
+	      *worst_x = x;
+	    }
+	  if (e > 1.0)
+	    {
+	      if (fails < 10)
+		printf ("  FAIL x=%.17g got=%.17g err=%.4f ULP\n",
+			x, lanes[k], e);
+	      fails++;
+	    }
+	}
+    }
+  return fails;
+}
+
+/* Check the large-argument table: each result must be within 1 ULP (one
+ * representable double) of the correctly-rounded reference.  */
+static long
+check_big_ref (double *worst, double *worst_x)
+{
+  size_t vl = __riscv_vsetvlmax_e64m1 ();
+  size_t n = sizeof big_ref / sizeof big_ref[0];
+  long fails = 0;
+  double lanes[64];
+  for (size_t off = 0; off < n; off += vl)
+    {
+      size_t cnt = (off + vl <= n) ? vl : (n - off);
+      for (size_t k = 0; k < vl; k++)
+	lanes[k] = (k < cnt) ? as_double (big_ref[off + k].x) : 0.0;
+      vfloat64m1_t rv = _ZGVr1Nxv_sin (__riscv_vle64_v_f64m1 (lanes, vl));
+      __riscv_vse64_v_f64m1 (lanes, rv, vl);
+      for (size_t k = 0; k < cnt; k++)
+	{
+	  /* Reconstruct the reference as long double from the dd pair. */
+	  long double ref = (long double) as_double (big_ref[off + k].sin_hi)
+			  + (long double) as_double (big_ref[off + k].sin_lo);
+	  long double diff = (long double) lanes[k] - ref;
+	  if (diff < 0)
+	    diff = -diff;
+	  double e = (double) (diff / (long double) ulp_of ((double) ref));
+	  if (e > *worst)
+	    {
+	      *worst = e;
+	      *worst_x = as_double (big_ref[off + k].x);
+	    }
+	  if (e > 1.0)
+	    {
+	      if (fails < 10)
+		printf ("  FAIL x=%.17g got=%.17g err=%.4f ULP\n",
+			as_double (big_ref[off + k].x), lanes[k], e);
+	      fails++;
+	    }
+	}
+    }
+  return fails;
+}
+
+#define NBUF 4096
+
+int
+main (void)
+{
+  static double xs[NBUF];
+  double worst = 0.0, worst_x = 0.0;
+  long fails = 0, total = 0;
+  size_t i;
+
+  /* Region 1: |x| <= pi/4 (no argument reduction). */
+  for (i = 0; i < NBUF; i++)
+    xs[i] = rng_uniform (-M_PI / 4, M_PI / 4);
+  fails += check_batch (xs, NBUF, &worst, &worst_x); total += NBUF;
+
+  /* Region 2: fast Cody-Waite reduction, growing magnitudes. */
+  static const double hi[] = { 3.15, 10.0, 100.0, 1.0e3, 1.0e4, 1.0e5, 9.9e5 };
+  for (size_t b = 0; b < sizeof hi / sizeof hi[0]; b++)
+    {
+      for (i = 0; i < NBUF; i++)
+	xs[i] = rng_uniform (-hi[b], hi[b]);
+      fails += check_batch (xs, NBUF, &worst, &worst_x); total += NBUF;
+    }
+
+  /* Region 3a: Payne-Hanek slow path, checked live against sinl() while it
+   * is trustworthy (|x| < SINL_REFERENCE_LIMIT). */
+  for (int decade = 6; decade <= 11; decade++)
+    {
+      double scale = (double) powl (10.0L, (long double) decade);
+      for (i = 0; i < NBUF; i++)
+	{
+	  double s = (rng_next () & 1) ? 1.0 : -1.0;
+	  xs[i] = s * rng_uniform (1.0, 9.9) * scale;
+	}
+      fails += check_batch (xs, NBUF, &worst, &worst_x); total += NBUF;
+    }
+
+  /* Region 3b: very large magnitudes, checked against the correctly-rounded
+   * reference table (avoids relying on a large-argument sinl()). */
+  fails += check_big_ref (&worst, &worst_x);
+  total += (long) (sizeof big_ref / sizeof big_ref[0]);
+
+  /* Adversarial: arguments very close to k*pi/2 and k*pi where sin is tiny
+   * and relative error is hardest to control. */
+  for (int k = -2048; k <= 2048; k++)
+    {
+      i = 0;
+      xs[i++] = k * (M_PI / 2) + rng_uniform (-1e-5, 1e-5);
+      xs[i++] = k * M_PI + rng_uniform (-1e-9, 1e-9);
+      fails += check_batch (xs, i, &worst, &worst_x); total += i;
+    }
+
+  /* Special values: signed zero must be preserved; Inf/NaN must give NaN.
+   * Each value is broadcast across a full vector so the check is valid for
+   * any VLEN (a lane count as small as 2).  */
+  {
+    size_t vl = __riscv_vsetvlmax_e64m1 ();
+    double lanes[64];
+
+    __riscv_vse64_v_f64m1 (lanes,
+			   _ZGVr1Nxv_sin (__riscv_vfmv_v_f_f64m1 (-0.0, vl)),
+			   vl);
+    if (!(lanes[0] == 0.0 && signbit (lanes[0])))
+      { printf ("  FAIL sin(-0) not -0\n"); fails++; }
+
+    __riscv_vse64_v_f64m1 (lanes,
+			   _ZGVr1Nxv_sin (__riscv_vfmv_v_f_f64m1 (0.0, vl)),
+			   vl);
+    if (!(lanes[0] == 0.0 && !signbit (lanes[0])))
+      { printf ("  FAIL sin(+0) not +0\n"); fails++; }
+
+    double bad[] = { INFINITY, -INFINITY, NAN };
+    for (size_t j = 0; j < sizeof bad / sizeof bad[0]; j++)
+      {
+	__riscv_vse64_v_f64m1 (lanes,
+			       _ZGVr1Nxv_sin (__riscv_vfmv_v_f_f64m1 (bad[j], vl)),
+			       vl);
+	if (!isnan (lanes[0]))
+	  { printf ("  FAIL sin(%g) not NaN\n", bad[j]); fails++; }
+      }
+    total += 5;
+  }
+
+  printf ("vec sin: %ld samples, max error %.6f ULP at x=%.17g, %ld failures\n",
+	  total, worst, worst_x, fails);
+  if (fails == 0 && worst <= 1.0)
+    {
+      printf ("PASS: max error <= 1 ULP\n");
+      return 0;
+    }
+  printf ("FAIL: accuracy bound exceeded\n");
+  return 1;
+}
+
+#else /* !__riscv_vector */
+
+int
+main (void)
+{
+  printf ("vec sin test skipped: target has no V extension\n");
+  return 0;
+}
+
+#endif /* __riscv_vector */
+
diff --git a/newlib/libm/machine/riscv/test_vec_sin_bigref.h b/newlib/libm/machine/riscv/test_vec_sin_bigref.h
new file mode 100644
index 000000000..9316b1d14
--- /dev/null
+++ b/newlib/libm/machine/riscv/test_vec_sin_bigref.h
@@ -0,0 +1,250 @@ 
+/* Auto-generated correctly-rounded reference values for sin(double) at
+   large arguments.  Format: { input_bits, sin_hi_bits, sin_lo_bits },
+   where the reference sin value is the double-double sum hi + lo of a
+   300-bit computation.  Used by test_vec_sin.c.  Do not edit.  */
+  { 0x44a9dbb4ff908fb5ULL, 0xbfefc07760ab6354ULL, 0xbc7d5b4e724faf93ULL },
+  { 0xdbfbc15774f33afeULL, 0xbfe77e039dbb7348ULL, 0x3c8564fe62c841d4ULL },
+  { 0x6582353d215fa02bULL, 0xbfeefea2e334d557ULL, 0x3c8e2b07fe644ac8ULL },
+  { 0x7d7add74a882dee4ULL, 0x3fec31addc7e7074ULL, 0xbc8400ef6e285faeULL },
+  { 0xecc7c6178db646b3ULL, 0xbfeb3a89c87e6f8aULL, 0x3c57c5a24ad8aa0dULL },
+  { 0xefa504161fd00b47ULL, 0x3fd4a9d75cb23a15ULL, 0x3c725108a2a25ebcULL },
+  { 0xe534f4894bd602f3ULL, 0x3fcee79fa978d966ULL, 0xbc61174154f4d9bfULL },
+  { 0x4b34e1e2e82d6c82ULL, 0xbf9b1bf927c893e4ULL, 0x3c3c987cd59eb0c5ULL },
+  { 0xc9b6efda16235718ULL, 0x3febfe5f23debae6ULL, 0x3c89400a90a9cb18ULL },
+  { 0xdeb23e83234ee6a4ULL, 0xbfee81bc183fbd29ULL, 0x3c7eaf076f4d339aULL },
+  { 0xc853b24cf82dcb0aULL, 0xbfd4446c07eb46e8ULL, 0x3c70b944bf07dad2ULL },
+  { 0xd568845f1020f760ULL, 0x3fd689163edc0d68ULL, 0xbc4f18c6ebade0f0ULL },
+  { 0xf847cf0e8587807dULL, 0x3fde71d33d5f6a38ULL, 0x3c5332bf9f650f80ULL },
+  { 0xf8688b4915b2340cULL, 0xbfeb2c9a2d97d745ULL, 0xbc501b0b17ab6adfULL },
+  { 0x5ad615616b4511ceULL, 0xbfc20243d1eb990bULL, 0x3c5ab46d814c1907ULL },
+  { 0x52c3b4beea74ec04ULL, 0xbfe73cac6930c2a1ULL, 0xbc8481737b2688c8ULL },
+  { 0xd458c66b9a888eebULL, 0x3fce88ff02fb8173ULL, 0xbc605f0a3fa08a1aULL },
+  { 0xcc99d269643e68b2ULL, 0xbfeb6cdb94146eb1ULL, 0x3c6b077f7c570a9aULL },
+  { 0xe6e00a19223c11b8ULL, 0x3fda3ec8bf6e8b04ULL, 0xbc593c5f34b4813cULL },
+  { 0x7ae9216f4b768e36ULL, 0xbfeff396fdb55b44ULL, 0xbc825a30790a28faULL },
+  { 0xd147e7367b556f14ULL, 0x3fe93591e70f67ddULL, 0xbc4b908a8bdc2004ULL },
+  { 0x7d4256e4960879dfULL, 0x3fcb4363099b289dULL, 0xbc437a4e18914237ULL },
+  { 0xe013c555bfaa270dULL, 0x3fdd595d80386a84ULL, 0x3c6b575848bb9dbeULL },
+  { 0xf4f9a1ba87d1e3b9ULL, 0x3fefda0a9cf410e1ULL, 0xbc4d58b14edc3bc2ULL },
+  { 0x49453f2165887abfULL, 0xbfdd512f6aeb6113ULL, 0xbc729eef6bc92ff4ULL },
+  { 0x536db0a8e2d0428cULL, 0xbfe4bd0d2ccaec08ULL, 0xbc8d7298b2d595b2ULL },
+  { 0xf79d9af4393cbd9aULL, 0xbfe6255752046e10ULL, 0xbc52e09f5cf3386dULL },
+  { 0xe67fd249d393152aULL, 0x3fc9b6e381429938ULL, 0xbc52ad43a083bfbfULL },
+  { 0xd27fcc5f41c6e488ULL, 0x3fde89166b282088ULL, 0xbc7d37769671915dULL },
+  { 0xe00a6992ce6c1ce4ULL, 0x3fbdff2baddc9a0bULL, 0xbc47116844da78f5ULL },
+  { 0xe77cb1e1b3d58926ULL, 0xbfe1edc413b7d7c7ULL, 0xbc8b8336d45d3d2eULL },
+  { 0xf57eda6d1ab72b50ULL, 0xbfe027b6743da17eULL, 0x3c7883c1422e26e5ULL },
+  { 0xd7c4f76c9c956f52ULL, 0x3fed074d52442f5bULL, 0xbc8be322b089d744ULL },
+  { 0x7c42c48992b0580cULL, 0xbfe2492ce6b315e6ULL, 0xbc8859569449c328ULL },
+  { 0x571843d305d135abULL, 0xbfd53de1ad799097ULL, 0x3c78c2f3d6f3e0aaULL },
+  { 0x65d262a58c3cb1f6ULL, 0xbfe6a1b96392c030ULL, 0xbc894dba66196a3eULL },
+  { 0x716ce75ac6e463beULL, 0x3fe8f8a64f068f5eULL, 0xbc81751252eac2a8ULL },
+  { 0x65f17b41fb9183a1ULL, 0x3fed6a2f2e420ce2ULL, 0x3c5ee4c86a4afa2bULL },
+  { 0xfa5a0b3667f4182dULL, 0x3fdff8218b12a393ULL, 0x3c622e6b12894a94ULL },
+  { 0xe3677e43684b974cULL, 0x3fbba2a2526eab37ULL, 0xbc5af23d8957bd23ULL },
+  { 0x4395fb27da08f010ULL, 0xbfe20ed71d689bcaULL, 0x3c7dd0dd7d9b7e25ULL },
+  { 0x5e48b0e4203542aeULL, 0xbfea43d41e8dcb1dULL, 0xbc6590d8e451ab33ULL },
+  { 0xc5f2512cdba5a27dULL, 0x3fe6f6bc1233ca95ULL, 0x3c87e49f2aec8035ULL },
+  { 0xfd4c86f77e590326ULL, 0xbfeaf2a168d330daULL, 0xbc8e2b1e3ad609a3ULL },
+  { 0xf0639f90a675b7adULL, 0x3fedafec0a806285ULL, 0xbc8b77d8e8a9394aULL },
+  { 0x78d0cf0a55c0c91fULL, 0x3fb78ad5a22f8d64ULL, 0xbc4a55c48540d0daULL },
+  { 0x7c8e30d4454b9821ULL, 0x3fefa7b85b3dcd6eULL, 0xbc6b0f9a6bd6f62dULL },
+  { 0xea615705de88fe3aULL, 0xbfafe7ed59ec8262ULL, 0x3c4e42bc7b886c90ULL },
+  { 0x6c7bfdfab32a81c1ULL, 0xbfee472774a43babULL, 0x3c7e570e1bd15f94ULL },
+  { 0x6cd96cd876949553ULL, 0x3fe561fdbcc0e0a9ULL, 0x3c86acde7cd4a8d3ULL },
+  { 0x6f94de89c0376a87ULL, 0x3fe9b4ca527c7fa6ULL, 0x3c79cd9d59b54031ULL },
+  { 0x6761f60ed01da25eULL, 0xbfe8eae8acb0a66fULL, 0x3c49bebd0cf78fbaULL },
+  { 0x56aa284e2c106ca7ULL, 0xbfd5ccaa1a4a745fULL, 0x3c678961367fb9a8ULL },
+  { 0x6610826f12575488ULL, 0xbfef225873ba6d75ULL, 0xbc89bf0cb01945bdULL },
+  { 0x44b5f074dd5e5f91ULL, 0xbfe44b4390c64229ULL, 0x3c7a58b19f1408efULL },
+  { 0x5a7082d0e1c59decULL, 0xbfb6213c825d8b85ULL, 0xbc537503c6e0cddfULL },
+  { 0xde8d1fdbab167564ULL, 0xbfd04dc168165571ULL, 0xbc5420b74043fcd9ULL },
+  { 0xd6815208d7272823ULL, 0x3feeafb94a2f6c0fULL, 0x3c894a16430feee3ULL },
+  { 0xd95a3333ab2184d4ULL, 0x3fe92fdb9ae8b728ULL, 0xbc81fd33677898c4ULL },
+  { 0xfb4ae55a83558975ULL, 0x3fec96cd70a1a670ULL, 0xbc8309455f25fb9bULL },
+  { 0x4aee072add723ad9ULL, 0xbfe7e06d695d602aULL, 0xbc6a2995709bd38fULL },
+  { 0xcd026beefedc96c1ULL, 0xbfef4cf6eb5a884fULL, 0xbc7c798dd1cc293dULL },
+  { 0x5f24f8c21a79c3d5ULL, 0xbfea42ddd1c17682ULL, 0xbc84da8a18b3c37dULL },
+  { 0x7ae907f70d0b5fdcULL, 0xbfeededb92d58459ULL, 0xbc76785595cf306fULL },
+  { 0x6eacef4d70d22d77ULL, 0xbfec426d3578352eULL, 0xbc8b27555d7a823fULL },
+  { 0x55d18bddc73d7d19ULL, 0x3fc4a054eba9225aULL, 0xbc6b63485a377d88ULL },
+  { 0x42b71f32cbaa673aULL, 0x3fd6da32d22b42e2ULL, 0x3c7bb6b4a5e01209ULL },
+  { 0xe2b79014b74eae06ULL, 0xbfee5f431515f7ddULL, 0x3c7aa0b227d87181ULL },
+  { 0xf08971259ebf74d2ULL, 0x3fef63ce5ff53438ULL, 0x3c8f49fa1c47cfb4ULL },
+  { 0x7152db6cd53dd92dULL, 0xbfeb96537c255382ULL, 0xbc65083aa496ee1dULL },
+  { 0xcb11e519f157c3e3ULL, 0xbfcf23c6eec9b1d8ULL, 0x3c530dc6d41dee43ULL },
+  { 0xf1f50536ce3945fcULL, 0x3feabe8582ab144cULL, 0x3c4ed7efdcaab868ULL },
+  { 0x5e818d6ec72948b7ULL, 0x3fefb59d0ac6a7ecULL, 0xbc8773fd78927ebcULL },
+  { 0xea872ae2fbc53ceeULL, 0xbfee82da2a4b8acfULL, 0x3c88a6c64a744977ULL },
+  { 0xc3a26f16e32fab53ULL, 0x3feeff799ab2ee50ULL, 0xbc8daf713f015ff9ULL },
+  { 0x7bdd5402143da712ULL, 0xbfe8690148e95e74ULL, 0xbc86bfaa806196a6ULL },
+  { 0x6cd4bf43e59b9f0eULL, 0x3fefaa5ba89f71f1ULL, 0xbc49803cf49a7cd7ULL },
+  { 0xea72a5ee14efc6f9ULL, 0xbfe66a8c814165d9ULL, 0xbc84d79087f03e95ULL },
+  { 0xe4b4d7f8d1dc534fULL, 0x3fe666089452f0fcULL, 0x3c6b53a4330e3e6fULL },
+  { 0x77e8990d834ef92bULL, 0xbfd66ea9a9b36569ULL, 0x3c578cb1448eddeeULL },
+  { 0x4349ce8b6d745fd2ULL, 0xbfdd5fbb025e98c4ULL, 0x3c7e09613d4ff083ULL },
+  { 0xc371d094fd81a430ULL, 0xbfd104f4f59c35c9ULL, 0x3c7406abaf7d792fULL },
+  { 0xfa8585533ed8dd51ULL, 0x3fec2b3734be7df7ULL, 0x3c5e25fd2daeb9e1ULL },
+  { 0x64521026ae008463ULL, 0x3fe2a18f3eabcf7eULL, 0x3c457ffe19249afdULL },
+  { 0x4885853ef16bf001ULL, 0xbfebb37f3f88713dULL, 0xbc70871082b5264cULL },
+  { 0xfe12ac98fe404e2eULL, 0xbfef82002a84d70dULL, 0xbc7ec475df0e794dULL },
+  { 0xf00ea354f646b762ULL, 0xbfeff654fe56c26aULL, 0xbc841144607d36e9ULL },
+  { 0x4f31271978b78aa5ULL, 0xbfefd1a01f92c760ULL, 0xbc801970aa1b9229ULL },
+  { 0xc9e3c79dbab90bb9ULL, 0xbfeff6ee1b9d4928ULL, 0x3c70daacc547a73bULL },
+  { 0xee3ab1e4d905adc7ULL, 0x3fe9ad3b58ce5faeULL, 0xbc82349e67ef73bcULL },
+  { 0x6e01c4160382c330ULL, 0xbfdee9413d2b7536ULL, 0xbc77efa54c573babULL },
+  { 0x550208bbd0f21d27ULL, 0x3fee8aec0ce7ae7fULL, 0x3c7ba3fbc43960d2ULL },
+  { 0x6bcd98be95335228ULL, 0xbfe31b3df53c2b42ULL, 0x3c771dc425139d9eULL },
+  { 0xf9e630507811552aULL, 0xbfd67de486e0a39bULL, 0x3c606e8f51ab4b86ULL },
+  { 0x5263685b1cfa620fULL, 0x3fea8273913621aeULL, 0xbc87e3327ff1e306ULL },
+  { 0xcecf1a824be4d935ULL, 0x3fef65a694b8f8f7ULL, 0x3c71e9660b37b954ULL },
+  { 0x4d6aaae2238f3d71ULL, 0xbfc0c1893c492b2dULL, 0xbc61bd68521bb7d3ULL },
+  { 0x5364f7af58d26971ULL, 0x3fefda000a3d560fULL, 0x3c70795277604280ULL },
+  { 0xddfab1d8ccfb924dULL, 0x3fef8d8c8d9727fbULL, 0xbc80fd17d3fbb7f7ULL },
+  { 0x57bf256d425173dbULL, 0x3fef66b11e66188eULL, 0xbc463e50962c783bULL },
+  { 0xeaaeee5bc26ca14eULL, 0xbfcd908beb3b7527ULL, 0x3c696e36e746eca9ULL },
+  { 0xfd007999e73d0153ULL, 0x3fe6ae4a855588dbULL, 0x3c863a43e53d0b8eULL },
+  { 0x7b3d8fcceff22d32ULL, 0x3fef6d651ae0e510ULL, 0x3c89800f562ae087ULL },
+  { 0x6e2028b30ae34929ULL, 0xbfed8f7f297ca5b4ULL, 0x3c892297fc4ccd45ULL },
+  { 0x68abacd9594c034dULL, 0x3fe393ffc7a9ea72ULL, 0xbc8339bcf7eeed7bULL },
+  { 0xf54f48cf65f99808ULL, 0xbfefd28d402b98c7ULL, 0xbc8b98c3ced855d9ULL },
+  { 0x74ae2e64b64829d3ULL, 0xbfeff1bf510ba65fULL, 0xbc8dea08c9b6877aULL },
+  { 0xf9d8fbc71950c68eULL, 0x3fd4e3f908fe036cULL, 0xbc74400cb90f1963ULL },
+  { 0xe9f81d95d3a008daULL, 0xbfeae8bc700ea627ULL, 0x3c82d159fe3fd720ULL },
+  { 0xeb15400c5c9c792aULL, 0x3fb266058c34f144ULL, 0x3c3e17808cc9a530ULL },
+  { 0x4eb9f786422fb33eULL, 0x3fe0c34f5e8066f5ULL, 0x3c71d7089622959dULL },
+  { 0xfc63d8049a9ff525ULL, 0xbfeee6aea91ef94aULL, 0x3c6038b4e2c13e34ULL },
+  { 0xced5db4bd4a3d631ULL, 0x3fe525c0c4152120ULL, 0x3c8872446ecdabadULL },
+  { 0xeb7db2e753f12d26ULL, 0x3fe18c8a88c059faULL, 0x3c8d1b2c19037bf4ULL },
+  { 0x784f96b568580c13ULL, 0xbfdf3badc719754aULL, 0x3c76b1948cd4cde5ULL },
+  { 0xd2a41a31c5cf09fbULL, 0x3fd8e0564e905d6fULL, 0xbc659b2e13478961ULL },
+  { 0xdc58decaae6fb25cULL, 0x3fe47abeb58598bdULL, 0x3c56abd64019e4beULL },
+  { 0x484248ec70ba8047ULL, 0xbfe8d0872ee8db96ULL, 0xbc755ebc8fccf47fULL },
+  { 0xd888cf7ed17b95faULL, 0xbfef1d92b8ce5ab1ULL, 0x3c820661260c2966ULL },
+  { 0xdf244d931f1d0979ULL, 0xbfea06b9f1861517ULL, 0xbc64eab8fb6a963cULL },
+  { 0x42e7bea87a06bb97ULL, 0xbf80cc5df27cc893ULL, 0xbc2f887836ea6188ULL },
+  { 0x42e030810af10a8aULL, 0xbf80aa27ab18c146ULL, 0xbc0c8e366f6ce709ULL },
+  { 0x42d6915d9129a89dULL, 0x3f4b035c5cbe5317ULL, 0x3bd633e5aafcbce1ULL },
+  { 0x42a7e6098a48380aULL, 0xbf8412e0e05c9e80ULL, 0xbc12d461930e9c7fULL },
+  { 0x42f0eb1cd187c866ULL, 0x3fa380278e2023a7ULL, 0x3c472837f3881d2cULL },
+  { 0x42e9ec8ea0dc5b69ULL, 0x3f9076dabcd77f53ULL, 0x3c06984a658b62a0ULL },
+  { 0x42e7c8e1c184db33ULL, 0xbf8b6bf586a5e44aULL, 0x3c219a22965884e5ULL },
+  { 0x42f0dd0108ba84b3ULL, 0x3f72dffade7da8e7ULL, 0x3bf99d5f6d5ac851ULL },
+  { 0x42cffefaf33ee8c8ULL, 0xbf77d5508a6748eaULL, 0xbc15ed52410bad0dULL },
+  { 0x42e3837bfef06182ULL, 0xbf5220a9eb7a8d1aULL, 0xbbf8fc0deedb3253ULL },
+  { 0x42f113102aa2ddc9ULL, 0x3f60e1e32e9b8db1ULL, 0x3c042bc681c17a7cULL },
+  { 0x42f07a2036b196abULL, 0xbf98ddb068481cf1ULL, 0xbbfe5c3282da937cULL },
+  { 0x42f0f9add596adceULL, 0x3f5bd6f6a7a5b109ULL, 0xbbee6fe5848141f4ULL },
+  { 0x42d4e078b3fbe60cULL, 0x3f7c85cd69d47748ULL, 0xbc15b27a777f2d08ULL },
+  { 0x42d77feb017b379cULL, 0x3f40d4ea3aaad201ULL, 0xbbee49553aee2db0ULL },
+  { 0x42eee13ae8acb1e1ULL, 0xbf6e17a8351be2beULL, 0x3bfe6c4f9216c940ULL },
+  { 0x42efda72022e8165ULL, 0x3f7401c30a912bffULL, 0x3c0ecb8cc07b0f07ULL },
+  { 0x42e597bb5ad08eedULL, 0x3f7184607ea6c688ULL, 0x3c14968ff64f50b3ULL },
+  { 0x42e515c33faf2e0bULL, 0x3f878b6a5d032689ULL, 0x3c2979d0e33e7f65ULL },
+  { 0x42d076d3e2bc75caULL, 0x3f79b4507d6e5652ULL, 0x3c147b3d3058c04fULL },
+  { 0x42ce35a57c9bd40bULL, 0x3f80895f3c2ebc56ULL, 0x3c12225fd8c7e28aULL },
+  { 0x42d8e714dd8b95e9ULL, 0xbf8037b6d60448efULL, 0xbc15be19168ff7d1ULL },
+  { 0x42ca770e8688ea8eULL, 0x3f55efc64bb3a1d8ULL, 0x3bf41cd8e23cd5b1ULL },
+  { 0x42da2e25ac11a92dULL, 0x3f9ba378f9b9309cULL, 0xbc3fda65f378dc03ULL },
+  { 0x42e401e6fefeaf9fULL, 0xbf79915f6954ab1aULL, 0xbc0e2da306c553b1ULL },
+  { 0x42f0cfc024770e8dULL, 0x3f81d312d07e7249ULL, 0x3be6aa89ba75636eULL },
+  { 0x42bf8cc4c2cc9a0eULL, 0x3f7a7a5a068e4480ULL, 0x3c04f792ea0e4bf9ULL },
+  { 0x42f119566f205f00ULL, 0xbf93b8b1f9290c22ULL, 0x3c254c90aa55b77fULL },
+  { 0x42e4f81f6c2d7c02ULL, 0x3f7d05e7c78b208fULL, 0x3bf615a3a3d40194ULL },
+  { 0x42f0fdda33c1a75cULL, 0x3fa156cdcf31fb92ULL, 0xbc3d545f9306c381ULL },
+  { 0x42f16a94796b2c34ULL, 0xbf8369fe6bbc4612ULL, 0xbc2557edee6d9916ULL },
+  { 0x42e707f284ddea20ULL, 0x3f97a29d65d188f6ULL, 0xbc335e3a48f90c1cULL },
+  { 0x42dc8afccd056efeULL, 0xbf6a01e46476fe8fULL, 0x3c011ba54acbc76aULL },
+  { 0x42e94b74a40fdd48ULL, 0xbf7003b1a7274281ULL, 0x3be87e3995c16129ULL },
+  { 0x42b23f8f465f9e58ULL, 0x3f40f443ccf1832dULL, 0x3be7beefa1b9a940ULL },
+  { 0x42ecc8755c949b22ULL, 0x3f9344fd36e8022bULL, 0xbc3c0c2e527b826cULL },
+  { 0x42e0b054c53b5d39ULL, 0x3f70e9a011f6d65fULL, 0x3c1b554415ec728aULL },
+  { 0x42d3b6b804fbc5a7ULL, 0xbf6bc97e2c0b5246ULL, 0xbc052c094c75f315ULL },
+  { 0x42e1ca33a34dec6dULL, 0xbf74d77a65e3010fULL, 0x3c1924471d418048ULL },
+  { 0x42eda6f9b07d92f5ULL, 0xbf62aa37ea67bb4eULL, 0x3c00abc80fecc17fULL },
+  { 0x42f1b24bc2880f75ULL, 0x3f93477b1d9fe336ULL, 0x3c188184ab1a54e9ULL },
+  { 0x42e01543d879e2c9ULL, 0x3f8257edfed1cea8ULL, 0x3c27b03211ee7c35ULL },
+  { 0x42ca1a5ec0128654ULL, 0x3f5d6cb12216217bULL, 0x3bf1f0ce3fa4b4caULL },
+  { 0x42eb8d66ed98cedaULL, 0x3f92609c01355a2bULL, 0xbc2ddef12e22f6fdULL },
+  { 0x42f0a609cc46058cULL, 0xbf7804b5ea754c98ULL, 0xbc1dd427683fe1f8ULL },
+  { 0x42f0f8c1866a9f7bULL, 0x3f9c6c87698485d3ULL, 0x3c2d489477eee9b5ULL },
+  { 0x42e34cde47414cf8ULL, 0x3f956c29569c60c9ULL, 0x3c3a7633dafe2486ULL },
+  { 0x42efa735f8ea6544ULL, 0xbf7309328e1b4768ULL, 0x3c11f842e70c5698ULL },
+  { 0x42ce9809b9a64e63ULL, 0xbf80265a51dc5441ULL, 0x3c2e772829673ddfULL },
+  { 0x42ec8240dcd90783ULL, 0xbf78d25f06bd3736ULL, 0xbbedd2b59783d940ULL },
+  { 0x42e2c94dbd018eabULL, 0x3f8e4da44272b5caULL, 0xbc0dd155219ba6d0ULL },
+  { 0x42de0d2d8757b8a6ULL, 0xbf86c793b7d9943dULL, 0xbc23aa3209922a51ULL },
+  { 0x42deecaeff996904ULL, 0xbf78fa12771ec7b5ULL, 0xbc19c8fc9ad4948aULL },
+  { 0x42e972c23a9fc175ULL, 0xbf71af5132592aedULL, 0xbc1a431c4054a951ULL },
+  { 0x42e39a6b08bce147ULL, 0xbf8da8a43f55190aULL, 0xbc2d7ea7a8b2f66bULL },
+  { 0x42e5cb6607974ad3ULL, 0xbf7443061c8fa61fULL, 0xbbc99bfa7fa22075ULL },
+  { 0x42e6c694c342d903ULL, 0xbf60d88cfaf5ebe8ULL, 0x3c09444cbaf85e3dULL },
+  { 0x42da72cf5b9ac96aULL, 0x3f84e565ba209029ULL, 0x3c2051d0fa1aff93ULL },
+  { 0x42ef4ccc9d14979eULL, 0xbf8228bec193e115ULL, 0xbbe9dc461434cd3fULL },
+  { 0x42ee47a485c27578ULL, 0xbf80395b2498221cULL, 0x3c14101266690f5cULL },
+  { 0x42dad2d7d32eba44ULL, 0x3f70238dad3c59caULL, 0x3c1dc82b45d88bc7ULL },
+  { 0x42ef95ca6761299dULL, 0xbf5dc89b2f65b1beULL, 0x3bd8a775d7e12eb0ULL },
+  { 0x42cb5977aa359db6ULL, 0x3f7fa88c1455ace2ULL, 0x3c0f407ce17827a5ULL },
+  { 0x42f1616e2fed4c11ULL, 0x3fa13f9e9a351a2aULL, 0xbc4090ae4b479190ULL },
+  { 0x42e82ee2761c74b7ULL, 0x3f72c5a242c6c613ULL, 0x3c05e06f5e516cb6ULL },
+  { 0x427b22d12b8ad554ULL, 0x3f5d136909f6c369ULL, 0xbbb4ad6ba4f9b2e6ULL },
+  { 0x42e103e86fcd28edULL, 0xbf6d1ca987175599ULL, 0x3c06fdecbadf16ffULL },
+  { 0x42e811c70d666bbbULL, 0xbf91984e3a85d010ULL, 0x3c3983d8998e9553ULL },
+  { 0x42f1b5f5f276f97aULL, 0xbfa12e2e46e47523ULL, 0xbc4b9646d4f630e7ULL },
+  { 0x42e94a54a9c55472ULL, 0xbf80bffd8d482f14ULL, 0x3c2f06a60b20cb7dULL },
+  { 0x42dfb5d738e95002ULL, 0x3f858d3ec9d4366fULL, 0xbc18d1f9efacd2aeULL },
+  { 0x42dd0da41d84d1ddULL, 0x3f814cd6d4b81456ULL, 0x3c2973826c5b0b65ULL },
+  { 0x42c24e8fb5f472afULL, 0x3f825baa7033e089ULL, 0x3bff587965271dc7ULL },
+  { 0x42b10644d14b9b6dULL, 0x3f747590605e052dULL, 0xbc16bd5a106c8991ULL },
+  { 0x42efab585b64809bULL, 0xbf6d56f83303ff3fULL, 0xbc0f42d166c2ab9fULL },
+  { 0x42e85ed862068624ULL, 0x3f7e2c4c0226a1aeULL, 0xbc1ccc9fbe04ac53ULL },
+  { 0x42e6d9859145c214ULL, 0x3f7201aad8cd6d2aULL, 0xbbf6a1303210799eULL },
+  { 0x4299ef2669ca1626ULL, 0xbf803e0e1dd78addULL, 0xbc1ea5d671866bc4ULL },
+  { 0x42e6c20d3c9dd322ULL, 0x3f7cb72dd7256582ULL, 0x3c17c09e4a97519dULL },
+  { 0x42e5d1765657f566ULL, 0xbf7f59cfd0379fafULL, 0xbbfe2675f26e0cb4ULL },
+  { 0x4274cccccccccccdULL, 0xbfeb652877ab8257ULL, 0x3c8f4bb2d8e7b7beULL },
+  { 0xc266666666666666ULL, 0xbfeea4586a2dfee4ULL, 0x3c8bf04c740eb938ULL },
+  { 0x4284cccccccccccdULL, 0xbfec50fb070a07b5ULL, 0xbc7324c01f041830ULL },
+  { 0xc276666666666666ULL, 0x3fe1a9ed19c2642bULL, 0xbc7b84831233a3aeULL },
+  { 0x4294cccccccccccdULL, 0x3fea6147a2dc7225ULL, 0xbc2cff8d76ee2990ULL },
+  { 0xc286666666666666ULL, 0xbfed75348cdaf022ULL, 0x3c7647860e225329ULL },
+  { 0x42a4cccccccccccdULL, 0xbfeddd4edcbd9f0fULL, 0xbc84bafe3b573c55ULL },
+  { 0xc296666666666666ULL, 0xbfe7034dd111a92eULL, 0x3c609c14662e13fdULL },
+  { 0x42b4cccccccccccdULL, 0x3fe5743585652dddULL, 0x3c7f753ca1dc3ea1ULL },
+  { 0xc2a6666666666666ULL, 0x3feffb2975cf0540ULL, 0x3c700a80104ad5dbULL },
+  { 0x42c4cccccccccccdULL, 0xbfefd6153e02dfa7ULL, 0x3c67d00955d2e783ULL },
+  { 0xc2b6666666666666ULL, 0xbfb1955d8644e304ULL, 0x3c514eeb4785df2bULL },
+  { 0x42d4cccccccccccdULL, 0xbfc9bb5a957ff77cULL, 0x3c6552523bb114e9ULL },
+  { 0xc2c6666666666666ULL, 0x3fc18abc1a08cc84ULL, 0x3c63285cde354315ULL },
+  { 0x42e4cccccccccccdULL, 0x3fd934df9b1998f7ULL, 0x3c77edbfe8329aedULL },
+  { 0xc2d6666666666666ULL, 0x3fd1605cf12f62a3ULL, 0xbc5b400190f82577ULL },
+  { 0x42f4cccccccccccdULL, 0x3fe72b4ff19781a8ULL, 0xbc79bca6775772f7ULL },
+  { 0xc2e6666666666666ULL, 0x3fe0b9447432258aULL, 0xbc34b3486d93f031ULL },
+  { 0x4304cccccccccccdULL, 0x3feff66026744e9eULL, 0xbc78ceb76011db8aULL },
+  { 0xc2f6666666666666ULL, 0x3fec842589258a43ULL, 0x3c8be0e63c382022ULL },
+  { 0x4314cccccccccccdULL, 0xbfb8c83b02d0edd8ULL, 0xbc56aefa58c5343aULL },
+  { 0xc306666666666666ULL, 0x3fe9e0d23d7b63fbULL, 0xbc63df0489efac8aULL },
+  { 0x4324cccccccccccdULL, 0x3fc8aa6f0eb7d6e8ULL, 0xbc6f0d05d98ad00bULL },
+  { 0xc316666666666666ULL, 0xbfee71d4d43065c8ULL, 0xbc3c11066a7c7820ULL },
+  { 0x4334cccccccccccdULL, 0x3fd83415dcc39cf5ULL, 0x3c7ec504249d12f4ULL },
+  { 0xc326666666666666ULL, 0x3fe2c090300f8b41ULL, 0xbc64e4612cfafa3fULL },
+  { 0x4344cccccccccccdULL, 0x3fe667eadf0c9687ULL, 0xbc7d15e3579ca723ULL },
+  { 0xc336666666666666ULL, 0xbfee63daff3f7a38ULL, 0x3c6f422c46d3b643ULL },
+  { 0x4354cccccccccccdULL, 0x3feffe7201c77109ULL, 0xbc7a2f5a9a315bc5ULL },
+  { 0xc346666666666666ULL, 0xbfe30932a56c8d60ULL, 0xbc7e3ffe82882405ULL },
+  { 0x4364cccccccccccdULL, 0x3fa3f1ed89cea39aULL, 0x3c2da0dbd2d9b162ULL },
+  { 0xc356666666666666ULL, 0x3fee9a58b002a034ULL, 0xbc6c545be6465beaULL },
+  { 0x4374cccccccccccdULL, 0xbfb3ee0d626f0451ULL, 0x3c38d8d5a58deec7ULL },
+  { 0xc366666666666666ULL, 0x3fe1e337ef53849dULL, 0xbc6ae2ff488320f3ULL },
+  { 0x4384cccccccccccdULL, 0xbfc3de9149623dedULL, 0x3c637241b7759eeaULL },
+  { 0xc376666666666666ULL, 0xbfeda9f6565e4ad4ULL, 0xbc8abcda8c5ed688ULL },
+  { 0x4394cccccccccccdULL, 0xbfd3a0e90232184bULL, 0x3c7f6e585666b849ULL },
+  { 0xc386666666666666ULL, 0xbfe64080b64705d9ULL, 0xbc89732e5261d935ULL },
+  { 0x43a4cccccccccccdULL, 0xbfe2aebf3df4916bULL, 0x3c8257a9dbcfe608ULL },
+  { 0xc396666666666666ULL, 0x3feffb8ffd30a77eULL, 0xbc836f7b57c09ddaULL },
+  { 0x43b4cccccccccccdULL, 0xbfee55fc106d55f0ULL, 0x3c885a72252865aaULL },
+  { 0xc3a6666666666666ULL, 0x3fb0d749e0c3b4a7ULL, 0xbc597900b9f6f0fdULL },
+  { 0x43c4cccccccccccdULL, 0xbfe34f8ac636abe3ULL, 0x3c8937b74f68ae73ULL },
+  { 0xc3b6666666666666ULL, 0xbfc0cdf315af3596ULL, 0x3c512538ad03ee87ULL },
+  { 0x43d4cccccccccccdULL, 0x3feecbe57c52f065ULL, 0xbc8f10b1032a8e5aULL },
+  { 0xc3c6666666666666ULL, 0xbfd0a8b6f666a71fULL, 0x3c7c1132e46f8c06ULL },
diff --git a/newlib/libm/machine/riscv/vec_sin.c b/newlib/libm/machine/riscv/vec_sin.c
new file mode 100644
index 000000000..c4ea93196
--- /dev/null
+++ b/newlib/libm/machine/riscv/vec_sin.c
@@ -0,0 +1,219 @@ 
+/*
+ * Vectorized sin(double) for the RISC-V Vector extension (RVV).
+ *
+ * Exports the vector-function-ABI symbol
+ *
+ *	vfloat64m1_t _ZGVr1Nxv_sin (vfloat64m1_t x);
+ *
+ * following the RISC-V vector function calling convention proposed in
+ * riscv-non-isa/riscv-elf-psabi-doc PR #455.  The mangled name decodes as
+ * "_ZGV" <isa="r"> <lmul=1> <mask="N" (unmasked)> <len="x" (VLA mode)>
+ * <param="v" (vector)> "_" <func="sin">, i.e. the LMUL=1, unmasked,
+ * vector-length-agnostic variant that the LLVM/GCC vectorizers emit when
+ * lowering a scalar sin() over a double loop.
+ *
+ * Accuracy: the worst-case error is <= 1 ULP.  See test_vec_sin.c.
+ *
+ * This file is only meaningful when compiled for a target that has the V
+ * extension; on scalar multilibs it compiles to an empty translation unit
+ * so that a single --enable-vecmath build stays multilib-safe (no -march
+ * override is applied to this file; it relies on the multilib's own ISA).
+ */
+
+#pragma STDC FP_CONTRACT OFF
+
+#if defined(__riscv_vector)
+
+#include <math.h>
+#include <stddef.h>
+#include <riscv_vector.h>
+
+/* Argument-reduction and polynomial constants (fdlibm, SunPro).  pi/2 is
+ * split into three 33-bit-significand doubles so that n*P{1,2,3} is exact
+ * for the fast-path range |n| < 2^20, plus a tiny tail P3t.  */
+static const double
+  INVPIO2 = 6.36619772367581382433e-01, /* 2/pi                       */
+  PIO2_1  = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000     */
+  PIO2_2  = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000     */
+  PIO2_3  = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000     */
+  PIO2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1     */
+
+static const double
+  half = 5.00000000000000000000e-01,
+  S1 = -1.66666666666666324348e-01,     /* sin kernel coefficients    */
+  S2 =  8.33333333332248946124e-03,
+  S3 = -1.98412698298579493134e-04,
+  S4 =  2.75573137070700676789e-06,
+  S5 = -2.50507602534068634195e-08,
+  S6 =  1.58969099521155010221e-10,
+  one = 1.00000000000000000000e+00,
+  C1 =  4.16666666666666019037e-02,     /* cos kernel coefficients    */
+  C2 = -1.38888888888741095749e-03,
+  C3 =  2.48015872894767294178e-05,
+  C4 = -2.75573143513906633035e-07,
+  C5 =  2.08757232129817482790e-09,
+  C6 = -1.13596475577881948265e-11;
+
+/* Above this magnitude the fast Cody-Waite reduction can no longer keep
+ * n*PIO2_1 exact, so those lanes fall back to the scalar Payne-Hanek
+ * reducer __ieee754_rem_pio2().  2^20 is well inside the exact region.  */
+#define VEC_SIN_FAST_LIMIT 1.0e6
+
+/* Scalar Payne-Hanek reducer shared with the rest of libm.  Returns n and
+ * writes the reduced argument as the unevaluated sum y[0]+y[1], |y[0]+y[1]|
+ * <= pi/4.  Used only by the slow-path lanes.  */
+extern __int32_t __ieee754_rem_pio2 (double, double *);
+
+/* ---- shared double-double trig kernels (scalar reference form) ----------
+ * These evaluate sin/cos on [-pi/4, pi/4] given the reduced argument as a
+ * head+tail pair (y0 large, y1 the correction).  They are identical in
+ * spirit to fdlibm __kernel_sin/__kernel_cos but always take a tail.  */
+static double
+sin_kernel_scalar (double y0, double y1)
+{
+  double z = y0 * y0;
+  double v = z * y0;
+  double r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6)));
+  return y0 - ((z * (half * y1 - v * r) - y1) - v * S1);
+}
+
+static double
+cos_kernel_scalar (double y0, double y1)
+{
+  double z = y0 * y0;
+  double r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6)))));
+  return one - (0.5 * z - (z * r - y0 * y1));
+}
+
+/* Slow path for a single lane: full-range sin using Payne-Hanek reduction.
+ * Handles |x| >= VEC_SIN_FAST_LIMIT as well as Inf/NaN (rem_pio2 returns
+ * x-x = NaN for those, which propagates through the kernels).  */
+static double
+sin_scalar_slow (double x)
+{
+  double y[2];
+  __int32_t n = __ieee754_rem_pio2 (x, y);
+  /* Renormalize the pair so the kernel sees a clean head+tail. */
+  double s = y[0] + y[1];
+  double t = y[1] - (s - y[0]);
+  double sk = sin_kernel_scalar (s, t);
+  double ck = cos_kernel_scalar (s, t);
+  double res = (n & 1) ? ck : sk;
+  return (n & 2) ? -res : res;
+}
+
+/* ---- vector double-double primitives (exact add with error term) --------
+ * Written with discrete vfadd/vfsub intrinsics; no fused multiply-add is
+ * emitted between them, so the Knuth/Dekker error terms are exact.  */
+static inline vfloat64m1_t
+vtwo_sum (vfloat64m1_t a, vfloat64m1_t b, vfloat64m1_t *err, size_t vl)
+{
+  vfloat64m1_t s  = __riscv_vfadd_vv_f64m1 (a, b, vl);
+  vfloat64m1_t bb = __riscv_vfsub_vv_f64m1 (s, a, vl);
+  vfloat64m1_t ap = __riscv_vfsub_vv_f64m1 (a, __riscv_vfsub_vv_f64m1 (s, bb, vl), vl);
+  vfloat64m1_t bp = __riscv_vfsub_vv_f64m1 (b, bb, vl);
+  *err = __riscv_vfadd_vv_f64m1 (ap, bp, vl);
+  return s;
+}
+
+static inline vfloat64m1_t
+vfast_two_sum (vfloat64m1_t a, vfloat64m1_t b, vfloat64m1_t *err, size_t vl)
+{
+  vfloat64m1_t s = __riscv_vfadd_vv_f64m1 (a, b, vl);
+  *err = __riscv_vfsub_vv_f64m1 (b, __riscv_vfsub_vv_f64m1 (s, a, vl), vl);
+  return s;
+}
+
+/* Vectorized sin, LMUL=1, unmasked, VLA mode (RISC-V vector function ABI). */
+vfloat64m1_t
+_ZGVr1Nxv_sin (vfloat64m1_t x)
+{
+  size_t vl = __riscv_vsetvlmax_e64m1 ();
+
+  /* ---- fast path: Cody-Waite reduction with dd error tracking ---------- */
+  /* n = round(x * 2/pi); fn = (double)n, ni = (int64)n. */
+  vfloat64m1_t prod = __riscv_vfmul_vf_f64m1 (x, INVPIO2, vl);
+  vint64m1_t   ni   = __riscv_vfcvt_x_f_v_i64m1_rm (prod, __RISCV_FRM_RNE, vl);
+  vfloat64m1_t fn   = __riscv_vfcvt_f_x_v_f64m1 (ni, vl);
+
+  /* r = x - fn*P1  (exact); accumulate the reduction tail in e. */
+  vfloat64m1_t r = __riscv_vfsub_vv_f64m1 (x, __riscv_vfmul_vf_f64m1 (fn, PIO2_1, vl), vl);
+  vfloat64m1_t e, c;
+  r = vtwo_sum (r, __riscv_vfmul_vf_f64m1 (fn, -PIO2_2, vl), &c, vl);
+  e = c;
+  r = vtwo_sum (r, __riscv_vfmul_vf_f64m1 (fn, -PIO2_3, vl), &c, vl);
+  e = __riscv_vfadd_vv_f64m1 (e, c, vl);
+  e = __riscv_vfsub_vv_f64m1 (e, __riscv_vfmul_vf_f64m1 (fn, PIO2_3t, vl), vl);
+  /* renormalize (r + e) into the reduced argument (y0 + y1). */
+  vfloat64m1_t y1;
+  vfloat64m1_t y0 = vfast_two_sum (r, e, &y1, vl);
+
+  /* sin kernel: y0 - ((z*(half*y1 - v*rs) - y1) - v*S1), z=y0^2, v=z*y0 */
+  vfloat64m1_t z = __riscv_vfmul_vv_f64m1 (y0, y0, vl);
+  vfloat64m1_t v = __riscv_vfmul_vv_f64m1 (z, y0, vl);
+  vfloat64m1_t rs = __riscv_vfadd_vf_f64m1 (
+      __riscv_vfmul_vv_f64m1 (z, __riscv_vfadd_vf_f64m1 (
+        __riscv_vfmul_vv_f64m1 (z, __riscv_vfadd_vf_f64m1 (
+          __riscv_vfmul_vv_f64m1 (z, __riscv_vfadd_vf_f64m1 (
+            __riscv_vfmul_vf_f64m1 (z, S6, vl), S5, vl), vl), S4, vl), vl), S3, vl), vl), S2, vl);
+  vfloat64m1_t t1 = __riscv_vfsub_vv_f64m1 (
+      __riscv_vfmul_vf_f64m1 (y1, half, vl), __riscv_vfmul_vv_f64m1 (v, rs, vl), vl);
+  vfloat64m1_t t2 = __riscv_vfsub_vv_f64m1 (__riscv_vfmul_vv_f64m1 (z, t1, vl), y1, vl);
+  vfloat64m1_t t3 = __riscv_vfsub_vv_f64m1 (t2, __riscv_vfmul_vf_f64m1 (v, S1, vl), vl);
+  vfloat64m1_t sk = __riscv_vfsub_vv_f64m1 (y0, t3, vl);
+
+  /* cos kernel: one - (0.5*z - (z*rc - y0*y1)) */
+  vfloat64m1_t rc = __riscv_vfmul_vv_f64m1 (z, __riscv_vfadd_vf_f64m1 (
+      __riscv_vfmul_vv_f64m1 (z, __riscv_vfadd_vf_f64m1 (
+        __riscv_vfmul_vv_f64m1 (z, __riscv_vfadd_vf_f64m1 (
+          __riscv_vfmul_vv_f64m1 (z, __riscv_vfadd_vf_f64m1 (
+            __riscv_vfmul_vv_f64m1 (z, __riscv_vfadd_vf_f64m1 (
+              __riscv_vfmul_vf_f64m1 (z, C6, vl), C5, vl), vl), C4, vl), vl), C3, vl), vl), C2, vl), vl), C1, vl), vl);
+  vfloat64m1_t ck_inner = __riscv_vfsub_vv_f64m1 (
+      __riscv_vfmul_vf_f64m1 (z, 0.5, vl),
+      __riscv_vfsub_vv_f64m1 (__riscv_vfmul_vv_f64m1 (z, rc, vl),
+                              __riscv_vfmul_vv_f64m1 (y0, y1, vl), vl), vl);
+  vfloat64m1_t ck = __riscv_vfrsub_vf_f64m1 (ck_inner, one, vl);
+
+  /* Quadrant select: (n & 1) ? cos : sin, then negate if (n & 2). */
+  vbool64_t use_cos = __riscv_vmsne_vx_i64m1_b64 (
+      __riscv_vand_vx_i64m1 (ni, 1, vl), 0, vl);
+  vfloat64m1_t res = __riscv_vmerge_vvm_f64m1 (sk, ck, use_cos, vl);
+  vbool64_t neg = __riscv_vmsne_vx_i64m1_b64 (
+      __riscv_vand_vx_i64m1 (ni, 2, vl), 0, vl);
+  res = __riscv_vmerge_vvm_f64m1 (res, __riscv_vfneg_v_f64m1 (res, vl), neg, vl);
+
+  /* sin is odd, so the result must carry the sign of x when it is exactly
+   * zero (sin(-0) = -0).  The only representable input whose result is an
+   * exact zero is x = +-0, so applying copysign(res, x) to zero lanes is
+   * safe and matches the scalar sin().  */
+  vbool64_t is_zero = __riscv_vmfeq_vf_f64m1_b64 (res, 0.0, vl);
+  vfloat64m1_t signed_zero = __riscv_vfsgnj_vv_f64m1 (
+      __riscv_vfmv_v_f_f64m1 (0.0, vl), x, vl);
+  res = __riscv_vmerge_vvm_f64m1 (res, signed_zero, is_zero, vl);
+
+  /* ---- slow path: |x| >= limit, and Inf/NaN (which fail the < test) ---- */
+  vfloat64m1_t ax = __riscv_vfabs_v_f64m1 (x, vl);
+  vbool64_t slow = __riscv_vmnot_m_b64 (
+      __riscv_vmflt_vf_f64m1_b64 (ax, VEC_SIN_FAST_LIMIT, vl), vl);
+  if (__riscv_vcpop_m_b64 (slow, vl) > 0)
+    {
+      vuint64m1_t idx = __riscv_vid_v_u64m1 (vl);
+      for (size_t i = 0; i < vl; i++)
+        {
+          double xi = __riscv_vfmv_f_s_f64m1_f64 (
+              __riscv_vslidedown_vx_f64m1 (x, i, vl));
+          if (!(fabs (xi) < VEC_SIN_FAST_LIMIT)) /* true for large/Inf/NaN */
+            {
+              double ri = sin_scalar_slow (xi);
+              vbool64_t lane = __riscv_vmseq_vx_u64m1_b64 (idx, i, vl);
+              res = __riscv_vfmerge_vfm_f64m1 (res, ri, lane, vl);
+            }
+        }
+    }
+
+  return res;
+}
+
+#endif /* __riscv_vector */
+