Add vector_vset_tests.

Change-Id: I449279dd110c4f727c95c2fc596f09f143904254
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 69de19a..58f6cb5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,4 +17,5 @@
 add_subdirectory(vector_tests)
 add_subdirectory(vector_load_tests)
 add_subdirectory(vector_vadd_vsub_tests)
-add_subdirectory(vector_executive)
\ No newline at end of file
+add_subdirectory(vector_executive)
+add_subdirectory(vector_vset_tests)
\ No newline at end of file
diff --git a/vector_vset_tests/CMakeLists.txt b/vector_vset_tests/CMakeLists.txt
new file mode 100644
index 0000000..b0efd24
--- /dev/null
+++ b/vector_vset_tests/CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.10)
+
+project(vector_vset_tests)
+
+
+set(TARGET vector_vset_tests)
+set(ELF ${TARGET}.elf)
+
+add_executable(${ELF} vector_vset_tests.c)
+
+target_include_directories(${ELF} PUBLIC include)
+
+set_target_properties(${ELF} PROPERTIES LINK_DEPENDS "${LINKER_SCRIPT}")
+
+target_link_libraries(${ELF} vector_tests)
+
+set_target_properties(
+	${ELF}
+	PROPERTIES
+	LINK_FLAGS
+	"-T${LINKER_SCRIPT} \
+	 -specs=nano.specs \
+	 -Wl,--gc-sections \
+	 -Wl,--print-memory-usage \
+	 -Wl,-Map=${PROJECT_NAME}.map")
+
+target_compile_options(${ELF} PUBLIC
+	-nostdlib
+	-ffreestanding
+	-ffunction-sections
+	-Wall
+	-Werror
+	-std=gnu11
+	-O3
+	-g)
+
diff --git a/vector_vset_tests/include/vector_vset_tests.h b/vector_vset_tests/include/vector_vset_tests.h
new file mode 100644
index 0000000..843c7b7
--- /dev/null
+++ b/vector_vset_tests/include/vector_vset_tests.h
@@ -0,0 +1,11 @@
+#ifndef VECTOR_TESTS_VECTOR_VSET_TESTS_H_
+#define VECTOR_TESTS_VECTOR_VSET_TESTS_H_
+
+#include "test_vector.h"
+#include "common_vector_test.h"
+
+void test_vector_vsetvl(void);
+void test_vector_vsetvli(void);
+void test_vector_vsetivli(void);
+
+#endif
\ No newline at end of file
diff --git a/vector_vset_tests/vector_vset_tests.c b/vector_vset_tests/vector_vset_tests.c
new file mode 100644
index 0000000..fd61a7a
--- /dev/null
+++ b/vector_vset_tests/vector_vset_tests.c
@@ -0,0 +1,1723 @@
+#include <springbok.h>
+#include <string.h>
+#include "vector_vset_tests.h"
+
+uint8_t lmul_string_to_vlmul(const char *);
+uint32_t construct_vtype(const char *, uint8_t, bool, bool);
+void subtest_vsetvl(const char *, const char *, uint32_t, bool, bool, uint32_t,
+                    uint32_t);
+
+bool test_vector(void) {
+  uint32_t vlenb;
+  __asm__ volatile("csrr %0, vlenb" : "=r"(vlenb));
+  assert(vlenb == _TEST_VLENB);
+  test_vector_vsetvl();
+  test_vector_vsetvli();
+  test_vector_vsetivli();
+  return true;
+}
+
+uint8_t lmul_string_to_vlmul(const char *lmul) {
+  uint8_t vlmul = 0;
+  if (strequal(lmul, "1/8")) {
+    vlmul = 5;
+  } else if (strequal(lmul, "1/4")) {
+    vlmul = 6;
+  } else if (strequal(lmul, "1/2")) {
+    vlmul = 7;
+  } else if (strequal(lmul, "1")) {
+    vlmul = 0;
+  } else if (strequal(lmul, "2")) {
+    vlmul = 1;
+  } else if (strequal(lmul, "4")) {
+    vlmul = 2;
+  } else if (strequal(lmul, "8")) {
+    vlmul = 3;
+  } else {
+    assert(false);  // unhandled lmul
+  }
+  return vlmul;
+}
+
+uint32_t construct_vtype(const char *vtypei, uint8_t vlmul, bool tail_agnostic,
+                         bool mask_agnostic) {
+  uint32_t vtype = 0;
+  if (strequal(vtypei, "e8")) {
+    vtype = get_vtype_e8(vlmul, tail_agnostic, mask_agnostic);
+  } else if (strequal(vtypei, "e16")) {
+    vtype = get_vtype_e16(vlmul, tail_agnostic, mask_agnostic);
+  } else if (strequal(vtypei, "e32")) {
+    vtype = get_vtype_e32(vlmul, tail_agnostic, mask_agnostic);
+  } else if (strequal(vtypei, "e64")) {
+    vtype = get_vtype_e64(vlmul, tail_agnostic, mask_agnostic);
+  } else {
+    assert(false);  // unhandled vtypei
+  }
+
+  return vtype;
+}
+
+void subtest_vsetvl(const char *vtypei, const char *lmul, uint32_t avl,
+                    bool tail_agnostic, bool mask_agnostic,
+                    uint32_t expected_vl, uint32_t line) {
+  uint32_t observed_vl = 0;
+  uint8_t vlmul = lmul_string_to_vlmul(lmul);
+  uint32_t vtype = construct_vtype(vtypei, vlmul, tail_agnostic, mask_agnostic);
+  volatile uint32_t avl_vol = avl;
+
+  // vsetvl  rd, rs1, rs2      # rd = new vl, rs1 = AVL, rs2 = new vtype value
+  __asm__ volatile("vsetvl t0, %[AVL], %[VTYPE]" ::[AVL] "r"(avl_vol),
+                   [ VTYPE ] "r"(vtype));
+
+  COPY_SCALAR_REG("t0", observed_vl);
+  if (observed_vl != expected_vl) {
+    LOG_INFO("observed_vl = %lu, expected_vl = %lu, test_line = %lu ", observed_vl,
+             expected_vl, line);
+  }
+  assert(observed_vl == expected_vl);
+}
+
+void test_vector_vsetvl(void) {
+  LOG_INFO("%s", __FUNCTION__);
+  struct subtest_s {
+    const char *vtypei;  // e8, e16, e32, e64
+    const char *lmul;    // 1/8, 1/4, 1/2, 1, 2, 4, 8
+    uint32_t avl;
+    uint32_t expected_vl;  // blindly copy expected_vl from qemu simulation
+    uint32_t line;
+  };
+
+  struct subtest_s subtests[] = {
+      {.vtypei = "e8",
+       .lmul = "1/8",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/8",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/8",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/8",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/8",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/8",
+       .avl = 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/8",
+       .avl = 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/8",
+       .avl = 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 4) - 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 5) - 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 6) - 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 4),
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 5),
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 6),
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 4) + 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 5) + 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/8",
+       .avl = (_TEST_VLENB >> 6) + 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+
+      {.vtypei = "e8",
+       .lmul = "1/4",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/4",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/4",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/4",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/4",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/4",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/4",
+       .avl = 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/4",
+       .avl = 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 4) - 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 5) - 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 4),
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 5),
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 4) + 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/4",
+       .avl = (_TEST_VLENB >> 5) + 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+
+      {.vtypei = "e8",
+       .lmul = "1/2",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/2",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/2",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/2",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/2",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/2",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/2",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/2",
+       .avl = 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 4) - 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 4),
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1/2",
+       .avl = (_TEST_VLENB >> 4) + 1,
+       .expected_vl = 0,
+       .line = __LINE__},
+
+      {.vtypei = "e8",
+       .lmul = "1",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3),
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "1",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3),
+       .line = __LINE__},
+
+      {.vtypei = "e8",
+       .lmul = "2",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "2",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "2",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "2",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "2",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "2",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "2",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "2",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "2",
+       .avl = (_TEST_VLENB << 1) - 1,
+       .expected_vl = (_TEST_VLENB << 1) - 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "2",
+       .avl = (_TEST_VLENB << 1),
+       .expected_vl = (_TEST_VLENB << 1),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2),
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "2",
+       .avl = (_TEST_VLENB << 1) + 1,
+       .expected_vl = (_TEST_VLENB << 1),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "2",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2),
+       .line = __LINE__},
+
+      {.vtypei = "e8",
+       .lmul = "4",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "4",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "4",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "4",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "4",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "4",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "4",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "4",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "4",
+       .avl = (_TEST_VLENB << 2) - 1,
+       .expected_vl = (_TEST_VLENB << 2) - 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "4",
+       .avl = (_TEST_VLENB << 1) - 1,
+       .expected_vl = (_TEST_VLENB << 1) - 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "4",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "4",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "4",
+       .avl = (_TEST_VLENB << 2),
+       .expected_vl = (_TEST_VLENB << 2),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "4",
+       .avl = (_TEST_VLENB << 1),
+       .expected_vl = (_TEST_VLENB << 1),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "4",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "4",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1),
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "4",
+       .avl = (_TEST_VLENB << 2) + 1,
+       .expected_vl = (_TEST_VLENB << 2),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "4",
+       .avl = (_TEST_VLENB << 1) + 1,
+       .expected_vl = (_TEST_VLENB << 1),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "4",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "4",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1),
+       .line = __LINE__},
+
+      {.vtypei = "e8",
+       .lmul = "8",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "8",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "8",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "8",
+       .avl = 0,
+       .expected_vl = 0,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "8",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "8",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "8",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "8",
+       .avl = 1,
+       .expected_vl = 1,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 3) - 1,
+       .expected_vl = (_TEST_VLENB << 3) - 1,
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 2) - 1,
+       .expected_vl = (_TEST_VLENB << 2) - 1,
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 1) - 1,
+       .expected_vl = (_TEST_VLENB << 1) - 1,
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "8",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1,
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 3),
+       .expected_vl = (_TEST_VLENB << 3),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 2),
+       .expected_vl = (_TEST_VLENB << 2),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 1),
+       .expected_vl = (_TEST_VLENB << 1),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "8",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0),
+       .line = __LINE__},
+      {.vtypei = "e8",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 3) + 1,
+       .expected_vl = (_TEST_VLENB << 3),
+       .line = __LINE__},
+      {.vtypei = "e16",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 2) + 1,
+       .expected_vl = (_TEST_VLENB << 2),
+       .line = __LINE__},
+      {.vtypei = "e32",
+       .lmul = "8",
+       .avl = (_TEST_VLENB << 1) + 1,
+       .expected_vl = (_TEST_VLENB << 1),
+       .line = __LINE__},
+      {.vtypei = "e64",
+       .lmul = "8",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0),
+       .line = __LINE__},
+  };
+
+  uint32_t len = sizeof(subtests) / sizeof(struct subtest_s);
+  for (uint32_t i = 0; i < len; i++) {
+    LOG_INFO("Subtest %lu", i);
+    struct subtest_s subtest = subtests[i];
+    subtest_vsetvl(subtest.vtypei, subtest.lmul, subtest.avl, false, false,
+                   subtest.expected_vl, subtest.line);
+    subtest_vsetvl(subtest.vtypei, subtest.lmul, subtest.avl, false, true,
+                   subtest.expected_vl, subtest.line);
+    subtest_vsetvl(subtest.vtypei, subtest.lmul, subtest.avl, true, false,
+                   subtest.expected_vl, subtest.line);
+    subtest_vsetvl(subtest.vtypei, subtest.lmul, subtest.avl, true, true,
+                   subtest.expected_vl, subtest.line);
+  }
+}
+
+// vsetvli rd, rs1, vtypei   # rd = new vl, rs1 = AVL, vtypei = new vtype
+// setting
+#define VSETVLI_TEST_HELPER(VTYPEI_VAR, VTYPEI_SYMBOL, AVL_VAR,      \
+                            MATCH_VARIABLE)                          \
+  do {                                                               \
+    if (strequal(VTYPEI_VAR, VTYPEI_SYMBOL)) {                      \
+      __asm__ volatile(                                              \
+          "vsetvli t0, %[AVL], " VTYPEI_SYMBOL::[AVL] "r"(AVL_VAR)); \
+      MATCH_VARIABLE = true;                                         \
+    }                                                                \
+  } while (0)
+
+void subtest_vsetvli(const char *vtypei, uint32_t avl, uint32_t expected_vl) {
+  uint32_t observed_vl = 0;
+  bool was_instruction_executed = false;
+
+  VSETVLI_TEST_HELPER(vtypei, "e8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e16", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e32", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e64", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf8,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf8,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf8,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf8,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf4", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf4,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf4,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf4,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf4,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf4", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf4,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf4,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf4,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf4,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf4", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf4,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf4,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf4,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf4,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf4", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf4,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf4,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf4,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf4,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf2", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf2,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf2,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf2,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,mf2,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf2", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf2,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf2,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf2,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,mf2,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf2", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf2,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf2,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf2,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,mf2,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf2", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf2,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf2,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf2,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,mf2,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e8,m1", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m1,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m1,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m1,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m1,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e16,m1", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m1,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m1,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m1,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m1,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e32,m1", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m1,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m1,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m1,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m1,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e64,m1", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m1,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m1,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m1,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m1,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e8,m2", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m2,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m2,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m2,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m2,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e16,m2", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m2,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m2,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m2,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m2,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e32,m2", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m2,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m2,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m2,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m2,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e64,m2", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m2,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m2,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m2,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m2,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e8,m4", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m4,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m4,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m4,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m4,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e16,m4", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m4,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m4,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m4,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m4,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e32,m4", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m4,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m4,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m4,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m4,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e64,m4", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m4,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m4,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m4,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m4,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e8,m8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e8,m8,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e16,m8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e16,m8,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e32,m8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e32,m8,ta,ma", avl, was_instruction_executed);
+
+  VSETVLI_TEST_HELPER(vtypei, "e64,m8", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m8,tu,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m8,tu,ma", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m8,ta,mu", avl, was_instruction_executed);
+  VSETVLI_TEST_HELPER(vtypei, "e64,m8,ta,ma", avl, was_instruction_executed);
+
+  assert(was_instruction_executed);
+  COPY_SCALAR_REG("t0", observed_vl);
+  if (observed_vl != expected_vl) {
+    LOG_INFO("Subtest failed, observed_vl = %lu, expected_vl = %lu", observed_vl,
+             expected_vl);
+  }
+  assert(observed_vl == expected_vl);
+}
+
+void test_vector_vsetvli(void) {
+  LOG_INFO("%s", __FUNCTION__);
+  struct subtest_s {
+    const char *vtypei;
+    uint32_t avl;
+    uint32_t expected_vl;  // blindly copy expected_vl from qemu simulation
+  };
+
+  struct subtest_s subtests[] = {
+      {.vtypei = "e8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e16", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e32", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e64", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e8", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e16", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e32", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e64", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e8",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1},
+      {.vtypei = "e16",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1},
+      {.vtypei = "e32",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1},
+      {.vtypei = "e64",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1},
+      {.vtypei = "e8",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e16",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e32",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e64",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3)},
+      {.vtypei = "e8",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e16",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e32",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e64",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3)},
+
+      {.vtypei = "e8,mf8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e16,mf8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e32,mf8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e64,mf8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e8,mf8", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e16,mf8", .avl = 1, .expected_vl = 0},
+      {.vtypei = "e32,mf8", .avl = 1, .expected_vl = 0},
+      {.vtypei = "e64,mf8", .avl = 1, .expected_vl = 0},
+      {.vtypei = "e8,mf8",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1},
+      {.vtypei = "e16,mf8", .avl = (_TEST_VLENB >> 4) - 1, .expected_vl = 0},
+      {.vtypei = "e32,mf8", .avl = (_TEST_VLENB >> 5) - 1, .expected_vl = 0},
+      {.vtypei = "e64,mf8", .avl = (_TEST_VLENB >> 6) - 1, .expected_vl = 0},
+      {.vtypei = "e8,mf8",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3)},
+      {.vtypei = "e16,mf8", .avl = (_TEST_VLENB >> 4), .expected_vl = 0},
+      {.vtypei = "e32,mf8", .avl = (_TEST_VLENB >> 5), .expected_vl = 0},
+      {.vtypei = "e64,mf8", .avl = (_TEST_VLENB >> 6), .expected_vl = 0},
+      {.vtypei = "e8,mf8",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3)},
+      {.vtypei = "e16,mf8", .avl = (_TEST_VLENB >> 4) + 1, .expected_vl = 0},
+      {.vtypei = "e32,mf8", .avl = (_TEST_VLENB >> 5) + 1, .expected_vl = 0},
+      {.vtypei = "e64,mf8", .avl = (_TEST_VLENB >> 6) + 1, .expected_vl = 0},
+
+      {.vtypei = "e8,mf4", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e16,mf4", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e32,mf4", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e64,mf4", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e8,mf4", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e16,mf4", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e32,mf4", .avl = 1, .expected_vl = 0},
+      {.vtypei = "e64,mf4", .avl = 1, .expected_vl = 0},
+      {.vtypei = "e8,mf4",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1},
+      {.vtypei = "e16,mf4",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1},
+      {.vtypei = "e32,mf4", .avl = (_TEST_VLENB >> 4) - 1, .expected_vl = 0},
+      {.vtypei = "e64,mf4", .avl = (_TEST_VLENB >> 5) - 1, .expected_vl = 0},
+      {.vtypei = "e8,mf4",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e16,mf4",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3)},
+      {.vtypei = "e32,mf4", .avl = (_TEST_VLENB >> 4), .expected_vl = 0},
+      {.vtypei = "e64,mf4", .avl = (_TEST_VLENB >> 5), .expected_vl = 0},
+      {.vtypei = "e8,mf4",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e16,mf4",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3)},
+      {.vtypei = "e32,mf4", .avl = (_TEST_VLENB >> 4) + 1, .expected_vl = 0},
+      {.vtypei = "e64,mf4", .avl = (_TEST_VLENB >> 5) + 1, .expected_vl = 0},
+
+      {.vtypei = "e8,mf2", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e16,mf2", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e32,mf2", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e64,mf2", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e8,mf2", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e16,mf2", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e32,mf2", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e64,mf2", .avl = 1, .expected_vl = 0},
+      {.vtypei = "e8,mf2",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1},
+      {.vtypei = "e16,mf2",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1},
+      {.vtypei = "e32,mf2",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1},
+      {.vtypei = "e64,mf2", .avl = (_TEST_VLENB >> 4) - 1, .expected_vl = 0},
+      {.vtypei = "e8,mf2",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e16,mf2",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e32,mf2",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3)},
+      {.vtypei = "e64,mf2", .avl = (_TEST_VLENB >> 4), .expected_vl = 0},
+      {.vtypei = "e8,mf2",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e16,mf2",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e32,mf2",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3)},
+      {.vtypei = "e64,mf2", .avl = (_TEST_VLENB >> 4) + 1, .expected_vl = 0},
+
+      {.vtypei = "e8,m1", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e16,m1", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e32,m1", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e64,m1", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e8,m1", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e16,m1", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e32,m1", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e64,m1", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e8,m1",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1},
+      {.vtypei = "e16,m1",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1},
+      {.vtypei = "e32,m1",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1},
+      {.vtypei = "e64,m1",
+       .avl = (_TEST_VLENB >> 3) - 1,
+       .expected_vl = (_TEST_VLENB >> 3) - 1},
+      {.vtypei = "e8,m1",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e16,m1",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e32,m1",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e64,m1",
+       .avl = (_TEST_VLENB >> 3),
+       .expected_vl = (_TEST_VLENB >> 3)},
+      {.vtypei = "e8,m1",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e16,m1",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e32,m1",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e64,m1",
+       .avl = (_TEST_VLENB >> 3) + 1,
+       .expected_vl = (_TEST_VLENB >> 3)},
+
+      {.vtypei = "e8,m2", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e16,m2", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e32,m2", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e64,m2", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e8,m2", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e16,m2", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e32,m2", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e64,m2", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e8,m2",
+       .avl = (_TEST_VLENB << 1) - 1,
+       .expected_vl = (_TEST_VLENB << 1) - 1},
+      {.vtypei = "e16,m2",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1},
+      {.vtypei = "e32,m2",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1},
+      {.vtypei = "e64,m2",
+       .avl = (_TEST_VLENB >> 2) - 1,
+       .expected_vl = (_TEST_VLENB >> 2) - 1},
+      {.vtypei = "e8,m2",
+       .avl = (_TEST_VLENB << 1),
+       .expected_vl = (_TEST_VLENB << 1)},
+      {.vtypei = "e16,m2",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e32,m2",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e64,m2",
+       .avl = (_TEST_VLENB >> 2),
+       .expected_vl = (_TEST_VLENB >> 2)},
+      {.vtypei = "e8,m2",
+       .avl = (_TEST_VLENB << 1) + 1,
+       .expected_vl = (_TEST_VLENB << 1)},
+      {.vtypei = "e16,m2",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e32,m2",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e64,m2",
+       .avl = (_TEST_VLENB >> 2) + 1,
+       .expected_vl = (_TEST_VLENB >> 2)},
+
+      {.vtypei = "e8,m4", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e16,m4", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e32,m4", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e64,m4", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e8,m4", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e16,m4", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e32,m4", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e64,m4", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e8,m4",
+       .avl = (_TEST_VLENB << 2) - 1,
+       .expected_vl = (_TEST_VLENB << 2) - 1},
+      {.vtypei = "e16,m4",
+       .avl = (_TEST_VLENB << 1) - 1,
+       .expected_vl = (_TEST_VLENB << 1) - 1},
+      {.vtypei = "e32,m4",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1},
+      {.vtypei = "e64,m4",
+       .avl = (_TEST_VLENB >> 1) - 1,
+       .expected_vl = (_TEST_VLENB >> 1) - 1},
+      {.vtypei = "e8,m4",
+       .avl = (_TEST_VLENB << 2),
+       .expected_vl = (_TEST_VLENB << 2)},
+      {.vtypei = "e16,m4",
+       .avl = (_TEST_VLENB << 1),
+       .expected_vl = (_TEST_VLENB << 1)},
+      {.vtypei = "e32,m4",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e64,m4",
+       .avl = (_TEST_VLENB >> 1),
+       .expected_vl = (_TEST_VLENB >> 1)},
+      {.vtypei = "e8,m4",
+       .avl = (_TEST_VLENB << 2) + 1,
+       .expected_vl = (_TEST_VLENB << 2)},
+      {.vtypei = "e16,m4",
+       .avl = (_TEST_VLENB << 1) + 1,
+       .expected_vl = (_TEST_VLENB << 1)},
+      {.vtypei = "e32,m4",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e64,m4",
+       .avl = (_TEST_VLENB >> 1) + 1,
+       .expected_vl = (_TEST_VLENB >> 1)},
+
+      {.vtypei = "e8,m8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e16,m8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e32,m8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e64,m8", .avl = 0, .expected_vl = 0},
+      {.vtypei = "e8,m8", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e16,m8", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e32,m8", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e64,m8", .avl = 1, .expected_vl = 1},
+      {.vtypei = "e8,m8",
+       .avl = (_TEST_VLENB << 3) - 1,
+       .expected_vl = (_TEST_VLENB << 3) - 1},
+      {.vtypei = "e16,m8",
+       .avl = (_TEST_VLENB << 2) - 1,
+       .expected_vl = (_TEST_VLENB << 2) - 1},
+      {.vtypei = "e32,m8",
+       .avl = (_TEST_VLENB << 1) - 1,
+       .expected_vl = (_TEST_VLENB << 1) - 1},
+      {.vtypei = "e64,m8",
+       .avl = (_TEST_VLENB >> 0) - 1,
+       .expected_vl = (_TEST_VLENB >> 0) - 1},
+      {.vtypei = "e8,m8",
+       .avl = (_TEST_VLENB << 3),
+       .expected_vl = (_TEST_VLENB << 3)},
+      {.vtypei = "e16,m8",
+       .avl = (_TEST_VLENB << 2),
+       .expected_vl = (_TEST_VLENB << 2)},
+      {.vtypei = "e32,m8",
+       .avl = (_TEST_VLENB << 1),
+       .expected_vl = (_TEST_VLENB << 1)},
+      {.vtypei = "e64,m8",
+       .avl = (_TEST_VLENB >> 0),
+       .expected_vl = (_TEST_VLENB >> 0)},
+      {.vtypei = "e8,m8",
+       .avl = (_TEST_VLENB << 3) + 1,
+       .expected_vl = (_TEST_VLENB << 3)},
+      {.vtypei = "e16,m8",
+       .avl = (_TEST_VLENB << 2) + 1,
+       .expected_vl = (_TEST_VLENB << 2)},
+      {.vtypei = "e32,m8",
+       .avl = (_TEST_VLENB << 1) + 1,
+       .expected_vl = (_TEST_VLENB << 1)},
+      {.vtypei = "e64,m8",
+       .avl = (_TEST_VLENB >> 0) + 1,
+       .expected_vl = (_TEST_VLENB >> 0)},
+  };
+
+  uint32_t len = sizeof(subtests) / sizeof(struct subtest_s);
+  for (uint32_t i = 0; i < len; i++) {
+    LOG_INFO("Subtest %lu", i);
+    struct subtest_s subtest = subtests[i];
+    subtest_vsetvli(subtest.vtypei, subtest.avl, subtest.expected_vl);
+
+    char new_vtypei[32];
+    uint32_t vtypei_len = strlength(subtest.vtypei);
+    memcpy(new_vtypei, subtest.vtypei, vtypei_len);
+
+    memcpy(new_vtypei + vtypei_len, ",tu,mu\0", (size_t)7);
+    subtest_vsetvli(new_vtypei, subtest.avl, subtest.expected_vl);
+    memcpy(new_vtypei + vtypei_len, ",tu,ma\0", (size_t)7);
+    subtest_vsetvli(new_vtypei, subtest.avl, subtest.expected_vl);
+    memcpy(new_vtypei + vtypei_len, ",ta,mu\0", (size_t)7);
+    subtest_vsetvli(new_vtypei, subtest.avl, subtest.expected_vl);
+    memcpy(new_vtypei + vtypei_len, ",ta,ma\0", (size_t)7);
+    subtest_vsetvli(new_vtypei, subtest.avl, subtest.expected_vl);
+  }
+}
+
+#define _STRING_LITERAL(x) #x
+#define STRING_LITERAL(x) _STRING_LITERAL(x)
+
+// vsetivli rd, uimm, vtypei # rd = new vl, uimm = AVL, vtypei = new vtype
+// setting
+#define VSETIVLI_SUBTEST(AVL, VTYPEI, EXPECTED_VL)                        \
+  do {                                                                    \
+    LOG_INFO("Subtest %lu", subtest_count++);                              \
+    uint32_t observed_vl = 0;                                             \
+    __asm__ volatile("vsetivli t0, " STRING_LITERAL(AVL) ", " VTYPEI);    \
+    COPY_SCALAR_REG("t0", observed_vl);                                   \
+    if (observed_vl != EXPECTED_VL) {                                     \
+      LOG_INFO("Subtest observed_vl = %lu, expected_vl = %d", observed_vl, \
+               EXPECTED_VL);                                              \
+    }                                                                     \
+    assert(observed_vl == EXPECTED_VL);                                   \
+    __asm__ volatile("vsetivli t0, " STRING_LITERAL(AVL) ", " VTYPEI      \
+                                                         ",tu,mu");       \
+    COPY_SCALAR_REG("t0", observed_vl);                                   \
+    if (observed_vl != EXPECTED_VL) {                                     \
+      LOG_INFO("Subtest observed_vl = %lu, expected_vl = %d", observed_vl, \
+               EXPECTED_VL);                                              \
+    }                                                                     \
+    assert(observed_vl == EXPECTED_VL);                                   \
+    __asm__ volatile("vsetivli t0, " STRING_LITERAL(AVL) ", " VTYPEI      \
+                                                         ",tu,ma");       \
+    COPY_SCALAR_REG("t0", observed_vl);                                   \
+    if (observed_vl != EXPECTED_VL) {                                     \
+      LOG_INFO("Subtest observed_vl = %lu, expected_vl = %d", observed_vl, \
+               EXPECTED_VL);                                              \
+    }                                                                     \
+    assert(observed_vl == EXPECTED_VL);                                   \
+    __asm__ volatile("vsetivli t0, " STRING_LITERAL(AVL) ", " VTYPEI      \
+                                                         ",ta,mu");       \
+    COPY_SCALAR_REG("t0", observed_vl);                                   \
+    if (observed_vl != EXPECTED_VL) {                                     \
+      LOG_INFO("Subtest observed_vl = %lu, expected_vl = %d", observed_vl, \
+               EXPECTED_VL);                                              \
+    }                                                                     \
+    assert(observed_vl == EXPECTED_VL);                                   \
+    __asm__ volatile("vsetivli t0, " STRING_LITERAL(AVL) ", " VTYPEI      \
+                                                         ",ta,ma");       \
+    COPY_SCALAR_REG("t0", observed_vl);                                   \
+    if (observed_vl != EXPECTED_VL) {                                     \
+      LOG_INFO("Subtest observed_vl = %lu, expected_vl = %d", observed_vl, \
+               EXPECTED_VL);                                              \
+    }                                                                     \
+    assert(observed_vl == EXPECTED_VL);                                   \
+  } while (0)
+
+#if _TEST_VLEN == 256
+#define VLENB_DIV8_SUB1 3
+#define VLENB_DIV8 4
+#define VLENB_DIV8_ADD1 5
+
+#define VLENB_DIV4_SUB1 7
+#define VLENB_DIV4 8
+#define VLENB_DIV4_ADD1 9
+
+#define VLENB_DIV2_SUB1 15
+#define VLENB_DIV2 16
+#define VLENB_DIV2_ADD1 17
+
+#define VLENB_SUB1 31
+#define VLENB 32
+#define VLENB_ADD1 33
+
+#define VLENB_MUL2_SUB1 63
+#define VLENB_MUL2 64
+#define VLENB_MUL2_ADD1 65
+
+#define VLENB_MUL4_SUB1 127
+#define VLENB_MUL4 128
+#define VLENB_MUL4_ADD1 129
+
+#define VLENB_MUL8_SUB1 255
+#define VLENB_MUL8 256
+#define VLENB_MUL8_ADD1 257
+
+#elif _TEST_VLEN == 512
+#define VLENB_DIV8_SUB1 7
+#define VLENB_DIV8 8
+#define VLENB_DIV8_ADD1 9
+
+#define VLENB_DIV4_SUB1 15
+#define VLENB_DIV4 16
+#define VLENB_DIV4_ADD1 17
+
+#define VLENB_DIV2_SUB1 31
+#define VLENB_DIV2 32
+#define VLENB_DIV2_ADD1 33
+
+#define VLENB_SUB1 63
+#define VLENB 64
+#define VLENB_ADD1 65
+
+#define VLENB_MUL2_SUB1 127
+#define VLENB_MUL2 128
+#define VLENB_MUL2_ADD1 129
+
+#define VLENB_MUL4_SUB1 255
+#define VLENB_MUL4 256
+#define VLENB_MUL4_ADD1 257
+
+#define VLENB_MUL8_SUB1 511
+#define VLENB_MUL8 512
+#define VLENB_MUL8_ADD1 513
+#endif
+
+void test_vector_vsetivli(void) {
+  LOG_INFO("%s", __FUNCTION__);
+  // AVL immediate is 5 bits -> 31 is the max
+  uint32_t subtest_count = 0;
+
+  VSETIVLI_SUBTEST(0, "e8", 0);
+  VSETIVLI_SUBTEST(0, "e16", 0);
+  VSETIVLI_SUBTEST(0, "e32", 0);
+  VSETIVLI_SUBTEST(0, "e64", 0);
+  VSETIVLI_SUBTEST(1, "e8", 1);
+  VSETIVLI_SUBTEST(1, "e16", 1);
+  VSETIVLI_SUBTEST(1, "e32", 1);
+  VSETIVLI_SUBTEST(1, "e64", 1);
+  VSETIVLI_SUBTEST(0, "e8,mf8", 0);
+  VSETIVLI_SUBTEST(0, "e16,mf8", 0);
+  VSETIVLI_SUBTEST(0, "e32,mf8", 0);
+  VSETIVLI_SUBTEST(0, "e64,mf8", 0);
+  VSETIVLI_SUBTEST(1, "e8,mf8", 1);
+  VSETIVLI_SUBTEST(1, "e16,mf8", 0);
+  VSETIVLI_SUBTEST(1, "e32,mf8", 0);
+  VSETIVLI_SUBTEST(1, "e64,mf8", 0);
+  VSETIVLI_SUBTEST(0, "e8,mf4", 0);
+  VSETIVLI_SUBTEST(0, "e16,mf4", 0);
+  VSETIVLI_SUBTEST(0, "e32,mf4", 0);
+  VSETIVLI_SUBTEST(0, "e64,mf4", 0);
+  VSETIVLI_SUBTEST(1, "e8,mf4", 1);
+  VSETIVLI_SUBTEST(1, "e16,mf4", 1);
+  VSETIVLI_SUBTEST(1, "e32,mf4", 0);
+  VSETIVLI_SUBTEST(1, "e64,mf4", 0);
+  VSETIVLI_SUBTEST(0, "e8,mf2", 0);
+  VSETIVLI_SUBTEST(0, "e16,mf2", 0);
+  VSETIVLI_SUBTEST(0, "e32,mf2", 0);
+  VSETIVLI_SUBTEST(0, "e64,mf2", 0);
+  VSETIVLI_SUBTEST(1, "e8,mf2", 1);
+  VSETIVLI_SUBTEST(1, "e16,mf2", 1);
+  VSETIVLI_SUBTEST(1, "e32,mf2", 1);
+  VSETIVLI_SUBTEST(1, "e64,mf2", 0);
+  VSETIVLI_SUBTEST(0, "e8,m1", 0);
+  VSETIVLI_SUBTEST(0, "e16,m1", 0);
+  VSETIVLI_SUBTEST(0, "e32,m1", 0);
+  VSETIVLI_SUBTEST(0, "e64,m1", 0);
+  VSETIVLI_SUBTEST(1, "e8,m1", 1);
+  VSETIVLI_SUBTEST(1, "e16,m1", 1);
+  VSETIVLI_SUBTEST(1, "e32,m1", 1);
+  VSETIVLI_SUBTEST(1, "e64,m1", 1);
+  VSETIVLI_SUBTEST(0, "e8,m2", 0);
+  VSETIVLI_SUBTEST(0, "e16,m2", 0);
+  VSETIVLI_SUBTEST(0, "e32,m2", 0);
+  VSETIVLI_SUBTEST(0, "e64,m2", 0);
+  VSETIVLI_SUBTEST(1, "e8,m2", 1);
+  VSETIVLI_SUBTEST(1, "e16,m2", 1);
+  VSETIVLI_SUBTEST(1, "e32,m2", 1);
+  VSETIVLI_SUBTEST(1, "e64,m2", 1);
+  VSETIVLI_SUBTEST(0, "e8,m4", 0);
+  VSETIVLI_SUBTEST(0, "e16,m4", 0);
+  VSETIVLI_SUBTEST(0, "e32,m4", 0);
+  VSETIVLI_SUBTEST(0, "e64,m4", 0);
+  VSETIVLI_SUBTEST(1, "e8,m4", 1);
+  VSETIVLI_SUBTEST(1, "e16,m4", 1);
+  VSETIVLI_SUBTEST(1, "e32,m4", 1);
+  VSETIVLI_SUBTEST(1, "e64,m4", 1);
+  VSETIVLI_SUBTEST(0, "e8,m8", 0);
+  VSETIVLI_SUBTEST(0, "e16,m8", 0);
+  VSETIVLI_SUBTEST(0, "e32,m8", 0);
+  VSETIVLI_SUBTEST(0, "e64,m8", 0);
+  VSETIVLI_SUBTEST(1, "e8,m8", 1);
+  VSETIVLI_SUBTEST(1, "e16,m8", 1);
+  VSETIVLI_SUBTEST(1, "e32,m8", 1);
+  VSETIVLI_SUBTEST(1, "e64,m8", 1);
+
+#if VLENB_DIV8_SUB1 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV8_SUB1, "e64", VLENB_DIV8_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV8_SUB1, "e8,mf8", VLENB_DIV8_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV8_SUB1, "e16,mf4", VLENB_DIV8_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV8_SUB1, "e32,mf2", VLENB_DIV8_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV8_SUB1, "e64,m1", VLENB_DIV8_SUB1);
+#endif
+
+#if VLENB_DIV8 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV8, "e64", VLENB_DIV8);
+  VSETIVLI_SUBTEST(VLENB_DIV8, "e8,mf8", VLENB_DIV8);
+  VSETIVLI_SUBTEST(VLENB_DIV8, "e16,mf4", VLENB_DIV8);
+  VSETIVLI_SUBTEST(VLENB_DIV8, "e32,mf2", VLENB_DIV8);
+  VSETIVLI_SUBTEST(VLENB_DIV8, "e64,m1", VLENB_DIV8);
+#endif
+
+#if VLENB_DIV8_ADD1 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV8_ADD1, "e64", VLENB_DIV8);
+  VSETIVLI_SUBTEST(VLENB_DIV8_ADD1, "e8,mf8", VLENB_DIV8);
+  VSETIVLI_SUBTEST(VLENB_DIV8_ADD1, "e16,mf4", VLENB_DIV8);
+  VSETIVLI_SUBTEST(VLENB_DIV8_ADD1, "e32,mf2", VLENB_DIV8);
+  VSETIVLI_SUBTEST(VLENB_DIV8_ADD1, "e64,m1", VLENB_DIV8);
+#endif
+
+#if VLENB_DIV4_SUB1 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV4_SUB1, "e32", VLENB_DIV4_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV4_SUB1, "e8,mf4", VLENB_DIV4_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV4_SUB1, "e16,mf2", VLENB_DIV4_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV4_SUB1, "e32,m1", VLENB_DIV4_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV4_SUB1, "e64,m2", VLENB_DIV4_SUB1);
+#endif
+
+#if VLENB_DIV4 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV4, "e32", VLENB_DIV4);
+  VSETIVLI_SUBTEST(VLENB_DIV4, "e8,mf4", VLENB_DIV4);
+  VSETIVLI_SUBTEST(VLENB_DIV4, "e16,mf2", VLENB_DIV4);
+  VSETIVLI_SUBTEST(VLENB_DIV4, "e32,m1", VLENB_DIV4);
+  VSETIVLI_SUBTEST(VLENB_DIV4, "e64,m2", VLENB_DIV4);
+#endif
+
+#if VLENB_DIV4_ADD1 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV4_ADD1, "e32", VLENB_DIV4);
+  VSETIVLI_SUBTEST(VLENB_DIV4_ADD1, "e8,mf4", VLENB_DIV4);
+  VSETIVLI_SUBTEST(VLENB_DIV4_ADD1, "e16,mf2", VLENB_DIV4);
+  VSETIVLI_SUBTEST(VLENB_DIV4_ADD1, "e32,m1", VLENB_DIV4);
+  VSETIVLI_SUBTEST(VLENB_DIV4_ADD1, "e64,m2", VLENB_DIV4);
+#endif
+
+#if VLENB_DIV2_SUB1 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV2_SUB1, "e16", VLENB_DIV2_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV2_SUB1, "e8,mf2", VLENB_DIV2_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV2_SUB1, "e16,m1", VLENB_DIV2_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV2_SUB1, "e32,m2", VLENB_DIV2_SUB1);
+  VSETIVLI_SUBTEST(VLENB_DIV2_SUB1, "e64,m4", VLENB_DIV2_SUB1);
+#endif
+
+#if VLENB_DIV2 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV2, "e16", VLENB_DIV2);
+  VSETIVLI_SUBTEST(VLENB_DIV2, "e8,mf2", VLENB_DIV2);
+  VSETIVLI_SUBTEST(VLENB_DIV2, "e16,m1", VLENB_DIV2);
+  VSETIVLI_SUBTEST(VLENB_DIV2, "e32,m2", VLENB_DIV2);
+  VSETIVLI_SUBTEST(VLENB_DIV2, "e64,m4", VLENB_DIV2);
+#endif
+
+#if VLENB_DIV2_ADD1 < 32
+  VSETIVLI_SUBTEST(VLENB_DIV2_ADD1, "e16", VLENB_DIV2);
+  VSETIVLI_SUBTEST(VLENB_DIV2_ADD1, "e8,mf2", VLENB_DIV2);
+  VSETIVLI_SUBTEST(VLENB_DIV2_ADD1, "e16,m1", VLENB_DIV2);
+  VSETIVLI_SUBTEST(VLENB_DIV2_ADD1, "e32,m2", VLENB_DIV2);
+  VSETIVLI_SUBTEST(VLENB_DIV2_ADD1, "e64,m4", VLENB_DIV2);
+#endif
+
+#if VLENB_SUB1 < 32
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e8", VLENB_SUB1);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e16,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e32,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e16,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e32,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e16,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e32,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf8", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e32,mf4", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf4", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e32,mf4", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf4", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e32,mf4", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf4", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf2", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf2", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,mf2", 0);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e8,m1", VLENB_SUB1);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e16,m2", VLENB_SUB1);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e32,m4", VLENB_SUB1);
+  VSETIVLI_SUBTEST(VLENB_SUB1, "e64,m8", VLENB_SUB1);
+#endif
+
+#if VLENB < 32
+  VSETIVLI_SUBTEST(VLENB, "e8", VLENB);
+  VSETIVLI_SUBTEST(VLENB, "e8,m1", VLENB);
+  VSETIVLI_SUBTEST(VLENB, "e16,m2", VLENB);
+  VSETIVLI_SUBTEST(VLENB, "e32,m4", VLENB);
+  VSETIVLI_SUBTEST(VLENB, "e64,m8", VLENB);
+#endif
+
+#if VLENB_ADD1 < 32
+  VSETIVLI_SUBTEST(VLENB_ADD1, "e8", VLENB);
+  VSETIVLI_SUBTEST(VLENB_ADD1, "e8,m1", VLENB);
+  VSETIVLI_SUBTEST(VLENB_ADD1, "e16,m2", VLENB);
+  VSETIVLI_SUBTEST(VLENB_ADD1, "e32,m4", VLENB);
+  VSETIVLI_SUBTEST(VLENB_ADD1, "e64,m8", VLENB);
+#endif
+
+#if VLENB_MUL2_SUB1 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL2_SUB1, "e8,m2", VLENB_MUL2_SUB1);
+  VSETIVLI_SUBTEST(VLENB_MUL2_SUB1, "e16,m4", VLENB_MUL2_SUB1);
+  VSETIVLI_SUBTEST(VLENB_MUL2_SUB1, "e32,m8", VLENB_MUL2_SUB1);
+#endif
+
+#if VLENB_MUL2 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL2, "e8,m2", VLENB_MUL2);
+  VSETIVLI_SUBTEST(VLENB_MUL2, "e16,m4", VLENB_MUL2);
+  VSETIVLI_SUBTEST(VLENB_MUL2, "e32,m8", VLENB_MUL2);
+#endif
+
+#if VLENB_MUL2_ADD1 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL2_ADD1, "e8,m2", VLENB_MUL2);
+  VSETIVLI_SUBTEST(VLENB_MUL2_ADD1, "e16,m4", VLENB_MUL2);
+  VSETIVLI_SUBTEST(VLENB_MUL2_ADD1, "e32,m8", VLENB_MUL2);
+#endif
+
+#if VLENB_MUL4_SUB1 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL4_SUB1, "e8,m4", VLENB_MUL4_SUB1);
+  VSETIVLI_SUBTEST(VLENB_MUL4_SUB1, "e16,m8", VLENB_MUL4_SUB1);
+#endif
+
+#if VLENB_MUL4 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL4, "e8,m4", VLENB_MUL4);
+  VSETIVLI_SUBTEST(VLENB_MUL4, "e16,m8", VLENB_MUL4);
+#endif
+
+#if VLENB_MUL4_ADD1 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL4_ADD1, "e8,m4", VLENB_MUL4);
+  VSETIVLI_SUBTEST(VLENB_MUL4_ADD1, "e16,m8", VLENB_MUL4);
+#endif
+
+#if VLENB_MUL8_SUB1 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL8_SUB1, "e8,m8", VLENB_MUL8_SUB1);
+#endif
+
+#if VLENB_MUL8 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL8, "e8,m8", VLENB_MUL8);
+#endif
+
+#if VLENB_MUL8_ADD1 < 32
+  VSETIVLI_SUBTEST(VLENB_MUL8_ADD1, "e8,m8", VLENB_MUL8);
+#endif
+}