@@ -9529,11 +9529,65 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
9529
9529
#endif
9530
9530
#ifdef TARGET_MIPS
9531
9531
case TARGET_PR_GET_FP_MODE :
9532
- /* TODO: Implement TARGET_PR_SET_FP_MODE handling.*/
9533
- return - TARGET_EINVAL ;
9532
+ {
9533
+ CPUMIPSState * env = ((CPUMIPSState * )cpu_env );
9534
+ ret = 0 ;
9535
+ if (env -> CP0_Status & (1 << CP0St_FR )) {
9536
+ ret |= TARGET_PR_FP_MODE_FR ;
9537
+ }
9538
+ if (env -> CP0_Config5 & (1 << CP0C5_FRE )) {
9539
+ ret |= TARGET_PR_FP_MODE_FRE ;
9540
+ }
9541
+ return ret ;
9542
+ }
9534
9543
case TARGET_PR_SET_FP_MODE :
9535
- /* TODO: Implement TARGET_PR_GET_FP_MODE handling.*/
9536
- return - TARGET_EINVAL ;
9544
+ {
9545
+ CPUMIPSState * env = ((CPUMIPSState * )cpu_env );
9546
+ bool old_fr = env -> CP0_Status & (1 << CP0St_FR );
9547
+ bool new_fr = arg2 & TARGET_PR_FP_MODE_FR ;
9548
+ bool new_fre = arg2 & TARGET_PR_FP_MODE_FRE ;
9549
+
9550
+ if (new_fr && !(env -> active_fpu .fcr0 & (1 << FCR0_F64 ))) {
9551
+ /* FR1 is not supported */
9552
+ return - TARGET_EOPNOTSUPP ;
9553
+ }
9554
+ if (!new_fr && (env -> active_fpu .fcr0 & (1 << FCR0_F64 ))
9555
+ && !(env -> CP0_Status_rw_bitmask & (1 << CP0St_FR ))) {
9556
+ /* cannot set FR=0 */
9557
+ return - TARGET_EOPNOTSUPP ;
9558
+ }
9559
+ if (new_fre && !(env -> active_fpu .fcr0 & (1 << FCR0_FREP ))) {
9560
+ /* Cannot set FRE=1 */
9561
+ return - TARGET_EOPNOTSUPP ;
9562
+ }
9563
+
9564
+ int i ;
9565
+ fpr_t * fpr = env -> active_fpu .fpr ;
9566
+ for (i = 0 ; i < 32 ; i += 2 ) {
9567
+ if (!old_fr && new_fr ) {
9568
+ fpr [i ].w [!FP_ENDIAN_IDX ] = fpr [i + 1 ].w [FP_ENDIAN_IDX ];
9569
+ } else if (old_fr && !new_fr ) {
9570
+ fpr [i + 1 ].w [FP_ENDIAN_IDX ] = fpr [i ].w [!FP_ENDIAN_IDX ];
9571
+ }
9572
+ }
9573
+
9574
+ if (new_fr ) {
9575
+ env -> CP0_Status |= (1 << CP0St_FR );
9576
+ env -> hflags |= MIPS_HFLAG_F64 ;
9577
+ } else {
9578
+ env -> CP0_Status &= ~(1 << CP0St_FR );
9579
+ }
9580
+ if (new_fre ) {
9581
+ env -> CP0_Config5 |= (1 << CP0C5_FRE );
9582
+ if (env -> active_fpu .fcr0 & (1 << FCR0_FREP )) {
9583
+ env -> hflags |= MIPS_HFLAG_FRE ;
9584
+ }
9585
+ } else {
9586
+ env -> CP0_Config5 &= ~(1 << CP0C5_FRE );
9587
+ }
9588
+
9589
+ return 0 ;
9590
+ }
9537
9591
#endif /* MIPS */
9538
9592
#ifdef TARGET_AARCH64
9539
9593
case TARGET_PR_SVE_SET_VL :
0 commit comments