aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuuta Liang <yuuta@yuuta.moe>2023-08-01 17:34:34 +0800
committerYuuta Liang <yuuta@yuuta.moe>2023-08-01 17:34:34 +0800
commit98a80a1128c910ae40fbec8a278f7bf0308e3d74 (patch)
tree1a3e2d1aed105349c0f6b79a407e95d28986a57a
downloadrvv-98a80a1128c910ae40fbec8a278f7bf0308e3d74.tar
rvv-98a80a1128c910ae40fbec8a278f7bf0308e3d74.tar.gz
rvv-98a80a1128c910ae40fbec8a278f7bf0308e3d74.tar.bz2
rvv-98a80a1128c910ae40fbec8a278f7bf0308e3d74.zip
First Commit
-rw-r--r--.gitignore2
-rw-r--r--Makefile25
-rw-r--r--README.txt19
-rw-r--r--rv.S58
-rw-r--r--rv.c35
5 files changed, 139 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..774f008
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.exe
+*.o
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..dc34210
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,25 @@
+.POSIX:
+
+# riscv-gnu-toolchain w/ --with-arch=rv64gcv + GCC 13.1
+TOOLCHAIN=/home/yuuta/toolchain13/bin/
+CROSS=riscv64-unknown-linux-gnu-
+_T=$(TOOLCHAIN)$(CROSS)
+
+run: rv.exe
+ qemu-riscv64 \
+ -g 10000 \
+ -cpu rv64,v=true,zba=true,vlen=256 \
+ ./rv.exe &
+ $(_T)gdb -ex 'target remote localhost:10000' -tui ./rv.exe
+
+rv.exe: rv.c.o rv.s.o
+ $(_T)ld -o rv.exe rv.c.o rv.s.o
+
+rv.c.o: rv.c
+ $(_T)gcc -O2 -march=rv64imv -g -c -o rv.c.o rv.c
+
+rv.s.o: rv.S
+ $(_T)as -march=rv64imv -g -o rv.s.o rv.S
+
+clean:
+ rm -f rv.exe rv.c.o rv.s.o
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..c85ce49
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,19 @@
+Learning RISC-V instructions, RISC-V assembly, and RISC-V Vector instructions /
+intrinsics.
+
+Start: Jul. 23 / 2023 (UTC + 8)
+First commit: Aug. 1 / 2023 (UTC + 8)
+
+Progress before first commimt:
+
+* Basic SIMD concepts
+* Assembly development environment (GNU assembler w/ RVV support + ld + qemu-us
+er + GDB)
+* Basic cross-compile concepts: tuple, etc.
+* Basic RVV assembly, registers, RV64I instructions
+* Basic RVV concepts: SEW, VL, AVL, VLMAX, VLEN
+* Basic RVV instructions: setvli, v[ls]e8.v, vmsne.vv, vcpop.m
+* C development environment (riscv-gnu-toolchain)
+* Basic RVV intrinsics
+
+WTFPL.
diff --git a/rv.S b/rv.S
new file mode 100644
index 0000000..b999a41
--- /dev/null
+++ b/rv.S
@@ -0,0 +1,58 @@
+.section .rodata
+STR:
+ .string "Hello, World!"
+ .zero 242
+
+SH1:
+ .incbin "/usr/bin/bash"
+
+SH2:
+ .incbin "/usr/bin/systemctl"
+
+.section .text
+memcpy: # void *memcpy(a0 dst, a1 src, a2 n)
+ mv t1, a0 # dst1
+loop:
+ vsetvli t0, a2, e8, m8, ta, ma # VL = min(a2, 8 * VLEN / 8)
+ vle8.v v0, (a1) # memcpy(v0, a1, VL)
+ vse8.v v0, (t1) # memcpy(t1, v0, VL)
+ sub a2, a2, t0 # n -= VL
+ add a1, a1, t0 # src += VL
+ add t1, t1, t0 # dst += VL
+ bnez a2, loop # if (n) goto loop
+ ret
+
+memcmp: # bool memcmp(a0 s0, a1 s1, a2 n)
+ vsetvli t0, a2, e8, m8, ta, ma
+ vle8.v v8, (a0) # [v8, v15] = s0
+ vle8.v v16, (a1) # [v16, v23] = s1
+ vmsne.vv v0, v8, v16 # v0 = diff(v8, v16)
+ vcpop.m t1, v0 # t1 = count(v0)
+ bnez t1, memcmp_ret # if (t1 != 0) ret
+ sub a2, a2, t0 # n -= t0
+ beqz a2, memcmp_ret # if (n == 0) ret
+ add a0, a0, t0 # s0 += t0
+ add a1, a1, t0 # s1 += t0
+ j memcmp # goto loop
+memcmp_ret:
+ mv a0, t1 # Copy t1 to return value
+ ret
+
+exit:
+ li a7, 93
+ ecall
+ jr ra
+
+.global _start
+_start:
+ addi sp, sp, -256
+ li a2, 130 # n
+ la a1, STR # src
+ mv a0, sp # dst
+ jal memcpy_c
+ li a2, 128 # n
+ mv a1, sp # src
+ la a0, STR # dst
+ jal memcmp
+ addi sp, sp, 256
+ jal exit
diff --git a/rv.c b/rv.c
new file mode 100644
index 0000000..b0f239d
--- /dev/null
+++ b/rv.c
@@ -0,0 +1,35 @@
+#include <riscv_vector.h>
+#include <stdbool.h>
+
+void *memcpy_c(void *dst, const void *src, size_t n) {
+ void *dst2 = dst;
+ while (n) {
+ size_t vl = __riscv_vsetvl_e8m8(n);
+ vuint8m8_t v = __riscv_vle8_v_u8m8(src, vl);
+ __riscv_vse8_v_u8m8(dst2, v, vl);
+ dst2 += vl;
+ src += vl;
+ n -= vl;
+ }
+ return dst;
+}
+
+bool memcmp_c(void *s1, void *s2, size_t n) {
+ while (n) {
+ size_t vl = __riscv_vsetvl_e8m8(n);
+ vuint8m8_t v1 = __riscv_vle8_v_u8m8(s1, vl);
+ vuint8m8_t v2 = __riscv_vle8_v_u8m8(s1, vl);
+ vuint8m8_t vd = __riscv_vle8_v_u8m8(s1, vl);
+ }
+}
+
+bool memcmp_naive(void *s1, void *s2, size_t n) {
+ while (n) {
+ if (*((char *) s1) != *((char *) s2)) {
+ return true;
+ }
+ s1 ++;
+ s2 ++;
+ n --;
+ }
+}