target-mips: optimize gen_op_addr_add() (2/2)
Instead of dynamically generating different code depending on the UX flag, add a new flag in ctx->flags to generate different code. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5677 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
d144d1d9e5
commit
2623c1ecfc
@ -411,7 +411,7 @@ struct CPUMIPSState {
|
|||||||
int error_code;
|
int error_code;
|
||||||
uint32_t hflags; /* CPU State */
|
uint32_t hflags; /* CPU State */
|
||||||
/* TMASK defines different execution modes */
|
/* TMASK defines different execution modes */
|
||||||
#define MIPS_HFLAG_TMASK 0x01FF
|
#define MIPS_HFLAG_TMASK 0x03FF
|
||||||
#define MIPS_HFLAG_MODE 0x0007 /* execution modes */
|
#define MIPS_HFLAG_MODE 0x0007 /* execution modes */
|
||||||
/* The KSU flags must be the lowest bits in hflags. The flag order
|
/* The KSU flags must be the lowest bits in hflags. The flag order
|
||||||
must be the same as defined for CP0 Status. This allows to use
|
must be the same as defined for CP0 Status. This allows to use
|
||||||
@ -430,15 +430,16 @@ struct CPUMIPSState {
|
|||||||
and RSQRT.D. */
|
and RSQRT.D. */
|
||||||
#define MIPS_HFLAG_COP1X 0x0080 /* COP1X instructions enabled */
|
#define MIPS_HFLAG_COP1X 0x0080 /* COP1X instructions enabled */
|
||||||
#define MIPS_HFLAG_RE 0x0100 /* Reversed endianness */
|
#define MIPS_HFLAG_RE 0x0100 /* Reversed endianness */
|
||||||
|
#define MIPS_HFLAG_UX 0x0200 /* 64-bit user mode */
|
||||||
/* If translation is interrupted between the branch instruction and
|
/* If translation is interrupted between the branch instruction and
|
||||||
* the delay slot, record what type of branch it is so that we can
|
* the delay slot, record what type of branch it is so that we can
|
||||||
* resume translation properly. It might be possible to reduce
|
* resume translation properly. It might be possible to reduce
|
||||||
* this from three bits to two. */
|
* this from three bits to two. */
|
||||||
#define MIPS_HFLAG_BMASK 0x0e00
|
#define MIPS_HFLAG_BMASK 0x1C00
|
||||||
#define MIPS_HFLAG_B 0x0200 /* Unconditional branch */
|
#define MIPS_HFLAG_B 0x0400 /* Unconditional branch */
|
||||||
#define MIPS_HFLAG_BC 0x0400 /* Conditional branch */
|
#define MIPS_HFLAG_BC 0x0800 /* Conditional branch */
|
||||||
#define MIPS_HFLAG_BL 0x0600 /* Likely branch */
|
#define MIPS_HFLAG_BL 0x0C00 /* Likely branch */
|
||||||
#define MIPS_HFLAG_BR 0x0800 /* branch to register (can't link TB) */
|
#define MIPS_HFLAG_BR 0x1000 /* branch to register (can't link TB) */
|
||||||
target_ulong btarget; /* Jump / branch target */
|
target_ulong btarget; /* Jump / branch target */
|
||||||
int bcond; /* Branch condition (if needed) */
|
int bcond; /* Branch condition (if needed) */
|
||||||
|
|
||||||
|
@ -66,7 +66,8 @@ static inline int cpu_halted(CPUState *env)
|
|||||||
static inline void compute_hflags(CPUState *env)
|
static inline void compute_hflags(CPUState *env)
|
||||||
{
|
{
|
||||||
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
|
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
|
||||||
MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU);
|
MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
|
||||||
|
MIPS_HFLAG_UX);
|
||||||
if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
|
if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
|
||||||
!(env->CP0_Status & (1 << CP0St_ERL)) &&
|
!(env->CP0_Status & (1 << CP0St_ERL)) &&
|
||||||
!(env->hflags & MIPS_HFLAG_DM)) {
|
!(env->hflags & MIPS_HFLAG_DM)) {
|
||||||
@ -77,6 +78,8 @@ static inline void compute_hflags(CPUState *env)
|
|||||||
(env->CP0_Status & (1 << CP0St_PX)) ||
|
(env->CP0_Status & (1 << CP0St_PX)) ||
|
||||||
(env->CP0_Status & (1 << CP0St_UX)))
|
(env->CP0_Status & (1 << CP0St_UX)))
|
||||||
env->hflags |= MIPS_HFLAG_64;
|
env->hflags |= MIPS_HFLAG_64;
|
||||||
|
if (env->CP0_Status & (1 << CP0St_UX))
|
||||||
|
env->hflags |= MIPS_HFLAG_UX;
|
||||||
#endif
|
#endif
|
||||||
if ((env->CP0_Status & (1 << CP0St_CU0)) ||
|
if ((env->CP0_Status & (1 << CP0St_CU0)) ||
|
||||||
!(env->hflags & MIPS_HFLAG_KSU))
|
!(env->hflags & MIPS_HFLAG_KSU))
|
||||||
|
@ -902,16 +902,9 @@ static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
|
|||||||
/* For compatibility with 32-bit code, data reference in user mode
|
/* For compatibility with 32-bit code, data reference in user mode
|
||||||
with Status_UX = 0 should be casted to 32-bit and sign extended.
|
with Status_UX = 0 should be casted to 32-bit and sign extended.
|
||||||
See the MIPS64 PRA manual, section 4.10. */
|
See the MIPS64 PRA manual, section 4.10. */
|
||||||
if ((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) {
|
if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
|
||||||
int l1 = gen_new_label();
|
!(ctx->hflags & MIPS_HFLAG_UX)) {
|
||||||
TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
|
|
||||||
|
|
||||||
tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
|
|
||||||
tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
|
|
||||||
tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
|
|
||||||
tcg_gen_ext32s_i64(t0, t0);
|
tcg_gen_ext32s_i64(t0, t0);
|
||||||
gen_set_label(l1);
|
|
||||||
tcg_temp_free(r_tmp);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user