diff options
author | Yuuta Liang <yuuta@yuuta.moe> | 2023-08-01 17:34:34 +0800 |
---|---|---|
committer | Yuuta Liang <yuuta@yuuta.moe> | 2023-08-01 17:34:34 +0800 |
commit | 98a80a1128c910ae40fbec8a278f7bf0308e3d74 (patch) | |
tree | 1a3e2d1aed105349c0f6b79a407e95d28986a57a | |
download | rvv-98a80a1128c910ae40fbec8a278f7bf0308e3d74.tar rvv-98a80a1128c910ae40fbec8a278f7bf0308e3d74.tar.gz rvv-98a80a1128c910ae40fbec8a278f7bf0308e3d74.tar.bz2 rvv-98a80a1128c910ae40fbec8a278f7bf0308e3d74.zip |
First Commit
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | README.txt | 19 | ||||
-rw-r--r-- | rv.S | 58 | ||||
-rw-r--r-- | rv.c | 35 |
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. @@ -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 @@ -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 --; + } +} |