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.