xref: /qemu/target/tricore/fpu_helper.c (revision 24f91e81b65fcdd0552d1f0fcb0ea7cfe3829c19)
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
9996a729fSBastian Koppelmann  * version 2 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"
23*24f91e81SAlex 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 
47996a729fSBastian Koppelmann static inline bool f_is_denormal(float32 arg)
48996a729fSBastian Koppelmann {
49996a729fSBastian Koppelmann     return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg);
50996a729fSBastian Koppelmann }
51996a729fSBastian Koppelmann 
52ddd7feadSBastian Koppelmann static inline float32 f_maddsub_nan_result(float32 arg1, float32 arg2,
53ddd7feadSBastian Koppelmann                                            float32 arg3, float32 result,
54ddd7feadSBastian Koppelmann                                            uint32_t muladd_negate_c)
55ddd7feadSBastian Koppelmann {
56ddd7feadSBastian Koppelmann     uint32_t aSign, bSign, cSign;
57ddd7feadSBastian Koppelmann     uint32_t aExp, bExp, cExp;
58ddd7feadSBastian Koppelmann 
59ddd7feadSBastian Koppelmann     if (float32_is_any_nan(arg1) || float32_is_any_nan(arg2) ||
60ddd7feadSBastian Koppelmann         float32_is_any_nan(arg3)) {
61ddd7feadSBastian Koppelmann         return QUIET_NAN;
62ddd7feadSBastian Koppelmann     } else if (float32_is_infinity(arg1) && float32_is_zero(arg2)) {
63ddd7feadSBastian Koppelmann         return MUL_NAN;
64ddd7feadSBastian Koppelmann     } else if (float32_is_zero(arg1) && float32_is_infinity(arg2)) {
65ddd7feadSBastian Koppelmann         return MUL_NAN;
66ddd7feadSBastian Koppelmann     } else {
67ddd7feadSBastian Koppelmann         aSign = arg1 >> 31;
68ddd7feadSBastian Koppelmann         bSign = arg2 >> 31;
69ddd7feadSBastian Koppelmann         cSign = arg3 >> 31;
70ddd7feadSBastian Koppelmann 
71ddd7feadSBastian Koppelmann         aExp = (arg1 >> 23) & 0xff;
72ddd7feadSBastian Koppelmann         bExp = (arg2 >> 23) & 0xff;
73ddd7feadSBastian Koppelmann         cExp = (arg3 >> 23) & 0xff;
74ddd7feadSBastian Koppelmann 
75ddd7feadSBastian Koppelmann         if (muladd_negate_c) {
76ddd7feadSBastian Koppelmann             cSign ^= 1;
77ddd7feadSBastian Koppelmann         }
78ddd7feadSBastian Koppelmann         if (((aExp == 0xff) || (bExp == 0xff)) && (cExp == 0xff)) {
79ddd7feadSBastian Koppelmann             if (aSign ^ bSign ^ cSign) {
80ddd7feadSBastian Koppelmann                 return ADD_NAN;
81ddd7feadSBastian Koppelmann             }
82ddd7feadSBastian Koppelmann         }
83ddd7feadSBastian Koppelmann     }
84ddd7feadSBastian Koppelmann 
85ddd7feadSBastian Koppelmann     return result;
86ddd7feadSBastian Koppelmann }
87ddd7feadSBastian Koppelmann 
88baf410dcSBastian Koppelmann static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
89996a729fSBastian Koppelmann {
90996a729fSBastian Koppelmann     uint8_t some_excp = 0;
91996a729fSBastian Koppelmann     set_float_exception_flags(0, &env->fp_status);
92996a729fSBastian Koppelmann 
93996a729fSBastian Koppelmann     if (flags & float_flag_invalid) {
94996a729fSBastian Koppelmann         env->FPU_FI = 1 << 31;
95996a729fSBastian Koppelmann         some_excp = 1;
96996a729fSBastian Koppelmann     }
97996a729fSBastian Koppelmann 
98996a729fSBastian Koppelmann     if (flags & float_flag_overflow) {
99996a729fSBastian Koppelmann         env->FPU_FV = 1 << 31;
100996a729fSBastian Koppelmann         some_excp = 1;
101996a729fSBastian Koppelmann     }
102996a729fSBastian Koppelmann 
103996a729fSBastian Koppelmann     if (flags & float_flag_underflow || flags & float_flag_output_denormal) {
104996a729fSBastian Koppelmann         env->FPU_FU = 1 << 31;
105996a729fSBastian Koppelmann         some_excp = 1;
106996a729fSBastian Koppelmann     }
107996a729fSBastian Koppelmann 
108996a729fSBastian Koppelmann     if (flags & float_flag_divbyzero) {
109996a729fSBastian Koppelmann         env->FPU_FZ = 1 << 31;
110996a729fSBastian Koppelmann         some_excp = 1;
111996a729fSBastian Koppelmann     }
112996a729fSBastian Koppelmann 
113996a729fSBastian Koppelmann     if (flags & float_flag_inexact || flags & float_flag_output_denormal) {
114996a729fSBastian Koppelmann         env->PSW |= 1 << 26;
115996a729fSBastian Koppelmann         some_excp = 1;
116996a729fSBastian Koppelmann     }
117996a729fSBastian Koppelmann 
118996a729fSBastian Koppelmann     env->FPU_FS = some_excp;
119996a729fSBastian Koppelmann }
120baf410dcSBastian Koppelmann 
121baf410dcSBastian Koppelmann #define FADD_SUB(op)                                                           \
122baf410dcSBastian Koppelmann uint32_t helper_f##op(CPUTriCoreState *env, uint32_t r1, uint32_t r2)          \
123baf410dcSBastian Koppelmann {                                                                              \
124baf410dcSBastian Koppelmann     float32 arg1 = make_float32(r1);                                           \
125baf410dcSBastian Koppelmann     float32 arg2 = make_float32(r2);                                           \
126baf410dcSBastian Koppelmann     uint32_t flags;                                                            \
127baf410dcSBastian Koppelmann     float32 f_result;                                                          \
128baf410dcSBastian Koppelmann                                                                                \
129baf410dcSBastian Koppelmann     f_result = float32_##op(arg2, arg1, &env->fp_status);                      \
130baf410dcSBastian Koppelmann     flags = f_get_excp_flags(env);                                             \
131baf410dcSBastian Koppelmann     if (flags) {                                                               \
132baf410dcSBastian Koppelmann         /* If the output is a NaN, but the inputs aren't,                      \
133baf410dcSBastian Koppelmann            we return a unique value.  */                                       \
134baf410dcSBastian Koppelmann         if ((flags & float_flag_invalid)                                       \
135baf410dcSBastian Koppelmann             && !float32_is_any_nan(arg1)                                       \
136baf410dcSBastian Koppelmann             && !float32_is_any_nan(arg2)) {                                    \
137baf410dcSBastian Koppelmann             f_result = ADD_NAN;                                                \
138baf410dcSBastian Koppelmann         }                                                                      \
139baf410dcSBastian Koppelmann         f_update_psw_flags(env, flags);                                        \
140baf410dcSBastian Koppelmann     } else {                                                                   \
141baf410dcSBastian Koppelmann         env->FPU_FS = 0;                                                       \
142baf410dcSBastian Koppelmann     }                                                                          \
143baf410dcSBastian Koppelmann     return (uint32_t)f_result;                                                 \
144baf410dcSBastian Koppelmann }
145baf410dcSBastian Koppelmann FADD_SUB(add)
146baf410dcSBastian Koppelmann FADD_SUB(sub)
147daab3f7fSBastian Koppelmann 
148daab3f7fSBastian Koppelmann uint32_t helper_fmul(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
149daab3f7fSBastian Koppelmann {
150daab3f7fSBastian Koppelmann     uint32_t flags;
151daab3f7fSBastian Koppelmann     float32 arg1 = make_float32(r1);
152daab3f7fSBastian Koppelmann     float32 arg2 = make_float32(r2);
153daab3f7fSBastian Koppelmann     float32 f_result;
154daab3f7fSBastian Koppelmann 
155daab3f7fSBastian Koppelmann     f_result = float32_mul(arg1, arg2, &env->fp_status);
156daab3f7fSBastian Koppelmann 
157daab3f7fSBastian Koppelmann     flags = f_get_excp_flags(env);
158daab3f7fSBastian Koppelmann     if (flags) {
159daab3f7fSBastian Koppelmann         /* If the output is a NaN, but the inputs aren't,
160daab3f7fSBastian Koppelmann            we return a unique value.  */
161daab3f7fSBastian Koppelmann         if ((flags & float_flag_invalid)
162daab3f7fSBastian Koppelmann             && !float32_is_any_nan(arg1)
163daab3f7fSBastian Koppelmann             && !float32_is_any_nan(arg2)) {
164daab3f7fSBastian Koppelmann                 f_result = MUL_NAN;
165daab3f7fSBastian Koppelmann         }
166daab3f7fSBastian Koppelmann         f_update_psw_flags(env, flags);
167daab3f7fSBastian Koppelmann     } else {
168daab3f7fSBastian Koppelmann         env->FPU_FS = 0;
169daab3f7fSBastian Koppelmann     }
170daab3f7fSBastian Koppelmann     return (uint32_t)f_result;
171daab3f7fSBastian Koppelmann 
172daab3f7fSBastian Koppelmann }
173446ee5b2SBastian Koppelmann 
174446ee5b2SBastian Koppelmann uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
175446ee5b2SBastian Koppelmann {
176446ee5b2SBastian Koppelmann     uint32_t flags;
177446ee5b2SBastian Koppelmann     float32 arg1 = make_float32(r1);
178446ee5b2SBastian Koppelmann     float32 arg2 = make_float32(r2);
179446ee5b2SBastian Koppelmann     float32 f_result;
180446ee5b2SBastian Koppelmann 
181446ee5b2SBastian Koppelmann     f_result = float32_div(arg1, arg2 , &env->fp_status);
182446ee5b2SBastian Koppelmann 
183446ee5b2SBastian Koppelmann     flags = f_get_excp_flags(env);
184446ee5b2SBastian Koppelmann     if (flags) {
185446ee5b2SBastian Koppelmann         /* If the output is a NaN, but the inputs aren't,
186446ee5b2SBastian Koppelmann            we return a unique value.  */
187446ee5b2SBastian Koppelmann         if ((flags & float_flag_invalid)
188446ee5b2SBastian Koppelmann             && !float32_is_any_nan(arg1)
189446ee5b2SBastian Koppelmann             && !float32_is_any_nan(arg2)) {
190446ee5b2SBastian Koppelmann                 f_result = DIV_NAN;
191446ee5b2SBastian Koppelmann         }
192446ee5b2SBastian Koppelmann         f_update_psw_flags(env, flags);
193446ee5b2SBastian Koppelmann     } else {
194446ee5b2SBastian Koppelmann         env->FPU_FS = 0;
195446ee5b2SBastian Koppelmann     }
196446ee5b2SBastian Koppelmann 
197446ee5b2SBastian Koppelmann     return (uint32_t)f_result;
198446ee5b2SBastian Koppelmann }
199743cd09dSBastian Koppelmann 
200ddd7feadSBastian Koppelmann uint32_t helper_fmadd(CPUTriCoreState *env, uint32_t r1,
201ddd7feadSBastian Koppelmann                       uint32_t r2, uint32_t r3)
202ddd7feadSBastian Koppelmann {
203ddd7feadSBastian Koppelmann     uint32_t flags;
204ddd7feadSBastian Koppelmann     float32 arg1 = make_float32(r1);
205ddd7feadSBastian Koppelmann     float32 arg2 = make_float32(r2);
206ddd7feadSBastian Koppelmann     float32 arg3 = make_float32(r3);
207ddd7feadSBastian Koppelmann     float32 f_result;
208ddd7feadSBastian Koppelmann 
209ddd7feadSBastian Koppelmann     f_result = float32_muladd(arg1, arg2, arg3, 0, &env->fp_status);
210ddd7feadSBastian Koppelmann 
211ddd7feadSBastian Koppelmann     flags = f_get_excp_flags(env);
212ddd7feadSBastian Koppelmann     if (flags) {
213ddd7feadSBastian Koppelmann         if (flags & float_flag_invalid) {
214ddd7feadSBastian Koppelmann             arg1 = float32_squash_input_denormal(arg1, &env->fp_status);
215ddd7feadSBastian Koppelmann             arg2 = float32_squash_input_denormal(arg2, &env->fp_status);
216ddd7feadSBastian Koppelmann             arg3 = float32_squash_input_denormal(arg3, &env->fp_status);
217ddd7feadSBastian Koppelmann             f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result, 0);
218ddd7feadSBastian Koppelmann         }
219ddd7feadSBastian Koppelmann         f_update_psw_flags(env, flags);
220ddd7feadSBastian Koppelmann     } else {
221ddd7feadSBastian Koppelmann         env->FPU_FS = 0;
222ddd7feadSBastian Koppelmann     }
223ddd7feadSBastian Koppelmann     return (uint32_t)f_result;
224ddd7feadSBastian Koppelmann }
225ddd7feadSBastian Koppelmann 
226ddd7feadSBastian Koppelmann uint32_t helper_fmsub(CPUTriCoreState *env, uint32_t r1,
227ddd7feadSBastian Koppelmann                       uint32_t r2, uint32_t r3)
228ddd7feadSBastian Koppelmann {
229ddd7feadSBastian Koppelmann     uint32_t flags;
230ddd7feadSBastian Koppelmann     float32 arg1 = make_float32(r1);
231ddd7feadSBastian Koppelmann     float32 arg2 = make_float32(r2);
232ddd7feadSBastian Koppelmann     float32 arg3 = make_float32(r3);
233ddd7feadSBastian Koppelmann     float32 f_result;
234ddd7feadSBastian Koppelmann 
235ddd7feadSBastian Koppelmann     f_result = float32_muladd(arg1, arg2, arg3, float_muladd_negate_product,
236ddd7feadSBastian Koppelmann                               &env->fp_status);
237ddd7feadSBastian Koppelmann 
238ddd7feadSBastian Koppelmann     flags = f_get_excp_flags(env);
239ddd7feadSBastian Koppelmann     if (flags) {
240ddd7feadSBastian Koppelmann         if (flags & float_flag_invalid) {
241ddd7feadSBastian Koppelmann             arg1 = float32_squash_input_denormal(arg1, &env->fp_status);
242ddd7feadSBastian Koppelmann             arg2 = float32_squash_input_denormal(arg2, &env->fp_status);
243ddd7feadSBastian Koppelmann             arg3 = float32_squash_input_denormal(arg3, &env->fp_status);
244ddd7feadSBastian Koppelmann 
245ddd7feadSBastian Koppelmann             f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result, 1);
246ddd7feadSBastian Koppelmann         }
247ddd7feadSBastian Koppelmann         f_update_psw_flags(env, flags);
248ddd7feadSBastian Koppelmann     } else {
249ddd7feadSBastian Koppelmann         env->FPU_FS = 0;
250ddd7feadSBastian Koppelmann     }
251ddd7feadSBastian Koppelmann     return (uint32_t)f_result;
252ddd7feadSBastian Koppelmann }
253ddd7feadSBastian Koppelmann 
254743cd09dSBastian Koppelmann uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
255743cd09dSBastian Koppelmann {
256743cd09dSBastian Koppelmann     uint32_t result, flags;
257743cd09dSBastian Koppelmann     float32 arg1 = make_float32(r1);
258743cd09dSBastian Koppelmann     float32 arg2 = make_float32(r2);
259743cd09dSBastian Koppelmann 
260743cd09dSBastian Koppelmann     set_flush_inputs_to_zero(0, &env->fp_status);
261743cd09dSBastian Koppelmann 
262743cd09dSBastian Koppelmann     result = 1 << (float32_compare_quiet(arg1, arg2, &env->fp_status) + 1);
263743cd09dSBastian Koppelmann     result |= f_is_denormal(arg1) << 4;
264743cd09dSBastian Koppelmann     result |= f_is_denormal(arg2) << 5;
265743cd09dSBastian Koppelmann 
266743cd09dSBastian Koppelmann     flags = f_get_excp_flags(env);
267743cd09dSBastian Koppelmann     if (flags) {
268743cd09dSBastian Koppelmann         f_update_psw_flags(env, flags);
269743cd09dSBastian Koppelmann     } else {
270743cd09dSBastian Koppelmann         env->FPU_FS = 0;
271743cd09dSBastian Koppelmann     }
272743cd09dSBastian Koppelmann 
273743cd09dSBastian Koppelmann     set_flush_inputs_to_zero(1, &env->fp_status);
274743cd09dSBastian Koppelmann     return result;
275743cd09dSBastian Koppelmann }
2760d4c3b80SBastian Koppelmann 
2770d4c3b80SBastian Koppelmann uint32_t helper_ftoi(CPUTriCoreState *env, uint32_t arg)
2780d4c3b80SBastian Koppelmann {
2790d4c3b80SBastian Koppelmann     float32 f_arg = make_float32(arg);
2800d4c3b80SBastian Koppelmann     int32_t result, flags;
2810d4c3b80SBastian Koppelmann 
2820d4c3b80SBastian Koppelmann     result = float32_to_int32(f_arg, &env->fp_status);
2830d4c3b80SBastian Koppelmann 
2840d4c3b80SBastian Koppelmann     flags = f_get_excp_flags(env);
2850d4c3b80SBastian Koppelmann     if (flags) {
2860d4c3b80SBastian Koppelmann         if (float32_is_any_nan(f_arg)) {
2870d4c3b80SBastian Koppelmann             result = 0;
2880d4c3b80SBastian Koppelmann         }
2890d4c3b80SBastian Koppelmann         f_update_psw_flags(env, flags);
2900d4c3b80SBastian Koppelmann     } else {
2910d4c3b80SBastian Koppelmann         env->FPU_FS = 0;
2920d4c3b80SBastian Koppelmann     }
2930d4c3b80SBastian Koppelmann     return (uint32_t)result;
2940d4c3b80SBastian Koppelmann }
2950d4c3b80SBastian Koppelmann 
2960d4c3b80SBastian Koppelmann uint32_t helper_itof(CPUTriCoreState *env, uint32_t arg)
2970d4c3b80SBastian Koppelmann {
2980d4c3b80SBastian Koppelmann     float32 f_result;
2990d4c3b80SBastian Koppelmann     uint32_t flags;
3000d4c3b80SBastian Koppelmann     f_result = int32_to_float32(arg, &env->fp_status);
3010d4c3b80SBastian Koppelmann 
3020d4c3b80SBastian Koppelmann     flags = f_get_excp_flags(env);
3030d4c3b80SBastian Koppelmann     if (flags) {
3040d4c3b80SBastian Koppelmann         f_update_psw_flags(env, flags);
3050d4c3b80SBastian Koppelmann     } else {
3060d4c3b80SBastian Koppelmann         env->FPU_FS = 0;
3070d4c3b80SBastian Koppelmann     }
3080d4c3b80SBastian Koppelmann     return (uint32_t)f_result;
3090d4c3b80SBastian Koppelmann }
3108f75983dSBastian Koppelmann 
3118f75983dSBastian Koppelmann uint32_t helper_ftouz(CPUTriCoreState *env, uint32_t arg)
3128f75983dSBastian Koppelmann {
3138f75983dSBastian Koppelmann     float32 f_arg = make_float32(arg);
3148f75983dSBastian Koppelmann     uint32_t result;
3158f75983dSBastian Koppelmann     int32_t flags;
3168f75983dSBastian Koppelmann 
3178f75983dSBastian Koppelmann     result = float32_to_uint32_round_to_zero(f_arg, &env->fp_status);
3188f75983dSBastian Koppelmann 
3198f75983dSBastian Koppelmann     flags = f_get_excp_flags(env);
3208f75983dSBastian Koppelmann     if (flags & float_flag_invalid) {
3218f75983dSBastian Koppelmann         flags &= ~float_flag_inexact;
3228f75983dSBastian Koppelmann         if (float32_is_any_nan(f_arg)) {
3238f75983dSBastian Koppelmann             result = 0;
3248f75983dSBastian Koppelmann         }
3258f75983dSBastian Koppelmann     } else if (float32_lt_quiet(f_arg, 0, &env->fp_status)) {
3268f75983dSBastian Koppelmann         flags = float_flag_invalid;
3278f75983dSBastian Koppelmann         result = 0;
3288f75983dSBastian Koppelmann     }
3298f75983dSBastian Koppelmann 
3308f75983dSBastian Koppelmann     if (flags) {
3318f75983dSBastian Koppelmann         f_update_psw_flags(env, flags);
3328f75983dSBastian Koppelmann     } else {
3338f75983dSBastian Koppelmann         env->FPU_FS = 0;
3348f75983dSBastian Koppelmann     }
3358f75983dSBastian Koppelmann     return result;
3368f75983dSBastian Koppelmann }
33750788a3fSBastian Koppelmann 
33850788a3fSBastian Koppelmann void helper_updfl(CPUTriCoreState *env, uint32_t arg)
33950788a3fSBastian Koppelmann {
34050788a3fSBastian Koppelmann     env->FPU_FS =  extract32(arg, 7, 1) & extract32(arg, 15, 1);
34150788a3fSBastian Koppelmann     env->FPU_FI = (extract32(arg, 6, 1) & extract32(arg, 14, 1)) << 31;
34250788a3fSBastian Koppelmann     env->FPU_FV = (extract32(arg, 5, 1) & extract32(arg, 13, 1)) << 31;
34350788a3fSBastian Koppelmann     env->FPU_FZ = (extract32(arg, 4, 1) & extract32(arg, 12, 1)) << 31;
34450788a3fSBastian Koppelmann     env->FPU_FU = (extract32(arg, 3, 1) & extract32(arg, 11, 1)) << 31;
34550788a3fSBastian Koppelmann     /* clear FX and RM */
34650788a3fSBastian Koppelmann     env->PSW &= ~(extract32(arg, 10, 1) << 26);
34750788a3fSBastian Koppelmann     env->PSW |= (extract32(arg, 2, 1) & extract32(arg, 10, 1)) << 26;
34850788a3fSBastian Koppelmann 
34950788a3fSBastian Koppelmann     fpu_set_state(env);
35050788a3fSBastian Koppelmann }
351