Merge "Update crt0 and matcha.ld to support IREE."
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c4b0d6a..00c9c8d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,13 @@
-cmake_minimum_required (VERSION 3.1)
+cmake_minimum_required (VERSION 3.10)
set(CMAKE_C_ABI_COMPILED ON)
set(CMAKE_CXX_ABI_COMPILED ON)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/riscv_baremetal.cmake")
+list(APPEND CMAKE_MODULE_PATH
+ ${CMAKE_CURRENT_LIST_DIR}/cmake/
+)
project(springbok_project)
@@ -19,13 +22,18 @@
set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/springbok/matcha.ld")
+include(vec_cc_binary)
+include(vec_cc_test)
+
add_subdirectory(springbok)
add_subdirectory(hello_vec)
+
add_subdirectory(vector_tests)
-add_subdirectory(vector_load_tests)
+add_subdirectory(vector_load_store_tests)
add_subdirectory(vector_vadd_vsub_tests)
add_subdirectory(vector_executive)
add_subdirectory(vector_vset_tests)
+
add_subdirectory(pw_unit_test_demo)
-add_subdirectory(test_vsetvl)
+add_subdirectory(tests)
\ No newline at end of file
diff --git a/cmake/riscv_baremetal.cmake b/cmake/riscv_baremetal.cmake
index 62e6c5a..9c8b93b 100644
--- a/cmake/riscv_baremetal.cmake
+++ b/cmake/riscv_baremetal.cmake
@@ -40,3 +40,16 @@
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "" )
set( CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "" )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostartfiles " )
+set( VEC_DEFAULT_COPTS
+ "-Wall"
+ "-Werror"
+ "-O0"
+ "-g3"
+ "-ggdb"
+ "-ffreestanding"
+ "-ffunction-sections"
+ "-fstack-usage"
+ "-mstrict-align"
+)
+
+set( VEC_DEFAULT_LINKOPTS -specs=nano.specs -Wl,--gc-sections -Wl,--print-memory-usage -Wl,-Map=${PROJECT_NAME}.map)
\ No newline at end of file
diff --git a/cmake/vec_cc_binary.cmake b/cmake/vec_cc_binary.cmake
new file mode 100644
index 0000000..97fd63c
--- /dev/null
+++ b/cmake/vec_cc_binary.cmake
@@ -0,0 +1,40 @@
+function(vec_cc_binary)
+ cmake_parse_arguments(
+ _RULE
+ ""
+ "NAME"
+ "SRCS;COPTS;DEFINES;LINKOPTS;DATA;DEPS;LABELS"
+ ${ARGN}
+ )
+
+set(_NAME "${_RULE_NAME}")
+project(${_RULE_NAME})
+set (CMAKE_CXX_STANDARD 17)
+
+set(_ELF_NAME "${_RULE_NAME}.elf")
+add_executable(${_ELF_NAME})
+target_include_directories(${_ELF_NAME} PUBLIC include)
+set_target_properties(${_ELF_NAME} PROPERTIES LINK_DEPENDS "${LINKER_SCRIPT}")
+
+target_sources(${_ELF_NAME}
+ PRIVATE
+ ${_RULE_SRCS}
+)
+
+target_link_libraries(${_ELF_NAME}
+ PUBLIC
+ ${_RULE_DEPS}
+)
+
+target_compile_options(${_ELF_NAME}
+ PUBLIC
+ ${VEC_DEFAULT_COPTS}
+ ${_RULE_COPTS}
+)
+
+target_link_options(${_ELF_NAME}
+ PUBLIC
+ ${_RULE_LINKOPTS}
+ ${VEC_DEFAULT_LINKOPTS}
+)
+endfunction()
diff --git a/cmake/vec_cc_test.cmake b/cmake/vec_cc_test.cmake
new file mode 100644
index 0000000..332a085
--- /dev/null
+++ b/cmake/vec_cc_test.cmake
@@ -0,0 +1,29 @@
+function(vec_cc_test)
+ cmake_parse_arguments(
+ _RULE
+ ""
+ "NAME"
+ "SRCS;COPTS;DEFINES;LINKOPTS;DATA;DEPS;LABELS"
+ ${ARGN}
+ )
+
+set(_NAME "${_RULE_NAME}")
+project(${_RULE_NAME})
+set (CMAKE_CXX_STANDARD 17)
+
+vec_cc_binary(
+ NAME
+ ${_RULE_NAME}
+ SRCS
+ ${_RULE_SRCS}
+ DEPS
+ pw_unit_test
+ pw_unit_test.main
+ pw_assert_basic
+ test_v_helpers
+ ${_RULE_DEPS}
+ LINKOPTS
+ ${_RULE_LINKOPTS}
+)
+
+endfunction()
diff --git a/hello_vec/CMakeLists.txt b/hello_vec/CMakeLists.txt
index 59efb80..4f84c45 100644
--- a/hello_vec/CMakeLists.txt
+++ b/hello_vec/CMakeLists.txt
@@ -1,35 +1,10 @@
-cmake_minimum_required(VERSION 3.10)
-
-project(hello_vec)
-
-set(TARGET hello_vec)
-set(ELF ${TARGET}.elf)
-
-add_executable(${ELF} main.cpp)
-
-target_include_directories(${ELF} PUBLIC include)
-
-set_target_properties(${ELF} PROPERTIES LINK_DEPENDS "${LINKER_SCRIPT}")
-
-target_link_libraries(${ELF} springbok)
-
-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}")
-
-target_compile_options(${ELF} PUBLIC
- -Wall
- -Werror
- -O3
- -g3
- -ggdb
- -ffreestanding
- -ffunction-sections
- -fstack-usage
- -mstrict-align)
+vec_cc_binary(
+ NAME
+ hello_vec
+ SRCS
+ main.cpp
+ DEPS
+ springbok
+ LINKOPTS
+ -T${LINKER_SCRIPT}
+)
\ No newline at end of file
diff --git a/pw_unit_test_demo/CMakeLists.txt b/pw_unit_test_demo/CMakeLists.txt
index 3bfaee0..b690644 100644
--- a/pw_unit_test_demo/CMakeLists.txt
+++ b/pw_unit_test_demo/CMakeLists.txt
@@ -1,42 +1,12 @@
-cmake_minimum_required(VERSION 3.10)
-project(pw_unit_test_demo)
-set (CMAKE_CXX_STANDARD 17)
-
-set(TARGET pw_unit_test_demo)
-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)
+vec_cc_test(
+ NAME
+ pw_unit_test_demo
+ SRCS
+ pw_unit_test_demo.cpp
+ DEPS
+ springbok
+ LINKOPTS
+ -T${LINKER_SCRIPT}
+ -Xlinker --defsym=__itcm_length__=128K
+)
diff --git a/springbok/CMakeLists.txt b/springbok/CMakeLists.txt
index 41acb68..0ba73f6 100644
--- a/springbok/CMakeLists.txt
+++ b/springbok/CMakeLists.txt
@@ -1,34 +1,29 @@
-cmake_minimum_required(VERSION 3.1)
enable_language(ASM)
add_library(springbok INTERFACE)
add_library(springbok_intrinsic STATIC)
-target_sources(springbok_intrinsic PRIVATE
- crt0.s
- springbok_gloss.cpp)
+target_sources(springbok_intrinsic
+ PRIVATE
+ crt0.s
+ springbok_gloss.cpp
+)
target_include_directories(springbok_intrinsic PUBLIC include)
target_link_libraries(springbok
INTERFACE
- springbok_intrinsic
+ springbok_intrinsic
)
target_include_directories(springbok INTERFACE include)
-target_compile_options(springbok_intrinsic PUBLIC
- -Wall
- -Werror
- -Os
- -g3
- -ggdb
- -ffreestanding
- -ffunction-sections
- -fstack-usage
- -mstrict-align)
+target_compile_options(springbok_intrinsic
+ PUBLIC
+ ${VEC_DEFAULT_COPTS}
+)
target_link_options(springbok
-INTERFACE
--Wl,--whole-archive ${CMAKE_CURRENT_BINARY_DIR}/libspringbok_intrinsic.a -Wl,--no-whole-archive
+ INTERFACE
+ -Wl,--whole-archive ${CMAKE_CURRENT_BINARY_DIR}/libspringbok_intrinsic.a -Wl,--no-whole-archive
)
diff --git a/test_vsetvl/CMakeLists.txt b/test_vsetvl/CMakeLists.txt
deleted file mode 100644
index cd7a075..0000000
--- a/test_vsetvl/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-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
deleted file mode 100644
index 8eb5912..0000000
--- a/test_vsetvl/test_vsetvl.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#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
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..fe84b42
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.10)
+
+enable_language(ASM)
+
+add_library(test_v_helpers
+ test_v_helpers.cpp)
+
+target_include_directories(test_v_helpers PUBLIC include)
+
+target_compile_options(test_v_helpers PUBLIC
+ ${VEC_DEFAULT_COPTS}
+)
+
+vec_cc_test(
+ NAME
+ vsetvl_test
+ SRCS
+ vsetvl_test.cpp
+ DEPS
+ springbok
+ LINKOPTS
+ -T${LINKER_SCRIPT}
+ -Xlinker --defsym=__itcm_length__=256K
+)
+
+vec_cc_test(
+ NAME
+ vle_vse_test
+ SRCS
+ vle_vse_test.cpp
+ DEPS
+ springbok
+ LINKOPTS
+ -T${LINKER_SCRIPT}
+ -Xlinker --defsym=__itcm_length__=256K
+)
diff --git a/tests/include/test_v_helpers.h b/tests/include/test_v_helpers.h
new file mode 100644
index 0000000..e8ac315
--- /dev/null
+++ b/tests/include/test_v_helpers.h
@@ -0,0 +1,44 @@
+#ifndef TEST_V_HELPERS_H
+#define TEST_V_HELPERS_H
+
+namespace test_v_helpers {
+
+enum VSEW {
+ SEW_E8 = 0,
+ SEW_E16 = 1,
+ SEW_E32 = 2,
+/* // SEW limited to E32
+ SEW_E64 = 3,
+ SEW_E128 = 4,
+ SEW_E256 = 5,
+ SEW_E512 = 6,
+ SEW_E1024 = 7,
+*/
+};
+
+enum VLMUL {
+
+/* // Fractional LMUL not supported by our intrinsic compiler
+ LMUL_MF8 = 5,
+ LMUL_MF4 = 6,
+ LMUL_MF2 = 7,
+*/
+ LMUL_M1 = 0,
+ LMUL_M2 = 1,
+ LMUL_M4 = 2,
+ LMUL_M8 = 3,
+};
+
+uint32_t get_vtype(VSEW sew, VLMUL lmul, bool tail_agnostic, bool mask_agnostic);
+
+// vsetvl rd, rs1, rs2 # rd = new vl, rs1 = AVL, rs2 = new vtype value
+uint32_t set_vsetvl(VSEW sew, VLMUL lmul, uint32_t avl, bool tail_agnostic, bool mask_agnostic);
+
+int set_vsetvl_intrinsic(VSEW sew, VLMUL lmul, uint32_t avl);
+
+int get_vsetvlmax_intrinsic(VSEW sew, VLMUL lmul);
+
+int set_vsetvli(VSEW sew, VLMUL lmul, uint32_t avl);
+
+}
+#endif
diff --git a/tests/test_v_helpers.cpp b/tests/test_v_helpers.cpp
new file mode 100644
index 0000000..f5404e3
--- /dev/null
+++ b/tests/test_v_helpers.cpp
@@ -0,0 +1,285 @@
+#include <riscv_vector.h>
+#include "test_v_helpers.h"
+
+
+namespace test_v_helpers {
+
+uint32_t get_vtype(VSEW sew, VLMUL lmul, bool tail_agnostic,
+ bool mask_agnostic) {
+ return (static_cast<int>(lmul) & 0x7) |
+ (static_cast<int>(sew) & 0x7) << 3 |
+ (tail_agnostic & 0x1) << 6 |
+ (mask_agnostic & 0x1) << 7;
+}
+
+uint32_t set_vsetvl(VSEW sew, VLMUL lmul, uint32_t avl, bool tail_agnostic, bool mask_agnostic) {
+ uint32_t vtype = get_vtype(sew, lmul, tail_agnostic, mask_agnostic);
+ uint32_t vl;
+ __asm__ volatile(
+ "vsetvl %[VL], %[AVL], %[VTYPE]"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl), [VTYPE] "r" (vtype)
+ );
+ return vl;
+}
+
+int set_vsetvl_intrinsic(VSEW sew, VLMUL lmul, uint32_t avl) {
+ switch(lmul) {
+ case VLMUL::LMUL_M1:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ return vsetvl_e8m1(avl);
+ break;
+ case VSEW::SEW_E16:
+ return vsetvl_e16m1(avl);
+ break;
+ case VSEW::SEW_E32:
+ return vsetvl_e32m1(avl);
+ break;
+ default:
+ return -1;
+ break;
+ }
+ break;
+ case VLMUL::LMUL_M2:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ return vsetvl_e8m2(avl);
+ break;
+ case VSEW::SEW_E16:
+ return vsetvl_e16m2(avl);
+ break;
+ case VSEW::SEW_E32:
+ return vsetvl_e32m2(avl);
+ break;
+ default:
+ return -1;
+ break;
+ }
+ case VLMUL::LMUL_M4:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ return vsetvl_e8m4(avl);
+ break;
+ case VSEW::SEW_E16:
+ return vsetvl_e16m4(avl);
+ break;
+ case VSEW::SEW_E32:
+ return vsetvl_e32m4(avl);
+ break;
+ default:
+ return -1;
+ break;
+ }
+ break;
+ case VLMUL::LMUL_M8:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ return vsetvl_e8m8(avl);
+ break;
+ case VSEW::SEW_E16:
+ return vsetvl_e16m8(avl);
+ break;
+ case VSEW::SEW_E32:
+ return vsetvl_e32m8(avl);
+ break;
+ default:
+ return -1;
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return -1;
+}
+
+int get_vsetvlmax_intrinsic(VSEW sew, VLMUL lmul) {
+ switch(lmul) {
+ case VLMUL::LMUL_M1:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ return vsetvlmax_e8m1();
+ break;
+ case VSEW::SEW_E16:
+ return vsetvlmax_e16m1();
+ break;
+ case VSEW::SEW_E32:
+ return vsetvlmax_e32m1();
+ break;
+ default:
+ return -1;
+ break;
+ }
+ break;
+ case VLMUL::LMUL_M2:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ return vsetvlmax_e8m2();
+ break;
+ case VSEW::SEW_E16:
+ return vsetvlmax_e16m2();
+ break;
+ case VSEW::SEW_E32:
+ return vsetvlmax_e32m2();
+ break;
+ default:
+ return -1;
+ break;
+ }
+ case VLMUL::LMUL_M4:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ return vsetvlmax_e8m4();
+ break;
+ case VSEW::SEW_E16:
+ return vsetvlmax_e16m4();
+ break;
+ case VSEW::SEW_E32:
+ return vsetvlmax_e32m4();
+ break;
+ default:
+ return -1;
+ break;
+ }
+ break;
+ case VLMUL::LMUL_M8:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ return vsetvlmax_e8m8();
+ break;
+ case VSEW::SEW_E16:
+ return vsetvlmax_e16m8();
+ break;
+ case VSEW::SEW_E32:
+ return vsetvlmax_e32m8();
+ break;
+ default:
+ return -1;
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return -1;
+}
+
+int set_vsetvli(VSEW sew, VLMUL lmul, uint32_t avl) {
+ uint32_t vl = 0;
+ switch(lmul) {
+ case VLMUL::LMUL_M1:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e8, m1"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ case VSEW::SEW_E16:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e16, m1"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ case VSEW::SEW_E32:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e32, m1"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ default:
+ return 0;
+ }
+ break;
+ case VLMUL::LMUL_M2:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e8, m2"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ case VSEW::SEW_E16:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e16, m2"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ case VSEW::SEW_E32:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e32, m2"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ default:
+ return 0;
+ }
+ break;
+ case VLMUL::LMUL_M4:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e8, m4"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ case VSEW::SEW_E16:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e16, m4"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ case VSEW::SEW_E32:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e32, m4"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ default:
+ return 0;
+ }
+ break;
+ case VLMUL::LMUL_M8:
+ switch(sew) {
+ case VSEW::SEW_E8:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e8, m8"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ case VSEW::SEW_E16:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e16, m8"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ case VSEW::SEW_E32:
+ __asm__ volatile(
+ "vsetvli %[VL], %[AVL], e32, m8"
+ : [VL] "=r" (vl)
+ : [AVL] "r" (avl)
+ );
+ break;
+ default:
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+ return vl;
+}
+
+}
diff --git a/tests/vle_vse_test.cpp b/tests/vle_vse_test.cpp
new file mode 100644
index 0000000..80a4172
--- /dev/null
+++ b/tests/vle_vse_test.cpp
@@ -0,0 +1,71 @@
+#include <riscv_vector.h>
+#include <stddef.h>
+#include <springbok_intrinsics.h>
+
+#include "test_v_helpers.h"
+#include "pw_unit_test/framework.h"
+
+namespace vle_vse_test {
+namespace {
+
+using namespace test_v_helpers;
+
+const int VLEN = 512u;
+const int ELEN = 32u;
+const int LMUL_MAX = 8u;
+const int MAXVL_BYTES = VLEN / sizeof(uint8_t) * LMUL_MAX;
+const int AVL_STEP = 4;
+
+uint8_t test_vector_1[MAXVL_BYTES];
+uint8_t test_vector_2[MAXVL_BYTES];
+
+static void vle8vse8_test(VSEW sew, VLMUL lmul, bool use_intrinsic) {
+ int vlmax = get_vsetvlmax_intrinsic(sew, lmul);
+
+ for (int avl = 0; avl <= vlmax; avl+=AVL_STEP) {
+ // clear arrays
+ memset(test_vector_1, 0, MAXVL_BYTES);
+ memset(test_vector_2, 0, MAXVL_BYTES);
+ int vl = set_vsetvl_intrinsic(sew, lmul, avl);
+ EXPECT_EQ(avl, vl);
+ uint8_t *dest = (uint8_t *)test_vector_1;
+ for (int idx = 0; idx < vl; idx++) {
+ dest[idx] = idx;
+ }
+
+ // load c-array values into vector
+ // TODO(gkielian): utilize intrinsics for vle
+ if (use_intrinsic) {
+
+ } else {
+ __asm__ volatile("vle8.v v0, (%0)" : : "r" (test_vector_1));
+
+ // 2) store the vector back into memory (into result c-array)
+ __asm__ volatile("vse8.v v0, (%0)" : : "r" (test_vector_2));
+ }
+ for(int idx = 0; idx < MAXVL_BYTES; idx++)
+ {
+ EXPECT_EQ(test_vector_1[idx], test_vector_2[idx]);
+ }
+ }
+}
+
+TEST(VleVseTest, vle8vse8_e8m1) {
+ vle8vse8_test(VSEW::SEW_E8, VLMUL::LMUL_M1, false);
+}
+
+TEST(VleVseTest, vle8vse8_e8m2) {
+ vle8vse8_test(VSEW::SEW_E8, VLMUL::LMUL_M2, false);
+}
+
+TEST(VleVseTest, vle8vse8_e8m4) {
+ vle8vse8_test(VSEW::SEW_E8, VLMUL::LMUL_M4, false);
+}
+
+TEST(VleVseTest, vle8vse8_e8m8) {
+ vle8vse8_test(VSEW::SEW_E8, VLMUL::LMUL_M8, false);
+}
+
+} // namespace
+} // namespace test_vle_vse
+
diff --git a/tests/vsetvl_test.cpp b/tests/vsetvl_test.cpp
new file mode 100644
index 0000000..09dafb4
--- /dev/null
+++ b/tests/vsetvl_test.cpp
@@ -0,0 +1,146 @@
+#include <riscv_vector.h>
+#include <springbok.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "test_v_helpers.h"
+#include "pw_unit_test/framework.h"
+
+namespace vsetvl_test {
+namespace {
+
+using namespace test_v_helpers;
+
+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);
+}
+
+static void test_vsetvl(VSEW sew, VLMUL vlmul, uint32_t width, float lmul) {
+ for (int i = 0; i < AVL_COUNT; i++) {
+ size_t vl = set_vsetvl_intrinsic(sew, vlmul, AVLS[i]);
+ EXPECT_EQ(vl, calculate_vl(width, AVLS[i], lmul));
+ }
+ for (int i = 0; i < AVL_COUNT; i++) {
+ uint32_t vl = set_vsetvl(sew, vlmul, AVLS[i], false, false);
+ EXPECT_EQ(vl, calculate_vl(width, AVLS[i], lmul));
+ }
+ for (int i = 0; i < AVL_COUNT; i++) {
+ uint32_t vl = set_vsetvli(sew, vlmul, AVLS[i]);
+ EXPECT_EQ(vl, calculate_vl(width, AVLS[i], lmul));
+ }
+}
+
+static void test_vsetvlmax(VSEW sew, VLMUL vlmul, uint32_t width, float lmul) {
+ EXPECT_EQ(get_vsetvlmax_intrinsic(sew, vlmul), (int)VLEN / width * lmul);
+}
+
+TEST(VsetvlTest, vsetvl_e8m1) {
+ test_vsetvl(VSEW::SEW_E8, VLMUL::LMUL_M1, 8, 1.0);
+}
+
+TEST(VsetvlTest, vsetvl_e16m1) {
+ test_vsetvl(VSEW::SEW_E16, VLMUL::LMUL_M1, 16, 1.0);
+}
+
+TEST(VsetvlTest, vsetvl_e32m1) {
+ test_vsetvl(VSEW::SEW_E32, VLMUL::LMUL_M1, 32, 1.0);
+}
+
+TEST(VsetvlTest, vsetvl_e8m2) {
+ test_vsetvl(VSEW::SEW_E8, VLMUL::LMUL_M2, 8, 2.0);
+}
+
+TEST(VsetvlTest, vsetvl_e16m2) {
+ test_vsetvl(VSEW::SEW_E16, VLMUL::LMUL_M2, 16, 2.0);
+}
+
+TEST(VsetvlTest, vsetvl_e32m2) {
+ test_vsetvl(VSEW::SEW_E32, VLMUL::LMUL_M2, 32, 2.0);
+}
+
+TEST(VsetvlTest, vsetvl_e8m4) {
+ test_vsetvl(VSEW::SEW_E8, VLMUL::LMUL_M4, 8, 4.0);
+}
+
+TEST(VsetvlTest, vsetvl_e16m4) {
+ test_vsetvl(VSEW::SEW_E16, VLMUL::LMUL_M4, 16, 4.0);
+}
+
+TEST(VsetvlTest, vsetvl_e32m4) {
+ test_vsetvl(VSEW::SEW_E32, VLMUL::LMUL_M4, 32, 4.0);
+}
+
+TEST(VsetvlTest, vsetvl_e8m8) {
+ test_vsetvl(VSEW::SEW_E8, VLMUL::LMUL_M8, 8, 8.0);
+}
+
+TEST(VsetvlTest, vsetvl_e16m8) {
+ test_vsetvl(VSEW::SEW_E16, VLMUL::LMUL_M8, 16, 8);
+}
+
+TEST(VsetvlTest, vsetvl_e32m8) {
+ test_vsetvl(VSEW::SEW_E32, VLMUL::LMUL_M8, 32, 8.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e8m1) {
+ test_vsetvlmax(VSEW::SEW_E8, VLMUL::LMUL_M1, 8, 1.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e8m2) {
+ test_vsetvlmax(VSEW::SEW_E8, VLMUL::LMUL_M2, 8, 2.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e8m4) {
+ test_vsetvlmax(VSEW::SEW_E8, VLMUL::LMUL_M4, 8, 4.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e8m8) {
+ test_vsetvlmax(VSEW::SEW_E8, VLMUL::LMUL_M8, 8, 8.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e16m1) {
+ test_vsetvlmax(VSEW::SEW_E16, VLMUL::LMUL_M1, 16, 1.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e16m2) {
+ test_vsetvlmax(VSEW::SEW_E16, VLMUL::LMUL_M2, 16, 2.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e16m4) {
+ test_vsetvlmax(VSEW::SEW_E16, VLMUL::LMUL_M4, 16, 4.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e16m8) {
+ test_vsetvlmax(VSEW::SEW_E16, VLMUL::LMUL_M8, 16, 8.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e32m1) {
+ test_vsetvlmax(VSEW::SEW_E32, VLMUL::LMUL_M1, 32, 1.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e32m2) {
+ test_vsetvlmax(VSEW::SEW_E32, VLMUL::LMUL_M2, 32, 2.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e32m4) {
+ test_vsetvlmax(VSEW::SEW_E32, VLMUL::LMUL_M4, 32, 4.0);
+}
+
+TEST(VsetvlTest, vsetvlmax_e32m8) {
+ test_vsetvlmax(VSEW::SEW_E32, VLMUL::LMUL_M8, 32, 8.0);
+}
+
+} // namespace
+} // namespace test_vsetvl
diff --git a/vector_executive/CMakeLists.txt b/vector_executive/CMakeLists.txt
index 1f762cc..4c9d003 100644
--- a/vector_executive/CMakeLists.txt
+++ b/vector_executive/CMakeLists.txt
@@ -1,33 +1,12 @@
-cmake_minimum_required(VERSION 3.10)
-project(vector_executive)
-
-set(TARGET vector_executive)
-set(ELF ${TARGET}.elf)
-
-add_executable(${ELF} ${TARGET}.c)
-
-set_target_properties(${ELF} PROPERTIES LINK_DEPENDS "${LINKER_SCRIPT}")
-
-target_link_libraries(${ELF} springbok)
-
-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}")
-
-target_compile_options(${ELF} PUBLIC
- -Wall
- -Werror
- -O3
- -g3
- -ggdb
- -ffreestanding
- -ffunction-sections
- -fstack-usage
- -mstrict-align)
+vec_cc_binary(
+ NAME
+ vector_executive
+ SRCS
+ vector_executive.c
+ DEPS
+ springbok
+ LINKOPTS
+ -T${LINKER_SCRIPT}
+ -Xlinker --defsym=__itcm_length__=128K
+)
\ No newline at end of file
diff --git a/vector_load_store_tests/CMakeLists.txt b/vector_load_store_tests/CMakeLists.txt
new file mode 100644
index 0000000..359d042
--- /dev/null
+++ b/vector_load_store_tests/CMakeLists.txt
@@ -0,0 +1,13 @@
+
+vec_cc_binary(
+ NAME
+ vector_load_store_tests
+ SRCS
+ vector_load_store_tests.c
+ DEPS
+ springbok
+ vector_tests
+ LINKOPTS
+ -T${LINKER_SCRIPT}
+ -Xlinker --defsym=__itcm_length__=128K
+)
diff --git a/vector_load_tests/include/vector_load_store_tests.h b/vector_load_store_tests/include/vector_load_store_tests.h
similarity index 100%
rename from vector_load_tests/include/vector_load_store_tests.h
rename to vector_load_store_tests/include/vector_load_store_tests.h
diff --git a/vector_load_tests/vector_load_store_tests.c b/vector_load_store_tests/vector_load_store_tests.c
similarity index 100%
rename from vector_load_tests/vector_load_store_tests.c
rename to vector_load_store_tests/vector_load_store_tests.c
diff --git a/vector_load_tests/CMakeLists.txt b/vector_load_tests/CMakeLists.txt
deleted file mode 100644
index 7d13871..0000000
--- a/vector_load_tests/CMakeLists.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-
-project(vector_load_tests)
-
-
-set(TARGET vector_load_tests)
-set(ELF ${TARGET}.elf)
-
-add_executable(${ELF} vector_load_store_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
- -O3
- -g)
-
diff --git a/vector_tests/CMakeLists.txt b/vector_tests/CMakeLists.txt
index d7f6bc1..e939871 100644
--- a/vector_tests/CMakeLists.txt
+++ b/vector_tests/CMakeLists.txt
@@ -1,4 +1,3 @@
-cmake_minimum_required(VERSION 3.1)
enable_language(ASM)
add_library(vector_tests
@@ -10,12 +9,5 @@
target_link_libraries(vector_tests springbok)
target_compile_options(vector_tests PUBLIC
- -Wall
- -Werror
- -O3
- -g3
- -ggdb
- -ffreestanding
- -ffunction-sections
- -fstack-usage
- -mstrict-align)
+ ${VEC_DEFAULT_COPTS}
+)
diff --git a/vector_vadd_vsub_tests/CMakeLists.txt b/vector_vadd_vsub_tests/CMakeLists.txt
index 008773a..dc52f7a 100644
--- a/vector_vadd_vsub_tests/CMakeLists.txt
+++ b/vector_vadd_vsub_tests/CMakeLists.txt
@@ -1,42 +1,20 @@
-cmake_minimum_required(VERSION 3.10)
set (OPERAND_TYPES VV VX VI)
foreach(OPERAND_TYPE ${OPERAND_TYPES})
-project(vector_vadd_vsub_tests_${OPERAND_TYPE})
-
-string(TOLOWER ${OPERAND_TYPE} OP_SUFFIX)
-
-set(TARGET vector_vadd_vsub_tests_${OP_SUFFIX})
-set(ELF ${TARGET}.elf)
-
-add_executable(${ELF} vector_vadd_vsub_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
- -Wno-unused-value
- -O3
- -g
- -D=TEST_${OPERAND_TYPE})
-
+vec_cc_binary(
+ NAME
+ vector_vadd_vsub_${OPERAND_TYPE}_tests
+ SRCS
+ vector_vadd_vsub_tests.c
+ DEPS
+ springbok
+ vector_tests
+ COPTS
+ -Wno-unused-value
+ -D=TEST_${OPERAND_TYPE}
+ LINKOPTS
+ -T${LINKER_SCRIPT}
+ -Xlinker --defsym=__itcm_length__=128K
+)
endforeach()
diff --git a/vector_vset_tests/CMakeLists.txt b/vector_vset_tests/CMakeLists.txt
index ba64c6b..1fa1776 100644
--- a/vector_vset_tests/CMakeLists.txt
+++ b/vector_vset_tests/CMakeLists.txt
@@ -1,35 +1,13 @@
-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
- -O3
- -g)
-
+vec_cc_binary(
+ NAME
+ vector_vset_tests
+ SRCS
+ vector_vset_tests.c
+ DEPS
+ springbok
+ vector_tests
+ LINKOPTS
+ -T${LINKER_SCRIPT}
+ -Xlinker --defsym=__itcm_length__=128K
+)