blob: 9d53f97d17b967e4ead756ebe5ba37623b41d428 [file] [log] [blame]
#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