Add vector tests library.

Change-Id: Ib8c14b0c96b3941b83fbb335cb7077474073414c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1c33457..53ac99b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,3 +14,5 @@
 
 add_subdirectory(springbok)
 add_subdirectory(hello_vec)
+add_subdirectory(vector_tests)
+#add_subdirectory(vector_load_tests)
diff --git a/springbok/CMakeLists.txt b/springbok/CMakeLists.txt
index 944bc8b..2abc1af 100644
--- a/springbok/CMakeLists.txt
+++ b/springbok/CMakeLists.txt
@@ -16,6 +16,8 @@
     springbok_intrinsic
 )
 
+target_include_directories(springbok INTERFACE include)
+
 target_compile_options(springbok_intrinsic PUBLIC
     -Wall
     -Werror
diff --git a/vector_tests/CMakeLists.txt b/vector_tests/CMakeLists.txt
new file mode 100644
index 0000000..554cacd
--- /dev/null
+++ b/vector_tests/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.1)
+
+enable_language(ASM)
+add_library(vector_tests
+	test_vector.c
+    common_vector_test.c)
+
+target_include_directories(vector_tests PUBLIC include)
+
+target_link_libraries(vector_tests springbok)
+
+target_compile_options(vector_tests PUBLIC
+    -Wall
+    -Werror
+    -std=c11
+    -O3
+    -g3
+    -ggdb
+    -ffreestanding
+    -ffunction-sections
+    -fstack-usage
+    -mstrict-align)
diff --git a/vector_tests/common_vector_test.c b/vector_tests/common_vector_test.c
new file mode 100644
index 0000000..07f1af4
--- /dev/null
+++ b/vector_tests/common_vector_test.c
@@ -0,0 +1,27 @@
+#include "common_vector_test.h"
+
+size_t strlength(const char *str) {
+  size_t index = 0;
+  while (str[index]) {
+    index++;
+  }
+  return index;
+}
+
+bool strequal(const char *str1, const char *str2) {
+  uint32_t index = 0;
+
+  while (str1[index] && str2[index] && str1[index] == str2[index]) {
+    index++;
+  }
+
+  return str1[index] == str2[index];
+}
+
+uint64_t random64(void) {
+  static uint64_t state = 4;  // chosen by fair dice roll.
+                              // guaranteed to be random.
+  state *= 1234512345;
+  state += 5432154321;
+  return state;
+}
diff --git a/vector_tests/include/common_vector_test.h b/vector_tests/include/common_vector_test.h
new file mode 100644
index 0000000..9565498
--- /dev/null
+++ b/vector_tests/include/common_vector_test.h
@@ -0,0 +1,11 @@
+#ifndef VECTOR_TESTS_COMMON_COMMON_VECTOR_TEST_H_
+#define VECTOR_TESTS_COMMON_COMMON_VECTOR_TEST_H_
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+size_t strlength(const char *);
+bool strequal(const char *, const char *);
+uint64_t random64(void);
+
+#endif
\ No newline at end of file
diff --git a/vector_tests/include/test_vector.h b/vector_tests/include/test_vector.h
new file mode 100644
index 0000000..0694ae2
--- /dev/null
+++ b/vector_tests/include/test_vector.h
@@ -0,0 +1,37 @@
+#ifndef VECTOR_TESTS_TEST_VECTOR_H_
+#define VECTOR_TESTS_TEST_VECTOR_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <assert.h>
+
+
+#ifndef _TEST_VLEN
+#define _TEST_VLEN 512
+#endif
+
+#define _TEST_VLENB _TEST_VLEN >> 3
+
+
+#define VSET(VLEN, VTYPE, LMUL)                           \
+  do {                                                    \
+    __asm__ volatile("vsetvli t0, %[A]," #VTYPE "," #LMUL \
+                     " \n" ::[A] "r"(VLEN));              \
+  } while (0)
+
+#define COPY_SCALAR_REG(REG, DST)         \
+  do {                                    \
+    {                                     \
+      register uint32_t tmp_reg __asm__(REG); \
+      DST = tmp_reg;                      \
+    }                                     \
+  } while (0)
+
+extern bool test_vector(void);
+bool test_main(void);
+uint32_t get_vtype_e8(uint8_t, bool, bool);
+uint32_t get_vtype_e16(uint8_t, bool, bool);
+uint32_t get_vtype_e32(uint8_t, bool, bool);
+uint32_t get_vtype_e64(uint8_t, bool, bool);
+
+#endif
\ No newline at end of file
diff --git a/vector_tests/test_vector.c b/vector_tests/test_vector.c
new file mode 100644
index 0000000..6c8306f
--- /dev/null
+++ b/vector_tests/test_vector.c
@@ -0,0 +1,62 @@
+#include "test_vector.h"
+#include <springbok.h>
+
+#define MSTATUS_VS 0x00000600
+#define enable_vec()                                        \
+  do {                                                      \
+    __asm__ volatile("csrs mstatus, %[bits];" ::[bits] "r"( \
+        MSTATUS_VS & (MSTATUS_VS >> 1)));                   \
+  } while (0);
+
+uint32_t get_vtype(uint8_t vsew, uint8_t vlmul, bool tail_agnostic,
+                   bool mask_agnostic) {
+  return (vlmul & 0x7) | (vsew & 0x7) << 3 | (tail_agnostic & 0x1) << 6 |
+         (mask_agnostic & 0x1) << 7;
+}
+
+uint32_t get_vtype_e8(uint8_t vlmul, bool tail_agnostic, bool mask_agnostic) {
+  uint8_t vsew = 0;
+  return get_vtype(vsew, vlmul, tail_agnostic, mask_agnostic);
+}
+
+uint32_t get_vtype_e16(uint8_t vlmul, bool tail_agnostic, bool mask_agnostic) {
+  uint8_t vsew = 1;
+  return get_vtype(vsew, vlmul, tail_agnostic, mask_agnostic);
+}
+
+uint32_t get_vtype_e32(uint8_t vlmul, bool tail_agnostic, bool mask_agnostic) {
+  uint8_t vsew = 2;
+  return get_vtype(vsew, vlmul, tail_agnostic, mask_agnostic);
+}
+
+uint32_t get_vtype_e64(uint8_t vlmul, bool tail_agnostic, bool mask_agnostic) {
+  uint8_t vsew = 3;
+  return get_vtype(vsew, vlmul, tail_agnostic, mask_agnostic);
+}
+
+bool main(void) {
+
+  LOG_INFO("Hello test_vector.c");
+  LOG_INFO("Built at: " __DATE__ ", " __TIME__);
+
+  uint32_t misa;
+  __asm__ volatile("csrr %0, misa" : "=r"(misa));
+  LOG_INFO("MISA: 0x%08x", (unsigned int)misa);
+
+  uint32_t mstatus;
+  __asm__ volatile("csrr %0, mstatus" : "=r"(mstatus));
+  LOG_INFO("BEFORE MSTATUS: 0x%08x", (unsigned int)mstatus);
+
+  enable_vec();
+
+  __asm__ volatile("csrr %0, mstatus" : "=r"(mstatus));
+  LOG_INFO("AFTER MSTATUS: 0x%08x", (unsigned int)mstatus);
+
+  uint32_t vlenb;
+  __asm__ volatile("csrr %0, vlenb" : "=r"(vlenb));
+  LOG_INFO("VLENB: 0x%08x, VLEN: %lu", (unsigned int)vlenb, vlenb << 3);
+
+  assert(test_vector());
+  LOG_INFO("test_main done.");
+  return true;
+}
\ No newline at end of file