summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorTaylor Simpson2022-07-19 01:03:18 +0200
committerTaylor Simpson2022-08-01 01:22:09 +0200
commit1e814a0dc4b255a58f2cdab54aee50b25af2a006 (patch)
tree255d9c271f509e259632f6375d3b10f36c1c500b /tests
parentMerge tag 'pull-la-20220729' of https://gitlab.com/rth7680/qemu into staging (diff)
downloadqemu-1e814a0dc4b255a58f2cdab54aee50b25af2a006.tar.gz
qemu-1e814a0dc4b255a58f2cdab54aee50b25af2a006.tar.xz
qemu-1e814a0dc4b255a58f2cdab54aee50b25af2a006.zip
Hexagon (target/hexagon) make VyV operands use a unique temp
VyV operand is only used in the vshuff and vdeal instructions. These instructions write to both VyV and VxV operands. In the case where both operands are the same register, we need a separate location for VyV. We use the existing vtmp field in CPUHexagonState. Test case added in tests/tcg/hexagon/hvx_misc.c Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220718230320.24444-2-tsimpson@quicinc.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/tcg/hexagon/hvx_misc.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/tests/tcg/hexagon/hvx_misc.c b/tests/tcg/hexagon/hvx_misc.c
index b896f5897e..6e2c9ab3cd 100644
--- a/tests/tcg/hexagon/hvx_misc.c
+++ b/tests/tcg/hexagon/hvx_misc.c
@@ -498,6 +498,49 @@ static void test_vsubuwsat_dv(void)
check_output_w(__LINE__, 2);
}
+static void test_vshuff(void)
+{
+ /* Test that vshuff works when the two operands are the same register */
+ const uint32_t splat = 0x089be55c;
+ const uint32_t shuff = 0x454fa926;
+ MMVector v0, v1;
+
+ memset(expect, 0x12, sizeof(MMVector));
+ memset(output, 0x34, sizeof(MMVector));
+
+ asm volatile("v25 = vsplat(%0)\n\t"
+ "vshuff(v25, v25, %1)\n\t"
+ "vmem(%2 + #0) = v25\n\t"
+ : /* no outputs */
+ : "r"(splat), "r"(shuff), "r"(output)
+ : "v25", "memory");
+
+ /*
+ * The semantics of Hexagon are the operands are pass-by-value, so create
+ * two copies of the vsplat result.
+ */
+ for (int i = 0; i < MAX_VEC_SIZE_BYTES / 4; i++) {
+ v0.uw[i] = splat;
+ v1.uw[i] = splat;
+ }
+ /* Do the vshuff operation */
+ for (int offset = 1; offset < MAX_VEC_SIZE_BYTES; offset <<= 1) {
+ if (shuff & offset) {
+ for (int k = 0; k < MAX_VEC_SIZE_BYTES; k++) {
+ if (!(k & offset)) {
+ uint8_t tmp = v0.ub[k];
+ v0.ub[k] = v1.ub[k + offset];
+ v1.ub[k + offset] = tmp;
+ }
+ }
+ }
+ }
+ /* Put the result in the expect buffer for verification */
+ expect[0] = v1;
+
+ check_output_b(__LINE__, 1);
+}
+
int main()
{
init_buffers();
@@ -533,6 +576,8 @@ int main()
test_vadduwsat();
test_vsubuwsat_dv();
+ test_vshuff();
+
puts(err ? "FAIL" : "PASS");
return err ? 1 : 0;
}