aboutsummaryrefslogtreecommitdiff
path: root/tests/tcg
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-05-18 20:44:34 -0700
committerRichard Henderson <richard.henderson@linaro.org>2023-05-18 20:44:34 -0700
commit449d6d9eb44772e69f11d002e3c1e2be8a91c350 (patch)
tree124ca1db8453cbdb7a9c6ab83c84785ed1097405 /tests/tcg
parent146f515110e86aefe3bc2e8eb581ab724614060f (diff)
parent9073bfd725440da0af44f1ee1e3bcf72e9de39b6 (diff)
Merge tag 'pull-hex-20230518-1' of https://github.com/quic/qemu into staging
Hexagon update # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEENjXHiM5iuR/UxZq0ewJE+xLeRCIFAmRmgQgACgkQewJE+xLe # RCJLtAf8C/0kQRa4mjnbsztXuFyca53UxAv3BSBEDla4ZcMfFBoVJsGB3OP7IPXd # KBQpkLyJAVye9idex5xqdp9nIfoGKDTsc6YtCfGujZ17cDpzLRDpHdUTex8PcZYK # wpfM3hoVJsYRBMsojZ4OaxatjFQ+FWzrIH6FcgH086Q8TH4w9dZLNEJzHC4lOj0s # 7qOuw2tgm+vOVlzsk/fv6/YD/BTeZTON3jgTPvAnvdRLb/482UpM9JkJ8E4rbte3 # Ss5PUK8QTQHU0yamspGy/PfsYxiptM+jIWGd836fAGzwF12Ug27mSc1enndRtQVW # pQTdnOnWuuRzOwEpd7x3xh9upACm4g== # =1CyJ # -----END PGP SIGNATURE----- # gpg: Signature made Thu 18 May 2023 12:48:24 PM PDT # gpg: using RSA key 3635C788CE62B91FD4C59AB47B0244FB12DE4422 # gpg: Good signature from "Taylor Simpson (Rock on) <tsimpson@quicinc.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 3635 C788 CE62 B91F D4C5 9AB4 7B02 44FB 12DE 4422 * tag 'pull-hex-20230518-1' of https://github.com/quic/qemu: (44 commits) Hexagon (linux-user/hexagon): handle breakpoints Hexagon (gdbstub): add HVX support Hexagon (gdbstub): fix p3:0 read and write via stub Hexagon: add core gdbstub xml data for LLDB gdbstub: add test for untimely stop-reply packets gdbstub: only send stop-reply packets when allowed to Remove test_vshuff from hvx_misc tests Hexagon (decode): look for pkts with multiple insns at the same slot Hexagon (iclass): update J4_hintjumpr slot constraints Hexagon: append eflags to unknown cpu model string Hexagon: list available CPUs with `-cpu help` Hexagon (target/hexagon/*.py): raise exception on reg parsing error target/hexagon: fix = vs. == mishap Hexagon (target/hexagon) Additional instructions handled by idef-parser Hexagon (target/hexagon) Move items to DisasContext Hexagon (target/hexagon) Move pkt_has_store_s1 to DisasContext Hexagon (target/hexagon) Move pred_written to DisasContext Hexagon (target/hexagon) Move new_pred_value to DisasContext Hexagon (target/hexagon) Move new_value to DisasContext Hexagon (target/hexagon) Make special new_value for USR ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tests/tcg')
-rw-r--r--tests/tcg/hexagon/Makefile.target21
-rw-r--r--tests/tcg/hexagon/fpstuff.c54
-rw-r--r--tests/tcg/hexagon/hvx_misc.c66
-rw-r--r--tests/tcg/hexagon/invalid-slots.c29
-rw-r--r--tests/tcg/hexagon/misc.c47
-rw-r--r--tests/tcg/hexagon/read_write_overlap.c136
-rw-r--r--tests/tcg/hexagon/v68_hvx.c90
-rw-r--r--tests/tcg/hexagon/v68_scalar.c186
-rw-r--r--tests/tcg/hexagon/v69_hvx.c318
-rw-r--r--tests/tcg/hexagon/v6mpy_ref.c.inc161
-rw-r--r--tests/tcg/hexagon/v73_scalar.c96
-rw-r--r--tests/tcg/multiarch/system/Makefile.softmmu-target16
12 files changed, 1174 insertions, 46 deletions
diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target
index 7c94db4bc4..890cceed5d 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -45,10 +45,18 @@ HEX_TESTS += fpstuff
HEX_TESTS += overflow
HEX_TESTS += signal_context
HEX_TESTS += reg_mut
+HEX_TESTS += read_write_overlap
HEX_TESTS += vector_add_int
HEX_TESTS += scatter_gather
HEX_TESTS += hvx_misc
HEX_TESTS += hvx_histogram
+HEX_TESTS += invalid-slots
+
+run-and-check-exception = $(call run-test,$2,$3 2>$2.stderr; \
+ test $$? -eq 1 && grep -q "exception $(strip $1)" $2.stderr)
+
+run-invalid-slots: invalid-slots
+ $(call run-and-check-exception, 0x15, $@, $(QEMU) $(QEMU_OPTS) $<)
HEX_TESTS += test_abs
HEX_TESTS += test_bitcnt
@@ -76,17 +84,30 @@ HEX_TESTS += test_vminh
HEX_TESTS += test_vpmpyh
HEX_TESTS += test_vspliceb
+HEX_TESTS += v68_scalar
+HEX_TESTS += v68_hvx
+HEX_TESTS += v69_hvx
+HEX_TESTS += v73_scalar
+
TESTS += $(HEX_TESTS)
# This test has to be compiled for the -mv67t target
usr: usr.c
$(CC) $(CFLAGS) -mv67t -O2 -Wno-inline-asm -Wno-expansion-to-defined $< -o $@ $(LDFLAGS)
+# Build this test with -mv71 to exercise the CABAC instruction
+misc: misc.c
+ $(CC) $(CFLAGS) -mv71 -O2 $< -o $@ $(LDFLAGS)
scatter_gather: CFLAGS += -mhvx
vector_add_int: CFLAGS += -mhvx -fvectorize
hvx_misc: hvx_misc.c hvx_misc.h
hvx_misc: CFLAGS += -mhvx
hvx_histogram: CFLAGS += -mhvx -Wno-gnu-folding-constant
+v68_hvx: v68_hvx.c hvx_misc.h v6mpy_ref.c.inc
+v68_hvx: CFLAGS += -mhvx -Wno-unused-function
+v69_hvx: v69_hvx.c hvx_misc.h
+v69_hvx: CFLAGS += -mhvx -Wno-unused-function
+v73_scalar: CFLAGS += -Wno-unused-function
hvx_histogram: hvx_histogram.c hvx_histogram_row.S
$(CC) $(CFLAGS) $(CROSS_CC_GUEST_CFLAGS) $^ -o $@ $(LDFLAGS)
diff --git a/tests/tcg/hexagon/fpstuff.c b/tests/tcg/hexagon/fpstuff.c
index 90ce9a6ef3..28f9397155 100644
--- a/tests/tcg/hexagon/fpstuff.c
+++ b/tests/tcg/hexagon/fpstuff.c
@@ -20,6 +20,7 @@
*/
#include <stdio.h>
+#include <float.h>
const int FPINVF_BIT = 1; /* Invalid */
const int FPINVF = 1 << FPINVF_BIT;
@@ -706,6 +707,57 @@ static void check_float2int_convs()
check_fpstatus(usr, FPINVF);
}
+static void check_float_consts(void)
+{
+ int res32;
+ unsigned long long res64;
+
+ asm("%0 = sfmake(#%1):neg\n\t" : "=r"(res32) : "i"(0xf));
+ check32(res32, 0xbc9e0000);
+
+ asm("%0 = sfmake(#%1):pos\n\t" : "=r"(res32) : "i"(0xf));
+ check32(res32, 0x3c9e0000);
+
+ asm("%0 = dfmake(#%1):neg\n\t" : "=r"(res64) : "i"(0xf));
+ check64(res64, 0xbf93c00000000000ULL);
+
+ asm("%0 = dfmake(#%1):pos\n\t" : "=r"(res64) : "i"(0xf));
+ check64(res64, 0x3f93c00000000000ULL);
+}
+
+static inline unsigned long long dfmpyll(double x, double y)
+{
+ unsigned long long res64;
+ asm("%0 = dfmpyll(%1, %2)" : "=r"(res64) : "r"(x), "r"(y));
+ return res64;
+}
+
+static inline unsigned long long dfmpylh(double acc, double x, double y)
+{
+ unsigned long long res64 = *(unsigned long long *)&acc;
+ asm("%0 += dfmpylh(%1, %2)" : "+r"(res64) : "r"(x), "r"(y));
+ return res64;
+}
+
+static void check_dfmpyxx(void)
+{
+ unsigned long long res64;
+
+ res64 = dfmpyll(DBL_MIN, DBL_MIN);
+ check64(res64, 0ULL);
+ res64 = dfmpyll(-1.0, DBL_MIN);
+ check64(res64, 0ULL);
+ res64 = dfmpyll(DBL_MAX, DBL_MAX);
+ check64(res64, 0x1fffffffdULL);
+
+ res64 = dfmpylh(DBL_MIN, DBL_MIN, DBL_MIN);
+ check64(res64, 0x10000000000000ULL);
+ res64 = dfmpylh(-1.0, DBL_MAX, DBL_MIN);
+ check64(res64, 0xc00fffffffe00000ULL);
+ res64 = dfmpylh(DBL_MAX, 0.0, -1.0);
+ check64(res64, 0x7fefffffffffffffULL);
+}
+
int main()
{
check_compare_exception();
@@ -718,6 +770,8 @@ int main()
check_sffixupd();
check_sffms();
check_float2int_convs();
+ check_float_consts();
+ check_dfmpyxx();
puts(err ? "FAIL" : "PASS");
return err ? 1 : 0;
diff --git a/tests/tcg/hexagon/hvx_misc.c b/tests/tcg/hexagon/hvx_misc.c
index d0e64e035f..09dec8d7a1 100644
--- a/tests/tcg/hexagon/hvx_misc.c
+++ b/tests/tcg/hexagon/hvx_misc.c
@@ -342,49 +342,6 @@ 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);
-}
-
static void test_load_tmp_predicated(void)
{
void *p0 = buffer0;
@@ -454,6 +411,25 @@ static void test_load_cur_predicated(void)
check_output_w(__LINE__, BUFSIZE);
}
+static void test_vcombine(void)
+{
+ for (int i = 0; i < BUFSIZE / 2; i++) {
+ asm volatile("v2 = vsplat(%0)\n\t"
+ "v3 = vsplat(%1)\n\t"
+ "v3:2 = vcombine(v2, v3)\n\t"
+ "vmem(%2+#0) = v2\n\t"
+ "vmem(%2+#1) = v3\n\t"
+ :
+ : "r"(2 * i), "r"(2 * i + 1), "r"(&output[2 * i])
+ : "v2", "v3", "memory");
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+ expect[2 * i].w[j] = 2 * i + 1;
+ expect[2 * i + 1].w[j] = 2 * i;
+ }
+ }
+ check_output_w(__LINE__, BUFSIZE);
+}
+
int main()
{
init_buffers();
@@ -489,11 +465,11 @@ int main()
test_vadduwsat();
test_vsubuwsat_dv();
- test_vshuff();
-
test_load_tmp_predicated();
test_load_cur_predicated();
+ test_vcombine();
+
puts(err ? "FAIL" : "PASS");
return err ? 1 : 0;
}
diff --git a/tests/tcg/hexagon/invalid-slots.c b/tests/tcg/hexagon/invalid-slots.c
new file mode 100644
index 0000000000..366ce4f42f
--- /dev/null
+++ b/tests/tcg/hexagon/invalid-slots.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright(c) 2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+char mem[8] __attribute__((aligned(8)));
+
+int main()
+{
+ asm volatile(
+ "r0 = #mem\n"
+ /* Invalid packet (2 instructions at slot 0): */
+ ".word 0xa1804100\n" /* { memw(r0) = r1; */
+ ".word 0x28032804\n" /* r3 = #0; r4 = #0 } */
+ : : : "r0", "r3", "r4", "memory");
+ return 0;
+}
diff --git a/tests/tcg/hexagon/misc.c b/tests/tcg/hexagon/misc.c
index e126751e3a..cfdda3fd09 100644
--- a/tests/tcg/hexagon/misc.c
+++ b/tests/tcg/hexagon/misc.c
@@ -18,6 +18,8 @@
#include <stdio.h>
#include <string.h>
+#define CORE_HAS_CABAC (__HEXAGON_ARCH__ <= 71)
+
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
@@ -245,6 +247,7 @@ static void check(int val, int expect)
}
}
+#if CORE_HAS_CABAC
static void check64(long long val, long long expect)
{
if (val != expect) {
@@ -252,6 +255,7 @@ static void check64(long long val, long long expect)
err++;
}
}
+#endif
uint32_t init[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
uint32_t array[10];
@@ -286,6 +290,7 @@ static long long creg_pair(int x, int y)
return retval;
}
+#if CORE_HAS_CABAC
static long long decbin(long long x, long long y, int *pred)
{
long long retval;
@@ -295,6 +300,7 @@ static long long decbin(long long x, long long y, int *pred)
: "r"(x), "r"(y));
return retval;
}
+#endif
/* Check that predicates are auto-and'ed in a packet */
static int auto_and(void)
@@ -385,11 +391,46 @@ void test_count_trailing_zeros_ones(void)
check(ct1p(0xffffff0fffffffffULL), 36);
}
+static inline int dpmpyss_rnd_s0(int x, int y)
+{
+ int res;
+ asm("%0 = mpy(%1, %2):rnd\n\t" : "=r"(res) : "r"(x), "r"(y));
+ return res;
+}
+
+void test_dpmpyss_rnd_s0(void)
+{
+ check(dpmpyss_rnd_s0(-1, 0x80000000), 1);
+ check(dpmpyss_rnd_s0(0, 0x80000000), 0);
+ check(dpmpyss_rnd_s0(1, 0x80000000), 0);
+ check(dpmpyss_rnd_s0(0x7fffffff, 0x80000000), 0xc0000001);
+ check(dpmpyss_rnd_s0(0x80000000, -1), 1);
+ check(dpmpyss_rnd_s0(-1, -1), 0);
+ check(dpmpyss_rnd_s0(0, -1), 0);
+ check(dpmpyss_rnd_s0(1, -1), 0);
+ check(dpmpyss_rnd_s0(0x7fffffff, -1), 0);
+ check(dpmpyss_rnd_s0(0x80000000, 0), 0);
+ check(dpmpyss_rnd_s0(-1, 0), 0);
+ check(dpmpyss_rnd_s0(0, 0), 0);
+ check(dpmpyss_rnd_s0(1, 0), 0);
+ check(dpmpyss_rnd_s0(-1, -1), 0);
+ check(dpmpyss_rnd_s0(0, -1), 0);
+ check(dpmpyss_rnd_s0(1, -1), 0);
+ check(dpmpyss_rnd_s0(0x7fffffff, 1), 0);
+ check(dpmpyss_rnd_s0(0x80000000, 0x7fffffff), 0xc0000001);
+ check(dpmpyss_rnd_s0(-1, 0x7fffffff), 0);
+ check(dpmpyss_rnd_s0(0, 0x7fffffff), 0);
+ check(dpmpyss_rnd_s0(1, 0x7fffffff), 0);
+ check(dpmpyss_rnd_s0(0x7fffffff, 0x7fffffff), 0x3fffffff);
+}
+
int main()
{
int res;
+#if CORE_HAS_CABAC
long long res64;
int pred;
+#endif
memcpy(array, init, sizeof(array));
S4_storerhnew_rr(array, 4, 0xffff);
@@ -505,6 +546,7 @@ int main()
res = test_clrtnew(2, 7);
check(res, 7);
+#if CORE_HAS_CABAC
res64 = decbin(0xf0f1f2f3f4f5f6f7LL, 0x7f6f5f4f3f2f1f0fLL, &pred);
check64(res64, 0x357980003700010cLL);
check(pred, 0);
@@ -512,6 +554,9 @@ int main()
res64 = decbin(0xfLL, 0x1bLL, &pred);
check64(res64, 0x78000100LL);
check(pred, 1);
+#else
+ puts("Skipping cabac tests");
+#endif
res = auto_and();
check(res, 0);
@@ -522,6 +567,8 @@ int main()
test_count_trailing_zeros_ones();
+ test_dpmpyss_rnd_s0();
+
puts(err ? "FAIL" : "PASS");
return err;
}
diff --git a/tests/tcg/hexagon/read_write_overlap.c b/tests/tcg/hexagon/read_write_overlap.c
new file mode 100644
index 0000000000..a75fc11dc4
--- /dev/null
+++ b/tests/tcg/hexagon/read_write_overlap.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright(c) 2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Test instructions where the semantics write to the destination
+ * before all the operand reads have been completed.
+ *
+ * These instructions are problematic when we short-circuit the
+ * register writes because the destination and source operands could
+ * be the same TCGv.
+ *
+ * We test by forcing the read and write to be register r7.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int err;
+
+static void __check(const char *filename, int line, int x, int expect)
+{
+ if (x != expect) {
+ printf("ERROR %s:%d - 0x%08x != 0x%08x\n",
+ filename, line, x, expect);
+ err++;
+ }
+}
+
+#define check(x, expect) __check(__FILE__, __LINE__, (x), (expect))
+
+#define insert(RES, X, WIDTH, OFFSET) \
+ asm("r7 = %1\n\t" \
+ "r7 = insert(r7, #" #WIDTH ", #" #OFFSET ")\n\t" \
+ "%0 = r7\n\t" \
+ : "=r"(RES) : "r"(X) : "r7")
+
+static void test_insert(void)
+{
+ uint32_t res;
+
+ insert(res, 0x12345678, 8, 1);
+ check(res, 0x123456f0);
+ insert(res, 0x12345678, 0, 1);
+ check(res, 0x12345678);
+ insert(res, 0x12345678, 20, 16);
+ check(res, 0x56785678);
+}
+
+static inline uint32_t insert_rp(uint32_t x, uint32_t width, uint32_t offset)
+{
+ uint64_t width_offset = (uint64_t)width << 32 | offset;
+ uint32_t res;
+ asm("r7 = %1\n\t"
+ "r7 = insert(r7, %2)\n\t"
+ "%0 = r7\n\t"
+ : "=r"(res) : "r"(x), "r"(width_offset) : "r7");
+ return res;
+
+}
+
+static void test_insert_rp(void)
+{
+ check(insert_rp(0x12345678, 8, 1), 0x123456f0);
+ check(insert_rp(0x12345678, 63, 8), 0x34567878);
+ check(insert_rp(0x12345678, 127, 8), 0x34567878);
+ check(insert_rp(0x12345678, 8, 24), 0x78345678);
+ check(insert_rp(0x12345678, 8, 63), 0x12345678);
+ check(insert_rp(0x12345678, 8, 64), 0x00000000);
+}
+
+static inline uint32_t asr_r_svw_trun(uint64_t x, uint32_t y)
+{
+ uint32_t res;
+ asm("r7 = %2\n\t"
+ "r7 = vasrw(%1, r7)\n\t"
+ "%0 = r7\n\t"
+ : "=r"(res) : "r"(x), "r"(y) : "r7");
+ return res;
+}
+
+static void test_asr_r_svw_trun(void)
+{
+ check(asr_r_svw_trun(0x1111111122222222ULL, 5),
+ 0x88881111);
+ check(asr_r_svw_trun(0x1111111122222222ULL, 63),
+ 0x00000000);
+ check(asr_r_svw_trun(0x1111111122222222ULL, 64),
+ 0x00000000);
+ check(asr_r_svw_trun(0x1111111122222222ULL, 127),
+ 0x22224444);
+ check(asr_r_svw_trun(0x1111111122222222ULL, 128),
+ 0x11112222);
+ check(asr_r_svw_trun(0xffffffff22222222ULL, 128),
+ 0xffff2222);
+}
+
+static inline uint32_t swiz(uint32_t x)
+{
+ uint32_t res;
+ asm("r7 = %1\n\t"
+ "r7 = swiz(r7)\n\t"
+ "%0 = r7\n\t"
+ : "=r"(res) : "r"(x) : "r7");
+ return res;
+}
+
+static void test_swiz(void)
+{
+ check(swiz(0x11223344), 0x44332211);
+}
+
+int main()
+{
+ test_insert();
+ test_insert_rp();
+ test_asr_r_svw_trun();
+ test_swiz();
+
+ puts(err ? "FAIL" : "PASS");
+ return err ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/tests/tcg/hexagon/v68_hvx.c b/tests/tcg/hexagon/v68_hvx.c
new file mode 100644
index 0000000000..02718722a3
--- /dev/null
+++ b/tests/tcg/hexagon/v68_hvx.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <limits.h>
+
+int err;
+
+#include "hvx_misc.h"
+
+MMVector v6mpy_buffer0[BUFSIZE] __attribute__((aligned(MAX_VEC_SIZE_BYTES)));
+MMVector v6mpy_buffer1[BUFSIZE] __attribute__((aligned(MAX_VEC_SIZE_BYTES)));
+
+static void init_v6mpy_buffers(void)
+{
+ int counter0 = 0;
+ int counter1 = 17;
+ for (int i = 0; i < BUFSIZE; i++) {
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+ v6mpy_buffer0[i].w[j] = counter0++;
+ v6mpy_buffer1[i].w[j] = counter1++;
+ }
+ }
+}
+
+int v6mpy_ref[BUFSIZE][MAX_VEC_SIZE_BYTES / 4] = {
+#include "v6mpy_ref.c.inc"
+};
+
+static void test_v6mpy(void)
+{
+ void *p00 = buffer0;
+ void *p01 = v6mpy_buffer0;
+ void *p10 = buffer1;
+ void *p11 = v6mpy_buffer1;
+ void *pout = output;
+
+ memset(expect, 0xff, sizeof(expect));
+ memset(output, 0xff, sizeof(expect));
+
+ for (int i = 0; i < BUFSIZE; i++) {
+ asm("v2 = vmem(%0 + #0)\n\t"
+ "v3 = vmem(%1 + #0)\n\t"
+ "v4 = vmem(%2 + #0)\n\t"
+ "v5 = vmem(%3 + #0)\n\t"
+ "v5:4.w = v6mpy(v5:4.ub, v3:2.b, #1):v\n\t"
+ "vmem(%4 + #0) = v4\n\t"
+ : : "r"(p00), "r"(p01), "r"(p10), "r"(p11), "r"(pout)
+ : "v2", "v3", "v4", "v5", "memory");
+ p00 += sizeof(MMVector);
+ p01 += sizeof(MMVector);
+ p10 += sizeof(MMVector);
+ p11 += sizeof(MMVector);
+ pout += sizeof(MMVector);
+
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+ expect[i].w[j] = v6mpy_ref[i][j];
+ }
+ }
+
+ check_output_w(__LINE__, BUFSIZE);
+}
+
+int main()
+{
+ init_buffers();
+ init_v6mpy_buffers();
+
+ test_v6mpy();
+
+ puts(err ? "FAIL" : "PASS");
+ return err ? 1 : 0;
+}
diff --git a/tests/tcg/hexagon/v68_scalar.c b/tests/tcg/hexagon/v68_scalar.c
new file mode 100644
index 0000000000..7a8adb1130
--- /dev/null
+++ b/tests/tcg/hexagon/v68_scalar.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright(c) 2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/*
+ * Test the scalar core instructions that are new in v68
+ */
+
+int err;
+
+static int buffer32[] = { 1, 2, 3, 4 };
+static long long buffer64[] = { 5, 6, 7, 8 };
+
+static void __check32(int line, uint32_t result, uint32_t expect)
+{
+ if (result != expect) {
+ printf("ERROR at line %d: 0x%08x != 0x%08x\n",
+ line, result, expect);
+ err++;
+ }
+}
+
+#define check32(RES, EXP) __check32(__LINE__, RES, EXP)
+
+static void __check64(int line, uint64_t result, uint64_t expect)
+{
+ if (result != expect) {
+ printf("ERROR at line %d: 0x%016llx != 0x%016llx\n",
+ line, result, expect);
+ err++;
+ }
+}
+
+#define check64(RES, EXP) __check64(__LINE__, RES, EXP)
+
+static inline int loadw_aq(int *p)
+{
+ int res;
+ asm volatile("%0 = memw_aq(%1)\n\t"
+ : "=r"(res) : "r"(p));
+ return res;
+}
+
+static void test_loadw_aq(void)
+{
+ int res;
+
+ res = loadw_aq(&buffer32[0]);
+ check32(res, 1);
+ res = loadw_aq(&buffer32[1]);
+ check32(res, 2);
+}
+
+static inline long long loadd_aq(long long *p)
+{
+ long long res;
+ asm volatile("%0 = memd_aq(%1)\n\t"
+ : "=r"(res) : "r"(p));
+ return res;
+}
+
+static void test_loadd_aq(void)
+{
+ long long res;
+
+ res = loadd_aq(&buffer64[2]);
+ check64(res, 7);
+ res = loadd_aq(&buffer64[3]);
+ check64(res, 8);
+}
+
+static inline void release_at(int *p)
+{
+ asm volatile("release(%0):at\n\t"
+ : : "r"(p));
+}
+
+static void test_release_at(void)
+{
+ release_at(&buffer32[2]);
+ check64(buffer32[2], 3);
+ release_at(&buffer32[3]);
+ check64(buffer32[3], 4);
+}
+
+static inline void release_st(int *p)
+{
+ asm volatile("release(%0):st\n\t"
+ : : "r"(p));
+}
+
+static void test_release_st(void)
+{
+ release_st(&buffer32[2]);
+ check64(buffer32[2], 3);
+ release_st(&buffer32[3]);
+ check64(buffer32[3], 4);
+}
+
+static inline void storew_rl_at(int *p, int val)
+{
+ asm volatile("memw_rl(%0):at = %1\n\t"
+ : : "r"(p), "r"(val) : "memory");
+}
+
+static void test_storew_rl_at(void)
+{
+ storew_rl_at(&buffer32[2], 9);
+ check64(buffer32[2], 9);
+ storew_rl_at(&buffer32[3], 10);
+ check64(buffer32[3], 10);
+}
+
+static inline void stored_rl_at(long long *p, long long val)
+{
+ asm volatile("memd_rl(%0):at = %1\n\t"
+ : : "r"(p), "r"(val) : "memory");
+}
+
+static void test_stored_rl_at(void)
+{
+ stored_rl_at(&buffer64[2], 11);
+ check64(buffer64[2], 11);
+ stored_rl_at(&buffer64[3], 12);
+ check64(buffer64[3], 12);
+}
+
+static inline void storew_rl_st(int *p, int val)
+{
+ asm volatile("memw_rl(%0):st = %1\n\t"
+ : : "r"(p), "r"(val) : "memory");
+}
+
+static void test_storew_rl_st(void)
+{
+ storew_rl_st(&buffer32[0], 13);
+ check64(buffer32[0], 13);
+ storew_rl_st(&buffer32[1], 14);
+ check64(buffer32[1], 14);
+}
+
+static inline void stored_rl_st(long long *p, long long val)
+{
+ asm volatile("memd_rl(%0):st = %1\n\t"
+ : : "r"(p), "r"(val) : "memory");
+}
+
+static void test_stored_rl_st(void)
+{
+ stored_rl_st(&buffer64[0], 15);
+ check64(buffer64[0], 15);
+ stored_rl_st(&buffer64[1], 15);
+ check64(buffer64[1], 15);
+}
+
+int main()
+{
+ test_loadw_aq();
+ test_loadd_aq();
+ test_release_at();
+ test_release_st();
+ test_storew_rl_at();
+ test_stored_rl_at();
+ test_storew_rl_st();
+ test_stored_rl_st();
+
+ puts(err ? "FAIL" : "PASS");
+ return err ? 1 : 0;
+}
diff --git a/tests/tcg/hexagon/v69_hvx.c b/tests/tcg/hexagon/v69_hvx.c
new file mode 100644
index 0000000000..a0d567d142
--- /dev/null
+++ b/tests/tcg/hexagon/v69_hvx.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright(c) 2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <limits.h>
+
+int err;
+
+#include "hvx_misc.h"
+
+#define fVROUND(VAL, SHAMT) \
+ ((VAL) + (((SHAMT) > 0) ? (1LL << ((SHAMT) - 1)) : 0))
+
+#define fVSATUB(VAL) \
+ ((((VAL) & 0xffLL) == (VAL)) ? \
+ (VAL) : \
+ ((((int32_t)(VAL)) < 0) ? 0 : 0xff))
+
+#define fVSATUH(VAL) \
+ ((((VAL) & 0xffffLL) == (VAL)) ? \
+ (VAL) : \
+ ((((int32_t)(VAL)) < 0) ? 0 : 0xffff))
+
+static void test_vasrvuhubrndsat(void)
+{
+ void *p0 = buffer0;
+ void *p1 = buffer1;
+ void *pout = output;
+
+ memset(expect, 0xaa, sizeof(expect));
+ memset(output, 0xbb, sizeof(output));
+
+ for (int i = 0; i < BUFSIZE / 2; i++) {
+ asm("v4 = vmem(%0 + #0)\n\t"
+ "v5 = vmem(%0 + #1)\n\t"
+ "v6 = vmem(%1 + #0)\n\t"
+ "v5.ub = vasr(v5:4.uh, v6.ub):rnd:sat\n\t"
+ "vmem(%2) = v5\n\t"
+ : : "r"(p0), "r"(p1), "r"(pout)
+ : "v4", "v5", "v6", "memory");
+ p0 += sizeof(MMVector) * 2;
+ p1 += sizeof(MMVector);
+ pout += sizeof(MMVector);
+
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 2; j++) {
+ int shamt;
+ uint8_t byte0;
+ uint8_t byte1;
+
+ shamt = buffer1[i].ub[2 * j + 0] & 0x7;
+ byte0 = fVSATUB(fVROUND(buffer0[2 * i + 0].uh[j], shamt) >> shamt);
+ shamt = buffer1[i].ub[2 * j + 1] & 0x7;
+ byte1 = fVSATUB(fVROUND(buffer0[2 * i + 1].uh[j], shamt) >> shamt);
+ expect[i].uh[j] = (byte1 << 8) | (byte0 & 0xff);
+ }
+ }
+
+ check_output_h(__LINE__, BUFSIZE / 2);
+}
+
+static void test_vasrvuhubsat(void)
+{
+ void *p0 = buffer0;
+ void *p1 = buffer1;
+ void *pout = output;
+
+ memset(expect, 0xaa, sizeof(expect));
+ memset(output, 0xbb, sizeof(output));
+
+ for (int i = 0; i < BUFSIZE / 2; i++) {
+ asm("v4 = vmem(%0 + #0)\n\t"
+ "v5 = vmem(%0 + #1)\n\t"
+ "v6 = vmem(%1 + #0)\n\t"
+ "v5.ub = vasr(v5:4.uh, v6.ub):sat\n\t"
+ "vmem(%2) = v5\n\t"
+ : : "r"(p0), "r"(p1), "r"(pout)
+ : "v4", "v5", "v6", "memory");
+ p0 += sizeof(MMVector) * 2;
+ p1 += sizeof(MMVector);
+ pout += sizeof(MMVector);
+
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 2; j++) {
+ int shamt;
+ uint8_t byte0;
+ uint8_t byte1;
+
+ shamt = buffer1[i].ub[2 * j + 0] & 0x7;
+ byte0 = fVSATUB(buffer0[2 * i + 0].uh[j] >> shamt);
+ shamt = buffer1[i].ub[2 * j + 1] & 0x7;
+ byte1 = fVSATUB(buffer0[2 * i + 1].uh[j] >> shamt);
+ expect[i].uh[j] = (byte1 << 8) | (byte0 & 0xff);
+ }
+ }
+
+ check_output_h(__LINE__, BUFSIZE / 2);
+}
+
+static void test_vasrvwuhrndsat(void)
+{
+ void *p0 = buffer0;
+ void *p1 = buffer1;
+ void *pout = output;
+
+ memset(expect, 0xaa, sizeof(expect));
+ memset(output, 0xbb, sizeof(output));
+
+ for (int i = 0; i < BUFSIZE / 2; i++) {
+ asm("v4 = vmem(%0 + #0)\n\t"
+ "v5 = vmem(%0 + #1)\n\t"
+ "v6 = vmem(%1 + #0)\n\t"
+ "v5.uh = vasr(v5:4.w, v6.uh):rnd:sat\n\t"
+ "vmem(%2) = v5\n\t"
+ : : "r"(p0), "r"(p1), "r"(pout)
+ : "v4", "v5", "v6", "memory");
+ p0 += sizeof(MMVector) * 2;
+ p1 += sizeof(MMVector);
+ pout += sizeof(MMVector);
+
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+ int shamt;
+ uint16_t half0;
+ uint16_t half1;
+
+ shamt = buffer1[i].uh[2 * j + 0] & 0xf;
+ half0 = fVSATUH(fVROUND(buffer0[2 * i + 0].w[j], shamt) >> shamt);
+ shamt = buffer1[i].uh[2 * j + 1] & 0xf;
+ half1 = fVSATUH(fVROUND(buffer0[2 * i + 1].w[j], shamt) >> shamt);
+ expect[i].w[j] = (half1 << 16) | (half0 & 0xffff);
+ }
+ }
+
+ check_output_w(__LINE__, BUFSIZE / 2);
+}
+
+static void test_vasrvwuhsat(void)
+{
+ void *p0 = buffer0;
+ void *p1 = buffer1;
+ void *pout = output;
+
+ memset(expect, 0xaa, sizeof(expect));
+ memset(output, 0xbb, sizeof(output));
+
+ for (int i = 0; i < BUFSIZE / 2; i++) {
+ asm("v4 = vmem(%0 + #0)\n\t"
+ "v5 = vmem(%0 + #1)\n\t"
+ "v6 = vmem(%1 + #0)\n\t"
+ "v5.uh = vasr(v5:4.w, v6.uh):sat\n\t"
+ "vmem(%2) = v5\n\t"
+ : : "r"(p0), "r"(p1), "r"(pout)
+ : "v4", "v5", "v6", "memory");
+ p0 += sizeof(MMVector) * 2;
+ p1 += sizeof(MMVector);
+ pout += sizeof(MMVector);
+
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+ int shamt;
+ uint16_t half0;
+ uint16_t half1;
+
+ shamt = buffer1[i].uh[2 * j + 0] & 0xf;
+ half0 = fVSATUH(buffer0[2 * i + 0].w[j] >> shamt);
+ shamt = buffer1[i].uh[2 * j + 1] & 0xf;
+ half1 = fVSATUH(buffer0[2 * i + 1].w[j] >> shamt);
+ expect[i].w[j] = (half1 << 16) | (half0 & 0xffff);
+ }
+ }
+
+ check_output_w(__LINE__, BUFSIZE / 2);
+}
+
+static void test_vassign_tmp(void)
+{
+ void *p0 = buffer0;
+ void *pout = output;
+
+ memset(expect, 0xaa, sizeof(expect));
+ memset(output, 0xbb, sizeof(output));
+
+ for (int i = 0; i < BUFSIZE; i++) {
+ /*
+ * Assign into v12 as .tmp, then use it in the next packet
+ * Should get the new value within the same packet and
+ * the old value in the next packet
+ */
+ asm("v3 = vmem(%0 + #0)\n\t"
+ "r1 = #1\n\t"
+ "v12 = vsplat(r1)\n\t"
+ "r1 = #2\n\t"
+ "v13 = vsplat(r1)\n\t"
+ "{\n\t"
+ " v12.tmp = v13\n\t"
+ " v4.w = vadd(v12.w, v3.w)\n\t"
+ "}\n\t"
+ "v4.w = vadd(v4.w, v12.w)\n\t"
+ "vmem(%1 + #0) = v4\n\t"
+ : : "r"(p0), "r"(pout)
+ : "r1", "v3", "v4", "v12", "v13", "memory");
+ p0 += sizeof(MMVector);
+ pout += sizeof(MMVector);
+
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+ expect[i].w[j] = buffer0[i].w[j] + 3;
+ }
+ }
+
+ check_output_w(__LINE__, BUFSIZE);
+}
+
+static void test_vcombine_tmp(void)
+{
+ void *p0 = buffer0;
+ void *p1 = buffer1;
+ void *pout = output;
+
+ memset(expect, 0xaa, sizeof(expect));
+ memset(output, 0xbb, sizeof(output));
+
+ for (int i = 0; i < BUFSIZE; i++) {
+ /*
+ * Combine into v13:12 as .tmp, then use it in the next packet
+ * Should get the new value within the same packet and
+ * the old value in the next packet
+ */
+ asm("v3 = vmem(%0 + #0)\n\t"
+ "r1 = #1\n\t"
+ "v12 = vsplat(r1)\n\t"
+ "r1 = #2\n\t"
+ "v13 = vsplat(r1)\n\t"
+ "r1 = #3\n\t"
+ "v14 = vsplat(r1)\n\t"
+ "r1 = #4\n\t"
+ "v15 = vsplat(r1)\n\t"
+ "{\n\t"
+ " v13:12.tmp = vcombine(v15, v14)\n\t"
+ " v4.w = vadd(v12.w, v3.w)\n\t"
+ " v16 = v13\n\t"
+ "}\n\t"
+ "v4.w = vadd(v4.w, v12.w)\n\t"
+ "v4.w = vadd(v4.w, v13.w)\n\t"
+ "v4.w = vadd(v4.w, v16.w)\n\t"
+ "vmem(%2 + #0) = v4\n\t"
+ : : "r"(p0), "r"(p1), "r"(pout)
+ : "r1", "v3", "v4", "v12", "v13", "v14", "v15", "v16", "memory");
+ p0 += sizeof(MMVector);
+ p1 += sizeof(MMVector);
+ pout += sizeof(MMVector);
+
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+ expect[i].w[j] = buffer0[i].w[j] + 10;
+ }
+ }
+
+ check_output_w(__LINE__, BUFSIZE);
+}
+
+static void test_vmpyuhvs(void)
+{
+ void *p0 = buffer0;
+ void *p1 = buffer1;
+ void *pout = output;
+
+ memset(expect, 0xaa, sizeof(expect));
+ memset(output, 0xbb, sizeof(output));
+
+ for (int i = 0; i < BUFSIZE; i++) {
+ asm("v4 = vmem(%0 + #0)\n\t"
+ "v5 = vmem(%1 + #0)\n\t"
+ "v4.uh = vmpy(V4.uh, v5.uh):>>16\n\t"
+ "vmem(%2) = v4\n\t"
+ : : "r"(p0), "r"(p1), "r"(pout)
+ : "v4", "v5", "memory");
+ p0 += sizeof(MMVector);
+ p1 += sizeof(MMVector);
+ pout += sizeof(MMVector);
+
+ for (int j = 0; j < MAX_VEC_SIZE_BYTES / 2; j++) {
+ expect[i].uh[j] = (buffer0[i].uh[j] * buffer1[i].uh[j]) >> 16;
+ }
+ }
+
+ check_output_h(__LINE__, BUFSIZE);
+}
+
+int main()
+{
+ init_buffers();
+
+ test_vasrvuhubrndsat();
+ test_vasrvuhubsat();
+ test_vasrvwuhrndsat();
+ test_vasrvwuhsat();
+
+ test_vassign_tmp();
+ test_vcombine_tmp();
+
+ test_vmpyuhvs();
+
+ puts(err ? "FAIL" : "PASS");
+ return err ? 1 : 0;
+}
diff --git a/tests/tcg/hexagon/v6mpy_ref.c.inc b/tests/tcg/hexagon/v6mpy_ref.c.inc
new file mode 100644
index 0000000000..8258cddcb1
--- /dev/null
+++ b/tests/tcg/hexagon/v6mpy_ref.c.inc
@@ -0,0 +1,161 @@
+/*
+ * Copyright(c) 2021-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+{ 0xffffee11, 0xfffffcca, 0xffffc1b3, 0xffffd0cc,
+ 0xffffe215, 0xfffff58e, 0xffffaf37, 0xffffc310,
+ 0xffffd919, 0xfffff152, 0xffff9fbb, 0xffffb854,
+ 0xffffd31d, 0xfffff016, 0xffff933f, 0xffffb098,
+ 0xffffd021, 0xfffff1da, 0xffff89c3, 0xffffabdc,
+ 0xffffd025, 0xfffff69e, 0xffff8347, 0xffffaa20,
+ 0xffffd329, 0xfffffe62, 0xffff7fcb, 0xffffab64,
+ 0xffffd92d, 0x00000926, 0xffff7f4f, 0xffffafa8,
+ },
+{ 0xffffe231, 0x000016ea, 0xffff81d3, 0xffffb6ec,
+ 0xffffee35, 0x000027ae, 0xffff8757, 0xffffc130,
+ 0xfffffd39, 0x00003b72, 0xffff8fdb, 0xffffce74,
+ 0x00000f3d, 0x00005236, 0xffff9b5f, 0xffffdeb8,
+ 0x00002441, 0x00006bfa, 0xffffa9e3, 0xfffff1fc,
+ 0x00003c45, 0x000088be, 0xffffbb67, 0x00000840,
+ 0x00005749, 0x0000a882, 0xffffcfeb, 0xffffe684,
+ 0x0000494d, 0x00009a46, 0xffffb16f, 0x000002c8,
+ },
+{ 0xfffff351, 0x0000440a, 0xffff4af3, 0xffff9c0c,
+ 0xffffef55, 0x000044ce, 0xffff4077, 0xffff9650,
+ 0xffffee59, 0x00004892, 0xffff38fb, 0xffff9394,
+ 0xfffff05d, 0x00004f56, 0xffff347f, 0xffff93d8,
+ 0xfffff561, 0x0000591a, 0xffff3303, 0xffff971c,
+ 0xfffffd65, 0x000065de, 0xffff3487, 0xffff9d60,
+ 0x00000869, 0x000075a2, 0xffff390b, 0xffffa6a4,
+ 0x0000166d, 0x00008866, 0xffff408f, 0xffffb2e8,
+ },
+{ 0x00002771, 0x00009e2a, 0xffff4b13, 0xffffc22c,
+ 0x00003b75, 0x0000b6ee, 0xffff5897, 0xffffd470,
+ 0x00005279, 0x0000d2b2, 0xffff691b, 0xffffe9b4,
+ 0x00006c7d, 0x0000f176, 0xffff7c9f, 0x000001f8,
+ 0x00008981, 0x0001133a, 0xffff9323, 0x00001d3c,
+ 0x0000a985, 0x000137fe, 0xffffaca7, 0x00003b80,
+ 0x0000cc89, 0x00015fc2, 0xffffc92b, 0xffffe1c4,
+ 0x0000868d, 0x00011986, 0xffff72af, 0x00000608,
+ },
+{ 0xfffff891, 0x00008b4a, 0xfffed433, 0xffff674c,
+ 0xfffffc95, 0x0000940e, 0xfffed1b7, 0xffff6990,
+ 0x00000399, 0x00009fd2, 0xfffed23b, 0xffff6ed4,
+ 0x00000d9d, 0x0000ae96, 0xfffed5bf, 0xffff7718,
+ 0x00001aa1, 0x0000c05a, 0xfffedc43, 0xffff825c,
+ 0x00002aa5, 0x0000d51e, 0xfffee5c7, 0xffff90a0,
+ 0x00003da9, 0x0000ece2, 0xfffef24b, 0xffffa1e4,
+ 0x000053ad, 0x000107a6, 0xffff01cf, 0xffffb628,
+ },
+{ 0x00006cb1, 0x0001256a, 0xffff1453, 0xffffcd6c,
+ 0x000088b5, 0x0001462e, 0xffff29d7, 0xffffe7b0,
+ 0x0000a7b9, 0x000169f2, 0xffff425b, 0x000004f4,
+ 0x0000c9bd, 0x000190b6, 0xffff5ddf, 0x00002538,
+ 0x0000eec1, 0x0001ba7a, 0xffff7c63, 0x0000487c,
+ 0x000116c5, 0x0001e73e, 0xffff9de7, 0x00006ec0,
+ 0x000141c9, 0x00021702, 0xffffc26b, 0xffffdd04,
+ 0x0000c3cd, 0x000198c6, 0xffff33ef, 0x00000948,
+ },
+{ 0xfffffdd1, 0x0000d28a, 0xfffe5d73, 0xffff328c,
+ 0x000009d5, 0x0000e34e, 0xfffe62f7, 0xffff3cd0,
+ 0x000018d9, 0x0000f712, 0xfffe6b7b, 0xffff4a14,
+ 0x00002add, 0x00010dd6, 0xfffe76ff, 0xffff5a58,
+ 0x00003fe1, 0x0001279a, 0xfffe8583, 0xffff6d9c,
+ 0x000057e5, 0x0001445e, 0xfffe9707, 0xffff83e0,
+ 0x000072e9, 0x00016422, 0xfffeab8b, 0xffff9d24,
+ 0x000090ed, 0x000186e6, 0xfffec30f, 0xffffb968,
+ },
+{ 0x0000b1f1, 0x0001acaa, 0xfffedd93, 0xffffd8ac,
+ 0x0000d5f5, 0x0001d56e, 0xfffefb17, 0xfffffaf0,
+ 0x0000fcf9, 0x00020132, 0xffff1b9b, 0x00002034,
+ 0x000126fd, 0x00022ff6, 0xffff3f1f, 0x00008b36,
+ 0x000093c3, 0x00009d80, 0x00009d6d, 0x0000a78a,
+ 0x0000b4d7, 0x0000c354, 0x0000b801, 0x0000c6de,
+ 0x0000d4eb, 0x0000e828, 0x0000d195, 0xffffea32,
+ 0x00000fff, 0x000022fc, 0xfffffc29, 0x00000f86,
+ },
+{ 0xffffee13, 0xfffffcd0, 0xffffc1bd, 0xffffd0da,
+ 0xffffe327, 0xfffff6a4, 0xffffb051, 0xffffc42e,
+ 0xffffd73b, 0xffffef78, 0xffff9de5, 0xffffb682,
+ 0xffffd24f, 0xffffef4c, 0xffff9279, 0xffffafd6,
+ 0xffffd063, 0xfffff220, 0xffff8a0d, 0xffffac2a,
+ 0xffffd177, 0xfffff7f4, 0xffff84a1, 0xffffab7e,
+ 0xffffd18b, 0xfffffcc8, 0xffff7e35, 0xffffa9d2,
+ 0xffffd89f, 0x0000089c, 0xffff7ec9, 0xffffaf26,
+ },
+{ 0xffffe2b3, 0x00001770, 0xffff825d, 0xffffb77a,
+ 0xffffefc7, 0x00002944, 0xffff88f1, 0xffffc2ce,
+ 0xfffffbdb, 0x00003a18, 0xffff8e85, 0xffffcd22,
+ 0x00000eef, 0x000051ec, 0xffff9b19, 0xffffde76,
+ 0x00002503, 0x00006cc0, 0xffffaaad, 0xfffff2ca,
+ 0x00003e17, 0x00008a94, 0xffffbd41, 0x00000a1e,
+ 0x0000562b, 0x0000a768, 0xffffced5, 0xffffe572,
+ 0x0000493f, 0x00009a3c, 0xffffb169, 0x000002c6,
+ },
+{ 0xfffff353, 0x00004410, 0xffff4afd, 0xffff9c1a,
+ 0xfffff067, 0x000045e4, 0xffff4191, 0xffff976e,
+ 0xffffec7b, 0x000046b8, 0xffff3725, 0xffff91c2,
+ 0xffffef8f, 0x00004e8c, 0xffff33b9, 0xffff9316,
+ 0xfffff5a3, 0x00005960, 0xffff334d, 0xffff976a,
+ 0xfffffeb7, 0x00006734, 0xffff35e1, 0xffff9ebe,
+ 0x000006cb, 0x00007408, 0xffff3775, 0xffffa512,
+ 0x000015df, 0x000087dc, 0xffff4009, 0xffffb266,
+ },
+{ 0x000027f3, 0x00009eb0, 0xffff4b9d, 0xffffc2ba,
+ 0x00003d07, 0x0000b884, 0xffff5a31, 0xffffd60e,
+ 0x0000511b, 0x0000d158, 0xffff67c5, 0xffffe862,
+ 0x00006c2f, 0x0000f12c, 0xffff7c59, 0x000001b6,
+ 0x00008a43, 0x00011400, 0xffff93ed, 0x00001e0a,
+ 0x0000ab57, 0x000139d4, 0xffffae81, 0x00003d5e,
+ 0x0000cb6b, 0x00015ea8, 0xffffc815, 0xffffe0b2,
+ 0x0000867f, 0x0001197c, 0xffff72a9, 0x00000606,
+ },
+{ 0xfffff893, 0x00008b50, 0xfffed43d, 0xffff675a,
+ 0xfffffda7, 0x00009524, 0xfffed2d1, 0xffff6aae,
+ 0x000001bb, 0x00009df8, 0xfffed065, 0xffff6d02,
+ 0x00000ccf, 0x0000adcc, 0xfffed4f9, 0xffff7656,
+ 0x00001ae3, 0x0000c0a0, 0xfffedc8d, 0xffff82aa,
+ 0x00002bf7, 0x0000d674, 0xfffee721, 0xffff91fe,
+ 0x00003c0b, 0x0000eb48, 0xfffef0b5, 0xffffa052,
+ 0x0000531f, 0x0001071c, 0xffff0149, 0xffffb5a6,
+ },
+{ 0x00006d33, 0x000125f0, 0xffff14dd, 0xffffcdfa,
+ 0x00008a47, 0x000147c4, 0xffff2b71, 0xffffe94e,
+ 0x0000a65b, 0x00016898, 0xffff4105, 0x000003a2,
+ 0x0000c96f, 0x0001906c, 0xffff5d99, 0x000024f6,
+ 0x0000ef83, 0x0001bb40, 0xffff7d2d, 0x0000494a,
+ 0x00011897, 0x0001e914, 0xffff9fc1, 0x0000709e,
+ 0x000140ab, 0x000215e8, 0xffffc155, 0xffffdbf2,
+ 0x0000c3bf, 0x000198bc, 0xffff33e9, 0x00000946,
+ },
+{ 0xfffffdd3, 0x0000d290, 0xfffe5d7d, 0xffff329a,
+ 0x00000ae7, 0x0000e464, 0xfffe6411, 0xffff3dee,
+ 0x000016fb, 0x0000f538, 0xfffe69a5, 0xffff4842,
+ 0x00002a0f, 0x00010d0c, 0xfffe7639, 0xffff5996,
+ 0x00004023, 0x000127e0, 0xfffe85cd, 0xffff6dea,
+ 0x00005937, 0x000145b4, 0xfffe9861, 0xffff853e,
+ 0x0000714b, 0x00016288, 0xfffea9f5, 0xffff9b92,
+ 0x0000905f, 0x0001865c, 0xfffec289, 0xffffb8e6,
+ },
+{ 0x0000b273, 0x0001ad30, 0xfffede1d, 0xffffd93a,
+ 0x0000d787, 0x0001d704, 0xfffefcb1, 0xfffffc8e,
+ 0x0000fb9b, 0x0001ffd8, 0xffff1a45, 0x00001ee2,
+ 0x000126af, 0x00022fac, 0xffff3ed9, 0x00008af4,
+ 0x00009485, 0x00009e46, 0x00009e37, 0x0000a858,
+ 0x0000b6a9, 0x0000c52a, 0x0000b9db, 0x0000c8bc,
+ 0x0000d3cd, 0x0000e70e, 0x0000d07f, 0xffffe920,
+ 0x00000ff1, 0x000022f2, 0xfffffc23, 0x00000f84,
+ },
diff --git a/tests/tcg/hexagon/v73_scalar.c b/tests/tcg/hexagon/v73_scalar.c
new file mode 100644
index 0000000000..fee67fc531
--- /dev/null
+++ b/tests/tcg/hexagon/v73_scalar.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright(c) 2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/*
+ * Test the scalar core instructions that are new in v73
+ */
+
+int err;
+
+static void __check32(int line, uint32_t result, uint32_t expect)
+{
+ if (result != expect) {
+ printf("ERROR at line %d: 0x%08x != 0x%08x\n",
+ line, result, expect);
+ err++;
+ }
+}
+
+#define check32(RES, EXP) __check32(__LINE__, RES, EXP)
+
+static void __check64(int line, uint64_t result, uint64_t expect)
+{
+ if (result != expect) {
+ printf("ERROR at line %d: 0x%016llx != 0x%016llx\n",
+ line, result, expect);
+ err++;
+ }
+}
+
+#define check64(RES, EXP) __check64(__LINE__, RES, EXP)
+
+static bool my_func_called;
+
+static void my_func(void)
+{
+ my_func_called = true;
+}
+
+static inline void callrh(void *func)
+{
+ asm volatile("callrh %0\n\t"
+ : : "r"(func)
+ /* Mark the caller-save registers as clobbered */
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+ "r10", "r11", "r12", "r13", "r14", "r15", "r28",
+ "p0", "p1", "p2", "p3");
+}
+
+static void test_callrh(void)
+{
+ my_func_called = false;
+ callrh(&my_func);
+ check32(my_func_called, true);
+}
+
+static void test_jumprh(void)
+{
+ uint32_t res;
+ asm ("%0 = #5\n\t"
+ "r0 = ##1f\n\t"
+ "jumprh r0\n\t"
+ "%0 = #3\n\t"
+ "jump 2f\n\t"
+ "1:\n\t"
+ "%0 = #1\n\t"
+ "2:\n\t"
+ : "=r"(res) : : "r0");
+ check32(res, 1);
+}
+
+int main()
+{
+ test_callrh();
+ test_jumprh();
+
+ puts(err ? "FAIL" : "PASS");
+ return err ? 1 : 0;
+}
diff --git a/tests/tcg/multiarch/system/Makefile.softmmu-target b/tests/tcg/multiarch/system/Makefile.softmmu-target
index 5f432c95f3..fe40195d39 100644
--- a/tests/tcg/multiarch/system/Makefile.softmmu-target
+++ b/tests/tcg/multiarch/system/Makefile.softmmu-target
@@ -27,6 +27,20 @@ run-gdbstub-memory: memory
"-monitor none -display none -chardev file$(COMMA)path=$<.out$(COMMA)id=output $(QEMU_OPTS)" \
--bin $< --test $(MULTIARCH_SRC)/gdbstub/memory.py, \
softmmu gdbstub support)
+
+run-gdbstub-untimely-packet: hello
+ $(call run-test, $@, $(GDB_SCRIPT) \
+ --gdb $(HAVE_GDB_BIN) \
+ --gdb-args "-ex 'set debug remote 1'" \
+ --output untimely-packet.gdb.out \
+ --stderr untimely-packet.gdb.err \
+ --qemu $(QEMU) \
+ --bin $< --qargs \
+ "-monitor none -display none -chardev file$(COMMA)path=untimely-packet.out$(COMMA)id=output $(QEMU_OPTS)", \
+ "softmmu gdbstub untimely packets")
+ $(call quiet-command, \
+ (! grep -Fq 'Packet instead of Ack, ignoring it' untimely-packet.gdb.err), \
+ "GREP", "file untimely-packet.gdb.err")
else
run-gdbstub-%:
$(call skip-test, "gdbstub test $*", "no guest arch support")
@@ -36,4 +50,4 @@ run-gdbstub-%:
$(call skip-test, "gdbstub test $*", "need working gdb")
endif
-MULTIARCH_RUNS += run-gdbstub-memory
+MULTIARCH_RUNS += run-gdbstub-memory run-gdbstub-untimely-packet