Executing an HMX instruction with SSR:XE2 clear raises a NO_COPROC2_ENABLE
exception.

Log packets one as LOG_UNIMP for now.

Reviewed-by: Marco Liebel <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/cpu.h                      |  1 +
 target/hexagon/insn.h                     |  1 +
 target/hexagon/translate.h                |  2 ++
 target/hexagon/cpu.c                      |  2 ++
 target/hexagon/decode.c                   |  3 +++
 target/hexagon/translate.c                | 21 +++++++++++++++++++++
 tests/functional/hexagon/test_systests.py |  3 +++
 7 files changed, 33 insertions(+)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 22aa1630767..1cdff583da4 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -247,6 +247,7 @@ FIELD(TB_FLAGS, MMU_INDEX, 1, 3)
 FIELD(TB_FLAGS, HVX_COPROC_ENABLED, 5, 1)
 FIELD(TB_FLAGS, CPU_MODE, 6, 2)
 FIELD(TB_FLAGS, SS_ACTIVE, 8, 1)
+FIELD(TB_FLAGS, HMX_COPROC_ENABLED, 15, 1)
 
 G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
                                             uint32_t exception,
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index 5d59430da9e..afae928e679 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -70,6 +70,7 @@ struct Packet {
     bool pkt_has_scalar_store_s1;
 
     bool pkt_has_hvx;
+    bool pkt_has_hmx;
     Insn *vhist_insn;
 
     Insn insn[INSTRUCTIONS_MAX];
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index bc5f202163f..88b948e8669 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -101,6 +101,8 @@ typedef struct DisasContext {
     TCGv dczero_addr;
     bool hvx_coproc_enabled;
     bool hvx_check_emitted;
+    bool hmx_coproc_enabled;
+    bool hmx_check_emitted;
 } DisasContext;
 
 bool is_gather_store_insn(DisasContext *ctx);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 83e23775ea2..1bfb948227b 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -393,6 +393,8 @@ static TCGTBCPUState hexagon_get_tb_cpu_state(CPUState *cs)
     hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, SS_ACTIVE,
                            GET_SSR_FIELD(SSR_SS, env->t_sreg[HEX_SREG_SSR]) &&
                            get_cpu_mode(env) != HEX_CPU_MODE_MONITOR);
+    hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, HMX_COPROC_ENABLED,
+                           GET_SSR_FIELD(SSR_XE2, env->t_sreg[HEX_SREG_SSR]));
 #else
     hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX, MMU_USER_IDX);
 #endif
diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 0ac87bbee0c..2916e4c68df 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -773,9 +773,12 @@ int decode_packet(DisasContext *ctx, int max_words, const 
uint32_t *words,
 
     pkt->encod_pkt_size_in_bytes = words_read * 4;
     pkt->pkt_has_hvx = false;
+    pkt->pkt_has_hmx = false;
     for (i = 0; i < num_insns; i++) {
         pkt->pkt_has_hvx |=
             GET_ATTRIB(pkt->insn[i].opcode, A_CVI);
+        pkt->pkt_has_hmx |=
+            GET_ATTRIB(pkt->insn[i].opcode, A_HMX);
     }
 
     /*
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 91925d2ddb1..4c84feaeeb5 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -860,6 +860,24 @@ static void gen_start_packet(DisasContext *ctx)
         ctx->hvx_check_emitted = true;
     }
 #endif
+
+    if (ctx->pkt.pkt_has_hmx) {
+        for (i = 0; i < ctx->pkt.num_insns; i++) {
+            if (GET_ATTRIB(ctx->pkt.insn[i].opcode, A_HMX)) {
+                qemu_log_mask(LOG_UNIMP, "'%s' is not implemented\n",
+                              opcode_names[ctx->pkt.insn[i].opcode]);
+            }
+        }
+    }
+
+#ifndef CONFIG_USER_ONLY
+    /* HMX needs SSR:XE2 */
+    if (ctx->pkt.pkt_has_hmx && !ctx->hmx_coproc_enabled &&
+        !ctx->hmx_check_emitted) {
+        gen_precise_exception(HEX_CAUSE_NO_COPROC2_ENABLE, ctx->pkt.pc);
+        ctx->hmx_check_emitted = true;
+    }
+#endif
 }
 
 bool is_gather_store_insn(DisasContext *ctx)
@@ -1434,6 +1452,9 @@ static void 
hexagon_tr_init_disas_context(DisasContextBase *dcbase,
         ctx->base.max_insns = 1;
         ctx->is_tight_loop = false;
     }
+    ctx->hmx_coproc_enabled =
+        FIELD_EX32(hex_flags, TB_FLAGS, HMX_COPROC_ENABLED);
+    ctx->hmx_check_emitted = false;
 #endif
 }
 
diff --git a/tests/functional/hexagon/test_systests.py 
b/tests/functional/hexagon/test_systests.py
index 1c1d5440bb6..d3f9b95d961 100755
--- a/tests/functional/hexagon/test_systests.py
+++ b/tests/functional/hexagon/test_systests.py
@@ -90,6 +90,9 @@ def test_access(self):
     def test_semihost(self):
         self.run_console_pattern("semihost", "PASS", "-append", "arg1", "arg2")
 
+    def test_invalid_hmx(self):
+        self.run_exit_zero("invalid_hmx")
+
     def test_dtg_interrupt(self):
         self.run_exit_zero("dtg_interrupt")
 
-- 
2.34.1

Reply via email to