aboutsummaryrefslogtreecommitdiff
path: root/src/example/strncpy.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/example/strncpy.s')
-rw-r--r--src/example/strncpy.s36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/example/strncpy.s b/src/example/strncpy.s
new file mode 100644
index 0000000..87e5410
--- /dev/null
+++ b/src/example/strncpy.s
@@ -0,0 +1,36 @@
+ .text
+ .balign 4
+ .global strncpy
+ # char* strncpy(char *dst, const char* src, size_t n)
+strncpy:
+ mv a3, a0 # Copy dst
+loop:
+ vsetvli x0, a2, e8, m8, ta, ma # Vectors of bytes.
+ vle8ff.v v8, (a1) # Get src bytes
+ vmseq.vi v1, v8, 0 # Flag zero bytes
+ csrr t1, vl # Get number of bytes fetched
+ vfirst.m a4, v1 # Zero found?
+ vmsbf.m v0, v1 # Set mask up to before zero byte.
+ vse8.v v8, (a3), v0.t # Write out non-zero bytes
+ bgez a4, zero_tail # Zero remaining bytes.
+ sub a2, a2, t1 # Decrement count.
+ add a3, a3, t1 # Bump dest pointer
+ add a1, a1, t1 # Bump src pointer
+ bnez a2, loop # Anymore?
+
+ ret
+
+zero_tail:
+ sub a2, a2, a4 # Subtract count on non-zero bytes.
+ add a3, a3, a4 # Advance past non-zero bytes.
+ vsetvli t1, a2, e8, m8, ta, ma # Vectors of bytes.
+ vmv.v.i v0, 0 # Splat zero.
+
+zero_loop:
+ vse8.v v0, (a3) # Store zero.
+ sub a2, a2, t1 # Decrement count.
+ add a3, a3, t1 # Bump pointer
+ vsetvli t1, a2, e8, m8, ta, ma # Vectors of bytes.
+ bnez a2, zero_loop # Anymore?
+
+ ret