mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-23 04:01:07 +00:00
target-arm: introduce disas flag for endianness
Introduce a disas flag for setting the CPU data endianness. This allows control of the endianness from the CPU state rather than hard-coding it to TARGET_WORDS_BIGENDIAN. Backports commit dacf0a2ff7d39ab12bd90f2f5496a3889facd54a from qemu
This commit is contained in:
parent
e5cfcc3221
commit
9ab3d105fd
|
@ -11251,6 +11251,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
|
|||
!arm_el_is_aa64(env, 3);
|
||||
dc->thumb = 0;
|
||||
dc->sctlr_b = 0;
|
||||
dc->be_data = MO_TE;
|
||||
dc->condexec_mask = 0;
|
||||
dc->condexec_cond = 0;
|
||||
dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
|
||||
|
|
|
@ -952,23 +952,27 @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
|
|||
#define DO_GEN_LD(SUFF, OPC) \
|
||||
static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
|
||||
{ \
|
||||
tcg_gen_qemu_ld_i32(s->uc, val, addr, index, (OPC)); \
|
||||
TCGMemOp opc = (OPC) | s->be_data; \
|
||||
tcg_gen_qemu_ld_i32(s->uc, val, addr, index, opc); \
|
||||
}
|
||||
|
||||
#define DO_GEN_ST(SUFF, OPC) \
|
||||
static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
|
||||
{ \
|
||||
tcg_gen_qemu_st_i32(s->uc, val, addr, index, (OPC)); \
|
||||
TCGMemOp opc = (OPC) | s->be_data; \
|
||||
tcg_gen_qemu_st_i32(s->uc, val, addr, index, opc); \
|
||||
}
|
||||
|
||||
static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
|
||||
{
|
||||
tcg_gen_qemu_ld_i64(s->uc, val, addr, index, MO_TEQ);
|
||||
TCGMemOp opc = MO_Q | s->be_data;
|
||||
tcg_gen_qemu_ld_i64(s->uc, val, addr, index, opc);
|
||||
}
|
||||
|
||||
static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
|
||||
{
|
||||
tcg_gen_qemu_st_i64(s->uc, val, addr, index, MO_TEQ);
|
||||
TCGMemOp opc = MO_Q | s->be_data;
|
||||
tcg_gen_qemu_st_i64(s->uc, val, addr, index, opc);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -977,9 +981,10 @@ static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, i
|
|||
static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
|
||||
{ \
|
||||
TCGContext *tcg_ctx = s->uc->tcg_ctx; \
|
||||
TCGMemOp opc = (OPC) | s->be_data; \
|
||||
TCGv addr64 = tcg_temp_new(tcg_ctx); \
|
||||
tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr); \
|
||||
tcg_gen_qemu_ld_i32(s->uc, val, addr64, index, OPC); \
|
||||
tcg_gen_qemu_ld_i32(s->uc, val, addr64, index, opc); \
|
||||
tcg_temp_free(tcg_ctx, addr64); \
|
||||
}
|
||||
|
||||
|
@ -987,27 +992,30 @@ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 add
|
|||
static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
|
||||
{ \
|
||||
TCGContext *tcg_ctx = s->uc->tcg_ctx; \
|
||||
TCGMemOp opc = (OPC) | s->be_data; \
|
||||
TCGv addr64 = tcg_temp_new(tcg_ctx); \
|
||||
tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr); \
|
||||
tcg_gen_qemu_st_i32(s->uc, val, addr64, index, OPC); \
|
||||
tcg_gen_qemu_st_i32(s->uc, val, addr64, index, opc); \
|
||||
tcg_temp_free(tcg_ctx, addr64); \
|
||||
}
|
||||
|
||||
static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
|
||||
{
|
||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||
TCGMemOp opc = MO_Q | s->be_data;
|
||||
TCGv addr64 = tcg_temp_new(tcg_ctx);
|
||||
tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr);
|
||||
tcg_gen_qemu_ld_i64(s->uc, val, addr64, index, MO_TEQ);
|
||||
tcg_gen_qemu_ld_i64(s->uc, val, addr64, index, opc);
|
||||
tcg_temp_free(tcg_ctx, addr64);
|
||||
}
|
||||
|
||||
static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
|
||||
{
|
||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||
TCGMemOp opc = MO_Q | s->be_data;
|
||||
TCGv addr64 = tcg_temp_new(tcg_ctx);
|
||||
tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr);
|
||||
tcg_gen_qemu_st_i64(s->uc, val, addr64, index, MO_TEQ);
|
||||
tcg_gen_qemu_st_i64(s->uc, val, addr64, index, opc);
|
||||
tcg_temp_free(tcg_ctx, addr64);
|
||||
}
|
||||
|
||||
|
@ -1015,15 +1023,15 @@ static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, i
|
|||
|
||||
DO_GEN_LD(8s, MO_SB)
|
||||
DO_GEN_LD(8u, MO_UB)
|
||||
DO_GEN_LD(16s, MO_TESW)
|
||||
DO_GEN_LD(16u, MO_TEUW)
|
||||
DO_GEN_LD(32u, MO_TEUL)
|
||||
DO_GEN_LD(16s, MO_SW)
|
||||
DO_GEN_LD(16u, MO_UW)
|
||||
DO_GEN_LD(32u, MO_UL)
|
||||
/* 'a' variants include an alignment check */
|
||||
DO_GEN_LD(16ua, MO_TEUW | MO_ALIGN)
|
||||
DO_GEN_LD(32ua, MO_TEUL | MO_ALIGN)
|
||||
DO_GEN_LD(16ua, MO_UW | MO_ALIGN)
|
||||
DO_GEN_LD(32ua, MO_UL | MO_ALIGN)
|
||||
DO_GEN_ST(8, MO_UB)
|
||||
DO_GEN_ST(16, MO_TEUW)
|
||||
DO_GEN_ST(32, MO_TEUL)
|
||||
DO_GEN_ST(16, MO_UW)
|
||||
DO_GEN_ST(32, MO_UL)
|
||||
|
||||
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
|
||||
{
|
||||
|
@ -11482,6 +11490,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
|
|||
!arm_el_is_aa64(env, 3);
|
||||
dc->thumb = ARM_TBFLAG_THUMB(tb->flags); // qq
|
||||
dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
|
||||
dc->be_data = MO_TE;
|
||||
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
|
||||
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
|
||||
dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
|
||||
|
|
|
@ -17,6 +17,7 @@ typedef struct DisasContext {
|
|||
int singlestep_enabled;
|
||||
int thumb;
|
||||
int sctlr_b;
|
||||
TCGMemOp be_data;
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
int user;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue