root / target-s390x / fpu_helper.c @ f08a5c31
History | View | Annotate | Download (20.4 kB)
1 | e72ca652 | Blue Swirl | /*
|
---|---|---|---|
2 | e72ca652 | Blue Swirl | * S/390 FPU helper routines
|
3 | e72ca652 | Blue Swirl | *
|
4 | e72ca652 | Blue Swirl | * Copyright (c) 2009 Ulrich Hecht
|
5 | e72ca652 | Blue Swirl | * Copyright (c) 2009 Alexander Graf
|
6 | e72ca652 | Blue Swirl | *
|
7 | e72ca652 | Blue Swirl | * This library is free software; you can redistribute it and/or
|
8 | e72ca652 | Blue Swirl | * modify it under the terms of the GNU Lesser General Public
|
9 | e72ca652 | Blue Swirl | * License as published by the Free Software Foundation; either
|
10 | e72ca652 | Blue Swirl | * version 2 of the License, or (at your option) any later version.
|
11 | e72ca652 | Blue Swirl | *
|
12 | e72ca652 | Blue Swirl | * This library is distributed in the hope that it will be useful,
|
13 | e72ca652 | Blue Swirl | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | e72ca652 | Blue Swirl | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 | e72ca652 | Blue Swirl | * Lesser General Public License for more details.
|
16 | e72ca652 | Blue Swirl | *
|
17 | e72ca652 | Blue Swirl | * You should have received a copy of the GNU Lesser General Public
|
18 | e72ca652 | Blue Swirl | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
19 | e72ca652 | Blue Swirl | */
|
20 | e72ca652 | Blue Swirl | |
21 | e72ca652 | Blue Swirl | #include "cpu.h" |
22 | e72ca652 | Blue Swirl | #include "helper.h" |
23 | e72ca652 | Blue Swirl | |
24 | 19b0516f | Blue Swirl | #if !defined(CONFIG_USER_ONLY)
|
25 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_exec.h" |
26 | e72ca652 | Blue Swirl | #endif
|
27 | e72ca652 | Blue Swirl | |
28 | e72ca652 | Blue Swirl | /* #define DEBUG_HELPER */
|
29 | e72ca652 | Blue Swirl | #ifdef DEBUG_HELPER
|
30 | e72ca652 | Blue Swirl | #define HELPER_LOG(x...) qemu_log(x)
|
31 | e72ca652 | Blue Swirl | #else
|
32 | e72ca652 | Blue Swirl | #define HELPER_LOG(x...)
|
33 | e72ca652 | Blue Swirl | #endif
|
34 | e72ca652 | Blue Swirl | |
35 | 587626f8 | Richard Henderson | #define RET128(F) (env->retxl = F.low, F.high)
|
36 | 587626f8 | Richard Henderson | |
37 | 587626f8 | Richard Henderson | #define convert_bit(mask, from, to) \
|
38 | 587626f8 | Richard Henderson | (to < from \ |
39 | 587626f8 | Richard Henderson | ? (mask / (from / to)) & to \ |
40 | 587626f8 | Richard Henderson | : (mask & from) * (to / from)) |
41 | 587626f8 | Richard Henderson | |
42 | 587626f8 | Richard Henderson | static void ieee_exception(CPUS390XState *env, uint32_t dxc, uintptr_t retaddr) |
43 | 587626f8 | Richard Henderson | { |
44 | 587626f8 | Richard Henderson | /* Install the DXC code. */
|
45 | 587626f8 | Richard Henderson | env->fpc = (env->fpc & ~0xff00) | (dxc << 8); |
46 | 587626f8 | Richard Henderson | /* Trap. */
|
47 | 587626f8 | Richard Henderson | runtime_exception(env, PGM_DATA, retaddr); |
48 | 587626f8 | Richard Henderson | } |
49 | 587626f8 | Richard Henderson | |
50 | 587626f8 | Richard Henderson | /* Should be called after any operation that may raise IEEE exceptions. */
|
51 | 587626f8 | Richard Henderson | static void handle_exceptions(CPUS390XState *env, uintptr_t retaddr) |
52 | 587626f8 | Richard Henderson | { |
53 | 587626f8 | Richard Henderson | unsigned s390_exc, qemu_exc;
|
54 | 587626f8 | Richard Henderson | |
55 | 587626f8 | Richard Henderson | /* Get the exceptions raised by the current operation. Reset the
|
56 | 587626f8 | Richard Henderson | fpu_status contents so that the next operation has a clean slate. */
|
57 | 587626f8 | Richard Henderson | qemu_exc = env->fpu_status.float_exception_flags; |
58 | 587626f8 | Richard Henderson | if (qemu_exc == 0) { |
59 | 587626f8 | Richard Henderson | return;
|
60 | 587626f8 | Richard Henderson | } |
61 | 587626f8 | Richard Henderson | env->fpu_status.float_exception_flags = 0;
|
62 | 587626f8 | Richard Henderson | |
63 | 587626f8 | Richard Henderson | /* Convert softfloat exception bits to s390 exception bits. */
|
64 | 587626f8 | Richard Henderson | s390_exc = 0;
|
65 | 587626f8 | Richard Henderson | s390_exc |= convert_bit(qemu_exc, float_flag_invalid, 0x80);
|
66 | 587626f8 | Richard Henderson | s390_exc |= convert_bit(qemu_exc, float_flag_divbyzero, 0x40);
|
67 | 587626f8 | Richard Henderson | s390_exc |= convert_bit(qemu_exc, float_flag_overflow, 0x20);
|
68 | 587626f8 | Richard Henderson | s390_exc |= convert_bit(qemu_exc, float_flag_underflow, 0x10);
|
69 | 587626f8 | Richard Henderson | s390_exc |= convert_bit(qemu_exc, float_flag_inexact, 0x08);
|
70 | 587626f8 | Richard Henderson | |
71 | 587626f8 | Richard Henderson | /* Install the exceptions that we raised. */
|
72 | 587626f8 | Richard Henderson | env->fpc |= s390_exc << 16;
|
73 | 587626f8 | Richard Henderson | |
74 | 587626f8 | Richard Henderson | /* Send signals for enabled exceptions. */
|
75 | 587626f8 | Richard Henderson | s390_exc &= env->fpc >> 24;
|
76 | 587626f8 | Richard Henderson | if (s390_exc) {
|
77 | 587626f8 | Richard Henderson | ieee_exception(env, s390_exc, retaddr); |
78 | 587626f8 | Richard Henderson | } |
79 | 587626f8 | Richard Henderson | } |
80 | 587626f8 | Richard Henderson | |
81 | 449c0d70 | Blue Swirl | static inline int float_comp_to_cc(CPUS390XState *env, int float_compare) |
82 | e72ca652 | Blue Swirl | { |
83 | e72ca652 | Blue Swirl | switch (float_compare) {
|
84 | e72ca652 | Blue Swirl | case float_relation_equal:
|
85 | e72ca652 | Blue Swirl | return 0; |
86 | e72ca652 | Blue Swirl | case float_relation_less:
|
87 | e72ca652 | Blue Swirl | return 1; |
88 | e72ca652 | Blue Swirl | case float_relation_greater:
|
89 | e72ca652 | Blue Swirl | return 2; |
90 | e72ca652 | Blue Swirl | case float_relation_unordered:
|
91 | e72ca652 | Blue Swirl | return 3; |
92 | e72ca652 | Blue Swirl | default:
|
93 | e72ca652 | Blue Swirl | cpu_abort(env, "unknown return value for float compare\n");
|
94 | e72ca652 | Blue Swirl | } |
95 | e72ca652 | Blue Swirl | } |
96 | e72ca652 | Blue Swirl | |
97 | e72ca652 | Blue Swirl | /* condition codes for unary FP ops */
|
98 | e72ca652 | Blue Swirl | uint32_t set_cc_nz_f32(float32 v) |
99 | e72ca652 | Blue Swirl | { |
100 | e72ca652 | Blue Swirl | if (float32_is_any_nan(v)) {
|
101 | e72ca652 | Blue Swirl | return 3; |
102 | e72ca652 | Blue Swirl | } else if (float32_is_zero(v)) { |
103 | e72ca652 | Blue Swirl | return 0; |
104 | e72ca652 | Blue Swirl | } else if (float32_is_neg(v)) { |
105 | e72ca652 | Blue Swirl | return 1; |
106 | e72ca652 | Blue Swirl | } else {
|
107 | e72ca652 | Blue Swirl | return 2; |
108 | e72ca652 | Blue Swirl | } |
109 | e72ca652 | Blue Swirl | } |
110 | e72ca652 | Blue Swirl | |
111 | e72ca652 | Blue Swirl | uint32_t set_cc_nz_f64(float64 v) |
112 | e72ca652 | Blue Swirl | { |
113 | e72ca652 | Blue Swirl | if (float64_is_any_nan(v)) {
|
114 | e72ca652 | Blue Swirl | return 3; |
115 | e72ca652 | Blue Swirl | } else if (float64_is_zero(v)) { |
116 | e72ca652 | Blue Swirl | return 0; |
117 | e72ca652 | Blue Swirl | } else if (float64_is_neg(v)) { |
118 | e72ca652 | Blue Swirl | return 1; |
119 | e72ca652 | Blue Swirl | } else {
|
120 | e72ca652 | Blue Swirl | return 2; |
121 | e72ca652 | Blue Swirl | } |
122 | e72ca652 | Blue Swirl | } |
123 | e72ca652 | Blue Swirl | |
124 | 587626f8 | Richard Henderson | uint32_t set_cc_nz_f128(float128 v) |
125 | e72ca652 | Blue Swirl | { |
126 | e72ca652 | Blue Swirl | if (float128_is_any_nan(v)) {
|
127 | e72ca652 | Blue Swirl | return 3; |
128 | e72ca652 | Blue Swirl | } else if (float128_is_zero(v)) { |
129 | e72ca652 | Blue Swirl | return 0; |
130 | e72ca652 | Blue Swirl | } else if (float128_is_neg(v)) { |
131 | e72ca652 | Blue Swirl | return 1; |
132 | e72ca652 | Blue Swirl | } else {
|
133 | e72ca652 | Blue Swirl | return 2; |
134 | e72ca652 | Blue Swirl | } |
135 | e72ca652 | Blue Swirl | } |
136 | e72ca652 | Blue Swirl | |
137 | e72ca652 | Blue Swirl | /* convert 32-bit int to 64-bit float */
|
138 | 449c0d70 | Blue Swirl | void HELPER(cdfbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
|
139 | e72ca652 | Blue Swirl | { |
140 | e72ca652 | Blue Swirl | HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
|
141 | e72ca652 | Blue Swirl | env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status); |
142 | e72ca652 | Blue Swirl | } |
143 | e72ca652 | Blue Swirl | |
144 | e72ca652 | Blue Swirl | /* convert 32-bit int to 128-bit float */
|
145 | 449c0d70 | Blue Swirl | void HELPER(cxfbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
|
146 | e72ca652 | Blue Swirl | { |
147 | e72ca652 | Blue Swirl | CPU_QuadU v1; |
148 | e72ca652 | Blue Swirl | |
149 | e72ca652 | Blue Swirl | v1.q = int32_to_float128(v2, &env->fpu_status); |
150 | e72ca652 | Blue Swirl | env->fregs[f1].ll = v1.ll.upper; |
151 | e72ca652 | Blue Swirl | env->fregs[f1 + 2].ll = v1.ll.lower;
|
152 | e72ca652 | Blue Swirl | } |
153 | e72ca652 | Blue Swirl | |
154 | e72ca652 | Blue Swirl | /* convert 64-bit int to 32-bit float */
|
155 | 449c0d70 | Blue Swirl | void HELPER(cegbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
|
156 | e72ca652 | Blue Swirl | { |
157 | e72ca652 | Blue Swirl | HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
|
158 | e72ca652 | Blue Swirl | env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status); |
159 | e72ca652 | Blue Swirl | } |
160 | e72ca652 | Blue Swirl | |
161 | e72ca652 | Blue Swirl | /* convert 64-bit int to 64-bit float */
|
162 | 449c0d70 | Blue Swirl | void HELPER(cdgbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
|
163 | e72ca652 | Blue Swirl | { |
164 | e72ca652 | Blue Swirl | HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
|
165 | e72ca652 | Blue Swirl | env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status); |
166 | e72ca652 | Blue Swirl | } |
167 | e72ca652 | Blue Swirl | |
168 | e72ca652 | Blue Swirl | /* convert 64-bit int to 128-bit float */
|
169 | 449c0d70 | Blue Swirl | void HELPER(cxgbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
|
170 | e72ca652 | Blue Swirl | { |
171 | e72ca652 | Blue Swirl | CPU_QuadU x1; |
172 | e72ca652 | Blue Swirl | |
173 | e72ca652 | Blue Swirl | x1.q = int64_to_float128(v2, &env->fpu_status); |
174 | e72ca652 | Blue Swirl | HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __func__, v2,
|
175 | e72ca652 | Blue Swirl | x1.ll.upper, x1.ll.lower); |
176 | e72ca652 | Blue Swirl | env->fregs[f1].ll = x1.ll.upper; |
177 | e72ca652 | Blue Swirl | env->fregs[f1 + 2].ll = x1.ll.lower;
|
178 | e72ca652 | Blue Swirl | } |
179 | e72ca652 | Blue Swirl | |
180 | e72ca652 | Blue Swirl | /* convert 32-bit int to 32-bit float */
|
181 | 449c0d70 | Blue Swirl | void HELPER(cefbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
|
182 | e72ca652 | Blue Swirl | { |
183 | e72ca652 | Blue Swirl | env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status); |
184 | e72ca652 | Blue Swirl | HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
|
185 | e72ca652 | Blue Swirl | env->fregs[f1].l.upper, f1); |
186 | e72ca652 | Blue Swirl | } |
187 | e72ca652 | Blue Swirl | |
188 | 587626f8 | Richard Henderson | /* 32-bit FP addition */
|
189 | 587626f8 | Richard Henderson | uint64_t HELPER(aeb)(CPUS390XState *env, uint64_t f1, uint64_t f2) |
190 | e72ca652 | Blue Swirl | { |
191 | 587626f8 | Richard Henderson | float32 ret = float32_add(f1, f2, &env->fpu_status); |
192 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
193 | 587626f8 | Richard Henderson | return ret;
|
194 | e72ca652 | Blue Swirl | } |
195 | e72ca652 | Blue Swirl | |
196 | 587626f8 | Richard Henderson | /* 64-bit FP addition */
|
197 | 587626f8 | Richard Henderson | uint64_t HELPER(adb)(CPUS390XState *env, uint64_t f1, uint64_t f2) |
198 | e72ca652 | Blue Swirl | { |
199 | 587626f8 | Richard Henderson | float64 ret = float64_add(f1, f2, &env->fpu_status); |
200 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
201 | 587626f8 | Richard Henderson | return ret;
|
202 | 587626f8 | Richard Henderson | } |
203 | e72ca652 | Blue Swirl | |
204 | 587626f8 | Richard Henderson | /* 128-bit FP addition */
|
205 | 587626f8 | Richard Henderson | uint64_t HELPER(axb)(CPUS390XState *env, uint64_t ah, uint64_t al, |
206 | 587626f8 | Richard Henderson | uint64_t bh, uint64_t bl) |
207 | 587626f8 | Richard Henderson | { |
208 | 587626f8 | Richard Henderson | float128 ret = float128_add(make_float128(ah, al), |
209 | 587626f8 | Richard Henderson | make_float128(bh, bl), |
210 | 587626f8 | Richard Henderson | &env->fpu_status); |
211 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
212 | 587626f8 | Richard Henderson | return RET128(ret);
|
213 | e72ca652 | Blue Swirl | } |
214 | e72ca652 | Blue Swirl | |
215 | 1a800a2d | Richard Henderson | /* 32-bit FP subtraction */
|
216 | 1a800a2d | Richard Henderson | uint64_t HELPER(seb)(CPUS390XState *env, uint64_t f1, uint64_t f2) |
217 | e72ca652 | Blue Swirl | { |
218 | 1a800a2d | Richard Henderson | float32 ret = float32_sub(f1, f2, &env->fpu_status); |
219 | 1a800a2d | Richard Henderson | handle_exceptions(env, GETPC()); |
220 | 1a800a2d | Richard Henderson | return ret;
|
221 | e72ca652 | Blue Swirl | } |
222 | e72ca652 | Blue Swirl | |
223 | 1a800a2d | Richard Henderson | /* 64-bit FP subtraction */
|
224 | 1a800a2d | Richard Henderson | uint64_t HELPER(sdb)(CPUS390XState *env, uint64_t f1, uint64_t f2) |
225 | e72ca652 | Blue Swirl | { |
226 | 1a800a2d | Richard Henderson | float64 ret = float64_sub(f1, f2, &env->fpu_status); |
227 | 1a800a2d | Richard Henderson | handle_exceptions(env, GETPC()); |
228 | 1a800a2d | Richard Henderson | return ret;
|
229 | 1a800a2d | Richard Henderson | } |
230 | e72ca652 | Blue Swirl | |
231 | 1a800a2d | Richard Henderson | /* 128-bit FP subtraction */
|
232 | 1a800a2d | Richard Henderson | uint64_t HELPER(sxb)(CPUS390XState *env, uint64_t ah, uint64_t al, |
233 | 1a800a2d | Richard Henderson | uint64_t bh, uint64_t bl) |
234 | 1a800a2d | Richard Henderson | { |
235 | 1a800a2d | Richard Henderson | float128 ret = float128_sub(make_float128(ah, al), |
236 | 1a800a2d | Richard Henderson | make_float128(bh, bl), |
237 | 1a800a2d | Richard Henderson | &env->fpu_status); |
238 | 1a800a2d | Richard Henderson | handle_exceptions(env, GETPC()); |
239 | 1a800a2d | Richard Henderson | return RET128(ret);
|
240 | e72ca652 | Blue Swirl | } |
241 | e72ca652 | Blue Swirl | |
242 | f08a5c31 | Richard Henderson | /* 32-bit FP division */
|
243 | f08a5c31 | Richard Henderson | uint64_t HELPER(deb)(CPUS390XState *env, uint64_t f1, uint64_t f2) |
244 | e72ca652 | Blue Swirl | { |
245 | f08a5c31 | Richard Henderson | float32 ret = float32_div(f1, f2, &env->fpu_status); |
246 | f08a5c31 | Richard Henderson | handle_exceptions(env, GETPC()); |
247 | f08a5c31 | Richard Henderson | return ret;
|
248 | e72ca652 | Blue Swirl | } |
249 | e72ca652 | Blue Swirl | |
250 | f08a5c31 | Richard Henderson | /* 64-bit FP division */
|
251 | f08a5c31 | Richard Henderson | uint64_t HELPER(ddb)(CPUS390XState *env, uint64_t f1, uint64_t f2) |
252 | e72ca652 | Blue Swirl | { |
253 | f08a5c31 | Richard Henderson | float64 ret = float64_div(f1, f2, &env->fpu_status); |
254 | f08a5c31 | Richard Henderson | handle_exceptions(env, GETPC()); |
255 | f08a5c31 | Richard Henderson | return ret;
|
256 | f08a5c31 | Richard Henderson | } |
257 | e72ca652 | Blue Swirl | |
258 | f08a5c31 | Richard Henderson | /* 128-bit FP division */
|
259 | f08a5c31 | Richard Henderson | uint64_t HELPER(dxb)(CPUS390XState *env, uint64_t ah, uint64_t al, |
260 | f08a5c31 | Richard Henderson | uint64_t bh, uint64_t bl) |
261 | f08a5c31 | Richard Henderson | { |
262 | f08a5c31 | Richard Henderson | float128 ret = float128_div(make_float128(ah, al), |
263 | f08a5c31 | Richard Henderson | make_float128(bh, bl), |
264 | f08a5c31 | Richard Henderson | &env->fpu_status); |
265 | f08a5c31 | Richard Henderson | handle_exceptions(env, GETPC()); |
266 | f08a5c31 | Richard Henderson | return RET128(ret);
|
267 | e72ca652 | Blue Swirl | } |
268 | e72ca652 | Blue Swirl | |
269 | e72ca652 | Blue Swirl | /* 64-bit FP multiplication RR */
|
270 | 449c0d70 | Blue Swirl | void HELPER(mdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
|
271 | e72ca652 | Blue Swirl | { |
272 | e72ca652 | Blue Swirl | env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d, |
273 | e72ca652 | Blue Swirl | &env->fpu_status); |
274 | e72ca652 | Blue Swirl | } |
275 | e72ca652 | Blue Swirl | |
276 | e72ca652 | Blue Swirl | /* 128-bit FP multiplication RR */
|
277 | 449c0d70 | Blue Swirl | void HELPER(mxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
|
278 | e72ca652 | Blue Swirl | { |
279 | e72ca652 | Blue Swirl | CPU_QuadU v1; |
280 | e72ca652 | Blue Swirl | CPU_QuadU v2; |
281 | e72ca652 | Blue Swirl | CPU_QuadU res; |
282 | e72ca652 | Blue Swirl | |
283 | e72ca652 | Blue Swirl | v1.ll.upper = env->fregs[f1].ll; |
284 | e72ca652 | Blue Swirl | v1.ll.lower = env->fregs[f1 + 2].ll;
|
285 | e72ca652 | Blue Swirl | v2.ll.upper = env->fregs[f2].ll; |
286 | e72ca652 | Blue Swirl | v2.ll.lower = env->fregs[f2 + 2].ll;
|
287 | e72ca652 | Blue Swirl | res.q = float128_mul(v1.q, v2.q, &env->fpu_status); |
288 | e72ca652 | Blue Swirl | env->fregs[f1].ll = res.ll.upper; |
289 | e72ca652 | Blue Swirl | env->fregs[f1 + 2].ll = res.ll.lower;
|
290 | e72ca652 | Blue Swirl | } |
291 | e72ca652 | Blue Swirl | |
292 | e72ca652 | Blue Swirl | /* convert 32-bit float to 64-bit float */
|
293 | 587626f8 | Richard Henderson | uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2) |
294 | e72ca652 | Blue Swirl | { |
295 | 587626f8 | Richard Henderson | float64 ret = float32_to_float64(f2, &env->fpu_status); |
296 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
297 | 587626f8 | Richard Henderson | return ret;
|
298 | e72ca652 | Blue Swirl | } |
299 | e72ca652 | Blue Swirl | |
300 | e72ca652 | Blue Swirl | /* convert 128-bit float to 64-bit float */
|
301 | 587626f8 | Richard Henderson | uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al) |
302 | e72ca652 | Blue Swirl | { |
303 | 587626f8 | Richard Henderson | float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status); |
304 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
305 | 587626f8 | Richard Henderson | return ret;
|
306 | e72ca652 | Blue Swirl | } |
307 | e72ca652 | Blue Swirl | |
308 | e72ca652 | Blue Swirl | /* convert 64-bit float to 128-bit float */
|
309 | 587626f8 | Richard Henderson | uint64_t HELPER(lxdb)(CPUS390XState *env, uint64_t f2) |
310 | e72ca652 | Blue Swirl | { |
311 | 587626f8 | Richard Henderson | float128 ret = float64_to_float128(f2, &env->fpu_status); |
312 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
313 | 587626f8 | Richard Henderson | return RET128(ret);
|
314 | 587626f8 | Richard Henderson | } |
315 | e72ca652 | Blue Swirl | |
316 | 587626f8 | Richard Henderson | /* convert 32-bit float to 128-bit float */
|
317 | 587626f8 | Richard Henderson | uint64_t HELPER(lxeb)(CPUS390XState *env, uint64_t f2) |
318 | 587626f8 | Richard Henderson | { |
319 | 587626f8 | Richard Henderson | float128 ret = float32_to_float128(f2, &env->fpu_status); |
320 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
321 | 587626f8 | Richard Henderson | return RET128(ret);
|
322 | e72ca652 | Blue Swirl | } |
323 | e72ca652 | Blue Swirl | |
324 | e72ca652 | Blue Swirl | /* convert 64-bit float to 32-bit float */
|
325 | 587626f8 | Richard Henderson | uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2) |
326 | e72ca652 | Blue Swirl | { |
327 | 587626f8 | Richard Henderson | float32 ret = float64_to_float32(f2, &env->fpu_status); |
328 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
329 | 587626f8 | Richard Henderson | return ret;
|
330 | e72ca652 | Blue Swirl | } |
331 | e72ca652 | Blue Swirl | |
332 | e72ca652 | Blue Swirl | /* convert 128-bit float to 32-bit float */
|
333 | 587626f8 | Richard Henderson | uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al) |
334 | e72ca652 | Blue Swirl | { |
335 | 587626f8 | Richard Henderson | float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status); |
336 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
337 | 587626f8 | Richard Henderson | return ret;
|
338 | e72ca652 | Blue Swirl | } |
339 | e72ca652 | Blue Swirl | |
340 | e72ca652 | Blue Swirl | /* absolute value of 32-bit float */
|
341 | 449c0d70 | Blue Swirl | uint32_t HELPER(lpebr)(CPUS390XState *env, uint32_t f1, uint32_t f2) |
342 | e72ca652 | Blue Swirl | { |
343 | e72ca652 | Blue Swirl | float32 v1; |
344 | e72ca652 | Blue Swirl | float32 v2 = env->fregs[f2].d; |
345 | e72ca652 | Blue Swirl | |
346 | e72ca652 | Blue Swirl | v1 = float32_abs(v2); |
347 | e72ca652 | Blue Swirl | env->fregs[f1].d = v1; |
348 | e72ca652 | Blue Swirl | return set_cc_nz_f32(v1);
|
349 | e72ca652 | Blue Swirl | } |
350 | e72ca652 | Blue Swirl | |
351 | e72ca652 | Blue Swirl | /* absolute value of 64-bit float */
|
352 | 449c0d70 | Blue Swirl | uint32_t HELPER(lpdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2) |
353 | e72ca652 | Blue Swirl | { |
354 | e72ca652 | Blue Swirl | float64 v1; |
355 | e72ca652 | Blue Swirl | float64 v2 = env->fregs[f2].d; |
356 | e72ca652 | Blue Swirl | |
357 | e72ca652 | Blue Swirl | v1 = float64_abs(v2); |
358 | e72ca652 | Blue Swirl | env->fregs[f1].d = v1; |
359 | e72ca652 | Blue Swirl | return set_cc_nz_f64(v1);
|
360 | e72ca652 | Blue Swirl | } |
361 | e72ca652 | Blue Swirl | |
362 | e72ca652 | Blue Swirl | /* absolute value of 128-bit float */
|
363 | 449c0d70 | Blue Swirl | uint32_t HELPER(lpxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2) |
364 | e72ca652 | Blue Swirl | { |
365 | e72ca652 | Blue Swirl | CPU_QuadU v1; |
366 | e72ca652 | Blue Swirl | CPU_QuadU v2; |
367 | e72ca652 | Blue Swirl | |
368 | e72ca652 | Blue Swirl | v2.ll.upper = env->fregs[f2].ll; |
369 | e72ca652 | Blue Swirl | v2.ll.lower = env->fregs[f2 + 2].ll;
|
370 | e72ca652 | Blue Swirl | v1.q = float128_abs(v2.q); |
371 | e72ca652 | Blue Swirl | env->fregs[f1].ll = v1.ll.upper; |
372 | e72ca652 | Blue Swirl | env->fregs[f1 + 2].ll = v1.ll.lower;
|
373 | e72ca652 | Blue Swirl | return set_cc_nz_f128(v1.q);
|
374 | e72ca652 | Blue Swirl | } |
375 | e72ca652 | Blue Swirl | |
376 | e72ca652 | Blue Swirl | /* load complement of 32-bit float */
|
377 | 449c0d70 | Blue Swirl | uint32_t HELPER(lcebr)(CPUS390XState *env, uint32_t f1, uint32_t f2) |
378 | e72ca652 | Blue Swirl | { |
379 | e72ca652 | Blue Swirl | env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper); |
380 | e72ca652 | Blue Swirl | |
381 | e72ca652 | Blue Swirl | return set_cc_nz_f32(env->fregs[f1].l.upper);
|
382 | e72ca652 | Blue Swirl | } |
383 | e72ca652 | Blue Swirl | |
384 | e72ca652 | Blue Swirl | /* load complement of 64-bit float */
|
385 | 449c0d70 | Blue Swirl | uint32_t HELPER(lcdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2) |
386 | e72ca652 | Blue Swirl | { |
387 | e72ca652 | Blue Swirl | env->fregs[f1].d = float64_chs(env->fregs[f2].d); |
388 | e72ca652 | Blue Swirl | |
389 | e72ca652 | Blue Swirl | return set_cc_nz_f64(env->fregs[f1].d);
|
390 | e72ca652 | Blue Swirl | } |
391 | e72ca652 | Blue Swirl | |
392 | e72ca652 | Blue Swirl | /* load complement of 128-bit float */
|
393 | 449c0d70 | Blue Swirl | uint32_t HELPER(lcxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2) |
394 | e72ca652 | Blue Swirl | { |
395 | e72ca652 | Blue Swirl | CPU_QuadU x1, x2; |
396 | e72ca652 | Blue Swirl | |
397 | e72ca652 | Blue Swirl | x2.ll.upper = env->fregs[f2].ll; |
398 | e72ca652 | Blue Swirl | x2.ll.lower = env->fregs[f2 + 2].ll;
|
399 | e72ca652 | Blue Swirl | x1.q = float128_chs(x2.q); |
400 | e72ca652 | Blue Swirl | env->fregs[f1].ll = x1.ll.upper; |
401 | e72ca652 | Blue Swirl | env->fregs[f1 + 2].ll = x1.ll.lower;
|
402 | e72ca652 | Blue Swirl | return set_cc_nz_f128(x1.q);
|
403 | e72ca652 | Blue Swirl | } |
404 | e72ca652 | Blue Swirl | |
405 | e72ca652 | Blue Swirl | /* 32-bit FP multiplication RM */
|
406 | 449c0d70 | Blue Swirl | void HELPER(meeb)(CPUS390XState *env, uint32_t f1, uint32_t val)
|
407 | e72ca652 | Blue Swirl | { |
408 | e72ca652 | Blue Swirl | float32 v1 = env->fregs[f1].l.upper; |
409 | e72ca652 | Blue Swirl | CPU_FloatU v2; |
410 | e72ca652 | Blue Swirl | |
411 | e72ca652 | Blue Swirl | v2.l = val; |
412 | e72ca652 | Blue Swirl | HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __func__,
|
413 | e72ca652 | Blue Swirl | v1, f1, v2.f); |
414 | e72ca652 | Blue Swirl | env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status); |
415 | e72ca652 | Blue Swirl | } |
416 | e72ca652 | Blue Swirl | |
417 | 587626f8 | Richard Henderson | /* 32-bit FP compare */
|
418 | 587626f8 | Richard Henderson | uint32_t HELPER(ceb)(CPUS390XState *env, uint64_t f1, uint64_t f2) |
419 | e72ca652 | Blue Swirl | { |
420 | 587626f8 | Richard Henderson | int cmp = float32_compare_quiet(f1, f2, &env->fpu_status);
|
421 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
422 | 587626f8 | Richard Henderson | return float_comp_to_cc(env, cmp);
|
423 | e72ca652 | Blue Swirl | } |
424 | e72ca652 | Blue Swirl | |
425 | 587626f8 | Richard Henderson | /* 64-bit FP compare */
|
426 | 587626f8 | Richard Henderson | uint32_t HELPER(cdb)(CPUS390XState *env, uint64_t f1, uint64_t f2) |
427 | e72ca652 | Blue Swirl | { |
428 | 587626f8 | Richard Henderson | int cmp = float64_compare_quiet(f1, f2, &env->fpu_status);
|
429 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
430 | 587626f8 | Richard Henderson | return float_comp_to_cc(env, cmp);
|
431 | e72ca652 | Blue Swirl | } |
432 | e72ca652 | Blue Swirl | |
433 | 587626f8 | Richard Henderson | /* 128-bit FP compare */
|
434 | 587626f8 | Richard Henderson | uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al, |
435 | 587626f8 | Richard Henderson | uint64_t bh, uint64_t bl) |
436 | e72ca652 | Blue Swirl | { |
437 | 587626f8 | Richard Henderson | int cmp = float128_compare_quiet(make_float128(ah, al),
|
438 | 587626f8 | Richard Henderson | make_float128(bh, bl), |
439 | 587626f8 | Richard Henderson | &env->fpu_status); |
440 | 587626f8 | Richard Henderson | handle_exceptions(env, GETPC()); |
441 | 587626f8 | Richard Henderson | return float_comp_to_cc(env, cmp);
|
442 | e72ca652 | Blue Swirl | } |
443 | e72ca652 | Blue Swirl | |
444 | e72ca652 | Blue Swirl | /* 64-bit FP multiplication RM */
|
445 | 449c0d70 | Blue Swirl | void HELPER(mdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
|
446 | e72ca652 | Blue Swirl | { |
447 | e72ca652 | Blue Swirl | float64 v1 = env->fregs[f1].d; |
448 | e72ca652 | Blue Swirl | CPU_DoubleU v2; |
449 | e72ca652 | Blue Swirl | |
450 | 449c0d70 | Blue Swirl | v2.ll = cpu_ldq_data(env, a2); |
451 | e72ca652 | Blue Swirl | HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
|
452 | e72ca652 | Blue Swirl | v1, f1, v2.d); |
453 | e72ca652 | Blue Swirl | env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status); |
454 | e72ca652 | Blue Swirl | } |
455 | e72ca652 | Blue Swirl | |
456 | 449c0d70 | Blue Swirl | static void set_round_mode(CPUS390XState *env, int m3) |
457 | e72ca652 | Blue Swirl | { |
458 | e72ca652 | Blue Swirl | switch (m3) {
|
459 | e72ca652 | Blue Swirl | case 0: |
460 | e72ca652 | Blue Swirl | /* current mode */
|
461 | e72ca652 | Blue Swirl | break;
|
462 | e72ca652 | Blue Swirl | case 1: |
463 | e72ca652 | Blue Swirl | /* biased round no nearest */
|
464 | e72ca652 | Blue Swirl | case 4: |
465 | e72ca652 | Blue Swirl | /* round to nearest */
|
466 | e72ca652 | Blue Swirl | set_float_rounding_mode(float_round_nearest_even, &env->fpu_status); |
467 | e72ca652 | Blue Swirl | break;
|
468 | e72ca652 | Blue Swirl | case 5: |
469 | e72ca652 | Blue Swirl | /* round to zero */
|
470 | e72ca652 | Blue Swirl | set_float_rounding_mode(float_round_to_zero, &env->fpu_status); |
471 | e72ca652 | Blue Swirl | break;
|
472 | e72ca652 | Blue Swirl | case 6: |
473 | e72ca652 | Blue Swirl | /* round to +inf */
|
474 | e72ca652 | Blue Swirl | set_float_rounding_mode(float_round_up, &env->fpu_status); |
475 | e72ca652 | Blue Swirl | break;
|
476 | e72ca652 | Blue Swirl | case 7: |
477 | e72ca652 | Blue Swirl | /* round to -inf */
|
478 | e72ca652 | Blue Swirl | set_float_rounding_mode(float_round_down, &env->fpu_status); |
479 | e72ca652 | Blue Swirl | break;
|
480 | e72ca652 | Blue Swirl | } |
481 | e72ca652 | Blue Swirl | } |
482 | e72ca652 | Blue Swirl | |
483 | e72ca652 | Blue Swirl | /* convert 32-bit float to 64-bit int */
|
484 | 449c0d70 | Blue Swirl | uint32_t HELPER(cgebr)(CPUS390XState *env, uint32_t r1, uint32_t f2, |
485 | 449c0d70 | Blue Swirl | uint32_t m3) |
486 | e72ca652 | Blue Swirl | { |
487 | e72ca652 | Blue Swirl | float32 v2 = env->fregs[f2].l.upper; |
488 | e72ca652 | Blue Swirl | |
489 | 449c0d70 | Blue Swirl | set_round_mode(env, m3); |
490 | e72ca652 | Blue Swirl | env->regs[r1] = float32_to_int64(v2, &env->fpu_status); |
491 | e72ca652 | Blue Swirl | return set_cc_nz_f32(v2);
|
492 | e72ca652 | Blue Swirl | } |
493 | e72ca652 | Blue Swirl | |
494 | e72ca652 | Blue Swirl | /* convert 64-bit float to 64-bit int */
|
495 | 449c0d70 | Blue Swirl | uint32_t HELPER(cgdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2, |
496 | 449c0d70 | Blue Swirl | uint32_t m3) |
497 | e72ca652 | Blue Swirl | { |
498 | e72ca652 | Blue Swirl | float64 v2 = env->fregs[f2].d; |
499 | e72ca652 | Blue Swirl | |
500 | 449c0d70 | Blue Swirl | set_round_mode(env, m3); |
501 | e72ca652 | Blue Swirl | env->regs[r1] = float64_to_int64(v2, &env->fpu_status); |
502 | e72ca652 | Blue Swirl | return set_cc_nz_f64(v2);
|
503 | e72ca652 | Blue Swirl | } |
504 | e72ca652 | Blue Swirl | |
505 | e72ca652 | Blue Swirl | /* convert 128-bit float to 64-bit int */
|
506 | 449c0d70 | Blue Swirl | uint32_t HELPER(cgxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2, |
507 | 449c0d70 | Blue Swirl | uint32_t m3) |
508 | e72ca652 | Blue Swirl | { |
509 | e72ca652 | Blue Swirl | CPU_QuadU v2; |
510 | e72ca652 | Blue Swirl | |
511 | e72ca652 | Blue Swirl | v2.ll.upper = env->fregs[f2].ll; |
512 | e72ca652 | Blue Swirl | v2.ll.lower = env->fregs[f2 + 2].ll;
|
513 | 449c0d70 | Blue Swirl | set_round_mode(env, m3); |
514 | e72ca652 | Blue Swirl | env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status); |
515 | e72ca652 | Blue Swirl | if (float128_is_any_nan(v2.q)) {
|
516 | e72ca652 | Blue Swirl | return 3; |
517 | e72ca652 | Blue Swirl | } else if (float128_is_zero(v2.q)) { |
518 | e72ca652 | Blue Swirl | return 0; |
519 | e72ca652 | Blue Swirl | } else if (float128_is_neg(v2.q)) { |
520 | e72ca652 | Blue Swirl | return 1; |
521 | e72ca652 | Blue Swirl | } else {
|
522 | e72ca652 | Blue Swirl | return 2; |
523 | e72ca652 | Blue Swirl | } |
524 | e72ca652 | Blue Swirl | } |
525 | e72ca652 | Blue Swirl | |
526 | e72ca652 | Blue Swirl | /* convert 32-bit float to 32-bit int */
|
527 | 449c0d70 | Blue Swirl | uint32_t HELPER(cfebr)(CPUS390XState *env, uint32_t r1, uint32_t f2, |
528 | 449c0d70 | Blue Swirl | uint32_t m3) |
529 | e72ca652 | Blue Swirl | { |
530 | e72ca652 | Blue Swirl | float32 v2 = env->fregs[f2].l.upper; |
531 | e72ca652 | Blue Swirl | |
532 | 449c0d70 | Blue Swirl | set_round_mode(env, m3); |
533 | e72ca652 | Blue Swirl | env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
|
534 | e72ca652 | Blue Swirl | float32_to_int32(v2, &env->fpu_status); |
535 | e72ca652 | Blue Swirl | return set_cc_nz_f32(v2);
|
536 | e72ca652 | Blue Swirl | } |
537 | e72ca652 | Blue Swirl | |
538 | e72ca652 | Blue Swirl | /* convert 64-bit float to 32-bit int */
|
539 | 449c0d70 | Blue Swirl | uint32_t HELPER(cfdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2, |
540 | 449c0d70 | Blue Swirl | uint32_t m3) |
541 | e72ca652 | Blue Swirl | { |
542 | e72ca652 | Blue Swirl | float64 v2 = env->fregs[f2].d; |
543 | e72ca652 | Blue Swirl | |
544 | 449c0d70 | Blue Swirl | set_round_mode(env, m3); |
545 | e72ca652 | Blue Swirl | env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
|
546 | e72ca652 | Blue Swirl | float64_to_int32(v2, &env->fpu_status); |
547 | e72ca652 | Blue Swirl | return set_cc_nz_f64(v2);
|
548 | e72ca652 | Blue Swirl | } |
549 | e72ca652 | Blue Swirl | |
550 | e72ca652 | Blue Swirl | /* convert 128-bit float to 32-bit int */
|
551 | 449c0d70 | Blue Swirl | uint32_t HELPER(cfxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2, |
552 | 449c0d70 | Blue Swirl | uint32_t m3) |
553 | e72ca652 | Blue Swirl | { |
554 | e72ca652 | Blue Swirl | CPU_QuadU v2; |
555 | e72ca652 | Blue Swirl | |
556 | e72ca652 | Blue Swirl | v2.ll.upper = env->fregs[f2].ll; |
557 | e72ca652 | Blue Swirl | v2.ll.lower = env->fregs[f2 + 2].ll;
|
558 | e72ca652 | Blue Swirl | env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
|
559 | e72ca652 | Blue Swirl | float128_to_int32(v2.q, &env->fpu_status); |
560 | e72ca652 | Blue Swirl | return set_cc_nz_f128(v2.q);
|
561 | e72ca652 | Blue Swirl | } |
562 | e72ca652 | Blue Swirl | |
563 | e72ca652 | Blue Swirl | /* load 32-bit FP zero */
|
564 | 449c0d70 | Blue Swirl | void HELPER(lzer)(CPUS390XState *env, uint32_t f1)
|
565 | e72ca652 | Blue Swirl | { |
566 | e72ca652 | Blue Swirl | env->fregs[f1].l.upper = float32_zero; |
567 | e72ca652 | Blue Swirl | } |
568 | e72ca652 | Blue Swirl | |
569 | e72ca652 | Blue Swirl | /* load 64-bit FP zero */
|
570 | 449c0d70 | Blue Swirl | void HELPER(lzdr)(CPUS390XState *env, uint32_t f1)
|
571 | e72ca652 | Blue Swirl | { |
572 | e72ca652 | Blue Swirl | env->fregs[f1].d = float64_zero; |
573 | e72ca652 | Blue Swirl | } |
574 | e72ca652 | Blue Swirl | |
575 | e72ca652 | Blue Swirl | /* load 128-bit FP zero */
|
576 | 449c0d70 | Blue Swirl | void HELPER(lzxr)(CPUS390XState *env, uint32_t f1)
|
577 | e72ca652 | Blue Swirl | { |
578 | e72ca652 | Blue Swirl | CPU_QuadU x; |
579 | e72ca652 | Blue Swirl | |
580 | e72ca652 | Blue Swirl | x.q = float64_to_float128(float64_zero, &env->fpu_status); |
581 | e72ca652 | Blue Swirl | env->fregs[f1].ll = x.ll.upper; |
582 | e72ca652 | Blue Swirl | env->fregs[f1 + 1].ll = x.ll.lower;
|
583 | e72ca652 | Blue Swirl | } |
584 | e72ca652 | Blue Swirl | |
585 | e72ca652 | Blue Swirl | /* 32-bit FP multiplication RR */
|
586 | 449c0d70 | Blue Swirl | void HELPER(meebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
|
587 | e72ca652 | Blue Swirl | { |
588 | e72ca652 | Blue Swirl | env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper, |
589 | e72ca652 | Blue Swirl | env->fregs[f2].l.upper, |
590 | e72ca652 | Blue Swirl | &env->fpu_status); |
591 | e72ca652 | Blue Swirl | } |
592 | e72ca652 | Blue Swirl | |
593 | e72ca652 | Blue Swirl | /* 64-bit FP multiply and add RM */
|
594 | 449c0d70 | Blue Swirl | void HELPER(madb)(CPUS390XState *env, uint32_t f1, uint64_t a2, uint32_t f3)
|
595 | e72ca652 | Blue Swirl | { |
596 | e72ca652 | Blue Swirl | CPU_DoubleU v2; |
597 | e72ca652 | Blue Swirl | |
598 | e72ca652 | Blue Swirl | HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
|
599 | 449c0d70 | Blue Swirl | v2.ll = cpu_ldq_data(env, a2); |
600 | e72ca652 | Blue Swirl | env->fregs[f1].d = float64_add(env->fregs[f1].d, |
601 | e72ca652 | Blue Swirl | float64_mul(v2.d, env->fregs[f3].d, |
602 | e72ca652 | Blue Swirl | &env->fpu_status), |
603 | e72ca652 | Blue Swirl | &env->fpu_status); |
604 | e72ca652 | Blue Swirl | } |
605 | e72ca652 | Blue Swirl | |
606 | e72ca652 | Blue Swirl | /* 64-bit FP multiply and add RR */
|
607 | 449c0d70 | Blue Swirl | void HELPER(madbr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
|
608 | e72ca652 | Blue Swirl | { |
609 | e72ca652 | Blue Swirl | HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
|
610 | e72ca652 | Blue Swirl | env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d, |
611 | e72ca652 | Blue Swirl | env->fregs[f3].d, |
612 | e72ca652 | Blue Swirl | &env->fpu_status), |
613 | e72ca652 | Blue Swirl | env->fregs[f1].d, &env->fpu_status); |
614 | e72ca652 | Blue Swirl | } |
615 | e72ca652 | Blue Swirl | |
616 | e72ca652 | Blue Swirl | /* 64-bit FP multiply and subtract RR */
|
617 | 449c0d70 | Blue Swirl | void HELPER(msdbr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
|
618 | e72ca652 | Blue Swirl | { |
619 | e72ca652 | Blue Swirl | HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
|
620 | e72ca652 | Blue Swirl | env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d, |
621 | e72ca652 | Blue Swirl | env->fregs[f3].d, |
622 | e72ca652 | Blue Swirl | &env->fpu_status), |
623 | e72ca652 | Blue Swirl | env->fregs[f1].d, &env->fpu_status); |
624 | e72ca652 | Blue Swirl | } |
625 | e72ca652 | Blue Swirl | |
626 | e72ca652 | Blue Swirl | /* 32-bit FP multiply and add RR */
|
627 | 449c0d70 | Blue Swirl | void HELPER(maebr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
|
628 | e72ca652 | Blue Swirl | { |
629 | e72ca652 | Blue Swirl | env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper, |
630 | e72ca652 | Blue Swirl | float32_mul(env->fregs[f2].l.upper, |
631 | e72ca652 | Blue Swirl | env->fregs[f3].l.upper, |
632 | e72ca652 | Blue Swirl | &env->fpu_status), |
633 | e72ca652 | Blue Swirl | &env->fpu_status); |
634 | e72ca652 | Blue Swirl | } |
635 | e72ca652 | Blue Swirl | |
636 | e72ca652 | Blue Swirl | /* test data class 32-bit */
|
637 | 449c0d70 | Blue Swirl | uint32_t HELPER(tceb)(CPUS390XState *env, uint32_t f1, uint64_t m2) |
638 | e72ca652 | Blue Swirl | { |
639 | e72ca652 | Blue Swirl | float32 v1 = env->fregs[f1].l.upper; |
640 | e72ca652 | Blue Swirl | int neg = float32_is_neg(v1);
|
641 | e72ca652 | Blue Swirl | uint32_t cc = 0;
|
642 | e72ca652 | Blue Swirl | |
643 | e72ca652 | Blue Swirl | HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg); |
644 | e72ca652 | Blue Swirl | if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) || |
645 | e72ca652 | Blue Swirl | (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) || |
646 | e72ca652 | Blue Swirl | (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) || |
647 | e72ca652 | Blue Swirl | (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) { |
648 | e72ca652 | Blue Swirl | cc = 1;
|
649 | e72ca652 | Blue Swirl | } else if (m2 & (1 << (9-neg))) { |
650 | e72ca652 | Blue Swirl | /* assume normalized number */
|
651 | e72ca652 | Blue Swirl | cc = 1;
|
652 | e72ca652 | Blue Swirl | } |
653 | e72ca652 | Blue Swirl | |
654 | e72ca652 | Blue Swirl | /* FIXME: denormalized? */
|
655 | e72ca652 | Blue Swirl | return cc;
|
656 | e72ca652 | Blue Swirl | } |
657 | e72ca652 | Blue Swirl | |
658 | e72ca652 | Blue Swirl | /* test data class 64-bit */
|
659 | 449c0d70 | Blue Swirl | uint32_t HELPER(tcdb)(CPUS390XState *env, uint32_t f1, uint64_t m2) |
660 | e72ca652 | Blue Swirl | { |
661 | e72ca652 | Blue Swirl | float64 v1 = env->fregs[f1].d; |
662 | e72ca652 | Blue Swirl | int neg = float64_is_neg(v1);
|
663 | e72ca652 | Blue Swirl | uint32_t cc = 0;
|
664 | e72ca652 | Blue Swirl | |
665 | e72ca652 | Blue Swirl | HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, v1, m2, neg);
|
666 | e72ca652 | Blue Swirl | if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) || |
667 | e72ca652 | Blue Swirl | (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) || |
668 | e72ca652 | Blue Swirl | (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) || |
669 | e72ca652 | Blue Swirl | (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) { |
670 | e72ca652 | Blue Swirl | cc = 1;
|
671 | e72ca652 | Blue Swirl | } else if (m2 & (1 << (9-neg))) { |
672 | e72ca652 | Blue Swirl | /* assume normalized number */
|
673 | e72ca652 | Blue Swirl | cc = 1;
|
674 | e72ca652 | Blue Swirl | } |
675 | e72ca652 | Blue Swirl | /* FIXME: denormalized? */
|
676 | e72ca652 | Blue Swirl | return cc;
|
677 | e72ca652 | Blue Swirl | } |
678 | e72ca652 | Blue Swirl | |
679 | e72ca652 | Blue Swirl | /* test data class 128-bit */
|
680 | 449c0d70 | Blue Swirl | uint32_t HELPER(tcxb)(CPUS390XState *env, uint32_t f1, uint64_t m2) |
681 | e72ca652 | Blue Swirl | { |
682 | e72ca652 | Blue Swirl | CPU_QuadU v1; |
683 | e72ca652 | Blue Swirl | uint32_t cc = 0;
|
684 | e72ca652 | Blue Swirl | int neg;
|
685 | e72ca652 | Blue Swirl | |
686 | e72ca652 | Blue Swirl | v1.ll.upper = env->fregs[f1].ll; |
687 | e72ca652 | Blue Swirl | v1.ll.lower = env->fregs[f1 + 2].ll;
|
688 | e72ca652 | Blue Swirl | |
689 | e72ca652 | Blue Swirl | neg = float128_is_neg(v1.q); |
690 | e72ca652 | Blue Swirl | if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) || |
691 | e72ca652 | Blue Swirl | (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) || |
692 | e72ca652 | Blue Swirl | (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) || |
693 | e72ca652 | Blue Swirl | (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg))))) { |
694 | e72ca652 | Blue Swirl | cc = 1;
|
695 | e72ca652 | Blue Swirl | } else if (m2 & (1 << (9-neg))) { |
696 | e72ca652 | Blue Swirl | /* assume normalized number */
|
697 | e72ca652 | Blue Swirl | cc = 1;
|
698 | e72ca652 | Blue Swirl | } |
699 | e72ca652 | Blue Swirl | /* FIXME: denormalized? */
|
700 | e72ca652 | Blue Swirl | return cc;
|
701 | e72ca652 | Blue Swirl | } |
702 | e72ca652 | Blue Swirl | |
703 | e72ca652 | Blue Swirl | /* square root 64-bit RR */
|
704 | 449c0d70 | Blue Swirl | void HELPER(sqdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
|
705 | e72ca652 | Blue Swirl | { |
706 | e72ca652 | Blue Swirl | env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status); |
707 | e72ca652 | Blue Swirl | } |