From: Brian Cain Date: Wed, 11 Feb 2026 22:19:51 +0000 (-0800) Subject: target/hexagon: Return decode failure for invalid non-duplex encodings X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0129a14a4fb34b2a3e3ac816dd74bd6391027e6;p=thirdparty%2Fqemu.git target/hexagon: Return decode failure for invalid non-duplex encodings 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. Reviewed-by: Pierrick Bouvier Reviewed-by: Taylor Simpson Signed-off-by: Brian Cain --- diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c index 69ba1ec96c..33ad60c5b4 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 010a5eb741..639d7f2495 100644 --- a/tests/tcg/hexagon/invalid-encoding.c +++ b/tests/tcg/hexagon/invalid-encoding.c @@ -65,6 +65,30 @@ static int test_invalid_duplex(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; @@ -75,6 +99,7 @@ int main() assert(sigaction(SIGILL, &act, NULL) == 0); assert(test_invalid_duplex() == SIGILL); + assert(test_invalid_nonduplex() == SIGILL); puts("PASS"); return EXIT_SUCCESS;