diff options
author | Taylor Simpson <tsimpson@quicinc.com> | 2022-11-08 08:29:02 -0800 |
---|---|---|
committer | Taylor Simpson <tsimpson@quicinc.com> | 2022-12-16 10:10:28 -0800 |
commit | 61c6c06e5df7ea960f814f4527f354823181247e (patch) | |
tree | 441a7384ff8206cc7a59ff2b1dcea007812978b9 | |
parent | 613653e500c0d482784f09aaa71f1297565b6815 (diff) |
Hexagon (target/hexagon) Add overrides for direct call instructions
Add overrides for
J2_call
J2_callt
J2_callf
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
Message-Id: <20221108162906.3166-8-tsimpson@quicinc.com>
-rw-r--r-- | target/hexagon/gen_tcg.h | 8 | ||||
-rw-r--r-- | target/hexagon/genptr.c | 55 |
2 files changed, 63 insertions, 0 deletions
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index df279ab43b..1bdc787a02 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -612,6 +612,14 @@ tcg_temp_free(tmp); \ } while (0) +#define fGEN_TCG_J2_call(SHORTCODE) \ + gen_call(ctx, riV) + +#define fGEN_TCG_J2_callt(SHORTCODE) \ + gen_cond_call(ctx, PuV, TCG_COND_EQ, riV) +#define fGEN_TCG_J2_callf(SHORTCODE) \ + gen_cond_call(ctx, PuV, TCG_COND_NE, riV) + #define fGEN_TCG_J2_pause(SHORTCODE) \ do { \ uiV = uiV; \ diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index cd3d74525e..580c403879 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -456,6 +456,61 @@ static TCGv gen_8bitsof(TCGv result, TCGv value) return result; } +static void gen_write_new_pc_addr(DisasContext *ctx, TCGv addr, + TCGCond cond, TCGv pred) +{ + TCGLabel *pred_false = NULL; + if (cond != TCG_COND_ALWAYS) { + pred_false = gen_new_label(); + tcg_gen_brcondi_tl(cond, pred, 0, pred_false); + } + + if (ctx->pkt->pkt_has_multi_cof) { + /* If there are multiple branches in a packet, ignore the second one */ + tcg_gen_movcond_tl(TCG_COND_NE, hex_gpr[HEX_REG_PC], + hex_branch_taken, tcg_constant_tl(0), + hex_gpr[HEX_REG_PC], addr); + tcg_gen_movi_tl(hex_branch_taken, 1); + } else { + tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], addr); + } + + if (cond != TCG_COND_ALWAYS) { + gen_set_label(pred_false); + } +} + +static void gen_write_new_pc_pcrel(DisasContext *ctx, int pc_off, + TCGCond cond, TCGv pred) +{ + target_ulong dest = ctx->pkt->pc + pc_off; + gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), cond, pred); +} + +static void gen_call(DisasContext *ctx, int pc_off) +{ + TCGv next_PC = + tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes); + gen_log_reg_write(HEX_REG_LR, next_PC); + gen_write_new_pc_pcrel(ctx, pc_off, TCG_COND_ALWAYS, NULL); +} + +static void gen_cond_call(DisasContext *ctx, TCGv pred, + TCGCond cond, int pc_off) +{ + TCGv next_PC; + TCGv lsb = tcg_temp_local_new(); + TCGLabel *skip = gen_new_label(); + tcg_gen_andi_tl(lsb, pred, 1); + gen_write_new_pc_pcrel(ctx, pc_off, cond, lsb); + tcg_gen_brcondi_tl(cond, lsb, 0, skip); + tcg_temp_free(lsb); + next_PC = + tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes); + gen_log_reg_write(HEX_REG_LR, next_PC); + gen_set_label(skip); +} + /* Shift left with saturation */ static void gen_shl_sat(TCGv dst, TCGv src, TCGv shift_amt) { |