diff --git a/newlib/libc/machine/riscv/memcpy-asm.S b/newlib/libc/machine/riscv/memcpy-asm.S
index 2771285f9..9d1d2d4bd 100644
--- a/newlib/libc/machine/riscv/memcpy-asm.S
+++ b/newlib/libc/machine/riscv/memcpy-asm.S
@@ -9,11 +9,11 @@
    http://www.opensource.org/licenses.
 */
 
-#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
 .text
 .global memcpy
 .type	memcpy, @function
 memcpy:
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
   mv a3, a0
   beqz a2, 2f
 
@@ -29,4 +29,25 @@ memcpy:
   ret
 
   .size	memcpy, .-memcpy
+#elif defined(__riscv_v)
+  .option push
+  .option arch, +v
+  mv      t0, a0                    /* running dst */
+  mv      t1, a1                    /* running src */
+  beqz    a2, .Ldone_copy           /* n == 0 then return */
+
+.Lbulk_copy:
+  vsetvli t2, a2, e8, m8, ta, ma    /* t2 = vl (bytes) */
+  vle8.v  v0, (t1)
+  vse8.v  v0, (t0)
+  add     t0, t0, t2
+  add     t1, t1, t2
+  sub     a2, a2, t2
+  bnez    a2, .Lbulk_copy
+  /* fallthrough */
+
+.Ldone_copy:
+  ret
+.size memcpy, .-memcpy
+.option pop
 #endif
diff --git a/newlib/libc/machine/riscv/memcpy.c b/newlib/libc/machine/riscv/memcpy.c
index a27e0ecb1..cd58c30a5 100644
--- a/newlib/libc/machine/riscv/memcpy.c
+++ b/newlib/libc/machine/riscv/memcpy.c
@@ -10,7 +10,7 @@
    http://www.opensource.org/licenses.
 */
 
-#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(__riscv_v)
 // memcpy defined in memcpy-asm.S
 #else
 
diff --git a/newlib/libc/machine/riscv/memmove-asm.S b/newlib/libc/machine/riscv/memmove-asm.S
index 061472ca2..5cc2e5143 100644
--- a/newlib/libc/machine/riscv/memmove-asm.S
+++ b/newlib/libc/machine/riscv/memmove-asm.S
@@ -9,11 +9,11 @@
    http://www.opensource.org/licenses.
 */
 
-#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
 .text
 .global memmove
 .type	memmove, @function
 memmove:
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
   beqz a2, .Ldone		/* in case there are 0 bytes to be copied, return immediately */
 
   mv a4, a0			/* copy the destination address over to a4, since memmove should return that address in a0 at the end */
@@ -37,4 +37,49 @@ memmove:
   ret
 
   .size	memmove, .-memmove
+#elif defined(__riscv_v)
+  .option push
+  .option arch, +v
+  beqz    a2, .Ldone_move           /* n == 0 */
+  beq     a0, a1, .Ldone_move       /* dst == src */
+
+  /* overlap check */
+  bgeu    a1, a0, .Lforward_move    /* src >= dst then forward move*/
+
+  sub     t2, a0, a1                /* t2 = dst - src */
+  bgeu    t2, a2, .Lforward_move    /* no overlap then forward move */
+
+  /* backward move */
+  add     t0, a0, a2                /* running dst_end */
+  add     t1, a1, a2                /* running src_end */
+
+.Lbackward_loop:
+  vsetvli t3, a2, e8, m8, ta, ma    /* t3 = vl (bytes) */
+  sub     t0, t0, t3
+  sub     t1, t1, t3
+  vle8.v  v0, (t1)
+  vse8.v  v0, (t0)
+  sub     a2, a2, t3
+  bnez    a2, .Lbackward_loop
+  j       .Ldone_move
+
+/* forward move, same as memcpy */
+.Lforward_move:
+  mv      t0, a0                    /* running dst */
+  mv      t1, a1                    /* running src */
+
+.Lforward_loop:
+  vsetvli t3, a2, e8, m8, ta, ma
+  vle8.v  v0, (t1)
+  vse8.v  v0, (t0)
+  add     t0, t0, t3
+  add     t1, t1, t3
+  sub     a2, a2, t3
+  bnez    a2, .Lforward_loop
+  /* fallthrough */
+
+.Ldone_move:
+  ret
+.size memmove, .-memmove
+.option pop
 #endif
diff --git a/newlib/libc/machine/riscv/memmove.c b/newlib/libc/machine/riscv/memmove.c
index 209a75c69..67ce08b02 100644
--- a/newlib/libc/machine/riscv/memmove.c
+++ b/newlib/libc/machine/riscv/memmove.c
@@ -10,7 +10,7 @@
    http://www.opensource.org/licenses.
 */
 
-#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(__riscv_v)
 /* memmove defined in memmove-asm.S */
 #else
 
diff --git a/newlib/libc/machine/riscv/memset.S b/newlib/libc/machine/riscv/memset.S
index 533f66758..80f43fbaf 100644
--- a/newlib/libc/machine/riscv/memset.S
+++ b/newlib/libc/machine/riscv/memset.S
@@ -63,6 +63,28 @@ memset:
 .Ldone:
   ret
 
+#elif defined(__riscv_v)
+  .option push
+  .option arch, +v
+  mv      t0, a0                    /* running dst; keep a0 as return */
+  beqz    a2, .Ldone_vect           /* n == 0 then return */
+
+  /* Broadcast fill byte once. */
+  vsetvli t1, zero, e8, m8, ta, ma
+  vmv.v.x v0, a1
+
+.Lbulk_vect:
+  vsetvli t1, a2, e8, m8, ta, ma    /* t1 = vl (bytes) */
+  vse8.v  v0, (t0)
+  add     t0, t0, t1
+  sub     a2, a2, t1
+  bnez    a2, .Lbulk_vect
+  /* fallthrough */
+
+.Ldone_vect:
+  ret
+  .option pop
+
 #else
   li     REG_TABLE, BYTE_TBL_SZ
   mv     a3, a0
