During decoding, check that the opcode is supported in the current Hexagon CPU definition
Co-authored-by: Matheus Tavares Bernardino <[email protected]> Co-authored-by: Brian Cain <[email protected]> Signed-off-by: Taylor Simpson <[email protected]> --- target/hexagon/decode.h | 2 ++ target/hexagon/decode.c | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/target/hexagon/decode.h b/target/hexagon/decode.h index 3f3012b978..d4b049961e 100644 --- a/target/hexagon/decode.h +++ b/target/hexagon/decode.h @@ -30,4 +30,6 @@ void decode_send_insn_to(Packet *packet, int start, int newloc); 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); + #endif diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c index dbc9c630e8..b8a1cd5b12 100644 --- a/target/hexagon/decode.c +++ b/target/hexagon/decode.c @@ -647,6 +647,22 @@ decode_set_slot_number(Packet *pkt) return has_valid_slot_assignment(pkt); } +bool opcode_supported(uint16_t opcode, const HexagonCPUDef *hex_def) +{ + HexagonVersion hex_version = hex_def->hex_version; +#include "tag_rev_info.c.inc" + + struct tag_rev_info info = tag_rev_info[opcode]; + if (hex_version == HEX_VER_ANY) { + return true; + } + if ((info.introduced != HEX_VER_NONE && hex_version < info.introduced) || + (info.removed != HEX_VER_NONE && hex_version >= info.removed)) { + return false; + } + return true; +} + /* * Check for GPR write conflicts in the packet. * A conflict exists when a register is written by more than one instruction @@ -746,6 +762,17 @@ int decode_packet(DisasContext *ctx, int max_words, const uint32_t *words, /* Ran out of words! */ return 0; } + + /* + * Check that all the opcodes are supported in this Hexagon definition + * If not, return decode error + */ + for (i = 0; i < num_insns; i++) { + if (!opcode_supported(pkt->insn[i].opcode, ctx->hex_def)) { + return 0; + } + } + pkt->encod_pkt_size_in_bytes = words_read * 4; pkt->pkt_has_hvx = false; for (i = 0; i < num_insns; i++) { -- 2.43.0
