// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

<%!
import vec_test_helpers
%>\
<%def name="test_opivx(op_code)">
namespace ${op_code}_vx_test {
namespace {

using namespace test_v_helpers;

uint8_t src_vector_2[MAXVL_BYTES];
uint8_t dest_vector[MAXVL_BYTES];
uint8_t ref_dest_vector[MAXVL_BYTES];

class ${op_code.capitalize()}Test : public ::testing::Test {
 protected:
  void SetUp() override { zero_vector_registers(); }
  void TearDown() override { zero_vector_registers(); }
};
<%
template_helper = vec_test_helpers.VecTemplateHelper(op_code)
sews = template_helper.get_sews()
lmuls = template_helper.get_lmuls()
%>\
% for sew in sews:
% for lmul in lmuls:
<%
template_helper.sew = sew
%>\
${insert_vx_test(template_helper, lmul)}
%endfor
%endfor

}  // namespace
}  // namespace ${op_code}_vx_test
</%def>

<%def name="insert_vx_test(template_helper, lmul)">
<%
# Initialize the variables for a given test config
op_code = template_helper.op_code
sew = template_helper.sew
ref_opcode = template_helper.get_ref_opcode()
dest_sew, src2_sew, _, __ = template_helper.get_sew_sizes()
datatypes = template_helper.get_softrvv_template_data_type()
var_types = template_helper.get_var_types()
mnemonic = template_helper.get_mnemonic(
  vec_test_helpers.VecTemplateHelper.OperandType.SCALAR)
is_narrowing = template_helper.is_narrowing()
is_widening = template_helper.is_widening()
%>\
TEST_F(${op_code.capitalize()}Test, ${mnemonic.lower().replace(".","_")}${sew}m${lmul}) {
  for (int i = 0; i < AVL_COUNT; i++) {
    int32_t avl = AVLS[i];
    int vlmax;
    int vl;
% if is_narrowing:
    /* When a narrowing instruction is used sew matches dest size */
    vector_test_setup<${var_types.src2_type}>(
        VLMUL::LMUL_M${lmul}, avl,
        {src_vector_2});
    /* SEW is set to size of dest type */
    std::tie(vlmax, vl) = vector_test_setup<${var_types.dest_type}>(
        VLMUL::LMUL_M${lmul}, avl,
        {dest_vector, ref_dest_vector});
% elif is_widening:
    /* When a widening instruction is used sew matches src2 size */
    vector_test_setup<${var_types.dest_type}>(
        VLMUL::LMUL_M${lmul}, avl,
        {dest_vector, ref_dest_vector});
    std::tie(vlmax, vl) = vector_test_setup<${var_types.src2_type}>(
        VLMUL::LMUL_M${lmul}, avl,
        {src_vector_2});
% else:
    /* For non narrowing instructions all vectors have same type*/
    std::tie(vlmax, vl) = vector_test_setup<${var_types.dest_type}>(
        VLMUL::LMUL_M${lmul}, avl,
        {dest_vector, ref_dest_vector, src_vector_2});
% endif
    if (avl > vlmax) {
      continue;
    }
    ${var_types.src2_type} *ptr_vec_2 = reinterpret_cast<${var_types.src2_type} *>(src_vector_2);
    ${var_types.imm_type} test_val = static_cast<${var_types.imm_type}>(rand());
    ${var_types.dest_type} *ptr_dest_vec = reinterpret_cast<${var_types.dest_type} *>(dest_vector);
    ${var_types.dest_type} *ptr_ref_dest_vec = reinterpret_cast<${var_types.dest_type} *>(ref_dest_vector);
    // set up values to test up to index of the AVL
    fill_random_vector<${var_types.src2_type}>(ptr_vec_2, avl);
    memset(dest_vector, 0, MAXVL_BYTES);
    memset(ref_dest_vector, 0, MAXVL_BYTES);

    // Generate reference vector
    softrvv::${ref_opcode}_vx<${datatypes}>(ptr_ref_dest_vec, ptr_vec_2, &test_val, avl);
    // Load vector registers
    __asm__ volatile("vle${src2_sew}.v v8, (%0)" : : "r"(ptr_vec_2));

    // Run target instruction
    __asm__ volatile("${mnemonic} v24, v8, %[RS1]" ::[RS1] "r"(test_val));

    // Store result vector register
    __asm__ volatile("vse${dest_sew}.v v24, (%0)" : : "r"(ptr_dest_vec));
    // Check vector elements
    assert_vec_elem_eq<${var_types.dest_type}>(vlmax, dest_vector, ref_dest_vector);
  }
}
</%def>
