| #include <limits.h> |
| #include <riscv_vector.h> |
| #include <springbok.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #include <bit> |
| #include <tuple> |
| |
| #include "pw_unit_test/framework.h" |
| #include "test_v_helpers.h" |
| |
| namespace vand_vi_test { |
| namespace { |
| |
| using namespace test_v_helpers; |
| |
| uint8_t test_vector_1[MAXVL_BYTES]; |
| uint8_t test_vector_2[MAXVL_BYTES]; |
| |
| class VandViTest : public ::testing::Test { |
| protected: |
| void SetUp() override { zero_vector_registers(); } |
| void TearDown() override { zero_vector_registers(); } |
| }; |
| |
| // Below is a non-macro version of the test for more convenient debugging. |
| // Remove the "DISABLED_" prefix to enable this test for debugging. |
| TEST_F(VandViTest, DISABLED_vand_vi_demo) { |
| for (int i = 0; i < AVL_COUNT; i++) { |
| int32_t avl = AVLS[i]; |
| int vlmax; |
| int vl; |
| std::tie(vlmax, vl) = vector_test_setup<int8_t>( |
| VLMUL::LMUL_M1, avl, test_vector_1, test_vector_2); |
| if (avl > vlmax) { |
| continue; |
| } |
| int8_t *ptr_vec_1 = reinterpret_cast<int8_t *>(test_vector_1); |
| int8_t *ptr_vec_2 = reinterpret_cast<int8_t *>(test_vector_2); |
| const int8_t test_val_1 = INT8_MIN; |
| const int8_t test_val_2 = 15; // range of SIMM5 is [-16, 15] |
| for (int i = 0; i < vl; i++) { |
| ptr_vec_1[i] = test_val_1; |
| } |
| __asm__ volatile("vle8.v v8, (%0)" : : "r"(ptr_vec_1)); |
| __asm__ volatile("vand.vi v8, v8, %[SIMM5]" ::[SIMM5] "n"(test_val_2)); |
| for (int i = 0; i < vl; i++) { |
| ptr_vec_1[i] = test_val_1 & test_val_2; |
| } |
| __asm__ volatile("vse8.v v8, (%0)" : : "r"(ptr_vec_2)); |
| assert_vec_elem_eq<int8_t>(vlmax, test_vector_1, test_vector_2); |
| } |
| } |
| |
| #define DEFINE_TEST_VAND_VI(_SEW_, _LMUL_, TEST_VAL_1, TEST_VAL_2) \ |
| TEST_F(VandViTest, vand_vi##_SEW_##m##_LMUL_) { \ |
| for (int i = 0; i < AVL_COUNT; i++) { \ |
| int32_t avl = AVLS[i]; \ |
| int vlmax; \ |
| int vl; \ |
| std::tie(vlmax, vl) = vector_test_setup<int##_SEW_##_t>( \ |
| VLMUL::LMUL_M##_LMUL_, avl, test_vector_1, test_vector_2); \ |
| if (avl > vlmax) { \ |
| continue; \ |
| } \ |
| int##_SEW_##_t *ptr_vec_1 = \ |
| reinterpret_cast<int##_SEW_##_t *>(test_vector_1); \ |
| int##_SEW_##_t *ptr_vec_2 = \ |
| reinterpret_cast<int##_SEW_##_t *>(test_vector_2); \ |
| const int##_SEW_##_t test_val_1 = TEST_VAL_1; \ |
| const int##_SEW_##_t test_val_2 = TEST_VAL_2; \ |
| for (int i = 0; i < vl; i++) { \ |
| ptr_vec_1[i] = test_val_1; \ |
| } \ |
| __asm__ volatile("vle" #_SEW_ ".v v8, (%0)" : : "r"(ptr_vec_1)); \ |
| __asm__ volatile("vand.vi v8, v8, %[SIMM5]" ::[SIMM5] "n"(test_val_2)); \ |
| for (int i = 0; i < vl; i++) { \ |
| ptr_vec_1[i] = test_val_1 & test_val_2; \ |
| } \ |
| __asm__ volatile("vse" #_SEW_ ".v v8, (%0)" : : "r"(ptr_vec_2)); \ |
| assert_vec_elem_eq<int##_SEW_##_t>(vlmax, test_vector_1, test_vector_2); \ |
| } \ |
| } |
| |
| // TODO(gkielian): modify macro to permit more than one test per sew/lmul pair |
| |
| // Macro Usage Note: |
| // First value just needs to be within SEW range |
| // Second value needs to be within range [-16, 15] (SIMM5 range) |
| DEFINE_TEST_VAND_VI(8, 1, INT8_MIN, 15) |
| DEFINE_TEST_VAND_VI(8, 2, INT8_MAX, 3) |
| DEFINE_TEST_VAND_VI(8, 4, -1, 15) |
| DEFINE_TEST_VAND_VI(8, 8, 0, -16) |
| |
| DEFINE_TEST_VAND_VI(16, 1, INT16_MIN, 15) |
| DEFINE_TEST_VAND_VI(16, 2, INT16_MAX, 3) |
| DEFINE_TEST_VAND_VI(16, 4, -1, 15) |
| DEFINE_TEST_VAND_VI(16, 8, 0, -16) |
| |
| DEFINE_TEST_VAND_VI(32, 1, INT32_MIN, 15) |
| DEFINE_TEST_VAND_VI(32, 2, INT32_MAX, 3) |
| DEFINE_TEST_VAND_VI(32, 4, -1, 15) |
| DEFINE_TEST_VAND_VI(32, 8, 0, -16) |
| |
| } // namespace |
| } // namespace vand_vi_test |
| |