Vector Tests: Add vsetvl tests.

Change-Id: I32ae05c58db8a4ec3b36c4f15d2ec1752a52117e
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6e3a227..c4b0d6a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,3 +27,5 @@
 add_subdirectory(vector_executive)
 add_subdirectory(vector_vset_tests)
 add_subdirectory(pw_unit_test_demo)
+
+add_subdirectory(test_vsetvl)
diff --git a/test_vsetvl/CMakeLists.txt b/test_vsetvl/CMakeLists.txt
new file mode 100644
index 0000000..cd7a075
--- /dev/null
+++ b/test_vsetvl/CMakeLists.txt
@@ -0,0 +1,42 @@
+cmake_minimum_required(VERSION 3.10)
+
+project(test_vsetvl)
+set (CMAKE_CXX_STANDARD 17)
+
+set(TARGET test_vsetvl)
+set(ELF ${TARGET}.elf)
+
+add_executable(${ELF} ${TARGET}.cpp)
+
+target_include_directories(${ELF} PUBLIC include)
+
+set_target_properties(${ELF} PROPERTIES LINK_DEPENDS "${LINKER_SCRIPT}")
+
+
+target_link_libraries(${ELF} springbok)
+target_link_libraries(${ELF} pw_unit_test)
+target_link_libraries(${ELF} pw_unit_test.main)
+target_link_libraries(${ELF} pw_assert_basic)
+
+
+set_target_properties(
+    ${ELF}
+    PROPERTIES
+    LINK_FLAGS
+     "-specs=nano.specs \
+    -Wl,--gc-sections \
+    -Wl,--print-memory-usage \
+    -Wl,-Map=${PROJECT_NAME}.map \
+    -T${LINKER_SCRIPT} \
+    -Xlinker --defsym=__itcm_length__=256K")
+
+target_compile_options(${ELF} PUBLIC
+    -Wall
+    -Werror
+    -O3
+    -g3
+    -ggdb
+    -ffreestanding
+    -ffunction-sections
+    -fstack-usage
+    -mstrict-align)
diff --git a/test_vsetvl/test_vsetvl.cpp b/test_vsetvl/test_vsetvl.cpp
new file mode 100644
index 0000000..8eb5912
--- /dev/null
+++ b/test_vsetvl/test_vsetvl.cpp
@@ -0,0 +1,160 @@
+#include <riscv_vector.h>
+#include <springbok_intrinsics.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pw_unit_test/framework.h"
+
+namespace test_vsetvl {
+namespace {
+
+const uint64_t VLEN = 512u;
+const uint64_t ELEN = 32u;
+
+uint32_t AVLS[] = {1,    2,    3,     4,     5,     8,    16,   17,
+                   32,   36,   55,    64,    100,   128,  256,  321,
+                   512,  623,  1024,  1100,  1543,  2048, 3052, 4096,
+                   5555, 8192, 10241, 16384, 24325, 32768};
+const int32_t AVL_COUNT = sizeof(AVLS) / sizeof(AVLS[0]);
+
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+
+static uint32_t calculate_vl(uint32_t sew, uint32_t avl, float lmul) {
+  uint32_t vlmax = (uint32_t)(VLEN * lmul / sew);
+  return MIN(avl, vlmax);
+}
+
+TEST(VsetvlTest, vsetvl_e8m1) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e8m1(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(8, AVLS[i], 1.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e16m1) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e16m1(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(16, AVLS[i], 1.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e32m1) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e32m1(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(32, AVLS[i], 1.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e8m2) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e8m2(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(8, AVLS[i], 2.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e16m2) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e16m2(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(16, AVLS[i], 2.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e32m2) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e32m2(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(32, AVLS[i], 2.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e8m4) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e8m4(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(8, AVLS[i], 4.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e16m4) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e16m4(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(16, AVLS[i], 4.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e32m4) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e32m4(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(32, AVLS[i], 4.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e8m8) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e8m8(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(8, AVLS[i], 8.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e16m8) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e16m8(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(16, AVLS[i], 8.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvl_e32m8) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    size_t vl = vsetvl_e32m8(AVLS[i]);
+    EXPECT_EQ(vl, calculate_vl(32, AVLS[i], 8.0));
+  }
+}
+
+TEST(VsetvlTest, vsetvlmax_e8m1) {
+  EXPECT_EQ(vsetvlmax_e8m1(), (int)VLEN / 8 * 1);
+}
+
+TEST(VsetvlTest, vsetvlmax_e8m2) {
+  EXPECT_EQ(vsetvlmax_e8m2(), (int)VLEN / 8 * 2);
+}
+
+TEST(VsetvlTest, vsetvlmax_e8m4) {
+  EXPECT_EQ(vsetvlmax_e8m4(), (int)VLEN / 8 * 4);
+}
+
+TEST(VsetvlTest, vsetvlmax_e8m8) {
+  EXPECT_EQ(vsetvlmax_e8m8(), (int)VLEN / 8 * 8);
+}
+
+TEST(VsetvlTest, vsetvlmax_e16m1) {
+  EXPECT_EQ(vsetvlmax_e16m1(), (int)VLEN / 16 * 1);
+}
+
+TEST(VsetvlTest, vsetvlmax_e16m2) {
+  EXPECT_EQ(vsetvlmax_e16m2(), (int)VLEN / 16 * 2);
+}
+
+TEST(VsetvlTest, vsetvlmax_e16m4) {
+  EXPECT_EQ(vsetvlmax_e16m4(), (int)VLEN / 16 * 4);
+}
+
+TEST(VsetvlTest, vsetvlmax_e16m8) {
+  EXPECT_EQ(vsetvlmax_e16m8(), (int)VLEN / 16 * 8);
+}
+
+TEST(VsetvlTest, vsetvlmax_e32m1) {
+  EXPECT_EQ(vsetvlmax_e32m1(), (int)VLEN / 32 * 1);
+}
+
+TEST(VsetvlTest, vsetvlmax_e32m2) {
+  EXPECT_EQ(vsetvlmax_e32m2(), (int)VLEN / 32 * 2);
+}
+
+TEST(VsetvlTest, vsetvlmax_e32m4) {
+  EXPECT_EQ(vsetvlmax_e32m4(), (int)VLEN / 32 * 4);
+}
+
+TEST(VsetvlTest, vsetvlmax_e32m8) {
+  EXPECT_EQ(vsetvlmax_e32m8(), (int)VLEN / 32 * 8);
+}
+
+}  // namespace
+}  // namespace test_vsetvl