1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "cpu.h"
23#include "exec/exec-all.h"
24#include "exec/cpu_ldst.h"
25#include "exec/helper-proto.h"
26
27
28#ifdef DEBUG_HELPER
29#define HELPER_LOG(x...) qemu_log(x)
30#else
31#define HELPER_LOG(x...)
32#endif
33
34#define RET128(F) (env->retxl = F.low, F.high)
35
36#define convert_bit(mask, from, to) \
37 (to < from \
38 ? (mask / (from / to)) & to \
39 : (mask & from) * (to / from))
40
41static void ieee_exception(CPUS390XState *env, uint32_t dxc, uintptr_t retaddr)
42{
43
44 env->fpc = (env->fpc & ~0xff00) | (dxc << 8);
45
46 runtime_exception(env, PGM_DATA, retaddr);
47}
48
49
50static void handle_exceptions(CPUS390XState *env, uintptr_t retaddr)
51{
52 unsigned s390_exc, qemu_exc;
53
54
55
56 qemu_exc = env->fpu_status.float_exception_flags;
57 if (qemu_exc == 0) {
58 return;
59 }
60 env->fpu_status.float_exception_flags = 0;
61
62
63 s390_exc = 0;
64 s390_exc |= convert_bit(qemu_exc, float_flag_invalid, 0x80);
65 s390_exc |= convert_bit(qemu_exc, float_flag_divbyzero, 0x40);
66 s390_exc |= convert_bit(qemu_exc, float_flag_overflow, 0x20);
67 s390_exc |= convert_bit(qemu_exc, float_flag_underflow, 0x10);
68 s390_exc |= convert_bit(qemu_exc, float_flag_inexact, 0x08);
69
70
71 env->fpc |= s390_exc << 16;
72
73
74 s390_exc &= env->fpc >> 24;
75 if (s390_exc) {
76 ieee_exception(env, s390_exc, retaddr);
77 }
78}
79
80static inline int float_comp_to_cc(CPUS390XState *env, int float_compare)
81{
82 S390CPU *cpu = s390_env_get_cpu(env);
83
84 switch (float_compare) {
85 case float_relation_equal:
86 return 0;
87 case float_relation_less:
88 return 1;
89 case float_relation_greater:
90 return 2;
91 case float_relation_unordered:
92 return 3;
93 default:
94 cpu_abort(CPU(cpu), "unknown return value for float compare\n");
95 }
96}
97
98
99uint32_t set_cc_nz_f32(float32 v)
100{
101 if (float32_is_any_nan(v)) {
102 return 3;
103 } else if (float32_is_zero(v)) {
104 return 0;
105 } else if (float32_is_neg(v)) {
106 return 1;
107 } else {
108 return 2;
109 }
110}
111
112uint32_t set_cc_nz_f64(float64 v)
113{
114 if (float64_is_any_nan(v)) {
115 return 3;
116 } else if (float64_is_zero(v)) {
117 return 0;
118 } else if (float64_is_neg(v)) {
119 return 1;
120 } else {
121 return 2;
122 }
123}
124
125uint32_t set_cc_nz_f128(float128 v)
126{
127 if (float128_is_any_nan(v)) {
128 return 3;
129 } else if (float128_is_zero(v)) {
130 return 0;
131 } else if (float128_is_neg(v)) {
132 return 1;
133 } else {
134 return 2;
135 }
136}
137
138
139uint64_t HELPER(aeb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
140{
141 float32 ret = float32_add(f1, f2, &env->fpu_status);
142 handle_exceptions(env, GETPC());
143 return ret;
144}
145
146
147uint64_t HELPER(adb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
148{
149 float64 ret = float64_add(f1, f2, &env->fpu_status);
150 handle_exceptions(env, GETPC());
151 return ret;
152}
153
154
155uint64_t HELPER(axb)(CPUS390XState *env, uint64_t ah, uint64_t al,
156 uint64_t bh, uint64_t bl)
157{
158 float128 ret = float128_add(make_float128(ah, al),
159 make_float128(bh, bl),
160 &env->fpu_status);
161 handle_exceptions(env, GETPC());
162 return RET128(ret);
163}
164
165
166uint64_t HELPER(seb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
167{
168 float32 ret = float32_sub(f1, f2, &env->fpu_status);
169 handle_exceptions(env, GETPC());
170 return ret;
171}
172
173
174uint64_t HELPER(sdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
175{
176 float64 ret = float64_sub(f1, f2, &env->fpu_status);
177 handle_exceptions(env, GETPC());
178 return ret;
179}
180
181
182uint64_t HELPER(sxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
183 uint64_t bh, uint64_t bl)
184{
185 float128 ret = float128_sub(make_float128(ah, al),
186 make_float128(bh, bl),
187 &env->fpu_status);
188 handle_exceptions(env, GETPC());
189 return RET128(ret);
190}
191
192
193uint64_t HELPER(deb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
194{
195 float32 ret = float32_div(f1, f2, &env->fpu_status);
196 handle_exceptions(env, GETPC());
197 return ret;
198}
199
200
201uint64_t HELPER(ddb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
202{
203 float64 ret = float64_div(f1, f2, &env->fpu_status);
204 handle_exceptions(env, GETPC());
205 return ret;
206}
207
208
209uint64_t HELPER(dxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
210 uint64_t bh, uint64_t bl)
211{
212 float128 ret = float128_div(make_float128(ah, al),
213 make_float128(bh, bl),
214 &env->fpu_status);
215 handle_exceptions(env, GETPC());
216 return RET128(ret);
217}
218
219
220uint64_t HELPER(meeb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
221{
222 float32 ret = float32_mul(f1, f2, &env->fpu_status);
223 handle_exceptions(env, GETPC());
224 return ret;
225}
226
227
228uint64_t HELPER(mdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
229{
230 float64 ret = float64_mul(f1, f2, &env->fpu_status);
231 handle_exceptions(env, GETPC());
232 return ret;
233}
234
235
236uint64_t HELPER(mdeb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
237{
238 float64 ret = float32_to_float64(f2, &env->fpu_status);
239 ret = float64_mul(f1, ret, &env->fpu_status);
240 handle_exceptions(env, GETPC());
241 return ret;
242}
243
244
245uint64_t HELPER(mxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
246 uint64_t bh, uint64_t bl)
247{
248 float128 ret = float128_mul(make_float128(ah, al),
249 make_float128(bh, bl),
250 &env->fpu_status);
251 handle_exceptions(env, GETPC());
252 return RET128(ret);
253}
254
255
256uint64_t HELPER(mxdb)(CPUS390XState *env, uint64_t ah, uint64_t al,
257 uint64_t f2)
258{
259 float128 ret = float64_to_float128(f2, &env->fpu_status);
260 ret = float128_mul(make_float128(ah, al), ret, &env->fpu_status);
261 handle_exceptions(env, GETPC());
262 return RET128(ret);
263}
264
265
266uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2)
267{
268 float64 ret = float32_to_float64(f2, &env->fpu_status);
269 handle_exceptions(env, GETPC());
270 return float64_maybe_silence_nan(ret, &env->fpu_status);
271}
272
273
274uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al)
275{
276 float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status);
277 handle_exceptions(env, GETPC());
278 return float64_maybe_silence_nan(ret, &env->fpu_status);
279}
280
281
282uint64_t HELPER(lxdb)(CPUS390XState *env, uint64_t f2)
283{
284 float128 ret = float64_to_float128(f2, &env->fpu_status);
285 handle_exceptions(env, GETPC());
286 return RET128(float128_maybe_silence_nan(ret, &env->fpu_status));
287}
288
289
290uint64_t HELPER(lxeb)(CPUS390XState *env, uint64_t f2)
291{
292 float128 ret = float32_to_float128(f2, &env->fpu_status);
293 handle_exceptions(env, GETPC());
294 return RET128(float128_maybe_silence_nan(ret, &env->fpu_status));
295}
296
297
298uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2)
299{
300 float32 ret = float64_to_float32(f2, &env->fpu_status);
301 handle_exceptions(env, GETPC());
302 return float32_maybe_silence_nan(ret, &env->fpu_status);
303}
304
305
306uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al)
307{
308 float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status);
309 handle_exceptions(env, GETPC());
310 return float32_maybe_silence_nan(ret, &env->fpu_status);
311}
312
313
314uint32_t HELPER(ceb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
315{
316 int cmp = float32_compare_quiet(f1, f2, &env->fpu_status);
317 handle_exceptions(env, GETPC());
318 return float_comp_to_cc(env, cmp);
319}
320
321
322uint32_t HELPER(cdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
323{
324 int cmp = float64_compare_quiet(f1, f2, &env->fpu_status);
325 handle_exceptions(env, GETPC());
326 return float_comp_to_cc(env, cmp);
327}
328
329
330uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
331 uint64_t bh, uint64_t bl)
332{
333 int cmp = float128_compare_quiet(make_float128(ah, al),
334 make_float128(bh, bl),
335 &env->fpu_status);
336 handle_exceptions(env, GETPC());
337 return float_comp_to_cc(env, cmp);
338}
339
340static int swap_round_mode(CPUS390XState *env, int m3)
341{
342 int ret = env->fpu_status.float_rounding_mode;
343 switch (m3) {
344 case 0:
345
346 break;
347 case 1:
348
349 case 4:
350
351 set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
352 break;
353 case 5:
354
355 set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
356 break;
357 case 6:
358
359 set_float_rounding_mode(float_round_up, &env->fpu_status);
360 break;
361 case 7:
362
363 set_float_rounding_mode(float_round_down, &env->fpu_status);
364 break;
365 }
366 return ret;
367}
368
369
370uint64_t HELPER(cegb)(CPUS390XState *env, int64_t v2, uint32_t m3)
371{
372 int hold = swap_round_mode(env, m3);
373 float32 ret = int64_to_float32(v2, &env->fpu_status);
374 set_float_rounding_mode(hold, &env->fpu_status);
375 handle_exceptions(env, GETPC());
376 return ret;
377}
378
379
380uint64_t HELPER(cdgb)(CPUS390XState *env, int64_t v2, uint32_t m3)
381{
382 int hold = swap_round_mode(env, m3);
383 float64 ret = int64_to_float64(v2, &env->fpu_status);
384 set_float_rounding_mode(hold, &env->fpu_status);
385 handle_exceptions(env, GETPC());
386 return ret;
387}
388
389
390uint64_t HELPER(cxgb)(CPUS390XState *env, int64_t v2, uint32_t m3)
391{
392 int hold = swap_round_mode(env, m3);
393 float128 ret = int64_to_float128(v2, &env->fpu_status);
394 set_float_rounding_mode(hold, &env->fpu_status);
395 handle_exceptions(env, GETPC());
396 return RET128(ret);
397}
398
399
400uint64_t HELPER(celgb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
401{
402 int hold = swap_round_mode(env, m3);
403 float32 ret = uint64_to_float32(v2, &env->fpu_status);
404 set_float_rounding_mode(hold, &env->fpu_status);
405 handle_exceptions(env, GETPC());
406 return ret;
407}
408
409
410uint64_t HELPER(cdlgb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
411{
412 int hold = swap_round_mode(env, m3);
413 float64 ret = uint64_to_float64(v2, &env->fpu_status);
414 set_float_rounding_mode(hold, &env->fpu_status);
415 handle_exceptions(env, GETPC());
416 return ret;
417}
418
419
420uint64_t HELPER(cxlgb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
421{
422 int hold = swap_round_mode(env, m3);
423 float128 ret = uint64_to_float128(v2, &env->fpu_status);
424 set_float_rounding_mode(hold, &env->fpu_status);
425 handle_exceptions(env, GETPC());
426 return RET128(ret);
427}
428
429
430uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
431{
432 int hold = swap_round_mode(env, m3);
433 int64_t ret = float32_to_int64(v2, &env->fpu_status);
434 set_float_rounding_mode(hold, &env->fpu_status);
435 handle_exceptions(env, GETPC());
436 return ret;
437}
438
439
440uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
441{
442 int hold = swap_round_mode(env, m3);
443 int64_t ret = float64_to_int64(v2, &env->fpu_status);
444 set_float_rounding_mode(hold, &env->fpu_status);
445 handle_exceptions(env, GETPC());
446 return ret;
447}
448
449
450uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
451{
452 int hold = swap_round_mode(env, m3);
453 float128 v2 = make_float128(h, l);
454 int64_t ret = float128_to_int64(v2, &env->fpu_status);
455 set_float_rounding_mode(hold, &env->fpu_status);
456 handle_exceptions(env, GETPC());
457 return ret;
458}
459
460
461uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
462{
463 int hold = swap_round_mode(env, m3);
464 int32_t ret = float32_to_int32(v2, &env->fpu_status);
465 set_float_rounding_mode(hold, &env->fpu_status);
466 handle_exceptions(env, GETPC());
467 return ret;
468}
469
470
471uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
472{
473 int hold = swap_round_mode(env, m3);
474 int32_t ret = float64_to_int32(v2, &env->fpu_status);
475 set_float_rounding_mode(hold, &env->fpu_status);
476 handle_exceptions(env, GETPC());
477 return ret;
478}
479
480
481uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
482{
483 int hold = swap_round_mode(env, m3);
484 float128 v2 = make_float128(h, l);
485 int32_t ret = float128_to_int32(v2, &env->fpu_status);
486 set_float_rounding_mode(hold, &env->fpu_status);
487 handle_exceptions(env, GETPC());
488 return ret;
489}
490
491
492uint64_t HELPER(clgeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
493{
494 int hold = swap_round_mode(env, m3);
495 uint64_t ret;
496 v2 = float32_to_float64(v2, &env->fpu_status);
497 ret = float64_to_uint64(v2, &env->fpu_status);
498 set_float_rounding_mode(hold, &env->fpu_status);
499 handle_exceptions(env, GETPC());
500 return ret;
501}
502
503
504uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
505{
506 int hold = swap_round_mode(env, m3);
507 uint64_t ret = float64_to_uint64(v2, &env->fpu_status);
508 set_float_rounding_mode(hold, &env->fpu_status);
509 handle_exceptions(env, GETPC());
510 return ret;
511}
512
513
514uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
515{
516 int hold = swap_round_mode(env, m3);
517 float128 v2 = make_float128(h, l);
518
519 uint64_t ret = float128_to_int64(v2, &env->fpu_status);
520 set_float_rounding_mode(hold, &env->fpu_status);
521 handle_exceptions(env, GETPC());
522 return ret;
523}
524
525
526uint64_t HELPER(clfeb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
527{
528 int hold = swap_round_mode(env, m3);
529 uint32_t ret = float32_to_uint32(v2, &env->fpu_status);
530 set_float_rounding_mode(hold, &env->fpu_status);
531 handle_exceptions(env, GETPC());
532 return ret;
533}
534
535
536uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m3)
537{
538 int hold = swap_round_mode(env, m3);
539 uint32_t ret = float64_to_uint32(v2, &env->fpu_status);
540 set_float_rounding_mode(hold, &env->fpu_status);
541 handle_exceptions(env, GETPC());
542 return ret;
543}
544
545
546uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
547{
548 int hold = swap_round_mode(env, m3);
549 float128 v2 = make_float128(h, l);
550
551 uint32_t ret = float128_to_int64(v2, &env->fpu_status);
552 set_float_rounding_mode(hold, &env->fpu_status);
553 handle_exceptions(env, GETPC());
554 return ret;
555}
556
557
558uint64_t HELPER(fieb)(CPUS390XState *env, uint64_t f2, uint32_t m3)
559{
560 int hold = swap_round_mode(env, m3);
561 float32 ret = float32_round_to_int(f2, &env->fpu_status);
562 set_float_rounding_mode(hold, &env->fpu_status);
563 handle_exceptions(env, GETPC());
564 return ret;
565}
566
567
568uint64_t HELPER(fidb)(CPUS390XState *env, uint64_t f2, uint32_t m3)
569{
570 int hold = swap_round_mode(env, m3);
571 float64 ret = float64_round_to_int(f2, &env->fpu_status);
572 set_float_rounding_mode(hold, &env->fpu_status);
573 handle_exceptions(env, GETPC());
574 return ret;
575}
576
577
578uint64_t HELPER(fixb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint32_t m3)
579{
580 int hold = swap_round_mode(env, m3);
581 float128 ret = float128_round_to_int(make_float128(ah, al),
582 &env->fpu_status);
583 set_float_rounding_mode(hold, &env->fpu_status);
584 handle_exceptions(env, GETPC());
585 return RET128(ret);
586}
587
588
589uint32_t HELPER(keb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
590{
591 int cmp = float32_compare(f1, f2, &env->fpu_status);
592 handle_exceptions(env, GETPC());
593 return float_comp_to_cc(env, cmp);
594}
595
596
597uint32_t HELPER(kdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
598{
599 int cmp = float64_compare(f1, f2, &env->fpu_status);
600 handle_exceptions(env, GETPC());
601 return float_comp_to_cc(env, cmp);
602}
603
604
605uint32_t HELPER(kxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
606 uint64_t bh, uint64_t bl)
607{
608 int cmp = float128_compare(make_float128(ah, al),
609 make_float128(bh, bl),
610 &env->fpu_status);
611 handle_exceptions(env, GETPC());
612 return float_comp_to_cc(env, cmp);
613}
614
615
616uint64_t HELPER(maeb)(CPUS390XState *env, uint64_t f1,
617 uint64_t f2, uint64_t f3)
618{
619 float32 ret = float32_muladd(f2, f3, f1, 0, &env->fpu_status);
620 handle_exceptions(env, GETPC());
621 return ret;
622}
623
624
625uint64_t HELPER(madb)(CPUS390XState *env, uint64_t f1,
626 uint64_t f2, uint64_t f3)
627{
628 float64 ret = float64_muladd(f2, f3, f1, 0, &env->fpu_status);
629 handle_exceptions(env, GETPC());
630 return ret;
631}
632
633
634uint64_t HELPER(mseb)(CPUS390XState *env, uint64_t f1,
635 uint64_t f2, uint64_t f3)
636{
637 float32 ret = float32_muladd(f2, f3, f1, float_muladd_negate_c,
638 &env->fpu_status);
639 handle_exceptions(env, GETPC());
640 return ret;
641}
642
643
644uint64_t HELPER(msdb)(CPUS390XState *env, uint64_t f1,
645 uint64_t f2, uint64_t f3)
646{
647 float64 ret = float64_muladd(f2, f3, f1, float_muladd_negate_c,
648 &env->fpu_status);
649 handle_exceptions(env, GETPC());
650 return ret;
651}
652
653
654uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2)
655{
656 float32 v1 = f1;
657 int neg = float32_is_neg(v1);
658 uint32_t cc = 0;
659
660 if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
661 (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
662 (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
663 (float32_is_signaling_nan(v1, &env->fpu_status) &&
664 (m2 & (1 << (1-neg))))) {
665 cc = 1;
666 } else if (m2 & (1 << (9-neg))) {
667
668 cc = 1;
669 }
670
671 return cc;
672}
673
674
675uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
676{
677 int neg = float64_is_neg(v1);
678 uint32_t cc = 0;
679
680 if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
681 (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
682 (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
683 (float64_is_signaling_nan(v1, &env->fpu_status) &&
684 (m2 & (1 << (1-neg))))) {
685 cc = 1;
686 } else if (m2 & (1 << (9-neg))) {
687
688 cc = 1;
689 }
690
691 return cc;
692}
693
694
695uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah,
696 uint64_t al, uint64_t m2)
697{
698 float128 v1 = make_float128(ah, al);
699 int neg = float128_is_neg(v1);
700 uint32_t cc = 0;
701
702 if ((float128_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
703 (float128_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
704 (float128_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
705 (float128_is_signaling_nan(v1, &env->fpu_status) &&
706 (m2 & (1 << (1-neg))))) {
707 cc = 1;
708 } else if (m2 & (1 << (9-neg))) {
709
710 cc = 1;
711 }
712
713 return cc;
714}
715
716
717uint64_t HELPER(sqeb)(CPUS390XState *env, uint64_t f2)
718{
719 float32 ret = float32_sqrt(f2, &env->fpu_status);
720 handle_exceptions(env, GETPC());
721 return ret;
722}
723
724
725uint64_t HELPER(sqdb)(CPUS390XState *env, uint64_t f2)
726{
727 float64 ret = float64_sqrt(f2, &env->fpu_status);
728 handle_exceptions(env, GETPC());
729 return ret;
730}
731
732
733uint64_t HELPER(sqxb)(CPUS390XState *env, uint64_t ah, uint64_t al)
734{
735 float128 ret = float128_sqrt(make_float128(ah, al), &env->fpu_status);
736 handle_exceptions(env, GETPC());
737 return RET128(ret);
738}
739
740static const int fpc_to_rnd[4] = {
741 float_round_nearest_even,
742 float_round_to_zero,
743 float_round_up,
744 float_round_down
745};
746
747
748void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
749{
750
751 env->fpc = fpc;
752
753
754 set_float_rounding_mode(fpc_to_rnd[fpc & 3], &env->fpu_status);
755}
756
757
758void HELPER(sfas)(CPUS390XState *env, uint64_t val)
759{
760 uint32_t signalling = env->fpc;
761 uint32_t source = val;
762 uint32_t s390_exc;
763
764
765
766
767 env->fpc = source | (signalling & 0x00ff0000);
768 set_float_rounding_mode(fpc_to_rnd[source & 3], &env->fpu_status);
769
770
771
772 s390_exc = (signalling >> 16) & (source >> 24);
773 if (s390_exc) {
774 ieee_exception(env, s390_exc | 3, GETPC());
775 }
776}
777