xref: /qemu/target/ppc/dfp_helper.c (revision 33432d7737b53c92791f90ece5dbe3b7bb1c79f5)
1 /*
2  *  PowerPC Decimal Floating Point (DPF) emulation helpers for QEMU.
3  *
4  *  Copyright (c) 2014 IBM Corporation.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "exec/helper-proto.h"
23 
24 #define DECNUMDIGITS 34
25 #include "libdecnumber/decContext.h"
26 #include "libdecnumber/decNumber.h"
27 #include "libdecnumber/dpd/decimal32.h"
28 #include "libdecnumber/dpd/decimal64.h"
29 #include "libdecnumber/dpd/decimal128.h"
30 
31 #if defined(HOST_WORDS_BIGENDIAN)
32 #define HI_IDX 0
33 #define LO_IDX 1
34 #else
35 #define HI_IDX 1
36 #define LO_IDX 0
37 #endif
38 
39 static void get_dfp64(uint64_t *dst, uint64_t *dfp)
40 {
41     dst[0] = dfp[0];
42 }
43 
44 static void get_dfp128(uint64_t *dst, uint64_t *dfp)
45 {
46     dst[0] = dfp[HI_IDX];
47     dst[1] = dfp[LO_IDX];
48 }
49 
50 static void set_dfp64(uint64_t *dfp, uint64_t *src)
51 {
52     dfp[0] = src[0];
53 }
54 
55 static void set_dfp128(uint64_t *dfp, uint64_t *src)
56 {
57     dfp[0] = src[HI_IDX];
58     dfp[1] = src[LO_IDX];
59 }
60 
61 struct PPC_DFP {
62     CPUPPCState *env;
63     uint64_t t64[2], a64[2], b64[2];
64     decNumber t, a, b;
65     decContext context;
66     uint8_t crbf;
67 };
68 
69 static void dfp_prepare_rounding_mode(decContext *context, uint64_t fpscr)
70 {
71     enum rounding rnd;
72 
73     switch ((fpscr & FP_DRN) >> FPSCR_DRN0) {
74     case 0:
75         rnd = DEC_ROUND_HALF_EVEN;
76         break;
77     case 1:
78         rnd = DEC_ROUND_DOWN;
79         break;
80     case 2:
81          rnd = DEC_ROUND_CEILING;
82          break;
83     case 3:
84          rnd = DEC_ROUND_FLOOR;
85          break;
86     case 4:
87          rnd = DEC_ROUND_HALF_UP;
88          break;
89     case 5:
90          rnd = DEC_ROUND_HALF_DOWN;
91          break;
92     case 6:
93          rnd = DEC_ROUND_UP;
94          break;
95     case 7:
96          rnd = DEC_ROUND_05UP;
97          break;
98     default:
99         g_assert_not_reached();
100     }
101 
102     decContextSetRounding(context, rnd);
103 }
104 
105 static void dfp_set_round_mode_from_immediate(uint8_t r, uint8_t rmc,
106                                                   struct PPC_DFP *dfp)
107 {
108     enum rounding rnd;
109     if (r == 0) {
110         switch (rmc & 3) {
111         case 0:
112             rnd = DEC_ROUND_HALF_EVEN;
113             break;
114         case 1:
115             rnd = DEC_ROUND_DOWN;
116             break;
117         case 2:
118             rnd = DEC_ROUND_HALF_UP;
119             break;
120         case 3: /* use FPSCR rounding mode */
121             return;
122         default:
123             assert(0); /* cannot get here */
124         }
125     } else { /* r == 1 */
126         switch (rmc & 3) {
127         case 0:
128             rnd = DEC_ROUND_CEILING;
129             break;
130         case 1:
131             rnd = DEC_ROUND_FLOOR;
132             break;
133         case 2:
134             rnd = DEC_ROUND_UP;
135             break;
136         case 3:
137             rnd = DEC_ROUND_HALF_DOWN;
138             break;
139         default:
140             assert(0); /* cannot get here */
141         }
142     }
143     decContextSetRounding(&dfp->context, rnd);
144 }
145 
146 static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
147                 uint64_t *b, CPUPPCState *env)
148 {
149     decContextDefault(&dfp->context, DEC_INIT_DECIMAL64);
150     dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
151     dfp->env = env;
152 
153     if (a) {
154         get_dfp64(dfp->a64, a);
155         decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a);
156     } else {
157         dfp->a64[0] = 0;
158         decNumberZero(&dfp->a);
159     }
160 
161     if (b) {
162         get_dfp64(dfp->b64, b);
163         decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b);
164     } else {
165         dfp->b64[0] = 0;
166         decNumberZero(&dfp->b);
167     }
168 }
169 
170 static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
171                 uint64_t *b, CPUPPCState *env)
172 {
173     decContextDefault(&dfp->context, DEC_INIT_DECIMAL128);
174     dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
175     dfp->env = env;
176 
177     if (a) {
178         get_dfp128(dfp->a64, a);
179         decimal128ToNumber((decimal128 *)dfp->a64, &dfp->a);
180     } else {
181         dfp->a64[0] = dfp->a64[1] = 0;
182         decNumberZero(&dfp->a);
183     }
184 
185     if (b) {
186         get_dfp128(dfp->b64, b);
187         decimal128ToNumber((decimal128 *)dfp->b64, &dfp->b);
188     } else {
189         dfp->b64[0] = dfp->b64[1] = 0;
190         decNumberZero(&dfp->b);
191     }
192 }
193 
194 static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag,
195                 uint64_t enabled)
196 {
197     dfp->env->fpscr |= (flag | FP_FX);
198     if (dfp->env->fpscr & enabled) {
199         dfp->env->fpscr |= FP_FEX;
200     }
201 }
202 
203 static void dfp_set_FPRF_from_FRT_with_context(struct PPC_DFP *dfp,
204                 decContext *context)
205 {
206     uint64_t fprf = 0;
207 
208     /* construct FPRF */
209     switch (decNumberClass(&dfp->t, context)) {
210     case DEC_CLASS_SNAN:
211         fprf = 0x01;
212         break;
213     case DEC_CLASS_QNAN:
214         fprf = 0x11;
215         break;
216     case DEC_CLASS_NEG_INF:
217         fprf = 0x09;
218         break;
219     case DEC_CLASS_NEG_NORMAL:
220         fprf = 0x08;
221         break;
222     case DEC_CLASS_NEG_SUBNORMAL:
223         fprf = 0x18;
224         break;
225     case DEC_CLASS_NEG_ZERO:
226         fprf = 0x12;
227         break;
228     case DEC_CLASS_POS_ZERO:
229         fprf = 0x02;
230         break;
231     case DEC_CLASS_POS_SUBNORMAL:
232         fprf = 0x14;
233         break;
234     case DEC_CLASS_POS_NORMAL:
235         fprf = 0x04;
236         break;
237     case DEC_CLASS_POS_INF:
238         fprf = 0x05;
239         break;
240     default:
241         assert(0); /* should never get here */
242     }
243     dfp->env->fpscr &= ~FP_FPRF;
244     dfp->env->fpscr |= (fprf << FPSCR_FPRF);
245 }
246 
247 static void dfp_set_FPRF_from_FRT(struct PPC_DFP *dfp)
248 {
249     dfp_set_FPRF_from_FRT_with_context(dfp, &dfp->context);
250 }
251 
252 static void dfp_set_FPRF_from_FRT_short(struct PPC_DFP *dfp)
253 {
254     decContext shortContext;
255     decContextDefault(&shortContext, DEC_INIT_DECIMAL32);
256     dfp_set_FPRF_from_FRT_with_context(dfp, &shortContext);
257 }
258 
259 static void dfp_set_FPRF_from_FRT_long(struct PPC_DFP *dfp)
260 {
261     decContext longContext;
262     decContextDefault(&longContext, DEC_INIT_DECIMAL64);
263     dfp_set_FPRF_from_FRT_with_context(dfp, &longContext);
264 }
265 
266 static void dfp_check_for_OX(struct PPC_DFP *dfp)
267 {
268     if (dfp->context.status & DEC_Overflow) {
269         dfp_set_FPSCR_flag(dfp, FP_OX, FP_OE);
270     }
271 }
272 
273 static void dfp_check_for_UX(struct PPC_DFP *dfp)
274 {
275     if (dfp->context.status & DEC_Underflow) {
276         dfp_set_FPSCR_flag(dfp, FP_UX, FP_UE);
277     }
278 }
279 
280 static void dfp_check_for_XX(struct PPC_DFP *dfp)
281 {
282     if (dfp->context.status & DEC_Inexact) {
283         dfp_set_FPSCR_flag(dfp, FP_XX | FP_FI, FP_XE);
284     }
285 }
286 
287 static void dfp_check_for_ZX(struct PPC_DFP *dfp)
288 {
289     if (dfp->context.status & DEC_Division_by_zero) {
290         dfp_set_FPSCR_flag(dfp, FP_ZX, FP_ZE);
291     }
292 }
293 
294 static void dfp_check_for_VXSNAN(struct PPC_DFP *dfp)
295 {
296     if (dfp->context.status & DEC_Invalid_operation) {
297         if (decNumberIsSNaN(&dfp->a) || decNumberIsSNaN(&dfp->b)) {
298             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FP_VE);
299         }
300     }
301 }
302 
303 static void dfp_check_for_VXSNAN_and_convert_to_QNaN(struct PPC_DFP *dfp)
304 {
305     if (decNumberIsSNaN(&dfp->t)) {
306         dfp->t.bits &= ~DECSNAN;
307         dfp->t.bits |= DECNAN;
308         dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FP_VE);
309     }
310 }
311 
312 static void dfp_check_for_VXISI(struct PPC_DFP *dfp, int testForSameSign)
313 {
314     if (dfp->context.status & DEC_Invalid_operation) {
315         if (decNumberIsInfinite(&dfp->a) && decNumberIsInfinite(&dfp->b)) {
316             int same = decNumberClass(&dfp->a, &dfp->context) ==
317                        decNumberClass(&dfp->b, &dfp->context);
318             if ((same && testForSameSign) || (!same && !testForSameSign)) {
319                 dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXISI, FP_VE);
320             }
321         }
322     }
323 }
324 
325 static void dfp_check_for_VXISI_add(struct PPC_DFP *dfp)
326 {
327     dfp_check_for_VXISI(dfp, 0);
328 }
329 
330 static void dfp_check_for_VXISI_subtract(struct PPC_DFP *dfp)
331 {
332     dfp_check_for_VXISI(dfp, 1);
333 }
334 
335 static void dfp_check_for_VXIMZ(struct PPC_DFP *dfp)
336 {
337     if (dfp->context.status & DEC_Invalid_operation) {
338         if ((decNumberIsInfinite(&dfp->a) && decNumberIsZero(&dfp->b)) ||
339             (decNumberIsInfinite(&dfp->b) && decNumberIsZero(&dfp->a))) {
340             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXIMZ, FP_VE);
341         }
342     }
343 }
344 
345 static void dfp_check_for_VXZDZ(struct PPC_DFP *dfp)
346 {
347     if (dfp->context.status & DEC_Division_undefined) {
348         dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXZDZ, FP_VE);
349     }
350 }
351 
352 static void dfp_check_for_VXIDI(struct PPC_DFP *dfp)
353 {
354     if (dfp->context.status & DEC_Invalid_operation) {
355         if (decNumberIsInfinite(&dfp->a) && decNumberIsInfinite(&dfp->b)) {
356             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXIDI, FP_VE);
357         }
358     }
359 }
360 
361 static void dfp_check_for_VXVC(struct PPC_DFP *dfp)
362 {
363     if (decNumberIsNaN(&dfp->a) || decNumberIsNaN(&dfp->b)) {
364         dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXVC, FP_VE);
365     }
366 }
367 
368 static void dfp_check_for_VXCVI(struct PPC_DFP *dfp)
369 {
370     if ((dfp->context.status & DEC_Invalid_operation) &&
371         (!decNumberIsSNaN(&dfp->a)) &&
372         (!decNumberIsSNaN(&dfp->b))) {
373         dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE);
374     }
375 }
376 
377 static void dfp_set_CRBF_from_T(struct PPC_DFP *dfp)
378 {
379     if (decNumberIsNaN(&dfp->t)) {
380         dfp->crbf = 1;
381     } else if (decNumberIsZero(&dfp->t)) {
382         dfp->crbf = 2;
383     } else if (decNumberIsNegative(&dfp->t)) {
384         dfp->crbf = 8;
385     } else {
386         dfp->crbf = 4;
387     }
388 }
389 
390 static void dfp_set_FPCC_from_CRBF(struct PPC_DFP *dfp)
391 {
392     dfp->env->fpscr &= ~FP_FPCC;
393     dfp->env->fpscr |= (dfp->crbf << FPSCR_FPCC);
394 }
395 
396 static inline void dfp_makeQNaN(decNumber *dn)
397 {
398     dn->bits &= ~DECSPECIAL;
399     dn->bits |= DECNAN;
400 }
401 
402 static inline int dfp_get_digit(decNumber *dn, int n)
403 {
404     assert(DECDPUN == 3);
405     int unit = n / DECDPUN;
406     int dig = n % DECDPUN;
407     switch (dig) {
408     case 0:
409         return dn->lsu[unit] % 10;
410     case 1:
411         return (dn->lsu[unit] / 10) % 10;
412     case 2:
413         return dn->lsu[unit] / 100;
414     }
415     g_assert_not_reached();
416 }
417 
418 #define DFP_HELPER_TAB(op, dnop, postprocs, size)                              \
419 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b)      \
420 {                                                                              \
421     struct PPC_DFP dfp;                                                        \
422     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
423     dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context);                                \
424     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
425     postprocs(&dfp);                                                           \
426     if (size == 64) {                                                          \
427         set_dfp64(t, dfp.t64);                                                 \
428     } else if (size == 128) {                                                  \
429         set_dfp128(t, dfp.t64);                                                \
430     }                                                                          \
431 }
432 
433 static void ADD_PPs(struct PPC_DFP *dfp)
434 {
435     dfp_set_FPRF_from_FRT(dfp);
436     dfp_check_for_OX(dfp);
437     dfp_check_for_UX(dfp);
438     dfp_check_for_XX(dfp);
439     dfp_check_for_VXSNAN(dfp);
440     dfp_check_for_VXISI_add(dfp);
441 }
442 
443 DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
444 DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
445 
446 static void SUB_PPs(struct PPC_DFP *dfp)
447 {
448     dfp_set_FPRF_from_FRT(dfp);
449     dfp_check_for_OX(dfp);
450     dfp_check_for_UX(dfp);
451     dfp_check_for_XX(dfp);
452     dfp_check_for_VXSNAN(dfp);
453     dfp_check_for_VXISI_subtract(dfp);
454 }
455 
456 DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
457 DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
458 
459 static void MUL_PPs(struct PPC_DFP *dfp)
460 {
461     dfp_set_FPRF_from_FRT(dfp);
462     dfp_check_for_OX(dfp);
463     dfp_check_for_UX(dfp);
464     dfp_check_for_XX(dfp);
465     dfp_check_for_VXSNAN(dfp);
466     dfp_check_for_VXIMZ(dfp);
467 }
468 
469 DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
470 DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
471 
472 static void DIV_PPs(struct PPC_DFP *dfp)
473 {
474     dfp_set_FPRF_from_FRT(dfp);
475     dfp_check_for_OX(dfp);
476     dfp_check_for_UX(dfp);
477     dfp_check_for_ZX(dfp);
478     dfp_check_for_XX(dfp);
479     dfp_check_for_VXSNAN(dfp);
480     dfp_check_for_VXZDZ(dfp);
481     dfp_check_for_VXIDI(dfp);
482 }
483 
484 DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
485 DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
486 
487 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)                            \
488 uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b)               \
489 {                                                                              \
490     struct PPC_DFP dfp;                                                        \
491     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
492     dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context);                                \
493     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
494     postprocs(&dfp);                                                           \
495     return dfp.crbf;                                                           \
496 }
497 
498 static void CMPU_PPs(struct PPC_DFP *dfp)
499 {
500     dfp_set_CRBF_from_T(dfp);
501     dfp_set_FPCC_from_CRBF(dfp);
502     dfp_check_for_VXSNAN(dfp);
503 }
504 
505 DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
506 DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
507 
508 static void CMPO_PPs(struct PPC_DFP *dfp)
509 {
510     dfp_set_CRBF_from_T(dfp);
511     dfp_set_FPCC_from_CRBF(dfp);
512     dfp_check_for_VXSNAN(dfp);
513     dfp_check_for_VXVC(dfp);
514 }
515 
516 DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
517 DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
518 
519 #define DFP_HELPER_TSTDC(op, size)                                       \
520 uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm)        \
521 {                                                                        \
522     struct PPC_DFP dfp;                                                  \
523     int match = 0;                                                       \
524                                                                          \
525     dfp_prepare_decimal##size(&dfp, a, 0, env);                          \
526                                                                          \
527     match |= (dcm & 0x20) && decNumberIsZero(&dfp.a);                    \
528     match |= (dcm & 0x10) && decNumberIsSubnormal(&dfp.a, &dfp.context); \
529     match |= (dcm & 0x08) && decNumberIsNormal(&dfp.a, &dfp.context);    \
530     match |= (dcm & 0x04) && decNumberIsInfinite(&dfp.a);                \
531     match |= (dcm & 0x02) && decNumberIsQNaN(&dfp.a);                    \
532     match |= (dcm & 0x01) && decNumberIsSNaN(&dfp.a);                    \
533                                                                          \
534     if (decNumberIsNegative(&dfp.a)) {                                   \
535         dfp.crbf = match ? 0xA : 0x8;                                    \
536     } else {                                                             \
537         dfp.crbf = match ? 0x2 : 0x0;                                    \
538     }                                                                    \
539                                                                          \
540     dfp_set_FPCC_from_CRBF(&dfp);                                        \
541     return dfp.crbf;                                                     \
542 }
543 
544 DFP_HELPER_TSTDC(dtstdc, 64)
545 DFP_HELPER_TSTDC(dtstdcq, 128)
546 
547 #define DFP_HELPER_TSTDG(op, size)                                       \
548 uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm)        \
549 {                                                                        \
550     struct PPC_DFP dfp;                                                  \
551     int minexp, maxexp, nzero_digits, nzero_idx, is_negative, is_zero,   \
552         is_extreme_exp, is_subnormal, is_normal, leftmost_is_nonzero,    \
553         match;                                                           \
554                                                                          \
555     dfp_prepare_decimal##size(&dfp, a, 0, env);                          \
556                                                                          \
557     if ((size) == 64) {                                                  \
558         minexp = -398;                                                   \
559         maxexp = 369;                                                    \
560         nzero_digits = 16;                                               \
561         nzero_idx = 5;                                                   \
562     } else if ((size) == 128) {                                          \
563         minexp = -6176;                                                  \
564         maxexp = 6111;                                                   \
565         nzero_digits = 34;                                               \
566         nzero_idx = 11;                                                  \
567     }                                                                    \
568                                                                          \
569     is_negative = decNumberIsNegative(&dfp.a);                           \
570     is_zero = decNumberIsZero(&dfp.a);                                   \
571     is_extreme_exp = (dfp.a.exponent == maxexp) ||                       \
572                      (dfp.a.exponent == minexp);                         \
573     is_subnormal = decNumberIsSubnormal(&dfp.a, &dfp.context);           \
574     is_normal = decNumberIsNormal(&dfp.a, &dfp.context);                 \
575     leftmost_is_nonzero = (dfp.a.digits == nzero_digits) &&              \
576                           (dfp.a.lsu[nzero_idx] != 0);                   \
577     match = 0;                                                           \
578                                                                          \
579     match |= (dcm & 0x20) && is_zero && !is_extreme_exp;                 \
580     match |= (dcm & 0x10) && is_zero && is_extreme_exp;                  \
581     match |= (dcm & 0x08) &&                                             \
582              (is_subnormal || (is_normal && is_extreme_exp));            \
583     match |= (dcm & 0x04) && is_normal && !is_extreme_exp &&             \
584              !leftmost_is_nonzero;                                       \
585     match |= (dcm & 0x02) && is_normal && !is_extreme_exp &&             \
586              leftmost_is_nonzero;                                        \
587     match |= (dcm & 0x01) && decNumberIsSpecial(&dfp.a);                 \
588                                                                          \
589     if (is_negative) {                                                   \
590         dfp.crbf = match ? 0xA : 0x8;                                    \
591     } else {                                                             \
592         dfp.crbf = match ? 0x2 : 0x0;                                    \
593     }                                                                    \
594                                                                          \
595     dfp_set_FPCC_from_CRBF(&dfp);                                        \
596     return dfp.crbf;                                                     \
597 }
598 
599 DFP_HELPER_TSTDG(dtstdg, 64)
600 DFP_HELPER_TSTDG(dtstdgq, 128)
601 
602 #define DFP_HELPER_TSTEX(op, size)                                       \
603 uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b)         \
604 {                                                                        \
605     struct PPC_DFP dfp;                                                  \
606     int expa, expb, a_is_special, b_is_special;                          \
607                                                                          \
608     dfp_prepare_decimal##size(&dfp, a, b, env);                          \
609                                                                          \
610     expa = dfp.a.exponent;                                               \
611     expb = dfp.b.exponent;                                               \
612     a_is_special = decNumberIsSpecial(&dfp.a);                           \
613     b_is_special = decNumberIsSpecial(&dfp.b);                           \
614                                                                          \
615     if (a_is_special || b_is_special) {                                  \
616         int atype = a_is_special ? (decNumberIsNaN(&dfp.a) ? 4 : 2) : 1; \
617         int btype = b_is_special ? (decNumberIsNaN(&dfp.b) ? 4 : 2) : 1; \
618         dfp.crbf = (atype ^ btype) ? 0x1 : 0x2;                          \
619     } else if (expa < expb) {                                            \
620         dfp.crbf = 0x8;                                                  \
621     } else if (expa > expb) {                                            \
622         dfp.crbf = 0x4;                                                  \
623     } else {                                                             \
624         dfp.crbf = 0x2;                                                  \
625     }                                                                    \
626                                                                          \
627     dfp_set_FPCC_from_CRBF(&dfp);                                        \
628     return dfp.crbf;                                                     \
629 }
630 
631 DFP_HELPER_TSTEX(dtstex, 64)
632 DFP_HELPER_TSTEX(dtstexq, 128)
633 
634 #define DFP_HELPER_TSTSF(op, size)                                       \
635 uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b)         \
636 {                                                                        \
637     struct PPC_DFP dfp;                                                  \
638     unsigned k;                                                          \
639     uint64_t a64;                                                        \
640                                                                          \
641     dfp_prepare_decimal##size(&dfp, 0, b, env);                          \
642                                                                          \
643     get_dfp64(&a64, a);                                                  \
644     k = a64 & 0x3F;                                                      \
645                                                                          \
646     if (unlikely(decNumberIsSpecial(&dfp.b))) {                          \
647         dfp.crbf = 1;                                                    \
648     } else if (k == 0) {                                                 \
649         dfp.crbf = 4;                                                    \
650     } else if (unlikely(decNumberIsZero(&dfp.b))) {                      \
651         /* Zero has no sig digits */                                     \
652         dfp.crbf = 4;                                                    \
653     } else {                                                             \
654         unsigned nsd = dfp.b.digits;                                     \
655         if (k < nsd) {                                                   \
656             dfp.crbf = 8;                                                \
657         } else if (k > nsd) {                                            \
658             dfp.crbf = 4;                                                \
659         } else {                                                         \
660             dfp.crbf = 2;                                                \
661         }                                                                \
662     }                                                                    \
663                                                                          \
664     dfp_set_FPCC_from_CRBF(&dfp);                                        \
665     return dfp.crbf;                                                     \
666 }
667 
668 DFP_HELPER_TSTSF(dtstsf, 64)
669 DFP_HELPER_TSTSF(dtstsfq, 128)
670 
671 #define DFP_HELPER_TSTSFI(op, size)                                     \
672 uint32_t helper_##op(CPUPPCState *env, uint32_t a, uint64_t *b)         \
673 {                                                                       \
674     struct PPC_DFP dfp;                                                 \
675     unsigned uim;                                                       \
676                                                                         \
677     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
678                                                                         \
679     uim = a & 0x3F;                                                     \
680                                                                         \
681     if (unlikely(decNumberIsSpecial(&dfp.b))) {                         \
682         dfp.crbf = 1;                                                   \
683     } else if (uim == 0) {                                              \
684         dfp.crbf = 4;                                                   \
685     } else if (unlikely(decNumberIsZero(&dfp.b))) {                     \
686         /* Zero has no sig digits */                                    \
687         dfp.crbf = 4;                                                   \
688     } else {                                                            \
689         unsigned nsd = dfp.b.digits;                                    \
690         if (uim < nsd) {                                                \
691             dfp.crbf = 8;                                               \
692         } else if (uim > nsd) {                                         \
693             dfp.crbf = 4;                                               \
694         } else {                                                        \
695             dfp.crbf = 2;                                               \
696         }                                                               \
697     }                                                                   \
698                                                                         \
699     dfp_set_FPCC_from_CRBF(&dfp);                                       \
700     return dfp.crbf;                                                    \
701 }
702 
703 DFP_HELPER_TSTSFI(dtstsfi, 64)
704 DFP_HELPER_TSTSFI(dtstsfiq, 128)
705 
706 static void QUA_PPs(struct PPC_DFP *dfp)
707 {
708     dfp_set_FPRF_from_FRT(dfp);
709     dfp_check_for_XX(dfp);
710     dfp_check_for_VXSNAN(dfp);
711     dfp_check_for_VXCVI(dfp);
712 }
713 
714 static void dfp_quantize(uint8_t rmc, struct PPC_DFP *dfp)
715 {
716     dfp_set_round_mode_from_immediate(0, rmc, dfp);
717     decNumberQuantize(&dfp->t, &dfp->b, &dfp->a, &dfp->context);
718     if (decNumberIsSNaN(&dfp->a)) {
719         dfp->t = dfp->a;
720         dfp_makeQNaN(&dfp->t);
721     } else if (decNumberIsSNaN(&dfp->b)) {
722         dfp->t = dfp->b;
723         dfp_makeQNaN(&dfp->t);
724     } else if (decNumberIsQNaN(&dfp->a)) {
725         dfp->t = dfp->a;
726     } else if (decNumberIsQNaN(&dfp->b)) {
727         dfp->t = dfp->b;
728     }
729 }
730 
731 #define DFP_HELPER_QUAI(op, size)                                       \
732 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,            \
733                  uint32_t te, uint32_t rmc)                             \
734 {                                                                       \
735     struct PPC_DFP dfp;                                                 \
736                                                                         \
737     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
738                                                                         \
739     decNumberFromUInt32(&dfp.a, 1);                                     \
740     dfp.a.exponent = (int32_t)((int8_t)(te << 3) >> 3);                 \
741                                                                         \
742     dfp_quantize(rmc, &dfp);                                            \
743     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
744                               &dfp.context);                            \
745     QUA_PPs(&dfp);                                                      \
746                                                                         \
747     if (size == 64) {                                                   \
748         set_dfp64(t, dfp.t64);                                          \
749     } else if (size == 128) {                                           \
750         set_dfp128(t, dfp.t64);                                         \
751     }                                                                   \
752 }
753 
754 DFP_HELPER_QUAI(dquai, 64)
755 DFP_HELPER_QUAI(dquaiq, 128)
756 
757 #define DFP_HELPER_QUA(op, size)                                        \
758 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
759                  uint64_t *b, uint32_t rmc)                             \
760 {                                                                       \
761     struct PPC_DFP dfp;                                                 \
762                                                                         \
763     dfp_prepare_decimal##size(&dfp, a, b, env);                         \
764                                                                         \
765     dfp_quantize(rmc, &dfp);                                            \
766     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
767                               &dfp.context);                            \
768     QUA_PPs(&dfp);                                                      \
769                                                                         \
770     if (size == 64) {                                                   \
771         set_dfp64(t, dfp.t64);                                          \
772     } else if (size == 128) {                                           \
773         set_dfp128(t, dfp.t64);                                         \
774     }                                                                   \
775 }
776 
777 DFP_HELPER_QUA(dqua, 64)
778 DFP_HELPER_QUA(dquaq, 128)
779 
780 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
781                              struct PPC_DFP *dfp)
782 {
783     int msd_orig, msd_rslt;
784 
785     if (unlikely((ref_sig == 0) || (dfp->b.digits <= ref_sig))) {
786         dfp->t = dfp->b;
787         if (decNumberIsSNaN(&dfp->b)) {
788             dfp_makeQNaN(&dfp->t);
789             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FPSCR_VE);
790         }
791         return;
792     }
793 
794     /* Reround is equivalent to quantizing b with 1**E(n) where */
795     /* n = exp(b) + numDigits(b) - reference_significance.      */
796 
797     decNumberFromUInt32(&dfp->a, 1);
798     dfp->a.exponent = dfp->b.exponent + dfp->b.digits - ref_sig;
799 
800     if (unlikely(dfp->a.exponent > xmax)) {
801         dfp->t.digits = 0;
802         dfp->t.bits &= ~DECNEG;
803         dfp_makeQNaN(&dfp->t);
804         dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);
805         return;
806     }
807 
808     dfp_quantize(rmc, dfp);
809 
810     msd_orig = dfp_get_digit(&dfp->b, dfp->b.digits-1);
811     msd_rslt = dfp_get_digit(&dfp->t, dfp->t.digits-1);
812 
813     /* If the quantization resulted in rounding up to the next magnitude, */
814     /* then we need to shift the significand and adjust the exponent.     */
815 
816     if (unlikely((msd_orig == 9) && (msd_rslt == 1))) {
817 
818         decNumber negone;
819 
820         decNumberFromInt32(&negone, -1);
821         decNumberShift(&dfp->t, &dfp->t, &negone, &dfp->context);
822         dfp->t.exponent++;
823 
824         if (unlikely(dfp->t.exponent > xmax)) {
825             dfp_makeQNaN(&dfp->t);
826             dfp->t.digits = 0;
827             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE);
828             /* Inhibit XX in this case */
829             decContextClearStatus(&dfp->context, DEC_Inexact);
830         }
831     }
832 }
833 
834 #define DFP_HELPER_RRND(op, size)                                       \
835 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
836                  uint64_t *b, uint32_t rmc)                             \
837 {                                                                       \
838     struct PPC_DFP dfp;                                                 \
839     uint64_t a64;                                                       \
840     int32_t ref_sig;                                                    \
841     int32_t xmax = ((size) == 64) ? 369 : 6111;                         \
842                                                                         \
843     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
844                                                                         \
845     get_dfp64(&a64, a);                                                 \
846     ref_sig = a64 & 0x3f;                                               \
847                                                                         \
848     _dfp_reround(rmc, ref_sig, xmax, &dfp);                             \
849     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
850                               &dfp.context);                            \
851     QUA_PPs(&dfp);                                                      \
852                                                                         \
853     if (size == 64) {                                                   \
854         set_dfp64(t, dfp.t64);                                          \
855     } else if (size == 128) {                                           \
856         set_dfp128(t, dfp.t64);                                         \
857     }                                                                   \
858 }
859 
860 DFP_HELPER_RRND(drrnd, 64)
861 DFP_HELPER_RRND(drrndq, 128)
862 
863 #define DFP_HELPER_RINT(op, postprocs, size)                                   \
864 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,                   \
865              uint32_t r, uint32_t rmc)                                         \
866 {                                                                              \
867     struct PPC_DFP dfp;                                                        \
868                                                                                \
869     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
870                                                                                \
871     dfp_set_round_mode_from_immediate(r, rmc, &dfp);                           \
872     decNumberToIntegralExact(&dfp.t, &dfp.b, &dfp.context);                    \
873     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
874     postprocs(&dfp);                                                           \
875                                                                                \
876     if (size == 64) {                                                          \
877         set_dfp64(t, dfp.t64);                                                 \
878     } else if (size == 128) {                                                  \
879         set_dfp128(t, dfp.t64);                                                \
880     }                                                                          \
881 }
882 
883 static void RINTX_PPs(struct PPC_DFP *dfp)
884 {
885     dfp_set_FPRF_from_FRT(dfp);
886     dfp_check_for_XX(dfp);
887     dfp_check_for_VXSNAN(dfp);
888 }
889 
890 DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
891 DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
892 
893 static void RINTN_PPs(struct PPC_DFP *dfp)
894 {
895     dfp_set_FPRF_from_FRT(dfp);
896     dfp_check_for_VXSNAN(dfp);
897 }
898 
899 DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
900 DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
901 
902 void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
903 {
904     struct PPC_DFP dfp;
905     uint64_t b64;
906     uint32_t b_short;
907 
908     get_dfp64(&b64, b);
909     b_short = (uint32_t)b64;
910 
911     dfp_prepare_decimal64(&dfp, 0, 0, env);
912     decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
913     decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.t, &dfp.context);
914     set_dfp64(t, dfp.t64);
915     dfp_set_FPRF_from_FRT(&dfp);
916 }
917 
918 void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
919 {
920     struct PPC_DFP dfp;
921     uint64_t b64;
922     dfp_prepare_decimal128(&dfp, 0, 0, env);
923     get_dfp64(&b64, b);
924     decimal64ToNumber((decimal64 *)&b64, &dfp.t);
925 
926     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
927     dfp_set_FPRF_from_FRT(&dfp);
928 
929     decimal128FromNumber((decimal128 *)&dfp.t64, &dfp.t, &dfp.context);
930     set_dfp128(t, dfp.t64);
931 }
932 
933 void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
934 {
935     struct PPC_DFP dfp;
936     uint32_t t_short = 0;
937     uint64_t t64;
938     dfp_prepare_decimal64(&dfp, 0, b, env);
939     decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context);
940     decimal32ToNumber((decimal32 *)&t_short, &dfp.t);
941 
942     dfp_set_FPRF_from_FRT_short(&dfp);
943     dfp_check_for_OX(&dfp);
944     dfp_check_for_UX(&dfp);
945     dfp_check_for_XX(&dfp);
946 
947     t64 = (uint64_t)t_short;
948     set_dfp64(t, &t64);
949 }
950 
951 void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
952 {
953     struct PPC_DFP dfp;
954     dfp_prepare_decimal128(&dfp, 0, b, env);
955     decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.b, &dfp.context);
956     decimal64ToNumber((decimal64 *)&dfp.t64, &dfp.t);
957 
958     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
959     dfp_set_FPRF_from_FRT_long(&dfp);
960     dfp_check_for_OX(&dfp);
961     dfp_check_for_UX(&dfp);
962     dfp_check_for_XX(&dfp);
963 
964     dfp.t64[0] = dfp.t64[1] = 0;
965     decimal64FromNumber((decimal64 *)dfp.t64, &dfp.t, &dfp.context);
966     set_dfp128(t, dfp.t64);
967 }
968 
969 #define DFP_HELPER_CFFIX(op, size)                                             \
970 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                   \
971 {                                                                              \
972     struct PPC_DFP dfp;                                                        \
973     uint64_t b64;                                                              \
974     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
975     get_dfp64(&b64, b);                                                        \
976     decNumberFromInt64(&dfp.t, (int64_t)b64);                                  \
977     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
978     CFFIX_PPs(&dfp);                                                           \
979                                                                                \
980     if (size == 64) {                                                          \
981         set_dfp64(t, dfp.t64);                                                 \
982     } else if (size == 128) {                                                  \
983         set_dfp128(t, dfp.t64);                                                \
984     }                                                                          \
985 }
986 
987 static void CFFIX_PPs(struct PPC_DFP *dfp)
988 {
989     dfp_set_FPRF_from_FRT(dfp);
990     dfp_check_for_XX(dfp);
991 }
992 
993 DFP_HELPER_CFFIX(dcffix, 64)
994 DFP_HELPER_CFFIX(dcffixq, 128)
995 
996 #define DFP_HELPER_CTFIX(op, size)                                            \
997 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                  \
998 {                                                                             \
999     struct PPC_DFP dfp;                                                       \
1000     dfp_prepare_decimal##size(&dfp, 0, b, env);                               \
1001                                                                               \
1002     if (unlikely(decNumberIsSpecial(&dfp.b))) {                               \
1003         uint64_t invalid_flags = FP_VX | FP_VXCVI;                            \
1004         if (decNumberIsInfinite(&dfp.b)) {                                    \
1005             dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
1006         } else { /* NaN */                                                    \
1007             dfp.t64[0] = INT64_MIN;                                           \
1008             if (decNumberIsSNaN(&dfp.b)) {                                    \
1009                 invalid_flags |= FP_VXSNAN;                                   \
1010             }                                                                 \
1011         }                                                                     \
1012         dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);                       \
1013     } else if (unlikely(decNumberIsZero(&dfp.b))) {                           \
1014         dfp.t64[0] = 0;                                                       \
1015     } else {                                                                  \
1016         decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);               \
1017         dfp.t64[0] = decNumberIntegralToInt64(&dfp.b, &dfp.context);          \
1018         if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {      \
1019             dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
1020             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);                \
1021         } else {                                                              \
1022             dfp_check_for_XX(&dfp);                                           \
1023         }                                                                     \
1024     }                                                                         \
1025                                                                               \
1026     set_dfp64(t, dfp.t64);                                                    \
1027 }
1028 
1029 DFP_HELPER_CTFIX(dctfix, 64)
1030 DFP_HELPER_CTFIX(dctfixq, 128)
1031 
1032 static inline void dfp_set_bcd_digit_64(uint64_t *t, uint8_t digit,
1033                                             unsigned n)
1034 {
1035     *t |= ((uint64_t)(digit & 0xF) << (n << 2));
1036 }
1037 
1038 static inline void dfp_set_bcd_digit_128(uint64_t *t, uint8_t digit,
1039                                              unsigned n)
1040 {
1041     t[(n & 0x10) ? HI_IDX : LO_IDX] |=
1042         ((uint64_t)(digit & 0xF) << ((n & 15) << 2));
1043 }
1044 
1045 static inline void dfp_set_sign_64(uint64_t *t, uint8_t sgn)
1046 {
1047     *t <<= 4;
1048     *t |= (sgn & 0xF);
1049 }
1050 
1051 static inline void dfp_set_sign_128(uint64_t *t, uint8_t sgn)
1052 {
1053     t[HI_IDX] <<= 4;
1054     t[HI_IDX] |= (t[LO_IDX] >> 60);
1055     t[LO_IDX] <<= 4;
1056     t[LO_IDX] |= (sgn & 0xF);
1057 }
1058 
1059 #define DFP_HELPER_DEDPD(op, size)                                        \
1060 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \
1061 {                                                                         \
1062     struct PPC_DFP dfp;                                                   \
1063     uint8_t digits[34];                                                   \
1064     int i, N;                                                             \
1065                                                                           \
1066     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
1067                                                                           \
1068     decNumberGetBCD(&dfp.b, digits);                                      \
1069     dfp.t64[0] = dfp.t64[1] = 0;                                          \
1070     N = dfp.b.digits;                                                     \
1071                                                                           \
1072     for (i = 0; (i < N) && (i < (size)/4); i++) {                         \
1073         dfp_set_bcd_digit_##size(dfp.t64, digits[N-i-1], i);              \
1074     }                                                                     \
1075                                                                           \
1076     if (sp & 2) {                                                         \
1077         uint8_t sgn;                                                      \
1078                                                                           \
1079         if (decNumberIsNegative(&dfp.b)) {                                \
1080             sgn = 0xD;                                                    \
1081         } else {                                                          \
1082             sgn = ((sp & 1) ? 0xF : 0xC);                                 \
1083         }                                                                 \
1084         dfp_set_sign_##size(dfp.t64, sgn);                                \
1085     }                                                                     \
1086                                                                           \
1087     if (size == 64) {                                                     \
1088         set_dfp64(t, dfp.t64);                                            \
1089     } else if (size == 128) {                                             \
1090         set_dfp128(t, dfp.t64);                                           \
1091     }                                                                     \
1092 }
1093 
1094 DFP_HELPER_DEDPD(ddedpd, 64)
1095 DFP_HELPER_DEDPD(ddedpdq, 128)
1096 
1097 static inline uint8_t dfp_get_bcd_digit_64(uint64_t *t, unsigned n)
1098 {
1099     return *t >> ((n << 2) & 63) & 15;
1100 }
1101 
1102 static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n)
1103 {
1104     return t[(n & 0x10) ? HI_IDX : LO_IDX] >> ((n << 2) & 63) & 15;
1105 }
1106 
1107 #define DFP_HELPER_ENBCD(op, size)                                           \
1108 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s)     \
1109 {                                                                            \
1110     struct PPC_DFP dfp;                                                      \
1111     uint8_t digits[32];                                                      \
1112     int n = 0, offset = 0, sgn = 0, nonzero = 0;                             \
1113                                                                              \
1114     dfp_prepare_decimal##size(&dfp, 0, b, env);                              \
1115                                                                              \
1116     decNumberZero(&dfp.t);                                                   \
1117                                                                              \
1118     if (s) {                                                                 \
1119         uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++);     \
1120         switch (sgnNibble) {                                                 \
1121         case 0xD:                                                            \
1122         case 0xB:                                                            \
1123             sgn = 1;                                                         \
1124             break;                                                           \
1125         case 0xC:                                                            \
1126         case 0xF:                                                            \
1127         case 0xA:                                                            \
1128         case 0xE:                                                            \
1129             sgn = 0;                                                         \
1130             break;                                                           \
1131         default:                                                             \
1132             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);            \
1133             return;                                                          \
1134         }                                                                    \
1135         }                                                                    \
1136                                                                              \
1137     while (offset < (size) / 4) {                                            \
1138         n++;                                                                 \
1139         digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
1140         if (digits[(size) / 4 - n] > 10) {                                   \
1141             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);            \
1142             return;                                                          \
1143         } else {                                                             \
1144             nonzero |= (digits[(size) / 4 - n] > 0);                         \
1145         }                                                                    \
1146     }                                                                        \
1147                                                                              \
1148     if (nonzero) {                                                           \
1149         decNumberSetBCD(&dfp.t, digits + ((size) / 4) - n, n);               \
1150     }                                                                        \
1151                                                                              \
1152     if (s && sgn)  {                                                         \
1153         dfp.t.bits |= DECNEG;                                                \
1154     }                                                                        \
1155     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,              \
1156                               &dfp.context);                                 \
1157     dfp_set_FPRF_from_FRT(&dfp);                                             \
1158     if ((size) == 64) {                                                      \
1159         set_dfp64(t, dfp.t64);                                               \
1160     } else if ((size) == 128) {                                              \
1161         set_dfp128(t, dfp.t64);                                              \
1162     }                                                                        \
1163 }
1164 
1165 DFP_HELPER_ENBCD(denbcd, 64)
1166 DFP_HELPER_ENBCD(denbcdq, 128)
1167 
1168 #define DFP_HELPER_XEX(op, size)                               \
1169 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)   \
1170 {                                                              \
1171     struct PPC_DFP dfp;                                        \
1172     uint64_t t64;                                              \
1173                                                                \
1174     dfp_prepare_decimal##size(&dfp, 0, b, env);                \
1175                                                                \
1176     if (unlikely(decNumberIsSpecial(&dfp.b))) {                \
1177         if (decNumberIsInfinite(&dfp.b)) {                     \
1178             t64 = -1;                                          \
1179         } else if (decNumberIsSNaN(&dfp.b)) {                  \
1180             t64 = -3;                                          \
1181         } else if (decNumberIsQNaN(&dfp.b)) {                  \
1182             t64 = -2;                                          \
1183         } else {                                               \
1184             assert(0);                                         \
1185         }                                                      \
1186         set_dfp64(t, &t64);                                    \
1187     } else {                                                   \
1188         if ((size) == 64) {                                    \
1189             t64 = dfp.b.exponent + 398;                        \
1190         } else if ((size) == 128) {                            \
1191             t64 = dfp.b.exponent + 6176;                       \
1192         } else {                                               \
1193             assert(0);                                         \
1194         }                                                      \
1195         set_dfp64(t, &t64);                                    \
1196     }                                                          \
1197 }
1198 
1199 DFP_HELPER_XEX(dxex, 64)
1200 DFP_HELPER_XEX(dxexq, 128)
1201 
1202 static void dfp_set_raw_exp_64(uint64_t *t, uint64_t raw)
1203 {
1204     *t &= 0x8003ffffffffffffULL;
1205     *t |= (raw << (63 - 13));
1206 }
1207 
1208 static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
1209 {
1210     t[HI_IDX] &= 0x80003fffffffffffULL;
1211     t[HI_IDX] |= (raw << (63 - 17));
1212 }
1213 
1214 #define DFP_HELPER_IEX(op, size)                                          \
1215 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
1216 {                                                                         \
1217     struct PPC_DFP dfp;                                                   \
1218     uint64_t raw_qnan, raw_snan, raw_inf, max_exp, a64;                   \
1219     int bias;                                                             \
1220     int64_t exp;                                                          \
1221                                                                           \
1222     get_dfp64(&a64, a);                                                   \
1223     exp = (int64_t)a64;                                                   \
1224     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
1225                                                                           \
1226     if ((size) == 64) {                                                   \
1227         max_exp = 767;                                                    \
1228         raw_qnan = 0x1F00;                                                \
1229         raw_snan = 0x1F80;                                                \
1230         raw_inf = 0x1E00;                                                 \
1231         bias = 398;                                                       \
1232     } else if ((size) == 128) {                                           \
1233         max_exp = 12287;                                                  \
1234         raw_qnan = 0x1f000;                                               \
1235         raw_snan = 0x1f800;                                               \
1236         raw_inf = 0x1e000;                                                \
1237         bias = 6176;                                                      \
1238     } else {                                                              \
1239         assert(0);                                                        \
1240     }                                                                     \
1241                                                                           \
1242     if (unlikely((exp < 0) || (exp > max_exp))) {                         \
1243         dfp.t64[0] = dfp.b64[0];                                          \
1244         dfp.t64[1] = dfp.b64[1];                                          \
1245         if (exp == -1) {                                                  \
1246             dfp_set_raw_exp_##size(dfp.t64, raw_inf);                     \
1247         } else if (exp == -3) {                                           \
1248             dfp_set_raw_exp_##size(dfp.t64, raw_snan);                    \
1249         } else {                                                          \
1250             dfp_set_raw_exp_##size(dfp.t64, raw_qnan);                    \
1251         }                                                                 \
1252     } else {                                                              \
1253         dfp.t = dfp.b;                                                    \
1254         if (unlikely(decNumberIsSpecial(&dfp.t))) {                       \
1255             dfp.t.bits &= ~DECSPECIAL;                                    \
1256         }                                                                 \
1257         dfp.t.exponent = exp - bias;                                      \
1258         decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,       \
1259                                   &dfp.context);                          \
1260     }                                                                     \
1261     if (size == 64) {                                                     \
1262         set_dfp64(t, dfp.t64);                                            \
1263     } else if (size == 128) {                                             \
1264         set_dfp128(t, dfp.t64);                                           \
1265     }                                                                     \
1266 }
1267 
1268 DFP_HELPER_IEX(diex, 64)
1269 DFP_HELPER_IEX(diexq, 128)
1270 
1271 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
1272 {
1273 
1274     /* The most significant 5 bits of the PowerPC DFP format combine bits  */
1275     /* from the left-most decimal digit (LMD) and the biased exponent.     */
1276     /* This  routine clears the LMD bits while preserving the exponent     */
1277     /*  bits.  See "Figure 80: Encoding of bits 0:4 of the G field for     */
1278     /*  Finite Numbers" in the Power ISA for additional details.           */
1279 
1280     uint64_t g5msb = (*t >> 58) & 0x1F;
1281 
1282     if ((g5msb >> 3) < 3) { /* LMD in [0-7] ? */
1283        *t &= ~(7ULL << 58);
1284     } else {
1285        switch (g5msb & 7) {
1286        case 0:
1287        case 1:
1288            g5msb = 0;
1289            break;
1290        case 2:
1291        case 3:
1292            g5msb = 0x8;
1293            break;
1294        case 4:
1295        case 5:
1296            g5msb = 0x10;
1297            break;
1298        case 6:
1299            g5msb = 0x1E;
1300            break;
1301        case 7:
1302            g5msb = 0x1F;
1303            break;
1304        }
1305 
1306         *t &= ~(0x1fULL << 58);
1307         *t |= (g5msb << 58);
1308     }
1309 }
1310 
1311 #define DFP_HELPER_SHIFT(op, size, shift_left)                      \
1312 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,        \
1313                  uint32_t sh)                                       \
1314 {                                                                   \
1315     struct PPC_DFP dfp;                                             \
1316     unsigned max_digits = ((size) == 64) ? 16 : 34;                 \
1317                                                                     \
1318     dfp_prepare_decimal##size(&dfp, a, 0, env);                     \
1319                                                                     \
1320     if (sh <= max_digits) {                                         \
1321                                                                     \
1322         decNumber shd;                                              \
1323         unsigned special = dfp.a.bits & DECSPECIAL;                 \
1324                                                                     \
1325         if (shift_left) {                                           \
1326             decNumberFromUInt32(&shd, sh);                          \
1327         } else {                                                    \
1328             decNumberFromInt32(&shd, -((int32_t)sh));               \
1329         }                                                           \
1330                                                                     \
1331         dfp.a.bits &= ~DECSPECIAL;                                  \
1332         decNumberShift(&dfp.t, &dfp.a, &shd, &dfp.context);         \
1333                                                                     \
1334         dfp.t.bits |= special;                                      \
1335         if (special && (dfp.t.digits >= max_digits)) {              \
1336             dfp.t.digits = max_digits - 1;                          \
1337         }                                                           \
1338                                                                     \
1339         decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
1340                                   &dfp.context);                    \
1341     } else {                                                        \
1342         if ((size) == 64) {                                         \
1343             dfp.t64[0] = dfp.a64[0] & 0xFFFC000000000000ULL;        \
1344             dfp_clear_lmd_from_g5msb(dfp.t64);                      \
1345         } else {                                                    \
1346             dfp.t64[HI_IDX] = dfp.a64[HI_IDX] &                     \
1347                               0xFFFFC00000000000ULL;                \
1348             dfp_clear_lmd_from_g5msb(dfp.t64 + HI_IDX);             \
1349             dfp.t64[LO_IDX] = 0;                                    \
1350         }                                                           \
1351     }                                                               \
1352                                                                     \
1353     if ((size) == 64) {                                             \
1354         set_dfp64(t, dfp.t64);                                      \
1355     } else {                                                        \
1356         set_dfp128(t, dfp.t64);                                     \
1357     }                                                               \
1358 }
1359 
1360 DFP_HELPER_SHIFT(dscli, 64, 1)
1361 DFP_HELPER_SHIFT(dscliq, 128, 1)
1362 DFP_HELPER_SHIFT(dscri, 64, 0)
1363 DFP_HELPER_SHIFT(dscriq, 128, 0)
1364