2 * MIPS specific prctl functions for linux-user
4 * SPDX-License-Identifier: GPL-2.0-or-later
6 #ifndef MIPS_TARGET_PRCTL_H
7 #define MIPS_TARGET_PRCTL_H
9 static abi_long
do_prctl_get_fp_mode(CPUArchState
*env
)
13 if (env
->CP0_Status
& (1 << CP0St_FR
)) {
16 if (env
->CP0_Config5
& (1 << CP0C5_FRE
)) {
17 ret
|= PR_FP_MODE_FRE
;
21 #define do_prctl_get_fp_mode do_prctl_get_fp_mode
23 static abi_long
do_prctl_set_fp_mode(CPUArchState
*env
, abi_long arg2
)
25 bool old_fr
= env
->CP0_Status
& (1 << CP0St_FR
);
26 bool old_fre
= env
->CP0_Config5
& (1 << CP0C5_FRE
);
27 bool new_fr
= arg2
& PR_FP_MODE_FR
;
28 bool new_fre
= arg2
& PR_FP_MODE_FRE
;
29 const unsigned int known_bits
= PR_FP_MODE_FR
| PR_FP_MODE_FRE
;
31 /* If nothing to change, return right away, successfully. */
32 if (old_fr
== new_fr
&& old_fre
== new_fre
) {
35 /* Check the value is valid */
36 if (arg2
& ~known_bits
) {
37 return -TARGET_EOPNOTSUPP
;
39 /* Setting FRE without FR is not supported. */
40 if (new_fre
&& !new_fr
) {
41 return -TARGET_EOPNOTSUPP
;
43 if (new_fr
&& !(env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
44 /* FR1 is not supported */
45 return -TARGET_EOPNOTSUPP
;
47 if (!new_fr
&& (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))
48 && !(env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
50 return -TARGET_EOPNOTSUPP
;
52 if (new_fre
&& !(env
->active_fpu
.fcr0
& (1 << FCR0_FREP
))) {
53 /* Cannot set FRE=1 */
54 return -TARGET_EOPNOTSUPP
;
58 fpr_t
*fpr
= env
->active_fpu
.fpr
;
59 for (i
= 0; i
< 32 ; i
+= 2) {
60 if (!old_fr
&& new_fr
) {
61 fpr
[i
].w
[!FP_ENDIAN_IDX
] = fpr
[i
+ 1].w
[FP_ENDIAN_IDX
];
62 } else if (old_fr
&& !new_fr
) {
63 fpr
[i
+ 1].w
[FP_ENDIAN_IDX
] = fpr
[i
].w
[!FP_ENDIAN_IDX
];
68 env
->CP0_Status
|= (1 << CP0St_FR
);
69 env
->hflags
|= MIPS_HFLAG_F64
;
71 env
->CP0_Status
&= ~(1 << CP0St_FR
);
72 env
->hflags
&= ~MIPS_HFLAG_F64
;
75 env
->CP0_Config5
|= (1 << CP0C5_FRE
);
76 if (env
->active_fpu
.fcr0
& (1 << FCR0_FREP
)) {
77 env
->hflags
|= MIPS_HFLAG_FRE
;
80 env
->CP0_Config5
&= ~(1 << CP0C5_FRE
);
81 env
->hflags
&= ~MIPS_HFLAG_FRE
;
86 #define do_prctl_set_fp_mode do_prctl_set_fp_mode
88 #endif /* MIPS_TARGET_PRCTL_H */