Hexagon (target/hexagon) Add overrides for allocframe/deallocframe
These instructions have implicit writes to registers, so we don't want them to be helpers when idef-parser is off. Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230427230012.3800327-5-tsimpson@quicinc.com>
This commit is contained in:
parent
17fda3c2d4
commit
085b6700f0
@ -500,6 +500,38 @@
|
||||
#define fGEN_TCG_Y2_icinva(SHORTCODE) \
|
||||
do { RsV = RsV; } while (0)
|
||||
|
||||
/*
|
||||
* allocframe(#uiV)
|
||||
* RxV == r29
|
||||
*/
|
||||
#define fGEN_TCG_S2_allocframe(SHORTCODE) \
|
||||
gen_allocframe(ctx, RxV, uiV)
|
||||
|
||||
/* sub-instruction version (no RxV, so handle it manually) */
|
||||
#define fGEN_TCG_SS2_allocframe(SHORTCODE) \
|
||||
do { \
|
||||
TCGv r29 = tcg_temp_new(); \
|
||||
tcg_gen_mov_tl(r29, hex_gpr[HEX_REG_SP]); \
|
||||
gen_allocframe(ctx, r29, uiV); \
|
||||
gen_log_reg_write(ctx, HEX_REG_SP, r29); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Rdd32 = deallocframe(Rs32):raw
|
||||
* RddV == r31:30
|
||||
* RsV == r30
|
||||
*/
|
||||
#define fGEN_TCG_L2_deallocframe(SHORTCODE) \
|
||||
gen_deallocframe(ctx, RddV, RsV)
|
||||
|
||||
/* sub-instruction version (no RddV/RsV, so handle it manually) */
|
||||
#define fGEN_TCG_SL2_deallocframe(SHORTCODE) \
|
||||
do { \
|
||||
TCGv_i64 r31_30 = tcg_temp_new_i64(); \
|
||||
gen_deallocframe(ctx, r31_30, hex_gpr[HEX_REG_FP]); \
|
||||
gen_log_reg_write_pair(ctx, HEX_REG_FP, r31_30); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* dealloc_return
|
||||
* Assembler mapped to
|
||||
|
@ -709,6 +709,18 @@ static void gen_cond_callr(DisasContext *ctx,
|
||||
gen_set_label(skip);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_HEXAGON_IDEF_PARSER
|
||||
/* frame = ((LR << 32) | FP) ^ (FRAMEKEY << 32)) */
|
||||
static TCGv_i64 gen_frame_scramble(void)
|
||||
{
|
||||
TCGv_i64 frame = tcg_temp_new_i64();
|
||||
TCGv tmp = tcg_temp_new();
|
||||
tcg_gen_xor_tl(tmp, hex_gpr[HEX_REG_LR], hex_gpr[HEX_REG_FRAMEKEY]);
|
||||
tcg_gen_concat_i32_i64(frame, hex_gpr[HEX_REG_FP], tmp);
|
||||
return frame;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* frame ^= (int64_t)FRAMEKEY << 32 */
|
||||
static void gen_frame_unscramble(TCGv_i64 frame)
|
||||
{
|
||||
@ -725,6 +737,41 @@ static void gen_load_frame(DisasContext *ctx, TCGv_i64 frame, TCGv EA)
|
||||
tcg_gen_qemu_ld_i64(frame, EA, ctx->mem_idx, MO_TEUQ);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_HEXAGON_IDEF_PARSER
|
||||
/* Stack overflow check */
|
||||
static void gen_framecheck(TCGv EA, int framesize)
|
||||
{
|
||||
/* Not modelled in linux-user mode */
|
||||
/* Placeholder for system mode */
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
g_assert_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gen_allocframe(DisasContext *ctx, TCGv r29, int framesize)
|
||||
{
|
||||
TCGv r30 = tcg_temp_new();
|
||||
TCGv_i64 frame;
|
||||
tcg_gen_addi_tl(r30, r29, -8);
|
||||
frame = gen_frame_scramble();
|
||||
gen_store8(cpu_env, r30, frame, ctx->insn->slot);
|
||||
gen_log_reg_write(ctx, HEX_REG_FP, r30);
|
||||
gen_framecheck(r30, framesize);
|
||||
tcg_gen_subi_tl(r29, r30, framesize);
|
||||
}
|
||||
|
||||
static void gen_deallocframe(DisasContext *ctx, TCGv_i64 r31_30, TCGv r30)
|
||||
{
|
||||
TCGv r29 = tcg_temp_new();
|
||||
TCGv_i64 frame = tcg_temp_new_i64();
|
||||
gen_load_frame(ctx, frame, r30);
|
||||
gen_frame_unscramble(frame);
|
||||
tcg_gen_mov_i64(r31_30, frame);
|
||||
tcg_gen_addi_tl(r29, r30, 8);
|
||||
gen_log_reg_write(ctx, HEX_REG_SP, r29);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gen_return(DisasContext *ctx, TCGv_i64 dst, TCGv src)
|
||||
{
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user