Bit 7 of L4_loadw_phys is valid through v81 but reserved starting
with v83. Decode it as a legacy don't-care bit, then reject it for v83
and later.

Reviewed-by: Pierrick Bouvier <[email protected]>
Reviewed-by: Marco Liebel <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/decode.h    |  2 ++
 target/hexagon/decode.c    | 19 +++++++++++++++++++
 target/hexagon/printinsn.c |  3 ++-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/target/hexagon/decode.h b/target/hexagon/decode.h
index d4b049961ed..1e1e339b08a 100644
--- a/target/hexagon/decode.h
+++ b/target/hexagon/decode.h
@@ -31,5 +31,7 @@ int decode_packet(DisasContext *ctx, int max_words, const 
uint32_t *words,
                   Packet *pkt, bool disas_only);
 
 bool opcode_supported(uint16_t opcode, const HexagonCPUDef *hex_def);
+bool encoding_supported(uint16_t opcode, uint32_t encoding,
+                        const HexagonCPUDef *hex_def);
 
 #endif
diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index a28bf9ce9fe..35d741ce864 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -692,6 +692,22 @@ bool opcode_supported(uint16_t opcode, const HexagonCPUDef 
*hex_def)
     return true;
 }
 
+/*
+ * Some encodings of an otherwise supported opcode are reserved on newer
+ * versions.  HEX_VER_ANY (used when only disassembling) accepts everything.
+ */
+bool encoding_supported(uint16_t opcode, uint32_t encoding,
+                        const HexagonCPUDef *hex_def)
+{
+    /* Bit 7 of L4_loadw_phys became reserved in v83. */
+    if (hex_def->hex_version != HEX_VER_ANY &&
+        hex_def->hex_version >= HEX_VER_V83 &&
+        opcode == L4_loadw_phys && (encoding & 0x80)) {
+        return false;
+    }
+    return true;
+}
+
 /*
  * decode_packet
  * Decodes packet with given words
@@ -722,6 +738,9 @@ int decode_packet(DisasContext *ctx, int max_words, const 
uint32_t *words,
             /* Invalid instruction encoding */
             return 0;
         }
+        if (!encoding_supported(insn->opcode, encoding32, ctx->hex_def)) {
+            return 0;
+        }
         /*
          * If we saw an extender, mark next word extended so immediate
          * decode works
diff --git a/target/hexagon/printinsn.c b/target/hexagon/printinsn.c
index 023ea12dba5..cdb9dcd7de9 100644
--- a/target/hexagon/printinsn.c
+++ b/target/hexagon/printinsn.c
@@ -171,7 +171,8 @@ void snprint_a_pkt_disas(GString *buf, Packet *pkt, 
uint32_t *words,
         }
 
         g_string_append(buf, "\t");
-        if (opcode_supported(pkt->insn[i].opcode, cfg->hex_def)) {
+        if (opcode_supported(pkt->insn[i].opcode, cfg->hex_def) &&
+            encoding_supported(pkt->insn[i].opcode, words[i], cfg->hex_def)) {
             snprintinsn(buf, &(pkt->insn[i]));
         } else {
             g_string_append(buf, "<invalid>");
-- 
2.34.1

Reply via email to