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
