Henry Herman | 349c533 | 2021-09-08 08:42:35 +0000 | [diff] [blame] | 1 | <%! |
| 2 | import vec_test_helpers |
| 3 | %>\ |
Henry Herman | 6f03704 | 2021-09-01 23:15:40 +0000 | [diff] [blame] | 4 | <%def name="test_opivx(op_code)"> |
Henry Herman | b941380 | 2021-08-17 20:19:56 +0000 | [diff] [blame] | 5 | namespace ${op_code}_vx_test { |
| 6 | namespace { |
| 7 | |
| 8 | using namespace test_v_helpers; |
| 9 | |
Henry Herman | 349c533 | 2021-09-08 08:42:35 +0000 | [diff] [blame] | 10 | uint8_t src_vector_2[MAXVL_BYTES]; |
Henry Herman | b941380 | 2021-08-17 20:19:56 +0000 | [diff] [blame] | 11 | uint8_t dest_vector[MAXVL_BYTES]; |
| 12 | uint8_t ref_dest_vector[MAXVL_BYTES]; |
| 13 | |
| 14 | class ${op_code.capitalize()}Test : public ::testing::Test { |
| 15 | protected: |
| 16 | void SetUp() override { zero_vector_registers(); } |
| 17 | void TearDown() override { zero_vector_registers(); } |
| 18 | }; |
Henry Herman | b941380 | 2021-08-17 20:19:56 +0000 | [diff] [blame] | 19 | <% |
Henry Herman | 349c533 | 2021-09-08 08:42:35 +0000 | [diff] [blame] | 20 | template_helper = vec_test_helpers.VecTemplateHelper(op_code) |
| 21 | sews = template_helper.get_sews() |
| 22 | lmuls = template_helper.get_lmuls() |
Henry Herman | 18e407c | 2021-08-18 07:30:41 +0000 | [diff] [blame] | 23 | %>\ |
| 24 | % for sew in sews: |
| 25 | % for lmul in lmuls: |
| 26 | <% |
Henry Herman | 349c533 | 2021-09-08 08:42:35 +0000 | [diff] [blame] | 27 | template_helper.sew = sew |
Henry Herman | b941380 | 2021-08-17 20:19:56 +0000 | [diff] [blame] | 28 | %>\ |
Henry Herman | 349c533 | 2021-09-08 08:42:35 +0000 | [diff] [blame] | 29 | ${insert_vx_test(template_helper, lmul)} |
Henry Herman | b941380 | 2021-08-17 20:19:56 +0000 | [diff] [blame] | 30 | %endfor |
| 31 | %endfor |
| 32 | |
| 33 | } // namespace |
| 34 | } // namespace ${op_code}_vx_test |
Henry Herman | 6f03704 | 2021-09-01 23:15:40 +0000 | [diff] [blame] | 35 | </%def> |
| 36 | |
Henry Herman | 349c533 | 2021-09-08 08:42:35 +0000 | [diff] [blame] | 37 | <%def name="insert_vx_test(template_helper, lmul)"> |
| 38 | <% |
| 39 | # Initialize the variables for a given test config |
| 40 | op_code = template_helper.op_code |
| 41 | sew = template_helper.sew |
| 42 | ref_opcode = template_helper.get_ref_opcode() |
| 43 | dest_sew, src2_sew, _, __ = template_helper.get_sew_sizes() |
| 44 | datatypes = template_helper.get_softrvv_template_data_type() |
| 45 | var_types = template_helper.get_var_types() |
| 46 | mnemonic = template_helper.get_mnemonic( |
| 47 | vec_test_helpers.VecTemplateHelper.OperandType.SCALAR) |
| 48 | is_narrowing = template_helper.is_narrowing() |
| 49 | is_widening = template_helper.is_widening() |
| 50 | %>\ |
| 51 | TEST_F(${op_code.capitalize()}Test, ${mnemonic.lower().replace(".","_")}${sew}m${lmul}) { |
| 52 | for (int i = 0; i < AVL_COUNT; i++) { |
| 53 | int32_t avl = AVLS[i]; |
| 54 | int vlmax; |
| 55 | int vl; |
| 56 | % if is_narrowing: |
| 57 | /* When a narrowing instruction is used sew matches dest size */ |
| 58 | vector_test_setup<${var_types.src2_type}>( |
| 59 | VLMUL::LMUL_M${lmul}, avl, |
| 60 | {src_vector_2}); |
| 61 | /* SEW is set to size of dest type */ |
| 62 | std::tie(vlmax, vl) = vector_test_setup<${var_types.dest_type}>( |
| 63 | VLMUL::LMUL_M${lmul}, avl, |
| 64 | {dest_vector, ref_dest_vector}); |
| 65 | % elif is_widening: |
| 66 | /* When a widening instruction is used sew matches src2 size */ |
| 67 | vector_test_setup<${var_types.dest_type}>( |
| 68 | VLMUL::LMUL_M${lmul}, avl, |
| 69 | {dest_vector, ref_dest_vector}); |
| 70 | std::tie(vlmax, vl) = vector_test_setup<${var_types.src2_type}>( |
| 71 | VLMUL::LMUL_M${lmul}, avl, |
| 72 | {src_vector_2}); |
| 73 | % else: |
| 74 | /* For non narrowing instructions all vectors have same type*/ |
| 75 | std::tie(vlmax, vl) = vector_test_setup<${var_types.dest_type}>( |
| 76 | VLMUL::LMUL_M${lmul}, avl, |
| 77 | {dest_vector, ref_dest_vector, src_vector_2}); |
| 78 | % endif |
| 79 | if (avl > vlmax) { |
| 80 | continue; |
| 81 | } |
| 82 | ${var_types.src2_type} *ptr_vec_2 = reinterpret_cast<${var_types.src2_type} *>(src_vector_2); |
| 83 | ${var_types.imm_type} test_val = static_cast<${var_types.imm_type}>(rand()); |
| 84 | ${var_types.dest_type} *ptr_dest_vec = reinterpret_cast<${var_types.dest_type} *>(dest_vector); |
| 85 | ${var_types.dest_type} *ptr_ref_dest_vec = reinterpret_cast<${var_types.dest_type} *>(ref_dest_vector); |
| 86 | // set up values to test up to index of the AVL |
| 87 | fill_random_vector<${var_types.src2_type}>(ptr_vec_2, avl); |
| 88 | memset(dest_vector, 0, MAXVL_BYTES); |
| 89 | memset(ref_dest_vector, 0, MAXVL_BYTES); |
| 90 | |
| 91 | // Generate reference vector |
| 92 | softrvv::${ref_opcode}_vx<${datatypes}>(ptr_ref_dest_vec, ptr_vec_2, &test_val, avl); |
| 93 | // Load vector registers |
| 94 | __asm__ volatile("vle${src2_sew}.v v8, (%0)" : : "r"(ptr_vec_2)); |
| 95 | |
| 96 | // Run target instruction |
| 97 | __asm__ volatile("${mnemonic} v24, v8, %[RS1]" ::[RS1] "r"(test_val)); |
| 98 | |
| 99 | // Store result vector register |
| 100 | __asm__ volatile("vse${dest_sew}.v v24, (%0)" : : "r"(ptr_dest_vec)); |
| 101 | // Check vector elements |
| 102 | assert_vec_elem_eq<${var_types.dest_type}>(vlmax, dest_vector, ref_dest_vector); |
| 103 | } |
| 104 | } |
| 105 | </%def> |