xref: /qemu/target/s390x/tcg/fpu_helper.c (revision 1a800a2dcee541dee4f51aed5110ca9d5811c5e8)
1e72ca652SBlue Swirl /*
2e72ca652SBlue Swirl  *  S/390 FPU helper routines
3e72ca652SBlue Swirl  *
4e72ca652SBlue Swirl  *  Copyright (c) 2009 Ulrich Hecht
5e72ca652SBlue Swirl  *  Copyright (c) 2009 Alexander Graf
6e72ca652SBlue Swirl  *
7e72ca652SBlue Swirl  * This library is free software; you can redistribute it and/or
8e72ca652SBlue Swirl  * modify it under the terms of the GNU Lesser General Public
9e72ca652SBlue Swirl  * License as published by the Free Software Foundation; either
10e72ca652SBlue Swirl  * version 2 of the License, or (at your option) any later version.
11e72ca652SBlue Swirl  *
12e72ca652SBlue Swirl  * This library is distributed in the hope that it will be useful,
13e72ca652SBlue Swirl  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14e72ca652SBlue Swirl  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15e72ca652SBlue Swirl  * Lesser General Public License for more details.
16e72ca652SBlue Swirl  *
17e72ca652SBlue Swirl  * You should have received a copy of the GNU Lesser General Public
18e72ca652SBlue Swirl  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19e72ca652SBlue Swirl  */
20e72ca652SBlue Swirl 
21e72ca652SBlue Swirl #include "cpu.h"
22e72ca652SBlue Swirl #include "helper.h"
23e72ca652SBlue Swirl 
2419b0516fSBlue Swirl #if !defined(CONFIG_USER_ONLY)
25022c62cbSPaolo Bonzini #include "exec/softmmu_exec.h"
26e72ca652SBlue Swirl #endif
27e72ca652SBlue Swirl 
28e72ca652SBlue Swirl /* #define DEBUG_HELPER */
29e72ca652SBlue Swirl #ifdef DEBUG_HELPER
30e72ca652SBlue Swirl #define HELPER_LOG(x...) qemu_log(x)
31e72ca652SBlue Swirl #else
32e72ca652SBlue Swirl #define HELPER_LOG(x...)
33e72ca652SBlue Swirl #endif
34e72ca652SBlue Swirl 
35587626f8SRichard Henderson #define RET128(F) (env->retxl = F.low, F.high)
36587626f8SRichard Henderson 
37587626f8SRichard Henderson #define convert_bit(mask, from, to) \
38587626f8SRichard Henderson     (to < from                      \
39587626f8SRichard Henderson      ? (mask / (from / to)) & to    \
40587626f8SRichard Henderson      : (mask & from) * (to / from))
41587626f8SRichard Henderson 
42587626f8SRichard Henderson static void ieee_exception(CPUS390XState *env, uint32_t dxc, uintptr_t retaddr)
43587626f8SRichard Henderson {
44587626f8SRichard Henderson     /* Install the DXC code.  */
45587626f8SRichard Henderson     env->fpc = (env->fpc & ~0xff00) | (dxc << 8);
46587626f8SRichard Henderson     /* Trap.  */
47587626f8SRichard Henderson     runtime_exception(env, PGM_DATA, retaddr);
48587626f8SRichard Henderson }
49587626f8SRichard Henderson 
50587626f8SRichard Henderson /* Should be called after any operation that may raise IEEE exceptions.  */
51587626f8SRichard Henderson static void handle_exceptions(CPUS390XState *env, uintptr_t retaddr)
52587626f8SRichard Henderson {
53587626f8SRichard Henderson     unsigned s390_exc, qemu_exc;
54587626f8SRichard Henderson 
55587626f8SRichard Henderson     /* Get the exceptions raised by the current operation.  Reset the
56587626f8SRichard Henderson        fpu_status contents so that the next operation has a clean slate.  */
57587626f8SRichard Henderson     qemu_exc = env->fpu_status.float_exception_flags;
58587626f8SRichard Henderson     if (qemu_exc == 0) {
59587626f8SRichard Henderson         return;
60587626f8SRichard Henderson     }
61587626f8SRichard Henderson     env->fpu_status.float_exception_flags = 0;
62587626f8SRichard Henderson 
63587626f8SRichard Henderson     /* Convert softfloat exception bits to s390 exception bits.  */
64587626f8SRichard Henderson     s390_exc = 0;
65587626f8SRichard Henderson     s390_exc |= convert_bit(qemu_exc, float_flag_invalid, 0x80);
66587626f8SRichard Henderson     s390_exc |= convert_bit(qemu_exc, float_flag_divbyzero, 0x40);
67587626f8SRichard Henderson     s390_exc |= convert_bit(qemu_exc, float_flag_overflow, 0x20);
68587626f8SRichard Henderson     s390_exc |= convert_bit(qemu_exc, float_flag_underflow, 0x10);
69587626f8SRichard Henderson     s390_exc |= convert_bit(qemu_exc, float_flag_inexact, 0x08);
70587626f8SRichard Henderson 
71587626f8SRichard Henderson     /* Install the exceptions that we raised.  */
72587626f8SRichard Henderson     env->fpc |= s390_exc << 16;
73587626f8SRichard Henderson 
74587626f8SRichard Henderson     /* Send signals for enabled exceptions.  */
75587626f8SRichard Henderson     s390_exc &= env->fpc >> 24;
76587626f8SRichard Henderson     if (s390_exc) {
77587626f8SRichard Henderson         ieee_exception(env, s390_exc, retaddr);
78587626f8SRichard Henderson     }
79587626f8SRichard Henderson }
80587626f8SRichard Henderson 
81449c0d70SBlue Swirl static inline int float_comp_to_cc(CPUS390XState *env, int float_compare)
82e72ca652SBlue Swirl {
83e72ca652SBlue Swirl     switch (float_compare) {
84e72ca652SBlue Swirl     case float_relation_equal:
85e72ca652SBlue Swirl         return 0;
86e72ca652SBlue Swirl     case float_relation_less:
87e72ca652SBlue Swirl         return 1;
88e72ca652SBlue Swirl     case float_relation_greater:
89e72ca652SBlue Swirl         return 2;
90e72ca652SBlue Swirl     case float_relation_unordered:
91e72ca652SBlue Swirl         return 3;
92e72ca652SBlue Swirl     default:
93e72ca652SBlue Swirl         cpu_abort(env, "unknown return value for float compare\n");
94e72ca652SBlue Swirl     }
95e72ca652SBlue Swirl }
96e72ca652SBlue Swirl 
97e72ca652SBlue Swirl /* condition codes for unary FP ops */
98e72ca652SBlue Swirl uint32_t set_cc_nz_f32(float32 v)
99e72ca652SBlue Swirl {
100e72ca652SBlue Swirl     if (float32_is_any_nan(v)) {
101e72ca652SBlue Swirl         return 3;
102e72ca652SBlue Swirl     } else if (float32_is_zero(v)) {
103e72ca652SBlue Swirl         return 0;
104e72ca652SBlue Swirl     } else if (float32_is_neg(v)) {
105e72ca652SBlue Swirl         return 1;
106e72ca652SBlue Swirl     } else {
107e72ca652SBlue Swirl         return 2;
108e72ca652SBlue Swirl     }
109e72ca652SBlue Swirl }
110e72ca652SBlue Swirl 
111e72ca652SBlue Swirl uint32_t set_cc_nz_f64(float64 v)
112e72ca652SBlue Swirl {
113e72ca652SBlue Swirl     if (float64_is_any_nan(v)) {
114e72ca652SBlue Swirl         return 3;
115e72ca652SBlue Swirl     } else if (float64_is_zero(v)) {
116e72ca652SBlue Swirl         return 0;
117e72ca652SBlue Swirl     } else if (float64_is_neg(v)) {
118e72ca652SBlue Swirl         return 1;
119e72ca652SBlue Swirl     } else {
120e72ca652SBlue Swirl         return 2;
121e72ca652SBlue Swirl     }
122e72ca652SBlue Swirl }
123e72ca652SBlue Swirl 
124587626f8SRichard Henderson uint32_t set_cc_nz_f128(float128 v)
125e72ca652SBlue Swirl {
126e72ca652SBlue Swirl     if (float128_is_any_nan(v)) {
127e72ca652SBlue Swirl         return 3;
128e72ca652SBlue Swirl     } else if (float128_is_zero(v)) {
129e72ca652SBlue Swirl         return 0;
130e72ca652SBlue Swirl     } else if (float128_is_neg(v)) {
131e72ca652SBlue Swirl         return 1;
132e72ca652SBlue Swirl     } else {
133e72ca652SBlue Swirl         return 2;
134e72ca652SBlue Swirl     }
135e72ca652SBlue Swirl }
136e72ca652SBlue Swirl 
137e72ca652SBlue Swirl /* convert 32-bit int to 64-bit float */
138449c0d70SBlue Swirl void HELPER(cdfbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
139e72ca652SBlue Swirl {
140e72ca652SBlue Swirl     HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
141e72ca652SBlue Swirl     env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
142e72ca652SBlue Swirl }
143e72ca652SBlue Swirl 
144e72ca652SBlue Swirl /* convert 32-bit int to 128-bit float */
145449c0d70SBlue Swirl void HELPER(cxfbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
146e72ca652SBlue Swirl {
147e72ca652SBlue Swirl     CPU_QuadU v1;
148e72ca652SBlue Swirl 
149e72ca652SBlue Swirl     v1.q = int32_to_float128(v2, &env->fpu_status);
150e72ca652SBlue Swirl     env->fregs[f1].ll = v1.ll.upper;
151e72ca652SBlue Swirl     env->fregs[f1 + 2].ll = v1.ll.lower;
152e72ca652SBlue Swirl }
153e72ca652SBlue Swirl 
154e72ca652SBlue Swirl /* convert 64-bit int to 32-bit float */
155449c0d70SBlue Swirl void HELPER(cegbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
156e72ca652SBlue Swirl {
157e72ca652SBlue Swirl     HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
158e72ca652SBlue Swirl     env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
159e72ca652SBlue Swirl }
160e72ca652SBlue Swirl 
161e72ca652SBlue Swirl /* convert 64-bit int to 64-bit float */
162449c0d70SBlue Swirl void HELPER(cdgbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
163e72ca652SBlue Swirl {
164e72ca652SBlue Swirl     HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
165e72ca652SBlue Swirl     env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
166e72ca652SBlue Swirl }
167e72ca652SBlue Swirl 
168e72ca652SBlue Swirl /* convert 64-bit int to 128-bit float */
169449c0d70SBlue Swirl void HELPER(cxgbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
170e72ca652SBlue Swirl {
171e72ca652SBlue Swirl     CPU_QuadU x1;
172e72ca652SBlue Swirl 
173e72ca652SBlue Swirl     x1.q = int64_to_float128(v2, &env->fpu_status);
174e72ca652SBlue Swirl     HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __func__, v2,
175e72ca652SBlue Swirl                x1.ll.upper, x1.ll.lower);
176e72ca652SBlue Swirl     env->fregs[f1].ll = x1.ll.upper;
177e72ca652SBlue Swirl     env->fregs[f1 + 2].ll = x1.ll.lower;
178e72ca652SBlue Swirl }
179e72ca652SBlue Swirl 
180e72ca652SBlue Swirl /* convert 32-bit int to 32-bit float */
181449c0d70SBlue Swirl void HELPER(cefbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
182e72ca652SBlue Swirl {
183e72ca652SBlue Swirl     env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
184e72ca652SBlue Swirl     HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
185e72ca652SBlue Swirl                env->fregs[f1].l.upper, f1);
186e72ca652SBlue Swirl }
187e72ca652SBlue Swirl 
188587626f8SRichard Henderson /* 32-bit FP addition */
189587626f8SRichard Henderson uint64_t HELPER(aeb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
190e72ca652SBlue Swirl {
191587626f8SRichard Henderson     float32 ret = float32_add(f1, f2, &env->fpu_status);
192587626f8SRichard Henderson     handle_exceptions(env, GETPC());
193587626f8SRichard Henderson     return ret;
194e72ca652SBlue Swirl }
195e72ca652SBlue Swirl 
196587626f8SRichard Henderson /* 64-bit FP addition */
197587626f8SRichard Henderson uint64_t HELPER(adb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
198e72ca652SBlue Swirl {
199587626f8SRichard Henderson     float64 ret = float64_add(f1, f2, &env->fpu_status);
200587626f8SRichard Henderson     handle_exceptions(env, GETPC());
201587626f8SRichard Henderson     return ret;
202587626f8SRichard Henderson }
203e72ca652SBlue Swirl 
204587626f8SRichard Henderson /* 128-bit FP addition */
205587626f8SRichard Henderson uint64_t HELPER(axb)(CPUS390XState *env, uint64_t ah, uint64_t al,
206587626f8SRichard Henderson                      uint64_t bh, uint64_t bl)
207587626f8SRichard Henderson {
208587626f8SRichard Henderson     float128 ret = float128_add(make_float128(ah, al),
209587626f8SRichard Henderson                                 make_float128(bh, bl),
210587626f8SRichard Henderson                                 &env->fpu_status);
211587626f8SRichard Henderson     handle_exceptions(env, GETPC());
212587626f8SRichard Henderson     return RET128(ret);
213e72ca652SBlue Swirl }
214e72ca652SBlue Swirl 
2151a800a2dSRichard Henderson /* 32-bit FP subtraction */
2161a800a2dSRichard Henderson uint64_t HELPER(seb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
217e72ca652SBlue Swirl {
2181a800a2dSRichard Henderson     float32 ret = float32_sub(f1, f2, &env->fpu_status);
2191a800a2dSRichard Henderson     handle_exceptions(env, GETPC());
2201a800a2dSRichard Henderson     return ret;
221e72ca652SBlue Swirl }
222e72ca652SBlue Swirl 
2231a800a2dSRichard Henderson /* 64-bit FP subtraction */
2241a800a2dSRichard Henderson uint64_t HELPER(sdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
225e72ca652SBlue Swirl {
2261a800a2dSRichard Henderson     float64 ret = float64_sub(f1, f2, &env->fpu_status);
2271a800a2dSRichard Henderson     handle_exceptions(env, GETPC());
2281a800a2dSRichard Henderson     return ret;
2291a800a2dSRichard Henderson }
230e72ca652SBlue Swirl 
2311a800a2dSRichard Henderson /* 128-bit FP subtraction */
2321a800a2dSRichard Henderson uint64_t HELPER(sxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
2331a800a2dSRichard Henderson                      uint64_t bh, uint64_t bl)
2341a800a2dSRichard Henderson {
2351a800a2dSRichard Henderson     float128 ret = float128_sub(make_float128(ah, al),
2361a800a2dSRichard Henderson                                 make_float128(bh, bl),
2371a800a2dSRichard Henderson                                 &env->fpu_status);
2381a800a2dSRichard Henderson     handle_exceptions(env, GETPC());
2391a800a2dSRichard Henderson     return RET128(ret);
240e72ca652SBlue Swirl }
241e72ca652SBlue Swirl 
242e72ca652SBlue Swirl /* 32-bit FP division RR */
243449c0d70SBlue Swirl void HELPER(debr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
244e72ca652SBlue Swirl {
245e72ca652SBlue Swirl     env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
246e72ca652SBlue Swirl                                          env->fregs[f2].l.upper,
247e72ca652SBlue Swirl                                          &env->fpu_status);
248e72ca652SBlue Swirl }
249e72ca652SBlue Swirl 
250e72ca652SBlue Swirl /* 128-bit FP division RR */
251449c0d70SBlue Swirl void HELPER(dxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
252e72ca652SBlue Swirl {
253e72ca652SBlue Swirl     CPU_QuadU v1;
254e72ca652SBlue Swirl     CPU_QuadU v2;
255e72ca652SBlue Swirl     CPU_QuadU res;
256e72ca652SBlue Swirl 
257e72ca652SBlue Swirl     v1.ll.upper = env->fregs[f1].ll;
258e72ca652SBlue Swirl     v1.ll.lower = env->fregs[f1 + 2].ll;
259e72ca652SBlue Swirl     v2.ll.upper = env->fregs[f2].ll;
260e72ca652SBlue Swirl     v2.ll.lower = env->fregs[f2 + 2].ll;
261e72ca652SBlue Swirl     res.q = float128_div(v1.q, v2.q, &env->fpu_status);
262e72ca652SBlue Swirl     env->fregs[f1].ll = res.ll.upper;
263e72ca652SBlue Swirl     env->fregs[f1 + 2].ll = res.ll.lower;
264e72ca652SBlue Swirl }
265e72ca652SBlue Swirl 
266e72ca652SBlue Swirl /* 64-bit FP multiplication RR */
267449c0d70SBlue Swirl void HELPER(mdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
268e72ca652SBlue Swirl {
269e72ca652SBlue Swirl     env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d,
270e72ca652SBlue Swirl                                    &env->fpu_status);
271e72ca652SBlue Swirl }
272e72ca652SBlue Swirl 
273e72ca652SBlue Swirl /* 128-bit FP multiplication RR */
274449c0d70SBlue Swirl void HELPER(mxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
275e72ca652SBlue Swirl {
276e72ca652SBlue Swirl     CPU_QuadU v1;
277e72ca652SBlue Swirl     CPU_QuadU v2;
278e72ca652SBlue Swirl     CPU_QuadU res;
279e72ca652SBlue Swirl 
280e72ca652SBlue Swirl     v1.ll.upper = env->fregs[f1].ll;
281e72ca652SBlue Swirl     v1.ll.lower = env->fregs[f1 + 2].ll;
282e72ca652SBlue Swirl     v2.ll.upper = env->fregs[f2].ll;
283e72ca652SBlue Swirl     v2.ll.lower = env->fregs[f2 + 2].ll;
284e72ca652SBlue Swirl     res.q = float128_mul(v1.q, v2.q, &env->fpu_status);
285e72ca652SBlue Swirl     env->fregs[f1].ll = res.ll.upper;
286e72ca652SBlue Swirl     env->fregs[f1 + 2].ll = res.ll.lower;
287e72ca652SBlue Swirl }
288e72ca652SBlue Swirl 
289e72ca652SBlue Swirl /* convert 32-bit float to 64-bit float */
290587626f8SRichard Henderson uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2)
291e72ca652SBlue Swirl {
292587626f8SRichard Henderson     float64 ret = float32_to_float64(f2, &env->fpu_status);
293587626f8SRichard Henderson     handle_exceptions(env, GETPC());
294587626f8SRichard Henderson     return ret;
295e72ca652SBlue Swirl }
296e72ca652SBlue Swirl 
297e72ca652SBlue Swirl /* convert 128-bit float to 64-bit float */
298587626f8SRichard Henderson uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al)
299e72ca652SBlue Swirl {
300587626f8SRichard Henderson     float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status);
301587626f8SRichard Henderson     handle_exceptions(env, GETPC());
302587626f8SRichard Henderson     return ret;
303e72ca652SBlue Swirl }
304e72ca652SBlue Swirl 
305e72ca652SBlue Swirl /* convert 64-bit float to 128-bit float */
306587626f8SRichard Henderson uint64_t HELPER(lxdb)(CPUS390XState *env, uint64_t f2)
307e72ca652SBlue Swirl {
308587626f8SRichard Henderson     float128 ret = float64_to_float128(f2, &env->fpu_status);
309587626f8SRichard Henderson     handle_exceptions(env, GETPC());
310587626f8SRichard Henderson     return RET128(ret);
311587626f8SRichard Henderson }
312e72ca652SBlue Swirl 
313587626f8SRichard Henderson /* convert 32-bit float to 128-bit float */
314587626f8SRichard Henderson uint64_t HELPER(lxeb)(CPUS390XState *env, uint64_t f2)
315587626f8SRichard Henderson {
316587626f8SRichard Henderson     float128 ret = float32_to_float128(f2, &env->fpu_status);
317587626f8SRichard Henderson     handle_exceptions(env, GETPC());
318587626f8SRichard Henderson     return RET128(ret);
319e72ca652SBlue Swirl }
320e72ca652SBlue Swirl 
321e72ca652SBlue Swirl /* convert 64-bit float to 32-bit float */
322587626f8SRichard Henderson uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2)
323e72ca652SBlue Swirl {
324587626f8SRichard Henderson     float32 ret = float64_to_float32(f2, &env->fpu_status);
325587626f8SRichard Henderson     handle_exceptions(env, GETPC());
326587626f8SRichard Henderson     return ret;
327e72ca652SBlue Swirl }
328e72ca652SBlue Swirl 
329e72ca652SBlue Swirl /* convert 128-bit float to 32-bit float */
330587626f8SRichard Henderson uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al)
331e72ca652SBlue Swirl {
332587626f8SRichard Henderson     float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status);
333587626f8SRichard Henderson     handle_exceptions(env, GETPC());
334587626f8SRichard Henderson     return ret;
335e72ca652SBlue Swirl }
336e72ca652SBlue Swirl 
337e72ca652SBlue Swirl /* absolute value of 32-bit float */
338449c0d70SBlue Swirl uint32_t HELPER(lpebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
339e72ca652SBlue Swirl {
340e72ca652SBlue Swirl     float32 v1;
341e72ca652SBlue Swirl     float32 v2 = env->fregs[f2].d;
342e72ca652SBlue Swirl 
343e72ca652SBlue Swirl     v1 = float32_abs(v2);
344e72ca652SBlue Swirl     env->fregs[f1].d = v1;
345e72ca652SBlue Swirl     return set_cc_nz_f32(v1);
346e72ca652SBlue Swirl }
347e72ca652SBlue Swirl 
348e72ca652SBlue Swirl /* absolute value of 64-bit float */
349449c0d70SBlue Swirl uint32_t HELPER(lpdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
350e72ca652SBlue Swirl {
351e72ca652SBlue Swirl     float64 v1;
352e72ca652SBlue Swirl     float64 v2 = env->fregs[f2].d;
353e72ca652SBlue Swirl 
354e72ca652SBlue Swirl     v1 = float64_abs(v2);
355e72ca652SBlue Swirl     env->fregs[f1].d = v1;
356e72ca652SBlue Swirl     return set_cc_nz_f64(v1);
357e72ca652SBlue Swirl }
358e72ca652SBlue Swirl 
359e72ca652SBlue Swirl /* absolute value of 128-bit float */
360449c0d70SBlue Swirl uint32_t HELPER(lpxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
361e72ca652SBlue Swirl {
362e72ca652SBlue Swirl     CPU_QuadU v1;
363e72ca652SBlue Swirl     CPU_QuadU v2;
364e72ca652SBlue Swirl 
365e72ca652SBlue Swirl     v2.ll.upper = env->fregs[f2].ll;
366e72ca652SBlue Swirl     v2.ll.lower = env->fregs[f2 + 2].ll;
367e72ca652SBlue Swirl     v1.q = float128_abs(v2.q);
368e72ca652SBlue Swirl     env->fregs[f1].ll = v1.ll.upper;
369e72ca652SBlue Swirl     env->fregs[f1 + 2].ll = v1.ll.lower;
370e72ca652SBlue Swirl     return set_cc_nz_f128(v1.q);
371e72ca652SBlue Swirl }
372e72ca652SBlue Swirl 
373e72ca652SBlue Swirl /* load complement of 32-bit float */
374449c0d70SBlue Swirl uint32_t HELPER(lcebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
375e72ca652SBlue Swirl {
376e72ca652SBlue Swirl     env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper);
377e72ca652SBlue Swirl 
378e72ca652SBlue Swirl     return set_cc_nz_f32(env->fregs[f1].l.upper);
379e72ca652SBlue Swirl }
380e72ca652SBlue Swirl 
381e72ca652SBlue Swirl /* load complement of 64-bit float */
382449c0d70SBlue Swirl uint32_t HELPER(lcdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
383e72ca652SBlue Swirl {
384e72ca652SBlue Swirl     env->fregs[f1].d = float64_chs(env->fregs[f2].d);
385e72ca652SBlue Swirl 
386e72ca652SBlue Swirl     return set_cc_nz_f64(env->fregs[f1].d);
387e72ca652SBlue Swirl }
388e72ca652SBlue Swirl 
389e72ca652SBlue Swirl /* load complement of 128-bit float */
390449c0d70SBlue Swirl uint32_t HELPER(lcxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
391e72ca652SBlue Swirl {
392e72ca652SBlue Swirl     CPU_QuadU x1, x2;
393e72ca652SBlue Swirl 
394e72ca652SBlue Swirl     x2.ll.upper = env->fregs[f2].ll;
395e72ca652SBlue Swirl     x2.ll.lower = env->fregs[f2 + 2].ll;
396e72ca652SBlue Swirl     x1.q = float128_chs(x2.q);
397e72ca652SBlue Swirl     env->fregs[f1].ll = x1.ll.upper;
398e72ca652SBlue Swirl     env->fregs[f1 + 2].ll = x1.ll.lower;
399e72ca652SBlue Swirl     return set_cc_nz_f128(x1.q);
400e72ca652SBlue Swirl }
401e72ca652SBlue Swirl 
402e72ca652SBlue Swirl /* 32-bit FP division RM */
403449c0d70SBlue Swirl void HELPER(deb)(CPUS390XState *env, uint32_t f1, uint32_t val)
404e72ca652SBlue Swirl {
405e72ca652SBlue Swirl     float32 v1 = env->fregs[f1].l.upper;
406e72ca652SBlue Swirl     CPU_FloatU v2;
407e72ca652SBlue Swirl 
408e72ca652SBlue Swirl     v2.l = val;
409e72ca652SBlue Swirl     HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __func__,
410e72ca652SBlue Swirl                v1, f1, v2.f);
411e72ca652SBlue Swirl     env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
412e72ca652SBlue Swirl }
413e72ca652SBlue Swirl 
414e72ca652SBlue Swirl /* 32-bit FP multiplication RM */
415449c0d70SBlue Swirl void HELPER(meeb)(CPUS390XState *env, uint32_t f1, uint32_t val)
416e72ca652SBlue Swirl {
417e72ca652SBlue Swirl     float32 v1 = env->fregs[f1].l.upper;
418e72ca652SBlue Swirl     CPU_FloatU v2;
419e72ca652SBlue Swirl 
420e72ca652SBlue Swirl     v2.l = val;
421e72ca652SBlue Swirl     HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __func__,
422e72ca652SBlue Swirl                v1, f1, v2.f);
423e72ca652SBlue Swirl     env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status);
424e72ca652SBlue Swirl }
425e72ca652SBlue Swirl 
426587626f8SRichard Henderson /* 32-bit FP compare */
427587626f8SRichard Henderson uint32_t HELPER(ceb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
428e72ca652SBlue Swirl {
429587626f8SRichard Henderson     int cmp = float32_compare_quiet(f1, f2, &env->fpu_status);
430587626f8SRichard Henderson     handle_exceptions(env, GETPC());
431587626f8SRichard Henderson     return float_comp_to_cc(env, cmp);
432e72ca652SBlue Swirl }
433e72ca652SBlue Swirl 
434587626f8SRichard Henderson /* 64-bit FP compare */
435587626f8SRichard Henderson uint32_t HELPER(cdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
436e72ca652SBlue Swirl {
437587626f8SRichard Henderson     int cmp = float64_compare_quiet(f1, f2, &env->fpu_status);
438587626f8SRichard Henderson     handle_exceptions(env, GETPC());
439587626f8SRichard Henderson     return float_comp_to_cc(env, cmp);
440e72ca652SBlue Swirl }
441e72ca652SBlue Swirl 
442587626f8SRichard Henderson /* 128-bit FP compare */
443587626f8SRichard Henderson uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
444587626f8SRichard Henderson                      uint64_t bh, uint64_t bl)
445e72ca652SBlue Swirl {
446587626f8SRichard Henderson     int cmp = float128_compare_quiet(make_float128(ah, al),
447587626f8SRichard Henderson                                      make_float128(bh, bl),
448587626f8SRichard Henderson                                      &env->fpu_status);
449587626f8SRichard Henderson     handle_exceptions(env, GETPC());
450587626f8SRichard Henderson     return float_comp_to_cc(env, cmp);
451e72ca652SBlue Swirl }
452e72ca652SBlue Swirl 
453e72ca652SBlue Swirl /* 64-bit FP multiplication RM */
454449c0d70SBlue Swirl void HELPER(mdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
455e72ca652SBlue Swirl {
456e72ca652SBlue Swirl     float64 v1 = env->fregs[f1].d;
457e72ca652SBlue Swirl     CPU_DoubleU v2;
458e72ca652SBlue Swirl 
459449c0d70SBlue Swirl     v2.ll = cpu_ldq_data(env, a2);
460e72ca652SBlue Swirl     HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
461e72ca652SBlue Swirl                v1, f1, v2.d);
462e72ca652SBlue Swirl     env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
463e72ca652SBlue Swirl }
464e72ca652SBlue Swirl 
465e72ca652SBlue Swirl /* 64-bit FP division RM */
466449c0d70SBlue Swirl void HELPER(ddb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
467e72ca652SBlue Swirl {
468e72ca652SBlue Swirl     float64 v1 = env->fregs[f1].d;
469e72ca652SBlue Swirl     CPU_DoubleU v2;
470e72ca652SBlue Swirl 
471449c0d70SBlue Swirl     v2.ll = cpu_ldq_data(env, a2);
472e72ca652SBlue Swirl     HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
473e72ca652SBlue Swirl                v1, f1, v2.d);
474e72ca652SBlue Swirl     env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
475e72ca652SBlue Swirl }
476e72ca652SBlue Swirl 
477449c0d70SBlue Swirl static void set_round_mode(CPUS390XState *env, int m3)
478e72ca652SBlue Swirl {
479e72ca652SBlue Swirl     switch (m3) {
480e72ca652SBlue Swirl     case 0:
481e72ca652SBlue Swirl         /* current mode */
482e72ca652SBlue Swirl         break;
483e72ca652SBlue Swirl     case 1:
484e72ca652SBlue Swirl         /* biased round no nearest */
485e72ca652SBlue Swirl     case 4:
486e72ca652SBlue Swirl         /* round to nearest */
487e72ca652SBlue Swirl         set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
488e72ca652SBlue Swirl         break;
489e72ca652SBlue Swirl     case 5:
490e72ca652SBlue Swirl         /* round to zero */
491e72ca652SBlue Swirl         set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
492e72ca652SBlue Swirl         break;
493e72ca652SBlue Swirl     case 6:
494e72ca652SBlue Swirl         /* round to +inf */
495e72ca652SBlue Swirl         set_float_rounding_mode(float_round_up, &env->fpu_status);
496e72ca652SBlue Swirl         break;
497e72ca652SBlue Swirl     case 7:
498e72ca652SBlue Swirl         /* round to -inf */
499e72ca652SBlue Swirl         set_float_rounding_mode(float_round_down, &env->fpu_status);
500e72ca652SBlue Swirl         break;
501e72ca652SBlue Swirl     }
502e72ca652SBlue Swirl }
503e72ca652SBlue Swirl 
504e72ca652SBlue Swirl /* convert 32-bit float to 64-bit int */
505449c0d70SBlue Swirl uint32_t HELPER(cgebr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
506449c0d70SBlue Swirl                        uint32_t m3)
507e72ca652SBlue Swirl {
508e72ca652SBlue Swirl     float32 v2 = env->fregs[f2].l.upper;
509e72ca652SBlue Swirl 
510449c0d70SBlue Swirl     set_round_mode(env, m3);
511e72ca652SBlue Swirl     env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
512e72ca652SBlue Swirl     return set_cc_nz_f32(v2);
513e72ca652SBlue Swirl }
514e72ca652SBlue Swirl 
515e72ca652SBlue Swirl /* convert 64-bit float to 64-bit int */
516449c0d70SBlue Swirl uint32_t HELPER(cgdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
517449c0d70SBlue Swirl                        uint32_t m3)
518e72ca652SBlue Swirl {
519e72ca652SBlue Swirl     float64 v2 = env->fregs[f2].d;
520e72ca652SBlue Swirl 
521449c0d70SBlue Swirl     set_round_mode(env, m3);
522e72ca652SBlue Swirl     env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
523e72ca652SBlue Swirl     return set_cc_nz_f64(v2);
524e72ca652SBlue Swirl }
525e72ca652SBlue Swirl 
526e72ca652SBlue Swirl /* convert 128-bit float to 64-bit int */
527449c0d70SBlue Swirl uint32_t HELPER(cgxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
528449c0d70SBlue Swirl                        uint32_t m3)
529e72ca652SBlue Swirl {
530e72ca652SBlue Swirl     CPU_QuadU v2;
531e72ca652SBlue Swirl 
532e72ca652SBlue Swirl     v2.ll.upper = env->fregs[f2].ll;
533e72ca652SBlue Swirl     v2.ll.lower = env->fregs[f2 + 2].ll;
534449c0d70SBlue Swirl     set_round_mode(env, m3);
535e72ca652SBlue Swirl     env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status);
536e72ca652SBlue Swirl     if (float128_is_any_nan(v2.q)) {
537e72ca652SBlue Swirl         return 3;
538e72ca652SBlue Swirl     } else if (float128_is_zero(v2.q)) {
539e72ca652SBlue Swirl         return 0;
540e72ca652SBlue Swirl     } else if (float128_is_neg(v2.q)) {
541e72ca652SBlue Swirl         return 1;
542e72ca652SBlue Swirl     } else {
543e72ca652SBlue Swirl         return 2;
544e72ca652SBlue Swirl     }
545e72ca652SBlue Swirl }
546e72ca652SBlue Swirl 
547e72ca652SBlue Swirl /* convert 32-bit float to 32-bit int */
548449c0d70SBlue Swirl uint32_t HELPER(cfebr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
549449c0d70SBlue Swirl                        uint32_t m3)
550e72ca652SBlue Swirl {
551e72ca652SBlue Swirl     float32 v2 = env->fregs[f2].l.upper;
552e72ca652SBlue Swirl 
553449c0d70SBlue Swirl     set_round_mode(env, m3);
554e72ca652SBlue Swirl     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
555e72ca652SBlue Swirl         float32_to_int32(v2, &env->fpu_status);
556e72ca652SBlue Swirl     return set_cc_nz_f32(v2);
557e72ca652SBlue Swirl }
558e72ca652SBlue Swirl 
559e72ca652SBlue Swirl /* convert 64-bit float to 32-bit int */
560449c0d70SBlue Swirl uint32_t HELPER(cfdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
561449c0d70SBlue Swirl                        uint32_t m3)
562e72ca652SBlue Swirl {
563e72ca652SBlue Swirl     float64 v2 = env->fregs[f2].d;
564e72ca652SBlue Swirl 
565449c0d70SBlue Swirl     set_round_mode(env, m3);
566e72ca652SBlue Swirl     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
567e72ca652SBlue Swirl         float64_to_int32(v2, &env->fpu_status);
568e72ca652SBlue Swirl     return set_cc_nz_f64(v2);
569e72ca652SBlue Swirl }
570e72ca652SBlue Swirl 
571e72ca652SBlue Swirl /* convert 128-bit float to 32-bit int */
572449c0d70SBlue Swirl uint32_t HELPER(cfxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
573449c0d70SBlue Swirl                        uint32_t m3)
574e72ca652SBlue Swirl {
575e72ca652SBlue Swirl     CPU_QuadU v2;
576e72ca652SBlue Swirl 
577e72ca652SBlue Swirl     v2.ll.upper = env->fregs[f2].ll;
578e72ca652SBlue Swirl     v2.ll.lower = env->fregs[f2 + 2].ll;
579e72ca652SBlue Swirl     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
580e72ca652SBlue Swirl         float128_to_int32(v2.q, &env->fpu_status);
581e72ca652SBlue Swirl     return set_cc_nz_f128(v2.q);
582e72ca652SBlue Swirl }
583e72ca652SBlue Swirl 
584e72ca652SBlue Swirl /* load 32-bit FP zero */
585449c0d70SBlue Swirl void HELPER(lzer)(CPUS390XState *env, uint32_t f1)
586e72ca652SBlue Swirl {
587e72ca652SBlue Swirl     env->fregs[f1].l.upper = float32_zero;
588e72ca652SBlue Swirl }
589e72ca652SBlue Swirl 
590e72ca652SBlue Swirl /* load 64-bit FP zero */
591449c0d70SBlue Swirl void HELPER(lzdr)(CPUS390XState *env, uint32_t f1)
592e72ca652SBlue Swirl {
593e72ca652SBlue Swirl     env->fregs[f1].d = float64_zero;
594e72ca652SBlue Swirl }
595e72ca652SBlue Swirl 
596e72ca652SBlue Swirl /* load 128-bit FP zero */
597449c0d70SBlue Swirl void HELPER(lzxr)(CPUS390XState *env, uint32_t f1)
598e72ca652SBlue Swirl {
599e72ca652SBlue Swirl     CPU_QuadU x;
600e72ca652SBlue Swirl 
601e72ca652SBlue Swirl     x.q = float64_to_float128(float64_zero, &env->fpu_status);
602e72ca652SBlue Swirl     env->fregs[f1].ll = x.ll.upper;
603e72ca652SBlue Swirl     env->fregs[f1 + 1].ll = x.ll.lower;
604e72ca652SBlue Swirl }
605e72ca652SBlue Swirl 
606e72ca652SBlue Swirl /* 32-bit FP multiplication RR */
607449c0d70SBlue Swirl void HELPER(meebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
608e72ca652SBlue Swirl {
609e72ca652SBlue Swirl     env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper,
610e72ca652SBlue Swirl                                          env->fregs[f2].l.upper,
611e72ca652SBlue Swirl                                          &env->fpu_status);
612e72ca652SBlue Swirl }
613e72ca652SBlue Swirl 
614e72ca652SBlue Swirl /* 64-bit FP division RR */
615449c0d70SBlue Swirl void HELPER(ddbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
616e72ca652SBlue Swirl {
617e72ca652SBlue Swirl     env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d,
618e72ca652SBlue Swirl                                    &env->fpu_status);
619e72ca652SBlue Swirl }
620e72ca652SBlue Swirl 
621e72ca652SBlue Swirl /* 64-bit FP multiply and add RM */
622449c0d70SBlue Swirl void HELPER(madb)(CPUS390XState *env, uint32_t f1, uint64_t a2, uint32_t f3)
623e72ca652SBlue Swirl {
624e72ca652SBlue Swirl     CPU_DoubleU v2;
625e72ca652SBlue Swirl 
626e72ca652SBlue Swirl     HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
627449c0d70SBlue Swirl     v2.ll = cpu_ldq_data(env, a2);
628e72ca652SBlue Swirl     env->fregs[f1].d = float64_add(env->fregs[f1].d,
629e72ca652SBlue Swirl                                    float64_mul(v2.d, env->fregs[f3].d,
630e72ca652SBlue Swirl                                                &env->fpu_status),
631e72ca652SBlue Swirl                                    &env->fpu_status);
632e72ca652SBlue Swirl }
633e72ca652SBlue Swirl 
634e72ca652SBlue Swirl /* 64-bit FP multiply and add RR */
635449c0d70SBlue Swirl void HELPER(madbr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
636e72ca652SBlue Swirl {
637e72ca652SBlue Swirl     HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
638e72ca652SBlue Swirl     env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
639e72ca652SBlue Swirl                                                env->fregs[f3].d,
640e72ca652SBlue Swirl                                                &env->fpu_status),
641e72ca652SBlue Swirl                                    env->fregs[f1].d, &env->fpu_status);
642e72ca652SBlue Swirl }
643e72ca652SBlue Swirl 
644e72ca652SBlue Swirl /* 64-bit FP multiply and subtract RR */
645449c0d70SBlue Swirl void HELPER(msdbr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
646e72ca652SBlue Swirl {
647e72ca652SBlue Swirl     HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
648e72ca652SBlue Swirl     env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
649e72ca652SBlue Swirl                                                env->fregs[f3].d,
650e72ca652SBlue Swirl                                                &env->fpu_status),
651e72ca652SBlue Swirl                                    env->fregs[f1].d, &env->fpu_status);
652e72ca652SBlue Swirl }
653e72ca652SBlue Swirl 
654e72ca652SBlue Swirl /* 32-bit FP multiply and add RR */
655449c0d70SBlue Swirl void HELPER(maebr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
656e72ca652SBlue Swirl {
657e72ca652SBlue Swirl     env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
658e72ca652SBlue Swirl                                          float32_mul(env->fregs[f2].l.upper,
659e72ca652SBlue Swirl                                                      env->fregs[f3].l.upper,
660e72ca652SBlue Swirl                                                      &env->fpu_status),
661e72ca652SBlue Swirl                                          &env->fpu_status);
662e72ca652SBlue Swirl }
663e72ca652SBlue Swirl 
664e72ca652SBlue Swirl /* test data class 32-bit */
665449c0d70SBlue Swirl uint32_t HELPER(tceb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
666e72ca652SBlue Swirl {
667e72ca652SBlue Swirl     float32 v1 = env->fregs[f1].l.upper;
668e72ca652SBlue Swirl     int neg = float32_is_neg(v1);
669e72ca652SBlue Swirl     uint32_t cc = 0;
670e72ca652SBlue Swirl 
671e72ca652SBlue Swirl     HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg);
672e72ca652SBlue Swirl     if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
673e72ca652SBlue Swirl         (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
674e72ca652SBlue Swirl         (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
675e72ca652SBlue Swirl         (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
676e72ca652SBlue Swirl         cc = 1;
677e72ca652SBlue Swirl     } else if (m2 & (1 << (9-neg))) {
678e72ca652SBlue Swirl         /* assume normalized number */
679e72ca652SBlue Swirl         cc = 1;
680e72ca652SBlue Swirl     }
681e72ca652SBlue Swirl 
682e72ca652SBlue Swirl     /* FIXME: denormalized? */
683e72ca652SBlue Swirl     return cc;
684e72ca652SBlue Swirl }
685e72ca652SBlue Swirl 
686e72ca652SBlue Swirl /* test data class 64-bit */
687449c0d70SBlue Swirl uint32_t HELPER(tcdb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
688e72ca652SBlue Swirl {
689e72ca652SBlue Swirl     float64 v1 = env->fregs[f1].d;
690e72ca652SBlue Swirl     int neg = float64_is_neg(v1);
691e72ca652SBlue Swirl     uint32_t cc = 0;
692e72ca652SBlue Swirl 
693e72ca652SBlue Swirl     HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, v1, m2, neg);
694e72ca652SBlue Swirl     if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
695e72ca652SBlue Swirl         (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
696e72ca652SBlue Swirl         (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
697e72ca652SBlue Swirl         (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
698e72ca652SBlue Swirl         cc = 1;
699e72ca652SBlue Swirl     } else if (m2 & (1 << (9-neg))) {
700e72ca652SBlue Swirl         /* assume normalized number */
701e72ca652SBlue Swirl         cc = 1;
702e72ca652SBlue Swirl     }
703e72ca652SBlue Swirl     /* FIXME: denormalized? */
704e72ca652SBlue Swirl     return cc;
705e72ca652SBlue Swirl }
706e72ca652SBlue Swirl 
707e72ca652SBlue Swirl /* test data class 128-bit */
708449c0d70SBlue Swirl uint32_t HELPER(tcxb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
709e72ca652SBlue Swirl {
710e72ca652SBlue Swirl     CPU_QuadU v1;
711e72ca652SBlue Swirl     uint32_t cc = 0;
712e72ca652SBlue Swirl     int neg;
713e72ca652SBlue Swirl 
714e72ca652SBlue Swirl     v1.ll.upper = env->fregs[f1].ll;
715e72ca652SBlue Swirl     v1.ll.lower = env->fregs[f1 + 2].ll;
716e72ca652SBlue Swirl 
717e72ca652SBlue Swirl     neg = float128_is_neg(v1.q);
718e72ca652SBlue Swirl     if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) ||
719e72ca652SBlue Swirl         (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) ||
720e72ca652SBlue Swirl         (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) ||
721e72ca652SBlue Swirl         (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg))))) {
722e72ca652SBlue Swirl         cc = 1;
723e72ca652SBlue Swirl     } else if (m2 & (1 << (9-neg))) {
724e72ca652SBlue Swirl         /* assume normalized number */
725e72ca652SBlue Swirl         cc = 1;
726e72ca652SBlue Swirl     }
727e72ca652SBlue Swirl     /* FIXME: denormalized? */
728e72ca652SBlue Swirl     return cc;
729e72ca652SBlue Swirl }
730e72ca652SBlue Swirl 
731e72ca652SBlue Swirl /* square root 64-bit RR */
732449c0d70SBlue Swirl void HELPER(sqdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
733e72ca652SBlue Swirl {
734e72ca652SBlue Swirl     env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
735e72ca652SBlue Swirl }
736