xref: /qemu/target/tricore/fpu_helper.c (revision 1fa79fb02d85c8f2ba9f6f9cabaf1b3ab34b7bcd)
1996a729fSBastian Koppelmann /*
2996a729fSBastian Koppelmann  *  TriCore emulation for qemu: fpu helper.
3996a729fSBastian Koppelmann  *
4996a729fSBastian Koppelmann  *  Copyright (c) 2016 Bastian Koppelmann University of Paderborn
5996a729fSBastian Koppelmann  *
6996a729fSBastian Koppelmann  * This library is free software; you can redistribute it and/or
7996a729fSBastian Koppelmann  * modify it under the terms of the GNU Lesser General Public
8996a729fSBastian Koppelmann  * License as published by the Free Software Foundation; either
902754acdSThomas Huth  * version 2.1 of the License, or (at your option) any later version.
10996a729fSBastian Koppelmann  *
11996a729fSBastian Koppelmann  * This library is distributed in the hope that it will be useful,
12996a729fSBastian Koppelmann  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13996a729fSBastian Koppelmann  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14996a729fSBastian Koppelmann  * Lesser General Public License for more details.
15996a729fSBastian Koppelmann  *
16996a729fSBastian Koppelmann  * You should have received a copy of the GNU Lesser General Public
17996a729fSBastian Koppelmann  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18996a729fSBastian Koppelmann  */
19996a729fSBastian Koppelmann 
20996a729fSBastian Koppelmann #include "qemu/osdep.h"
21996a729fSBastian Koppelmann #include "cpu.h"
22996a729fSBastian Koppelmann #include "exec/helper-proto.h"
2324f91e81SAlex Bennée #include "fpu/softfloat.h"
24996a729fSBastian Koppelmann 
25ddd7feadSBastian Koppelmann #define QUIET_NAN 0x7fc00000
26ddd7feadSBastian Koppelmann #define ADD_NAN   0x7fc00001
27996a729fSBastian Koppelmann #define DIV_NAN   0x7fc00008
28996a729fSBastian Koppelmann #define MUL_NAN   0x7fc00002
29996a729fSBastian Koppelmann #define FPU_FS PSW_USB_C
30996a729fSBastian Koppelmann #define FPU_FI PSW_USB_V
31996a729fSBastian Koppelmann #define FPU_FV PSW_USB_SV
32996a729fSBastian Koppelmann #define FPU_FZ PSW_USB_AV
33996a729fSBastian Koppelmann #define FPU_FU PSW_USB_SAV
34996a729fSBastian Koppelmann 
35996a729fSBastian Koppelmann /* we don't care about input_denormal */
36996a729fSBastian Koppelmann static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
37996a729fSBastian Koppelmann {
38996a729fSBastian Koppelmann     return get_float_exception_flags(&env->fp_status)
39996a729fSBastian Koppelmann            & (float_flag_invalid
40996a729fSBastian Koppelmann               | float_flag_overflow
41996a729fSBastian Koppelmann               | float_flag_underflow
42996a729fSBastian Koppelmann               | float_flag_output_denormal
43996a729fSBastian Koppelmann               | float_flag_divbyzero
44996a729fSBastian Koppelmann               | float_flag_inexact);
45996a729fSBastian Koppelmann }
46996a729fSBastian Koppelmann 
47ddd7feadSBastian Koppelmann static inline float32 f_maddsub_nan_result(float32 arg1, float32 arg2,
48ddd7feadSBastian Koppelmann                                            float32 arg3, float32 result,
49ddd7feadSBastian Koppelmann                                            uint32_t muladd_negate_c)
50ddd7feadSBastian Koppelmann {
51ddd7feadSBastian Koppelmann     uint32_t aSign, bSign, cSign;
52ddd7feadSBastian Koppelmann     uint32_t aExp, bExp, cExp;
53ddd7feadSBastian Koppelmann 
54ddd7feadSBastian Koppelmann     if (float32_is_any_nan(arg1) || float32_is_any_nan(arg2) ||
55ddd7feadSBastian Koppelmann         float32_is_any_nan(arg3)) {
56ddd7feadSBastian Koppelmann         return QUIET_NAN;
57ddd7feadSBastian Koppelmann     } else if (float32_is_infinity(arg1) && float32_is_zero(arg2)) {
58ddd7feadSBastian Koppelmann         return MUL_NAN;
59ddd7feadSBastian Koppelmann     } else if (float32_is_zero(arg1) && float32_is_infinity(arg2)) {
60ddd7feadSBastian Koppelmann         return MUL_NAN;
61ddd7feadSBastian Koppelmann     } else {
62ddd7feadSBastian Koppelmann         aSign = arg1 >> 31;
63ddd7feadSBastian Koppelmann         bSign = arg2 >> 31;
64ddd7feadSBastian Koppelmann         cSign = arg3 >> 31;
65ddd7feadSBastian Koppelmann 
66ddd7feadSBastian Koppelmann         aExp = (arg1 >> 23) & 0xff;
67ddd7feadSBastian Koppelmann         bExp = (arg2 >> 23) & 0xff;
68ddd7feadSBastian Koppelmann         cExp = (arg3 >> 23) & 0xff;
69ddd7feadSBastian Koppelmann 
70ddd7feadSBastian Koppelmann         if (muladd_negate_c) {
71ddd7feadSBastian Koppelmann             cSign ^= 1;
72ddd7feadSBastian Koppelmann         }
73ddd7feadSBastian Koppelmann         if (((aExp == 0xff) || (bExp == 0xff)) && (cExp == 0xff)) {
74ddd7feadSBastian Koppelmann             if (aSign ^ bSign ^ cSign) {
75ddd7feadSBastian Koppelmann                 return ADD_NAN;
76ddd7feadSBastian Koppelmann             }
77ddd7feadSBastian Koppelmann         }
78ddd7feadSBastian Koppelmann     }
79ddd7feadSBastian Koppelmann 
80ddd7feadSBastian Koppelmann     return result;
81ddd7feadSBastian Koppelmann }
82ddd7feadSBastian Koppelmann 
83baf410dcSBastian Koppelmann static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
84996a729fSBastian Koppelmann {
85996a729fSBastian Koppelmann     uint8_t some_excp = 0;
86996a729fSBastian Koppelmann     set_float_exception_flags(0, &env->fp_status);
87996a729fSBastian Koppelmann 
88996a729fSBastian Koppelmann     if (flags & float_flag_invalid) {
89996a729fSBastian Koppelmann         env->FPU_FI = 1 << 31;
90996a729fSBastian Koppelmann         some_excp = 1;
91996a729fSBastian Koppelmann     }
92996a729fSBastian Koppelmann 
93996a729fSBastian Koppelmann     if (flags & float_flag_overflow) {
94996a729fSBastian Koppelmann         env->FPU_FV = 1 << 31;
95996a729fSBastian Koppelmann         some_excp = 1;
96996a729fSBastian Koppelmann     }
97996a729fSBastian Koppelmann 
98996a729fSBastian Koppelmann     if (flags & float_flag_underflow || flags & float_flag_output_denormal) {
99996a729fSBastian Koppelmann         env->FPU_FU = 1 << 31;
100996a729fSBastian Koppelmann         some_excp = 1;
101996a729fSBastian Koppelmann     }
102996a729fSBastian Koppelmann 
103996a729fSBastian Koppelmann     if (flags & float_flag_divbyzero) {
104996a729fSBastian Koppelmann         env->FPU_FZ = 1 << 31;
105996a729fSBastian Koppelmann         some_excp = 1;
106996a729fSBastian Koppelmann     }
107996a729fSBastian Koppelmann 
108996a729fSBastian Koppelmann     if (flags & float_flag_inexact || flags & float_flag_output_denormal) {
109996a729fSBastian Koppelmann         env->PSW |= 1 << 26;
110996a729fSBastian Koppelmann         some_excp = 1;
111996a729fSBastian Koppelmann     }
112996a729fSBastian Koppelmann 
113996a729fSBastian Koppelmann     env->FPU_FS = some_excp;
114996a729fSBastian Koppelmann }
115baf410dcSBastian Koppelmann 
116baf410dcSBastian Koppelmann #define FADD_SUB(op)                                                           \
117baf410dcSBastian Koppelmann uint32_t helper_f##op(CPUTriCoreState *env, uint32_t r1, uint32_t r2)          \
118baf410dcSBastian Koppelmann {                                                                              \
119baf410dcSBastian Koppelmann     float32 arg1 = make_float32(r1);                                           \
120baf410dcSBastian Koppelmann     float32 arg2 = make_float32(r2);                                           \
121baf410dcSBastian Koppelmann     uint32_t flags;                                                            \
122baf410dcSBastian Koppelmann     float32 f_result;                                                          \
123baf410dcSBastian Koppelmann                                                                                \
124baf410dcSBastian Koppelmann     f_result = float32_##op(arg2, arg1, &env->fp_status);                      \
125baf410dcSBastian Koppelmann     flags = f_get_excp_flags(env);                                             \
126baf410dcSBastian Koppelmann     if (flags) {                                                               \
127baf410dcSBastian Koppelmann         /* If the output is a NaN, but the inputs aren't,                      \
128baf410dcSBastian Koppelmann            we return a unique value.  */                                       \
129baf410dcSBastian Koppelmann         if ((flags & float_flag_invalid)                                       \
130baf410dcSBastian Koppelmann             && !float32_is_any_nan(arg1)                                       \
131baf410dcSBastian Koppelmann             && !float32_is_any_nan(arg2)) {                                    \
132baf410dcSBastian Koppelmann             f_result = ADD_NAN;                                                \
133baf410dcSBastian Koppelmann         }                                                                      \
134baf410dcSBastian Koppelmann         f_update_psw_flags(env, flags);                                        \
135baf410dcSBastian Koppelmann     } else {                                                                   \
136baf410dcSBastian Koppelmann         env->FPU_FS = 0;                                                       \
137baf410dcSBastian Koppelmann     }                                                                          \
138baf410dcSBastian Koppelmann     return (uint32_t)f_result;                                                 \
139baf410dcSBastian Koppelmann }
140baf410dcSBastian Koppelmann FADD_SUB(add)
141baf410dcSBastian Koppelmann FADD_SUB(sub)
142daab3f7fSBastian Koppelmann 
143daab3f7fSBastian Koppelmann uint32_t helper_fmul(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
144daab3f7fSBastian Koppelmann {
145daab3f7fSBastian Koppelmann     uint32_t flags;
146daab3f7fSBastian Koppelmann     float32 arg1 = make_float32(r1);
147daab3f7fSBastian Koppelmann     float32 arg2 = make_float32(r2);
148daab3f7fSBastian Koppelmann     float32 f_result;
149daab3f7fSBastian Koppelmann 
150daab3f7fSBastian Koppelmann     f_result = float32_mul(arg1, arg2, &env->fp_status);
151daab3f7fSBastian Koppelmann 
152daab3f7fSBastian Koppelmann     flags = f_get_excp_flags(env);
153daab3f7fSBastian Koppelmann     if (flags) {
154daab3f7fSBastian Koppelmann         /* If the output is a NaN, but the inputs aren't,
155daab3f7fSBastian Koppelmann            we return a unique value.  */
156daab3f7fSBastian Koppelmann         if ((flags & float_flag_invalid)
157daab3f7fSBastian Koppelmann             && !float32_is_any_nan(arg1)
158daab3f7fSBastian Koppelmann             && !float32_is_any_nan(arg2)) {
159daab3f7fSBastian Koppelmann                 f_result = MUL_NAN;
160daab3f7fSBastian Koppelmann         }
161daab3f7fSBastian Koppelmann         f_update_psw_flags(env, flags);
162daab3f7fSBastian Koppelmann     } else {
163daab3f7fSBastian Koppelmann         env->FPU_FS = 0;
164daab3f7fSBastian Koppelmann     }
165daab3f7fSBastian Koppelmann     return (uint32_t)f_result;
166daab3f7fSBastian Koppelmann 
167daab3f7fSBastian Koppelmann }
168446ee5b2SBastian Koppelmann 
169446ee5b2SBastian Koppelmann uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
170446ee5b2SBastian Koppelmann {
171446ee5b2SBastian Koppelmann     uint32_t flags;
172446ee5b2SBastian Koppelmann     float32 arg1 = make_float32(r1);
173446ee5b2SBastian Koppelmann     float32 arg2 = make_float32(r2);
174446ee5b2SBastian Koppelmann     float32 f_result;
175446ee5b2SBastian Koppelmann 
176446ee5b2SBastian Koppelmann     f_result = float32_div(arg1, arg2 , &env->fp_status);
177446ee5b2SBastian Koppelmann 
178446ee5b2SBastian Koppelmann     flags = f_get_excp_flags(env);
179446ee5b2SBastian Koppelmann     if (flags) {
180446ee5b2SBastian Koppelmann         /* If the output is a NaN, but the inputs aren't,
181446ee5b2SBastian Koppelmann            we return a unique value.  */
182446ee5b2SBastian Koppelmann         if ((flags & float_flag_invalid)
183446ee5b2SBastian Koppelmann             && !float32_is_any_nan(arg1)
184446ee5b2SBastian Koppelmann             && !float32_is_any_nan(arg2)) {
185446ee5b2SBastian Koppelmann                 f_result = DIV_NAN;
186446ee5b2SBastian Koppelmann         }
187446ee5b2SBastian Koppelmann         f_update_psw_flags(env, flags);
188446ee5b2SBastian Koppelmann     } else {
189446ee5b2SBastian Koppelmann         env->FPU_FS = 0;
190446ee5b2SBastian Koppelmann     }
191446ee5b2SBastian Koppelmann 
192446ee5b2SBastian Koppelmann     return (uint32_t)f_result;
193446ee5b2SBastian Koppelmann }
194743cd09dSBastian Koppelmann 
195ddd7feadSBastian Koppelmann uint32_t helper_fmadd(CPUTriCoreState *env, uint32_t r1,
196ddd7feadSBastian Koppelmann                       uint32_t r2, uint32_t r3)
197ddd7feadSBastian Koppelmann {
198ddd7feadSBastian Koppelmann     uint32_t flags;
199ddd7feadSBastian Koppelmann     float32 arg1 = make_float32(r1);
200ddd7feadSBastian Koppelmann     float32 arg2 = make_float32(r2);
201ddd7feadSBastian Koppelmann     float32 arg3 = make_float32(r3);
202ddd7feadSBastian Koppelmann     float32 f_result;
203ddd7feadSBastian Koppelmann 
204ddd7feadSBastian Koppelmann     f_result = float32_muladd(arg1, arg2, arg3, 0, &env->fp_status);
205ddd7feadSBastian Koppelmann 
206ddd7feadSBastian Koppelmann     flags = f_get_excp_flags(env);
207ddd7feadSBastian Koppelmann     if (flags) {
208ddd7feadSBastian Koppelmann         if (flags & float_flag_invalid) {
209ddd7feadSBastian Koppelmann             arg1 = float32_squash_input_denormal(arg1, &env->fp_status);
210ddd7feadSBastian Koppelmann             arg2 = float32_squash_input_denormal(arg2, &env->fp_status);
211ddd7feadSBastian Koppelmann             arg3 = float32_squash_input_denormal(arg3, &env->fp_status);
212ddd7feadSBastian Koppelmann             f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result, 0);
213ddd7feadSBastian Koppelmann         }
214ddd7feadSBastian Koppelmann         f_update_psw_flags(env, flags);
215ddd7feadSBastian Koppelmann     } else {
216ddd7feadSBastian Koppelmann         env->FPU_FS = 0;
217ddd7feadSBastian Koppelmann     }
218ddd7feadSBastian Koppelmann     return (uint32_t)f_result;
219ddd7feadSBastian Koppelmann }
220ddd7feadSBastian Koppelmann 
221ddd7feadSBastian Koppelmann uint32_t helper_fmsub(CPUTriCoreState *env, uint32_t r1,
222ddd7feadSBastian Koppelmann                       uint32_t r2, uint32_t r3)
223ddd7feadSBastian Koppelmann {
224ddd7feadSBastian Koppelmann     uint32_t flags;
225ddd7feadSBastian Koppelmann     float32 arg1 = make_float32(r1);
226ddd7feadSBastian Koppelmann     float32 arg2 = make_float32(r2);
227ddd7feadSBastian Koppelmann     float32 arg3 = make_float32(r3);
228ddd7feadSBastian Koppelmann     float32 f_result;
229ddd7feadSBastian Koppelmann 
230ddd7feadSBastian Koppelmann     f_result = float32_muladd(arg1, arg2, arg3, float_muladd_negate_product,
231ddd7feadSBastian Koppelmann                               &env->fp_status);
232ddd7feadSBastian Koppelmann 
233ddd7feadSBastian Koppelmann     flags = f_get_excp_flags(env);
234ddd7feadSBastian Koppelmann     if (flags) {
235ddd7feadSBastian Koppelmann         if (flags & float_flag_invalid) {
236ddd7feadSBastian Koppelmann             arg1 = float32_squash_input_denormal(arg1, &env->fp_status);
237ddd7feadSBastian Koppelmann             arg2 = float32_squash_input_denormal(arg2, &env->fp_status);
238ddd7feadSBastian Koppelmann             arg3 = float32_squash_input_denormal(arg3, &env->fp_status);
239ddd7feadSBastian Koppelmann 
240ddd7feadSBastian Koppelmann             f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result, 1);
241ddd7feadSBastian Koppelmann         }
242ddd7feadSBastian Koppelmann         f_update_psw_flags(env, flags);
243ddd7feadSBastian Koppelmann     } else {
244ddd7feadSBastian Koppelmann         env->FPU_FS = 0;
245ddd7feadSBastian Koppelmann     }
246ddd7feadSBastian Koppelmann     return (uint32_t)f_result;
247ddd7feadSBastian Koppelmann }
248ddd7feadSBastian Koppelmann 
249743cd09dSBastian Koppelmann uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
250743cd09dSBastian Koppelmann {
251743cd09dSBastian Koppelmann     uint32_t result, flags;
252743cd09dSBastian Koppelmann     float32 arg1 = make_float32(r1);
253743cd09dSBastian Koppelmann     float32 arg2 = make_float32(r2);
254743cd09dSBastian Koppelmann 
255743cd09dSBastian Koppelmann     set_flush_inputs_to_zero(0, &env->fp_status);
256743cd09dSBastian Koppelmann 
257743cd09dSBastian Koppelmann     result = 1 << (float32_compare_quiet(arg1, arg2, &env->fp_status) + 1);
258b8c54700SEmilio G. Cota     result |= float32_is_denormal(arg1) << 4;
259b8c54700SEmilio G. Cota     result |= float32_is_denormal(arg2) << 5;
260743cd09dSBastian Koppelmann 
261743cd09dSBastian Koppelmann     flags = f_get_excp_flags(env);
262743cd09dSBastian Koppelmann     if (flags) {
263743cd09dSBastian Koppelmann         f_update_psw_flags(env, flags);
264743cd09dSBastian Koppelmann     } else {
265743cd09dSBastian Koppelmann         env->FPU_FS = 0;
266743cd09dSBastian Koppelmann     }
267743cd09dSBastian Koppelmann 
268743cd09dSBastian Koppelmann     set_flush_inputs_to_zero(1, &env->fp_status);
269743cd09dSBastian Koppelmann     return result;
270743cd09dSBastian Koppelmann }
2710d4c3b80SBastian Koppelmann 
2720d4c3b80SBastian Koppelmann uint32_t helper_ftoi(CPUTriCoreState *env, uint32_t arg)
2730d4c3b80SBastian Koppelmann {
2740d4c3b80SBastian Koppelmann     float32 f_arg = make_float32(arg);
2750d4c3b80SBastian Koppelmann     int32_t result, flags;
2760d4c3b80SBastian Koppelmann 
2770d4c3b80SBastian Koppelmann     result = float32_to_int32(f_arg, &env->fp_status);
2780d4c3b80SBastian Koppelmann 
2790d4c3b80SBastian Koppelmann     flags = f_get_excp_flags(env);
2800d4c3b80SBastian Koppelmann     if (flags) {
2810d4c3b80SBastian Koppelmann         if (float32_is_any_nan(f_arg)) {
2820d4c3b80SBastian Koppelmann             result = 0;
2830d4c3b80SBastian Koppelmann         }
2840d4c3b80SBastian Koppelmann         f_update_psw_flags(env, flags);
2850d4c3b80SBastian Koppelmann     } else {
2860d4c3b80SBastian Koppelmann         env->FPU_FS = 0;
2870d4c3b80SBastian Koppelmann     }
2880d4c3b80SBastian Koppelmann     return (uint32_t)result;
2890d4c3b80SBastian Koppelmann }
2900d4c3b80SBastian Koppelmann 
2910d4c3b80SBastian Koppelmann uint32_t helper_itof(CPUTriCoreState *env, uint32_t arg)
2920d4c3b80SBastian Koppelmann {
2930d4c3b80SBastian Koppelmann     float32 f_result;
2940d4c3b80SBastian Koppelmann     uint32_t flags;
2950d4c3b80SBastian Koppelmann     f_result = int32_to_float32(arg, &env->fp_status);
2960d4c3b80SBastian Koppelmann 
2970d4c3b80SBastian Koppelmann     flags = f_get_excp_flags(env);
2980d4c3b80SBastian Koppelmann     if (flags) {
2990d4c3b80SBastian Koppelmann         f_update_psw_flags(env, flags);
3000d4c3b80SBastian Koppelmann     } else {
3010d4c3b80SBastian Koppelmann         env->FPU_FS = 0;
3020d4c3b80SBastian Koppelmann     }
3030d4c3b80SBastian Koppelmann     return (uint32_t)f_result;
3040d4c3b80SBastian Koppelmann }
3058f75983dSBastian Koppelmann 
306*1fa79fb0SDavid Brenken uint32_t helper_ftoiz(CPUTriCoreState *env, uint32_t arg)
307*1fa79fb0SDavid Brenken {
308*1fa79fb0SDavid Brenken     float32 f_arg = make_float32(arg);
309*1fa79fb0SDavid Brenken     uint32_t result;
310*1fa79fb0SDavid Brenken     int32_t flags;
311*1fa79fb0SDavid Brenken 
312*1fa79fb0SDavid Brenken     result = float32_to_int32_round_to_zero(f_arg, &env->fp_status);
313*1fa79fb0SDavid Brenken 
314*1fa79fb0SDavid Brenken     flags = f_get_excp_flags(env);
315*1fa79fb0SDavid Brenken     if (flags & float_flag_invalid) {
316*1fa79fb0SDavid Brenken         flags &= ~float_flag_inexact;
317*1fa79fb0SDavid Brenken         if (float32_is_any_nan(f_arg)) {
318*1fa79fb0SDavid Brenken             result = 0;
319*1fa79fb0SDavid Brenken         }
320*1fa79fb0SDavid Brenken     }
321*1fa79fb0SDavid Brenken 
322*1fa79fb0SDavid Brenken     if (flags) {
323*1fa79fb0SDavid Brenken         f_update_psw_flags(env, flags);
324*1fa79fb0SDavid Brenken     } else {
325*1fa79fb0SDavid Brenken         env->FPU_FS = 0;
326*1fa79fb0SDavid Brenken     }
327*1fa79fb0SDavid Brenken 
328*1fa79fb0SDavid Brenken     return result;
329*1fa79fb0SDavid Brenken }
330*1fa79fb0SDavid Brenken 
3318f75983dSBastian Koppelmann uint32_t helper_ftouz(CPUTriCoreState *env, uint32_t arg)
3328f75983dSBastian Koppelmann {
3338f75983dSBastian Koppelmann     float32 f_arg = make_float32(arg);
3348f75983dSBastian Koppelmann     uint32_t result;
3358f75983dSBastian Koppelmann     int32_t flags;
3368f75983dSBastian Koppelmann 
3378f75983dSBastian Koppelmann     result = float32_to_uint32_round_to_zero(f_arg, &env->fp_status);
3388f75983dSBastian Koppelmann 
3398f75983dSBastian Koppelmann     flags = f_get_excp_flags(env);
3408f75983dSBastian Koppelmann     if (flags & float_flag_invalid) {
3418f75983dSBastian Koppelmann         flags &= ~float_flag_inexact;
3428f75983dSBastian Koppelmann         if (float32_is_any_nan(f_arg)) {
3438f75983dSBastian Koppelmann             result = 0;
3448f75983dSBastian Koppelmann         }
3458f75983dSBastian Koppelmann     } else if (float32_lt_quiet(f_arg, 0, &env->fp_status)) {
3468f75983dSBastian Koppelmann         flags = float_flag_invalid;
3478f75983dSBastian Koppelmann         result = 0;
3488f75983dSBastian Koppelmann     }
3498f75983dSBastian Koppelmann 
3508f75983dSBastian Koppelmann     if (flags) {
3518f75983dSBastian Koppelmann         f_update_psw_flags(env, flags);
3528f75983dSBastian Koppelmann     } else {
3538f75983dSBastian Koppelmann         env->FPU_FS = 0;
3548f75983dSBastian Koppelmann     }
3558f75983dSBastian Koppelmann     return result;
3568f75983dSBastian Koppelmann }
35750788a3fSBastian Koppelmann 
35850788a3fSBastian Koppelmann void helper_updfl(CPUTriCoreState *env, uint32_t arg)
35950788a3fSBastian Koppelmann {
36050788a3fSBastian Koppelmann     env->FPU_FS =  extract32(arg, 7, 1) & extract32(arg, 15, 1);
36150788a3fSBastian Koppelmann     env->FPU_FI = (extract32(arg, 6, 1) & extract32(arg, 14, 1)) << 31;
36250788a3fSBastian Koppelmann     env->FPU_FV = (extract32(arg, 5, 1) & extract32(arg, 13, 1)) << 31;
36350788a3fSBastian Koppelmann     env->FPU_FZ = (extract32(arg, 4, 1) & extract32(arg, 12, 1)) << 31;
36450788a3fSBastian Koppelmann     env->FPU_FU = (extract32(arg, 3, 1) & extract32(arg, 11, 1)) << 31;
36550788a3fSBastian Koppelmann     /* clear FX and RM */
36650788a3fSBastian Koppelmann     env->PSW &= ~(extract32(arg, 10, 1) << 26);
36750788a3fSBastian Koppelmann     env->PSW |= (extract32(arg, 2, 1) & extract32(arg, 10, 1)) << 26;
36850788a3fSBastian Koppelmann 
36950788a3fSBastian Koppelmann     fpu_set_state(env);
37050788a3fSBastian Koppelmann }
371