Il 03/06/2014 11:54, Peter Maydell ha scritto: > In user emulation, things are more complicated for BE32, > because we're sort of emulating the word-invariant > bigendian using byte-invariant big-endian (this is > safe because there's no way for a userspace program > to get at anything that would let it tell the > difference). So we can't just say "set SCTLR.B > and handle as if SCTLR.B is set in the way system > emulation would", because the behaviour has to > be different. > > So in summary I'm not sure of the right approach > any more...
I think overall sctlr_b makes for more accurate and overall clearer code. Here are the functions I'm using to map between the various properties: +static inline bool bswap_code(bool sctlr_b) +{ +#ifdef CONFIG_USER_ONLY + /* Mixed-endian modes are BE8 (SCTLR.B = 0, TARGET_WORDS_BIGENDIAN = 1) + * and LE8 (SCTLR.B = 1, TARGET_WORDS_BIGENDIAN = 0). + */ + return +#ifdef TARGET_WORDS_BIGENDIAN + 1 ^ +#endif + sctlr_b; +#else + /* We do not implement BE32 mode for system-mode emulation, but + * anyway it would always do little-endian accesses with + * TARGET_WORDS_BIGENDIAN = 0. + */ + return 0; +#endif +} + +#ifdef CONFIG_USER_ONLY +static inline bool arm_cpu_bswap_data(CPUARMState *env) +{ + return +#ifdef TARGET_WORDS_BIGENDIAN + 1 ^ +#endif + !!(env->cp15.c1_sys & SCTLR_B) ^ + !!(env->uncached_cpsr & CPSR_E); +} +#endif + +static inline bool arm_tbflag_is_data_be(unsigned tbflags) +{ + return +#ifdef CONFIG_USER_ONLY + ARM_TBFLAG_SCTLR_B(tbflags) ^ +#endif + ARM_TBFLAG_CPSR_E(tbflags); +} + I think this is reasonably close to what you would have for SCTLR.B emulation, only the XORing of addresses is missing. bswap_code is used in much fewer places than the current env->bswap_code, basically only in the definitions of arm_ld*_code and get_user_code_*. Everywhere else the code is accessing SCTLR.B, which is "real" architectural state. The confusing manner of handling it in user-mode emulation is wrapped by the above three inline functions. Paolo