aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLev Rumyantsev <levarum@google.com>2024-05-04 22:49:47 -0700
committerLev Rumyantsev <levarum@google.com>2024-05-06 23:06:00 -0700
commit39164a17fc06a3e0e61274c5e03cb9936cec78e8 (patch)
treec2207ff3d9be2f4a7cedb23ea2bf3f4ba3300954
parent4459ca2577c44f3c9f8a2af1210aa73ba428e20b (diff)
downloadbinary_translation-39164a17fc06a3e0e61274c5e03cb9936cec78e8.tar.gz
inline_asm_tests: pass tested insn as an arg
Test: This is the test Bug: 301577077 Change-Id: I959a383a2b6d55a671ab662bc513ba97a6685497
-rw-r--r--tests/inline_asm_tests/main_riscv64.cc121
1 files changed, 70 insertions, 51 deletions
diff --git a/tests/inline_asm_tests/main_riscv64.cc b/tests/inline_asm_tests/main_riscv64.cc
index 6887be47..b8a32aaa 100644
--- a/tests/inline_asm_tests/main_riscv64.cc
+++ b/tests/inline_asm_tests/main_riscv64.cc
@@ -16,6 +16,7 @@
#include "gtest/gtest.h"
+#include <cstdint>
#include <tuple>
namespace {
@@ -53,8 +54,66 @@ constexpr __v2du kVectorCalculationsSource[16] = {
constexpr __v2du kUndisturbedResult = {0x5555'5555'5555'5555, 0x5555'5555'5555'5555};
constexpr __v2du kAgnosticResult = {~uint64_t{0U}, ~uint64_t{0U}};
+using ExecInsnFunc = void (*)();
+
+void RunTwoVectorArgsOneRes(ExecInsnFunc exec_insn,
+ const __v2du* src,
+ __v2du* res,
+ uint64_t vtype,
+ uint64_t vlmax) {
+ uint64_t vstart, vl;
+ asm( // Load arguments and undisturbed result.
+ "vsetvli t0, zero, e64, m8, ta, ma\n\t"
+ "vle64.v v8, (%[res])\n\t"
+ "vle64.v v16, (%[src])\n\t"
+ "addi t0, %[src], 128\n\t"
+ "vle64.v v24, (t0)\n\t"
+ // Execute tested instruction.
+ "vsetvl t0, zero, %[vtype]\n\t"
+ "jalr %[exec_insn]\n\t"
+ // Save vstart and vl just after insn execution for checks.
+ "csrr %[vstart], vstart\n\t"
+ "csrr %[vl], vl\n\t"
+ // Store the result.
+ "vsetvli t0, zero, e64, m8, ta, ma\n\t"
+ "vse64.v v8, (%[res])\n\t"
+ : [vstart] "=&r"(vstart), [vl] "=&r"(vl)
+ : [exec_insn] "r"(exec_insn), [src] "r"(src), [res] "r"(res), [vtype] "r"(vtype)
+ : "t0",
+ "ra",
+ "v8",
+ "v9",
+ "v10",
+ "v11",
+ "v12",
+ "v13",
+ "v14",
+ "v15",
+ "v16",
+ "v17",
+ "v18",
+ "v19",
+ "v20",
+ "v21",
+ "v22",
+ "v23",
+ "v24",
+ "v25",
+ "v26",
+ "v27",
+ "v28",
+ "v29",
+ "v30",
+ "v31",
+ "memory");
+ // Every vector instruction must set vstart to 0, but shouldn't touch vl.
+ EXPECT_EQ(vstart, 0);
+ EXPECT_EQ(vl, vlmax);
+}
+
template <typename... ExpectedResultType>
void TestVectorReductionInstruction(
+ ExecInsnFunc exec_insn,
const __v2du (&source)[16],
std::tuple<const ExpectedResultType (&)[8],
const ExpectedResultType (&)[8]>... expected_result) {
@@ -62,7 +121,7 @@ void TestVectorReductionInstruction(
// of the possible vlmul, i.e. expected_result_vd0_int8[n] = vd[0], int8, no mask, vlmul=n.
//
// As vlmul=4 is reserved, expected_result_vd0_*[4] is ignored.
- auto Verify = [&source](uint8_t vsew, uint8_t vlmul, const auto& expected_result) {
+ auto Verify = [&source, exec_insn](uint8_t vsew, uint8_t vlmul, const auto& expected_result) {
for (uint8_t vta = 0; vta < 2; ++vta) {
for (uint8_t vma = 0; vma < 2; ++vma) {
uint64_t vtype = (vma << 7) | (vta << 6) | (vsew << 3) | vlmul;
@@ -78,55 +137,7 @@ void TestVectorReductionInstruction(
memcpy(&result[index], &kUndisturbedResult, sizeof(result[index]));
}
- uint64_t vstart, vl;
-
- asm( // Load arguments and undisturbed result.
- "vsetvli t0, zero, e64, m8, ta, ma\n\t"
- "vle64.v v8, (%[res])\n\t"
- "vle64.v v16, (%[src])\n\t"
- "addi t0, %[src], 128\n\t"
- "vle64.v v24, (t0)\n\t"
- // Execute tested instruction.
- "vsetvl t0, zero, %[vtype]\n\t"
- "vredsum.vs v8,v16,v24\n\t"
- // Save vstart and vl just after insn execution for checks.
- "csrr %[vstart], vstart\n\t"
- "csrr %[vl], vl\n\t"
- // Store the result.
- "vsetvli t0, zero, e64, m8, ta, ma\n\t"
- "vse64.v v8, (%[res])\n\t"
- : [vstart] "=&r"(vstart), [vl] "=&r"(vl)
- : [src] "r"(&kVectorCalculationsSource[0]), [res] "r"(&result[0]), [vtype] "r"(vtype)
- : "t0",
- "v8",
- "v9",
- "v10",
- "v11",
- "v12",
- "v13",
- "v14",
- "v15",
- "v16",
- "v17",
- "v18",
- "v19",
- "v20",
- "v21",
- "v22",
- "v23",
- "v24",
- "v25",
- "v26",
- "v27",
- "v28",
- "v29",
- "v30",
- "v31",
- "memory");
-
- // Every vector instruction must set vstart to 0, but shouldn't touch vl.
- EXPECT_EQ(vstart, 0);
- EXPECT_EQ(vl, vlmax);
+ RunTwoVectorArgsOneRes(exec_insn, &kVectorCalculationsSource[0], &result[0], vtype, vlmax);
// Reduction instructions are unique in that they produce a scalar
// output to a single vector register as opposed to a register group.
@@ -167,7 +178,8 @@ void TestVectorReductionInstruction(
}
}
-void TestVectorReductionInstruction(const uint8_t (&expected_result_vd0_int8)[8],
+void TestVectorReductionInstruction(ExecInsnFunc exec_insn,
+ const uint8_t (&expected_result_vd0_int8)[8],
const uint16_t (&expected_result_vd0_int16)[8],
const uint32_t (&expected_result_vd0_int32)[8],
const uint64_t (&expected_result_vd0_int64)[8],
@@ -177,6 +189,7 @@ void TestVectorReductionInstruction(const uint8_t (&expected_result_vd0_int8)[8]
const uint64_t (&expected_result_vd0_with_mask_int64)[8],
const __v2du (&source)[16]) {
TestVectorReductionInstruction(
+ exec_insn,
source,
std::tuple<const uint8_t(&)[8], const uint8_t(&)[8]>{expected_result_vd0_int8,
expected_result_vd0_with_mask_int8},
@@ -188,8 +201,14 @@ void TestVectorReductionInstruction(const uint8_t (&expected_result_vd0_int8)[8]
expected_result_vd0_with_mask_int64});
}
+[[gnu::naked]] void ExecVredsum() {
+ asm("vredsum.vs v8,v16,v24\n\t"
+ "ret\n\t");
+}
+
TEST(InlineAsmTestRiscv64, TestVredsum) {
TestVectorReductionInstruction(
+ ExecVredsum,
// expected_result_vd0_int8
{242, 228, 200, 144, /* unused */ 0, 146, 44, 121},
// expected_result_vd0_int16