mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-11 10:55:34 +00:00
target-arm: introduce tbflag for endianness
Introduce a tbflags for endianness, set based upon the CPUs current endianness. This in turn propagates through to the disas endianness flag. Backports commit 91cca2cda9823b1e7a049cb308a05104b5076cba from qemu
This commit is contained in:
parent
50a3c7f2ee
commit
902170741a
|
@ -1961,6 +1961,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
|
||||||
*/
|
*/
|
||||||
#define ARM_TBFLAG_NS_SHIFT 19
|
#define ARM_TBFLAG_NS_SHIFT 19
|
||||||
#define ARM_TBFLAG_NS_MASK (1 << ARM_TBFLAG_NS_SHIFT)
|
#define ARM_TBFLAG_NS_MASK (1 << ARM_TBFLAG_NS_SHIFT)
|
||||||
|
#define ARM_TBFLAG_BE_DATA_SHIFT 20
|
||||||
|
#define ARM_TBFLAG_BE_DATA_MASK (1 << ARM_TBFLAG_BE_DATA_SHIFT)
|
||||||
|
|
||||||
/* Bit usage when in AArch64 state: currently we have no A64 specific bits */
|
/* Bit usage when in AArch64 state: currently we have no A64 specific bits */
|
||||||
|
|
||||||
|
@ -1991,6 +1993,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
|
||||||
(((F) & ARM_TBFLAG_XSCALE_CPAR_MASK) >> ARM_TBFLAG_XSCALE_CPAR_SHIFT)
|
(((F) & ARM_TBFLAG_XSCALE_CPAR_MASK) >> ARM_TBFLAG_XSCALE_CPAR_SHIFT)
|
||||||
#define ARM_TBFLAG_NS(F) \
|
#define ARM_TBFLAG_NS(F) \
|
||||||
(((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
|
(((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
|
||||||
|
#define ARM_TBFLAG_BE_DATA(F) \
|
||||||
|
(((F) & ARM_TBFLAG_BE_DATA_MASK) >> ARM_TBFLAG_BE_DATA_SHIFT)
|
||||||
|
|
||||||
static inline bool bswap_code(bool sctlr_b)
|
static inline bool bswap_code(bool sctlr_b)
|
||||||
{
|
{
|
||||||
|
@ -2091,6 +2095,40 @@ static inline bool arm_sctlr_b(CPUARMState *env)
|
||||||
(env->cp15.sctlr_el[1] & SCTLR_B) != 0;
|
(env->cp15.sctlr_el[1] & SCTLR_B) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if the processor is in big-endian mode. */
|
||||||
|
static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
|
||||||
|
{
|
||||||
|
int cur_el;
|
||||||
|
|
||||||
|
/* In 32bit endianness is determined by looking at CPSR's E bit */
|
||||||
|
if (!is_a64(env)) {
|
||||||
|
return
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
/* In system mode, BE32 is modelled in line with the
|
||||||
|
* architecture (as word-invariant big-endianness), where loads
|
||||||
|
* and stores are done little endian but from addresses which
|
||||||
|
* are adjusted by XORing with the appropriate constant. So the
|
||||||
|
* endianness to use for the raw data access is not affected by
|
||||||
|
* SCTLR.B.
|
||||||
|
* In user mode, however, we model BE32 as byte-invariant
|
||||||
|
* big-endianness (because user-only code cannot tell the
|
||||||
|
* difference), and so we need to use a data access endianness
|
||||||
|
* that depends on SCTLR.B.
|
||||||
|
*/
|
||||||
|
arm_sctlr_b(env) ||
|
||||||
|
#endif
|
||||||
|
((env->uncached_cpsr & CPSR_E) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_el = arm_current_el(env);
|
||||||
|
|
||||||
|
if (cur_el == 0) {
|
||||||
|
return (env->cp15.sctlr_el[1] & SCTLR_E0E) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (env->cp15.sctlr_el[cur_el] & SCTLR_EE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|
||||||
target_ulong *cs_base, int *flags)
|
target_ulong *cs_base, int *flags)
|
||||||
{
|
{
|
||||||
|
@ -2135,6 +2173,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (arm_cpu_data_is_big_endian(env)) {
|
||||||
|
*flags |= ARM_TBFLAG_BE_DATA_MASK;
|
||||||
|
}
|
||||||
*flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
|
*flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
|
||||||
|
|
||||||
*cs_base = 0;
|
*cs_base = 0;
|
||||||
|
@ -2167,40 +2208,6 @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
|
||||||
return &env->vfp.regs[2 * regno];
|
return &env->vfp.regs[2 * regno];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if the processor is in big-endian mode. */
|
|
||||||
static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
|
|
||||||
{
|
|
||||||
int cur_el;
|
|
||||||
|
|
||||||
/* In 32bit endianness is determined by looking at CPSR's E bit */
|
|
||||||
if (!is_a64(env)) {
|
|
||||||
return
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
|
||||||
/* In system mode, BE32 is modelled in line with the
|
|
||||||
* architecture (as word-invariant big-endianness), where loads
|
|
||||||
* and stores are done little endian but from addresses which
|
|
||||||
* are adjusted by XORing with the appropriate constant. So the
|
|
||||||
* endianness to use for the raw data access is not affected by
|
|
||||||
* SCTLR.B.
|
|
||||||
* In user mode, however, we model BE32 as byte-invariant
|
|
||||||
* big-endianness (because user-only code cannot tell the
|
|
||||||
* difference), and so we need to use a data access endianness
|
|
||||||
* that depends on SCTLR.B.
|
|
||||||
*/
|
|
||||||
arm_sctlr_b(env) ||
|
|
||||||
#endif
|
|
||||||
((env->uncached_cpsr & CPSR_E) ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_el = arm_current_el(env);
|
|
||||||
|
|
||||||
if (cur_el == 0) {
|
|
||||||
return (env->cp15.sctlr_el[1] & SCTLR_E0E) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (env->cp15.sctlr_el[cur_el] & SCTLR_EE) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -11261,7 +11261,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
|
||||||
!arm_el_is_aa64(env, 3);
|
!arm_el_is_aa64(env, 3);
|
||||||
dc->thumb = 0;
|
dc->thumb = 0;
|
||||||
dc->sctlr_b = 0;
|
dc->sctlr_b = 0;
|
||||||
dc->be_data = MO_TE;
|
dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
|
||||||
dc->condexec_mask = 0;
|
dc->condexec_mask = 0;
|
||||||
dc->condexec_cond = 0;
|
dc->condexec_cond = 0;
|
||||||
dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
|
dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
|
||||||
|
|
|
@ -11490,7 +11490,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
|
||||||
!arm_el_is_aa64(env, 3);
|
!arm_el_is_aa64(env, 3);
|
||||||
dc->thumb = ARM_TBFLAG_THUMB(tb->flags); // qq
|
dc->thumb = ARM_TBFLAG_THUMB(tb->flags); // qq
|
||||||
dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
|
dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
|
||||||
dc->be_data = MO_TE;
|
dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
|
||||||
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
|
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
|
||||||
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
|
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
|
||||||
dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
|
dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
|
||||||
|
|
Loading…
Reference in a new issue