When a non-duplex encoding (parse_bits != 0) fails both decode_normal()
and decode_hvx(), the decoder hit an unreachable.  Instead, handle
the decode failure and raise an exception.

Signed-off-by: Brian Cain <[email protected]>
Reviewed-by: Pierrick Bouvier <[email protected]>
---
 target/hexagon/decode.c              |  3 ++-
 tests/tcg/hexagon/invalid-encoding.c | 25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 90499fc320..ebb4e02a17 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -489,7 +489,8 @@ decode_insns(DisasContext *ctx, Insn *insn, uint32_t 
encoding)
             insn->iclass = iclass_bits(encoding);
             return 1;
         }
-        g_assert_not_reached();
+        /* Invalid non-duplex encoding */
+        return 0;
     } else {
         uint32_t iclass = get_duplex_iclass(encoding);
         unsigned int slot0_subinsn = get_slot0_subinsn(encoding);
diff --git a/tests/tcg/hexagon/invalid-encoding.c 
b/tests/tcg/hexagon/invalid-encoding.c
index 1bbd312b61..040a7d9147 100644
--- a/tests/tcg/hexagon/invalid-encoding.c
+++ b/tests/tcg/hexagon/invalid-encoding.c
@@ -93,6 +93,30 @@ static int test_invalid_dups(void)
     return sig;
 }
 
+/*
+ * Invalid non-duplex encoding:
+ * The encoding 0xffffc000 has parse bits [15:14] = 0b11, making it a
+ * non-duplex instruction and packet end.  The remaining bits do not match
+ * any valid normal or HVX instruction encoding, so this should raise SIGILL.
+ */
+static int test_invalid_nonduplex(void)
+{
+    int sig;
+
+    asm volatile(
+        "r0 = #0\n"
+        "r1 = ##1f\n"
+        "memw(%1) = r1\n"
+        ".word 0xffffc000\n"
+        "1:\n"
+        "%0 = r0\n"
+        : "=r"(sig)
+        : "r"(&resume_pc)
+        : "r0", "r1", "memory");
+
+    return sig;
+}
+
 int main()
 {
     struct sigaction act;
@@ -104,6 +128,7 @@ int main()
 
     assert(test_invalid_duplex() == SIGILL);
     assert(test_invalid_dups() == SIGILL);
+    assert(test_invalid_nonduplex() == SIGILL);
 
     puts("PASS");
     return EXIT_SUCCESS;
-- 
2.34.1

Reply via email to