blob: e2a91529b5200f375b7f4c2a07cb617db1b3f3a1 [file] [log] [blame]
#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 int get_vsetvlmax(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;
}
static void vle8vse8_test(VSEW sew, VLMUL lmul, bool use_intrinsic) {
int vlmax = get_vsetvlmax(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