Previously the C program we wrote used C RVV intrinsics, but you might want to use the RISC-V RVV assembly instructions instead.
We use C to handle the setting up of the vector arrays and the display of these vectors to the terminal. Doing I/O in assembly language is, at best, painful, so I have no issue with letting C take the weight.
In this example we will be using RVV version 1.0. The Makefile has been set up for using with SPIKE, but I have tested the code on my Banana Pi F3 and it runs.
Below is the Makefile, the C file and the assembly function that the C program calls.
Makefile
CFLAGS=-march=rv64gcv -mabi=lp64d -mno-relax CC=riscv64-unknown-linux-gnu-gcc SRC=main.c RVVaddition.s TARGET=RVVaddition $(TARGET):$(SRC) $(CC) -v $(CFLAGS) -o $(TARGET) $(SRC) run: $(RISCV)/riscv-isa-sim/build/spike --isa=RV64IMACV $(RISCV)/riscv-pk/build/pk ./$(TARGET) clean: rm -f $(TARGET)
main.c
/* * program to add two 4 evelmet vectors together * using RISC-V RVV assembly instructions */ #include <stdio.h> // Function prototype for the vec_add assembly function void vec_add(int *vec1, int *vec2, int *result); int main() { // Initialize two small vectors and a result vector int vectorA[4] = {1, 2, 3, 4}; int vectorB[4] = {5, 6, 7, 8}; int vectorC[4] = {0}; // Output vectorA and vectorB to the terminal printf("Vector A: "); for (int i = 0; i < 4; i++) { printf("%2d ", vectorA[i]); } printf("\n"); printf("Vector B: "); for (int i = 0; i < 4; i++) { printf("%2d ", vectorB[i]); } printf("\n"); // Call the vec_add assembly function to add // vectorA and vectorB and return vectorC vec_add(vectorA, vectorB, vectorC); // Output the result to the terminal printf("vector C: "); for (int i = 0; i < 4; i++) { printf("%2d ", vectorC[i]); } printf("\n"); return 0; }
RVVaddition.s
# RISC-V assembly function to add two 4 element vectors # and return the result to the calling C program .global vec_add .section .text vec_add: # Set vector length to 4 elements of 32 bits each li t0, 4 # Number of elements vsetvli t0, t0, e32, m2 # Set vector length to 4 elements of # 32-bit each, with 2 registers per element # Load vectors from memory vle32.v v0, (a0) # Load vec1 into v0 vle32.v v8, (a1) # Load vec2 into v8 # Perform vector addition vadd.vv v0, v0, v8 # v0 = v0 + v8 # Store result in memory vse32.v v0, (a2) # Store v0 into result ret # Return to calling program
Compile and Run
me@bpif3:make me@bpif3:./RVVaddition Vector A: 1 2 3 4 Vector B: 5 6 7 8 Vector C: 6 8 10 12
Mission Accomplished
And there we have it, you have managed to do a vector addition of two 4 element arrays in RISC-V assembly with a calling C program handling the I/O.