#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 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++)
    {
      ASSERT_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

