mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 17:35:33 +00:00
target-mips: Implement FCR31's R/W bitmask and related functionalities
This patch implements read and write access rules for Mips floating point control and status register (FCR31). The change can be divided into following parts: - Add fields that will keep FCR31's R/W bitmask in procesor definitions and processor float_status structure. - Add appropriate value for FCR31's R/W bitmask for each supported processor. - Add function for setting snan_bit_is_one, and integrate it in appropriate places. - Modify handling of CTC1 (case 31) instruction to use FCR31's R/W bitmask. - Modify handling user mode executables for Mips, in relation to the bit EF_MIPS_NAN2008 from ELF header, that is in turn related to reading and writing to FCR31. - Modify gdb behavior in relation to FCR31. Backports commit 599bc5e89c46f95f86ccad0d747d041c89a28806 from qemu
This commit is contained in:
parent
84b516d9db
commit
4a540f88de
|
@ -112,6 +112,7 @@ struct CPUMIPSFPUContext {
|
|||
#define FCR0_PRID 8
|
||||
#define FCR0_REV 0
|
||||
/* fcsr */
|
||||
uint32_t fcr31_rw_bitmask;
|
||||
uint32_t fcr31;
|
||||
#define FCR31_ABS2008 19
|
||||
#define FCR31_NAN2008 18
|
||||
|
@ -843,10 +844,17 @@ static inline void restore_flush_mode(CPUMIPSState *env)
|
|||
&env->active_fpu.fp_status);
|
||||
}
|
||||
|
||||
static inline void restore_snan_bit_mode(CPUMIPSState *env)
|
||||
{
|
||||
set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == 0,
|
||||
&env->active_fpu.fp_status);
|
||||
}
|
||||
|
||||
static inline void restore_fp_status(CPUMIPSState *env)
|
||||
{
|
||||
restore_rounding_mode(env);
|
||||
restore_flush_mode(env);
|
||||
restore_snan_bit_mode(env);
|
||||
}
|
||||
|
||||
static inline void restore_msa_fp_status(CPUMIPSState *env)
|
||||
|
|
|
@ -2560,21 +2560,13 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
|
|||
((arg1 & 0x4) << 22);
|
||||
break;
|
||||
case 31:
|
||||
if (env->insn_flags & ISA_MIPS32R6) {
|
||||
uint32_t mask = 0xfefc0000;
|
||||
env->active_fpu.fcr31 = (arg1 & ~mask) |
|
||||
(env->active_fpu.fcr31 & mask);
|
||||
} else if (!(arg1 & 0x007c0000)) {
|
||||
env->active_fpu.fcr31 = arg1;
|
||||
}
|
||||
env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
|
||||
(env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
/* set rounding mode */
|
||||
restore_rounding_mode(env);
|
||||
/* set flush-to-zero mode */
|
||||
restore_flush_mode(env);
|
||||
restore_fp_status(env);
|
||||
set_float_exception_flags(0, &env->active_fpu.fp_status);
|
||||
if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & GET_FP_CAUSE(env->active_fpu.fcr31))
|
||||
do_raise_exception(env, EXCP_FPE, GETPC());
|
||||
|
|
|
@ -20377,8 +20377,8 @@ void cpu_state_reset(CPUMIPSState *env)
|
|||
env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
|
||||
env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
|
||||
env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
|
||||
env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
|
||||
env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
|
||||
set_snan_bit_is_one(1, &env->active_fpu.fp_status);
|
||||
env->msair = env->cpu_model->MSAIR;
|
||||
env->insn_flags = env->cpu_model->insn_flags;
|
||||
|
||||
|
@ -20484,8 +20484,7 @@ void cpu_state_reset(CPUMIPSState *env)
|
|||
}
|
||||
|
||||
compute_hflags(env);
|
||||
restore_rounding_mode(env);
|
||||
restore_flush_mode(env);
|
||||
restore_fp_status(env);
|
||||
restore_pamask(env);
|
||||
cs->exception_index = EXCP_NONE;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ struct mips_def_t {
|
|||
int32_t CP0_TCStatus_rw_bitmask;
|
||||
int32_t CP0_SRSCtl;
|
||||
int32_t CP1_fcr0;
|
||||
int32_t CP1_fcr31_rw_bitmask;
|
||||
int32_t CP1_fcr31;
|
||||
int32_t MSAIR;
|
||||
int32_t SEGBITS;
|
||||
|
@ -130,6 +131,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -164,6 +166,7 @@ static const mips_def_t mips_defs[] =
|
|||
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -194,6 +197,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -224,6 +228,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -255,6 +260,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -286,6 +292,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -318,6 +325,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -351,6 +359,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
(1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
|
||||
(1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
32,
|
||||
|
@ -383,12 +392,13 @@ static const mips_def_t mips_defs[] =
|
|||
(0x3 << CP0TCSt_TKSU) | (1 << CP0TCSt_IXMT) |
|
||||
(0xff << CP0TCSt_TASID),
|
||||
(0xf << CP0SRSCtl_HSS),
|
||||
0,
|
||||
32,
|
||||
32,
|
||||
(1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
|
||||
(1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
32,
|
||||
32,
|
||||
0x3fffffff,
|
||||
(1U << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) |
|
||||
(0x3fe << CP0SRSC0_SRS2) | (0x3fe << CP0SRSC0_SRS1),
|
||||
|
@ -433,6 +443,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
(1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
|
||||
(1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
32,
|
||||
|
@ -463,6 +474,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -494,6 +506,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
32,
|
||||
|
@ -540,6 +553,7 @@ static const mips_def_t mips_defs[] =
|
|||
(1 << FCR0_FREP) | (1 << FCR0_UFRP) | (1 << FCR0_HAS2008) |
|
||||
(1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
|
||||
(1 << FCR0_D) | (1 << FCR0_S) | (0x03 << FCR0_PRID),
|
||||
0xFF83FFFF,
|
||||
(1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
|
||||
0,
|
||||
32,
|
||||
|
@ -582,6 +596,7 @@ static const mips_def_t mips_defs[] =
|
|||
(1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_HAS2008) | (1 << FCR0_L) |
|
||||
(1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
|
||||
(0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0x0103FFFF,
|
||||
(1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
|
||||
0,
|
||||
32,
|
||||
|
@ -619,6 +634,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
/* The R4000 has a full 64bit FPU but doesn't use the fcr0 bits. */
|
||||
(0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0x0183FFFF,
|
||||
0,
|
||||
0,
|
||||
40,
|
||||
|
@ -648,6 +664,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
/* The VR5432 has a full 64bit FPU but doesn't use the fcr0 bits. */
|
||||
(0x54 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
40,
|
||||
|
@ -679,6 +696,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
42,
|
||||
|
@ -713,6 +731,7 @@ static const mips_def_t mips_defs[] =
|
|||
/* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
|
||||
(1 << FCR0_D) | (1 << FCR0_S) |
|
||||
(0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
42,
|
||||
|
@ -749,6 +768,7 @@ static const mips_def_t mips_defs[] =
|
|||
(1 << FCR0_3D) | (1 << FCR0_PS) |
|
||||
(1 << FCR0_D) | (1 << FCR0_S) |
|
||||
(0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
40,
|
||||
|
@ -784,6 +804,7 @@ static const mips_def_t mips_defs[] =
|
|||
(1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
|
||||
(1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
|
||||
(1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
42,
|
||||
|
@ -827,6 +848,7 @@ static const mips_def_t mips_defs[] =
|
|||
(1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) |
|
||||
(1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
|
||||
(1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0x0103FFFF,
|
||||
(1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
|
||||
0,
|
||||
48,
|
||||
|
@ -863,6 +885,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
0, // CP1_fcr0
|
||||
0,
|
||||
0, // CP1_fcr31
|
||||
0,
|
||||
42,
|
||||
|
@ -900,6 +923,7 @@ static const mips_def_t mips_defs[] =
|
|||
(0x89 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
42,
|
||||
36,
|
||||
0,0, 0,0, 0,0, 0,0, 0,0, 0,0,
|
||||
|
@ -928,6 +952,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
(0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
40,
|
||||
|
@ -958,6 +983,7 @@ static const mips_def_t mips_defs[] =
|
|||
0,
|
||||
0,
|
||||
(0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
40,
|
||||
|
@ -994,6 +1020,7 @@ static const mips_def_t mips_defs[] =
|
|||
(1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
|
||||
(1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
|
||||
(1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
|
||||
0xFF83FFFF,
|
||||
0,
|
||||
0,
|
||||
42,
|
||||
|
|
Loading…
Reference in a new issue