mirror of https://github.com/xemu-project/xemu.git
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) \
|
#define fGEN_TCG_Y2_icinva(SHORTCODE) \
|
||||||
do { RsV = RsV; } while (0)
|
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
|
* dealloc_return
|
||||||
* Assembler mapped to
|
* Assembler mapped to
|
||||||
|
|
|
@ -709,6 +709,18 @@ static void gen_cond_callr(DisasContext *ctx,
|
||||||
gen_set_label(skip);
|
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 */
|
/* frame ^= (int64_t)FRAMEKEY << 32 */
|
||||||
static void gen_frame_unscramble(TCGv_i64 frame)
|
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);
|
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)
|
static void gen_return(DisasContext *ctx, TCGv_i64 dst, TCGv src)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue