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 <brian.cain@oss.qualcomm.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
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