valid-slots: packets that legally share a slot and were wrongly rejected before the fix (load and transfer, load encoded first; dczeroa packed last with three transfers).
invalid-slots: unassignable packets that must still be rejected: store + duplex, load + indirect jump, three logical ops competing for slots 2 and 3, and five ops for four slots. Signed-off-by: Brian Cain <[email protected]> --- tests/tcg/hexagon/Makefile.target | 1 + tests/tcg/hexagon/invalid-slots.c | 72 +++++++++++++++++++++++++++++++ tests/tcg/hexagon/valid-slots.c | 62 ++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 tests/tcg/hexagon/valid-slots.c diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target index a2a0ffc69b2..80e56f7d055 100644 --- a/tests/tcg/hexagon/Makefile.target +++ b/tests/tcg/hexagon/Makefile.target @@ -51,6 +51,7 @@ HEX_TESTS += scatter_gather HEX_TESTS += hvx_misc HEX_TESTS += hvx_histogram HEX_TESTS += invalid-slots +HEX_TESTS += valid-slots HEX_TESTS += invalid-encoding HEX_TESTS += multiple-writes HEX_TESTS += unaligned_pc diff --git a/tests/tcg/hexagon/invalid-slots.c b/tests/tcg/hexagon/invalid-slots.c index 607027f314d..f2dace2e541 100644 --- a/tests/tcg/hexagon/invalid-slots.c +++ b/tests/tcg/hexagon/invalid-slots.c @@ -55,6 +55,75 @@ static int test_invalid_slots(void) return sig; } +/* Load then indirect jump, load encoded first: no high slot left for jump. */ +static int test_invalid_slots_highslot(void) +{ + int sig; + + asm volatile( + "r0 = #0\n" + "r1 = ##1f\n" + "memw(%1) = r1\n" + "r3 = #mem\n" + ".word 0x91834006\n" /* { r6 = memw(r3+#0); */ + ".word 0x529fc000\n" /* jumpr r31 } */ + "1:\n" + "%0 = r0\n" + : "=r"(sig) + : "r"(&resume_pc) + : "r0", "r1", "r3", "r6", "memory"); + + return sig; +} + +/* + * Three predicate-logical ops: each is restricted to slots 2 and 3, so the + * fourth-and-fifth-slot-free packet still has only two slots for three ops. + * No change-of-flow is involved, so the only reason to reject it is the slot + * conflict. + */ +static int test_invalid_slots_crslot23(void) +{ + int sig; + + asm volatile( + "r0 = #0\n" + "r1 = ##1f\n" + "memw(%1) = r1\n" + ".word 0x6b024100\n" /* { p0 = and(p1, p2); */ + ".word 0x6b224103\n" /* p3 = or(p1, p2); */ + ".word 0x6b42c301\n" /* p1 = xor(p2, p3) } */ + "1:\n" + "%0 = r0\n" + : "=r"(sig) + : "r"(&resume_pc) + : "r0", "r1", "p0", "p1", "p3", "memory"); + + return sig; +} + +/* Three transfers plus a duplex: five ops for four slots. */ +static int test_invalid_slots_five(void) +{ + int sig; + + asm volatile( + "r0 = #0\n" + "r1 = ##1f\n" + "memw(%1) = r1\n" + ".word 0x78004020\n" /* { r0 = #1; */ + ".word 0x78004041\n" /* r1 = #2; */ + ".word 0x78004062\n" /* r2 = #3; */ + ".word 0x28452856\n" /* r5 = #4; r6 = #5 } */ + "1:\n" + "%0 = r0\n" + : "=r"(sig) + : "r"(&resume_pc) + : "r0", "r1", "r2", "r5", "r6", "memory"); + + return sig; +} + int main() { struct sigaction act; @@ -65,6 +134,9 @@ int main() assert(sigaction(SIGILL, &act, NULL) == 0); assert(test_invalid_slots() == SIGILL); + assert(test_invalid_slots_highslot() == SIGILL); + assert(test_invalid_slots_crslot23() == SIGILL); + assert(test_invalid_slots_five() == SIGILL); puts("PASS"); return EXIT_SUCCESS; diff --git a/tests/tcg/hexagon/valid-slots.c b/tests/tcg/hexagon/valid-slots.c new file mode 100644 index 00000000000..70d9b0b6acf --- /dev/null +++ b/tests/tcg/hexagon/valid-slots.c @@ -0,0 +1,62 @@ +/* + * Regression tests for valid packets that qemu incorrectly rejected as + * invalid. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <stdio.h> +#include <stdint.h> + +int err; + +#include "hex_test.h" + +/* volatile to keep the load from being optimized away */ +static volatile int buf[2] = { 0x1234, 0 }; + +/* Load and register transfer in one packet, load encoded first. */ +static int32_t load_imm_pair(void) +{ + int32_t out; + /* { r6 = memw(r3+#-4); r7 = #0x4ae6 } */ + asm volatile( + "{ r3 = %1 }\n\t" + ".word 0x97837fe6\n\t" + ".word 0x7845dcc7\n\t" + "{ %0 = r6 }\n\t" + : "=r"(out) : "r"(&buf[1]) : "r3", "r6", "r7"); + return out; +} + +static int32_t dcbuf[8] __attribute__((aligned(32))); + +/* Slot-0-only op (dczeroa) packed last with three transfers. */ +static void slot0_restricted(int32_t *out) +{ + asm volatile( + "{ %0 = #0x11\n\t" + " %1 = #0x22\n\t" + " %2 = #0x33\n\t" + " dczeroa(%3) }\n\t" + : "=r"(out[0]), "=r"(out[1]), "=r"(out[2]) + : "r"(dcbuf) : "memory"); +} + +int main() +{ + int32_t r[3]; + + check32(load_imm_pair(), 0x1234); + + dcbuf[0] = 0x5a5a5a5a; + slot0_restricted(r); + check32(r[0], 0x11); + check32(r[1], 0x22); + check32(r[2], 0x33); + check32(dcbuf[0], 0); /* dczeroa cleared the line */ + + puts(err ? "FAIL" : "PASS"); + return err; +} -- 2.34.1
