v73 already added J2_callrh and J2_jumprh but unintentionally
omitted `unpause`.  Its effect is to cause other threads' pause
instructions to cease pausing, but we treat `pause` as a nop or
a yield in RR, so unpause can safely be a nop.

While here, spell the other two v73 entries' version as HEX_VER_V73
instead of the literal 0x73, matching every other entry in the table.

Reviewed-by: Marco Liebel <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
 tests/tcg/hexagon/check_rev_gating.c  | 12 +++++++++---
 tests/tcg/hexagon/v73_scalar.c        |  7 +++++++
 target/hexagon/tag_rev_info.c.inc     |  5 +++--
 target/hexagon/imported/encode_pp.def |  1 +
 target/hexagon/imported/system.idef   |  3 +++
 5 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/tests/tcg/hexagon/check_rev_gating.c 
b/tests/tcg/hexagon/check_rev_gating.c
index 26b66f54552..d5295bf24ab 100644
--- a/tests/tcg/hexagon/check_rev_gating.c
+++ b/tests/tcg/hexagon/check_rev_gating.c
@@ -3,9 +3,12 @@
  * are rejected with SIGILL.
  *
  * Compiled with -mv66 so that e_flags selects CPU v66. The test embeds
- * a v68 instruction (L2_loadw_aq: "r0 = memw_aq(r0)") via .word
- * encoding. The revision-gated decoder must reject it, and linux-user
- * must deliver SIGILL.
+ * instructions from v68 through v73 via .word encoding: the assembler
+ * enforces the selected CPU's own minimum version, so none of these --
+ * including ones it otherwise knows how to assemble at their own
+ * target, such as callrh or unpause -- can be written as themselves in
+ * a file built for v66. The revision-gated decoder must reject every
+ * one of them, and linux-user must deliver SIGILL.
  *
  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  * SPDX-License-Identifier: GPL-2.0-or-later
@@ -102,6 +105,8 @@ TRY_FUNC(v73_callrh,
          ".word 0x50c5c000    /* callrh r5 */\n")
 TRY_FUNC(v73_jumprh,
          ".word 0x52c0c000    /* jumprh r0 */\n")
+TRY_FUNC(v73_unpause,
+         ".word 0x57e0d000    /* unpause */\n")
 
 int main(void)
 {
@@ -133,6 +138,7 @@ int main(void)
 
     assert(try_v73_callrh() == SIGILL);
     assert(try_v73_jumprh() == SIGILL);
+    assert(try_v73_unpause() == SIGILL);
 
     assert(signals_handled == expected_signals);
 
diff --git a/tests/tcg/hexagon/v73_scalar.c b/tests/tcg/hexagon/v73_scalar.c
index fee67fc5311..2b5f3aa2149 100644
--- a/tests/tcg/hexagon/v73_scalar.c
+++ b/tests/tcg/hexagon/v73_scalar.c
@@ -86,10 +86,17 @@ static void test_jumprh(void)
     check32(res, 1);
 }
 
+static void test_unpause(void)
+{
+    /* Nothing is paused, so this just needs to execute without faulting. */
+    asm volatile("unpause\n\t");
+}
+
 int main()
 {
     test_callrh();
     test_jumprh();
+    test_unpause();
 
     puts(err ? "FAIL" : "PASS");
     return err ? 1 : 0;
diff --git a/target/hexagon/tag_rev_info.c.inc 
b/target/hexagon/tag_rev_info.c.inc
index a91b91a23e6..44513f46809 100644
--- a/target/hexagon/tag_rev_info.c.inc
+++ b/target/hexagon/tag_rev_info.c.inc
@@ -571,8 +571,9 @@ static const struct tag_rev_info 
tag_rev_info[XX_LAST_OPCODE] = {
     [F2_dfmpyhh] = { .introduced = HEX_VER_V67, .removed = HEX_VER_NONE },
     [F2_dfmpylh] = { .introduced = HEX_VER_V67, .removed = HEX_VER_NONE },
     [F2_dfmpyll] = { .introduced = HEX_VER_V67, .removed = HEX_VER_NONE },
-    [J2_callrh] = { .introduced = 0x73, .removed = HEX_VER_NONE },
-    [J2_jumprh] = { .introduced = 0x73, .removed = HEX_VER_NONE },
+    [J2_callrh] = { .introduced = HEX_VER_V73, .removed = HEX_VER_NONE },
+    [J2_jumprh] = { .introduced = HEX_VER_V73, .removed = HEX_VER_NONE },
+    [J2_unpause] = { .introduced = HEX_VER_V73, .removed = HEX_VER_NONE },
     [L2_loadw_aq] = { .introduced = HEX_VER_V68, .removed = HEX_VER_NONE },
     [L4_loadd_aq] = { .introduced = HEX_VER_V68, .removed = HEX_VER_NONE },
     [Y6_dmcfgrd] = { .introduced = HEX_VER_V68, .removed = HEX_VER_NONE },
diff --git a/target/hexagon/imported/encode_pp.def 
b/target/hexagon/imported/encode_pp.def
index d9e8ea2aebd..1fce318b2bb 100644
--- a/target/hexagon/imported/encode_pp.def
+++ b/target/hexagon/imported/encode_pp.def
@@ -585,6 +585,7 @@ DEF_FIELDROW_DESC32(ICLASS_J" 0100 -------- PP------ 
--------","[#4] (#u8) ")
 DEF_ENC32(J2_trap0,     ICLASS_J" 0100  00------  PP-iiiii  ---iii--")
 DEF_ENC32(J2_trap1,     ICLASS_J" 0100  10-xxxxx  PP-iiiii  ---iii--")
 DEF_ENC32(J2_pause,     ICLASS_J" 0100  01----ii  PP-iiiii  ---iii--")
+DEF_ENC32(J2_unpause,"01010111111-----PP01----000-----")
 
 DEF_FIELDROW_DESC32(ICLASS_J" 0101 -------- PP------ --------","[#5] Rd=(Rs) ")
 DEF_ENC32(Y2_icdatar,   ICLASS_J" 0101  101sssss  PP------  ---ddddd")
diff --git a/target/hexagon/imported/system.idef 
b/target/hexagon/imported/system.idef
index 02aee8ce8ee..b44e87565c3 100644
--- a/target/hexagon/imported/system.idef
+++ b/target/hexagon/imported/system.idef
@@ -51,6 +51,9 @@ 
Q6INSN(J2_trap1,"trap1(Rx32,#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPAC
 
Q6INSN(J2_pause,"pause(#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET),
 "Enter low-power state for #u8 cycles",{fPAUSE(uiV);})
 
+Q6INSN(J2_unpause,"unpause",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET),
+"Resume paused threads",{fUNPAUSE();})
+
 Q6INSN(J2_rte,  "rte", ATTRIBS(A_PRIV,A_NOTE_PRIV,A_NO_TIMING_LOG),
 "Return from Exception",
 {
-- 
2.34.1

Reply via email to