Loading linux-user/mips/target_syscall.h +2 −0 Original line number Diff line number Diff line Loading @@ -247,5 +247,7 @@ static inline abi_ulong target_shmlba(CPUMIPSState *env) /* MIPS-specific prctl() options */ #define TARGET_PR_SET_FP_MODE 45 #define TARGET_PR_GET_FP_MODE 46 #define TARGET_PR_FP_MODE_FR (1 << 0) #define TARGET_PR_FP_MODE_FRE (1 << 1) #endif /* MIPS_TARGET_SYSCALL_H */ linux-user/mips64/target_syscall.h +2 −0 Original line number Diff line number Diff line Loading @@ -244,5 +244,7 @@ static inline abi_ulong target_shmlba(CPUMIPSState *env) /* MIPS-specific prctl() options */ #define TARGET_PR_SET_FP_MODE 45 #define TARGET_PR_GET_FP_MODE 46 #define TARGET_PR_FP_MODE_FR (1 << 0) #define TARGET_PR_FP_MODE_FRE (1 << 1) #endif /* MIPS64_TARGET_SYSCALL_H */ linux-user/syscall.c +58 −4 Original line number Diff line number Diff line Loading @@ -9529,11 +9529,65 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_MIPS case TARGET_PR_GET_FP_MODE: /* TODO: Implement TARGET_PR_SET_FP_MODE handling.*/ return -TARGET_EINVAL; { CPUMIPSState *env = ((CPUMIPSState *)cpu_env); ret = 0; if (env->CP0_Status & (1 << CP0St_FR)) { ret |= TARGET_PR_FP_MODE_FR; } if (env->CP0_Config5 & (1 << CP0C5_FRE)) { ret |= TARGET_PR_FP_MODE_FRE; } return ret; } case TARGET_PR_SET_FP_MODE: /* TODO: Implement TARGET_PR_GET_FP_MODE handling.*/ return -TARGET_EINVAL; { CPUMIPSState *env = ((CPUMIPSState *)cpu_env); bool old_fr = env->CP0_Status & (1 << CP0St_FR); bool new_fr = arg2 & TARGET_PR_FP_MODE_FR; bool new_fre = arg2 & TARGET_PR_FP_MODE_FRE; if (new_fr && !(env->active_fpu.fcr0 & (1 << FCR0_F64))) { /* FR1 is not supported */ return -TARGET_EOPNOTSUPP; } if (!new_fr && (env->active_fpu.fcr0 & (1 << FCR0_F64)) && !(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) { /* cannot set FR=0 */ return -TARGET_EOPNOTSUPP; } if (new_fre && !(env->active_fpu.fcr0 & (1 << FCR0_FREP))) { /* Cannot set FRE=1 */ return -TARGET_EOPNOTSUPP; } int i; fpr_t *fpr = env->active_fpu.fpr; for (i = 0; i < 32 ; i += 2) { if (!old_fr && new_fr) { fpr[i].w[!FP_ENDIAN_IDX] = fpr[i + 1].w[FP_ENDIAN_IDX]; } else if (old_fr && !new_fr) { fpr[i + 1].w[FP_ENDIAN_IDX] = fpr[i].w[!FP_ENDIAN_IDX]; } } if (new_fr) { env->CP0_Status |= (1 << CP0St_FR); env->hflags |= MIPS_HFLAG_F64; } else { env->CP0_Status &= ~(1 << CP0St_FR); } if (new_fre) { env->CP0_Config5 |= (1 << CP0C5_FRE); if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) { env->hflags |= MIPS_HFLAG_FRE; } } else { env->CP0_Config5 &= ~(1 << CP0C5_FRE); } return 0; } #endif /* MIPS */ #ifdef TARGET_AARCH64 case TARGET_PR_SVE_SET_VL: Loading Loading
linux-user/mips/target_syscall.h +2 −0 Original line number Diff line number Diff line Loading @@ -247,5 +247,7 @@ static inline abi_ulong target_shmlba(CPUMIPSState *env) /* MIPS-specific prctl() options */ #define TARGET_PR_SET_FP_MODE 45 #define TARGET_PR_GET_FP_MODE 46 #define TARGET_PR_FP_MODE_FR (1 << 0) #define TARGET_PR_FP_MODE_FRE (1 << 1) #endif /* MIPS_TARGET_SYSCALL_H */
linux-user/mips64/target_syscall.h +2 −0 Original line number Diff line number Diff line Loading @@ -244,5 +244,7 @@ static inline abi_ulong target_shmlba(CPUMIPSState *env) /* MIPS-specific prctl() options */ #define TARGET_PR_SET_FP_MODE 45 #define TARGET_PR_GET_FP_MODE 46 #define TARGET_PR_FP_MODE_FR (1 << 0) #define TARGET_PR_FP_MODE_FRE (1 << 1) #endif /* MIPS64_TARGET_SYSCALL_H */
linux-user/syscall.c +58 −4 Original line number Diff line number Diff line Loading @@ -9529,11 +9529,65 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_MIPS case TARGET_PR_GET_FP_MODE: /* TODO: Implement TARGET_PR_SET_FP_MODE handling.*/ return -TARGET_EINVAL; { CPUMIPSState *env = ((CPUMIPSState *)cpu_env); ret = 0; if (env->CP0_Status & (1 << CP0St_FR)) { ret |= TARGET_PR_FP_MODE_FR; } if (env->CP0_Config5 & (1 << CP0C5_FRE)) { ret |= TARGET_PR_FP_MODE_FRE; } return ret; } case TARGET_PR_SET_FP_MODE: /* TODO: Implement TARGET_PR_GET_FP_MODE handling.*/ return -TARGET_EINVAL; { CPUMIPSState *env = ((CPUMIPSState *)cpu_env); bool old_fr = env->CP0_Status & (1 << CP0St_FR); bool new_fr = arg2 & TARGET_PR_FP_MODE_FR; bool new_fre = arg2 & TARGET_PR_FP_MODE_FRE; if (new_fr && !(env->active_fpu.fcr0 & (1 << FCR0_F64))) { /* FR1 is not supported */ return -TARGET_EOPNOTSUPP; } if (!new_fr && (env->active_fpu.fcr0 & (1 << FCR0_F64)) && !(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) { /* cannot set FR=0 */ return -TARGET_EOPNOTSUPP; } if (new_fre && !(env->active_fpu.fcr0 & (1 << FCR0_FREP))) { /* Cannot set FRE=1 */ return -TARGET_EOPNOTSUPP; } int i; fpr_t *fpr = env->active_fpu.fpr; for (i = 0; i < 32 ; i += 2) { if (!old_fr && new_fr) { fpr[i].w[!FP_ENDIAN_IDX] = fpr[i + 1].w[FP_ENDIAN_IDX]; } else if (old_fr && !new_fr) { fpr[i + 1].w[FP_ENDIAN_IDX] = fpr[i].w[!FP_ENDIAN_IDX]; } } if (new_fr) { env->CP0_Status |= (1 << CP0St_FR); env->hflags |= MIPS_HFLAG_F64; } else { env->CP0_Status &= ~(1 << CP0St_FR); } if (new_fre) { env->CP0_Config5 |= (1 << CP0C5_FRE); if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) { env->hflags |= MIPS_HFLAG_FRE; } } else { env->CP0_Config5 &= ~(1 << CP0C5_FRE); } return 0; } #endif /* MIPS */ #ifdef TARGET_AARCH64 case TARGET_PR_SVE_SET_VL: Loading