xref: /qemu/target/ppc/dfp_helper.c (revision d9acba3130314e2e4239d39a99eeca147c255584)
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, ppc_fprp_t *dfp)
40 {
41     dst[0] = dfp->VsrD(0);
42 }
43 
44 static void get_dfp128(uint64_t *dst, ppc_fprp_t *dfp)
45 {
46     dst[HI_IDX] = dfp[0].VsrD(0);
47     dst[LO_IDX] = dfp[1].VsrD(0);
48 }
49 
50 static void set_dfp64(ppc_fprp_t *dfp, uint64_t *src)
51 {
52     dfp->VsrD(0) = src[0];
53 }
54 
55 static void set_dfp128(ppc_fprp_t *dfp, uint64_t *src)
56 {
57     dfp[0].VsrD(0) = src[HI_IDX];
58     dfp[1].VsrD(0) = 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, ppc_fprp_t *a,
147                                   ppc_fprp_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, ppc_fprp_t *a,
171                                    ppc_fprp_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, ppc_fprp_t *t, ppc_fprp_t *a,               \
420                  ppc_fprp_t *b)                                                \
421 {                                                                              \
422     struct PPC_DFP dfp;                                                        \
423     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
424     dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context);                                \
425     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
426     postprocs(&dfp);                                                           \
427     if (size == 64) {                                                          \
428         set_dfp64(t, dfp.t64);                                                 \
429     } else if (size == 128) {                                                  \
430         set_dfp128(t, dfp.t64);                                                \
431     }                                                                          \
432 }
433 
434 static void ADD_PPs(struct PPC_DFP *dfp)
435 {
436     dfp_set_FPRF_from_FRT(dfp);
437     dfp_check_for_OX(dfp);
438     dfp_check_for_UX(dfp);
439     dfp_check_for_XX(dfp);
440     dfp_check_for_VXSNAN(dfp);
441     dfp_check_for_VXISI_add(dfp);
442 }
443 
444 DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
445 DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
446 
447 static void SUB_PPs(struct PPC_DFP *dfp)
448 {
449     dfp_set_FPRF_from_FRT(dfp);
450     dfp_check_for_OX(dfp);
451     dfp_check_for_UX(dfp);
452     dfp_check_for_XX(dfp);
453     dfp_check_for_VXSNAN(dfp);
454     dfp_check_for_VXISI_subtract(dfp);
455 }
456 
457 DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
458 DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
459 
460 static void MUL_PPs(struct PPC_DFP *dfp)
461 {
462     dfp_set_FPRF_from_FRT(dfp);
463     dfp_check_for_OX(dfp);
464     dfp_check_for_UX(dfp);
465     dfp_check_for_XX(dfp);
466     dfp_check_for_VXSNAN(dfp);
467     dfp_check_for_VXIMZ(dfp);
468 }
469 
470 DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
471 DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
472 
473 static void DIV_PPs(struct PPC_DFP *dfp)
474 {
475     dfp_set_FPRF_from_FRT(dfp);
476     dfp_check_for_OX(dfp);
477     dfp_check_for_UX(dfp);
478     dfp_check_for_ZX(dfp);
479     dfp_check_for_XX(dfp);
480     dfp_check_for_VXSNAN(dfp);
481     dfp_check_for_VXZDZ(dfp);
482     dfp_check_for_VXIDI(dfp);
483 }
484 
485 DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
486 DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
487 
488 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)                            \
489 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)           \
490 {                                                                              \
491     struct PPC_DFP dfp;                                                        \
492     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
493     dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context);                                \
494     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
495     postprocs(&dfp);                                                           \
496     return dfp.crbf;                                                           \
497 }
498 
499 static void CMPU_PPs(struct PPC_DFP *dfp)
500 {
501     dfp_set_CRBF_from_T(dfp);
502     dfp_set_FPCC_from_CRBF(dfp);
503     dfp_check_for_VXSNAN(dfp);
504 }
505 
506 DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
507 DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
508 
509 static void CMPO_PPs(struct PPC_DFP *dfp)
510 {
511     dfp_set_CRBF_from_T(dfp);
512     dfp_set_FPCC_from_CRBF(dfp);
513     dfp_check_for_VXSNAN(dfp);
514     dfp_check_for_VXVC(dfp);
515 }
516 
517 DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
518 DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
519 
520 #define DFP_HELPER_TSTDC(op, size)                                       \
521 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)      \
522 {                                                                        \
523     struct PPC_DFP dfp;                                                  \
524     int match = 0;                                                       \
525                                                                          \
526     dfp_prepare_decimal##size(&dfp, a, 0, env);                          \
527                                                                          \
528     match |= (dcm & 0x20) && decNumberIsZero(&dfp.a);                    \
529     match |= (dcm & 0x10) && decNumberIsSubnormal(&dfp.a, &dfp.context); \
530     match |= (dcm & 0x08) && decNumberIsNormal(&dfp.a, &dfp.context);    \
531     match |= (dcm & 0x04) && decNumberIsInfinite(&dfp.a);                \
532     match |= (dcm & 0x02) && decNumberIsQNaN(&dfp.a);                    \
533     match |= (dcm & 0x01) && decNumberIsSNaN(&dfp.a);                    \
534                                                                          \
535     if (decNumberIsNegative(&dfp.a)) {                                   \
536         dfp.crbf = match ? 0xA : 0x8;                                    \
537     } else {                                                             \
538         dfp.crbf = match ? 0x2 : 0x0;                                    \
539     }                                                                    \
540                                                                          \
541     dfp_set_FPCC_from_CRBF(&dfp);                                        \
542     return dfp.crbf;                                                     \
543 }
544 
545 DFP_HELPER_TSTDC(dtstdc, 64)
546 DFP_HELPER_TSTDC(dtstdcq, 128)
547 
548 #define DFP_HELPER_TSTDG(op, size)                                       \
549 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)      \
550 {                                                                        \
551     struct PPC_DFP dfp;                                                  \
552     int minexp, maxexp, nzero_digits, nzero_idx, is_negative, is_zero,   \
553         is_extreme_exp, is_subnormal, is_normal, leftmost_is_nonzero,    \
554         match;                                                           \
555                                                                          \
556     dfp_prepare_decimal##size(&dfp, a, 0, env);                          \
557                                                                          \
558     if ((size) == 64) {                                                  \
559         minexp = -398;                                                   \
560         maxexp = 369;                                                    \
561         nzero_digits = 16;                                               \
562         nzero_idx = 5;                                                   \
563     } else if ((size) == 128) {                                          \
564         minexp = -6176;                                                  \
565         maxexp = 6111;                                                   \
566         nzero_digits = 34;                                               \
567         nzero_idx = 11;                                                  \
568     }                                                                    \
569                                                                          \
570     is_negative = decNumberIsNegative(&dfp.a);                           \
571     is_zero = decNumberIsZero(&dfp.a);                                   \
572     is_extreme_exp = (dfp.a.exponent == maxexp) ||                       \
573                      (dfp.a.exponent == minexp);                         \
574     is_subnormal = decNumberIsSubnormal(&dfp.a, &dfp.context);           \
575     is_normal = decNumberIsNormal(&dfp.a, &dfp.context);                 \
576     leftmost_is_nonzero = (dfp.a.digits == nzero_digits) &&              \
577                           (dfp.a.lsu[nzero_idx] != 0);                   \
578     match = 0;                                                           \
579                                                                          \
580     match |= (dcm & 0x20) && is_zero && !is_extreme_exp;                 \
581     match |= (dcm & 0x10) && is_zero && is_extreme_exp;                  \
582     match |= (dcm & 0x08) &&                                             \
583              (is_subnormal || (is_normal && is_extreme_exp));            \
584     match |= (dcm & 0x04) && is_normal && !is_extreme_exp &&             \
585              !leftmost_is_nonzero;                                       \
586     match |= (dcm & 0x02) && is_normal && !is_extreme_exp &&             \
587              leftmost_is_nonzero;                                        \
588     match |= (dcm & 0x01) && decNumberIsSpecial(&dfp.a);                 \
589                                                                          \
590     if (is_negative) {                                                   \
591         dfp.crbf = match ? 0xA : 0x8;                                    \
592     } else {                                                             \
593         dfp.crbf = match ? 0x2 : 0x0;                                    \
594     }                                                                    \
595                                                                          \
596     dfp_set_FPCC_from_CRBF(&dfp);                                        \
597     return dfp.crbf;                                                     \
598 }
599 
600 DFP_HELPER_TSTDG(dtstdg, 64)
601 DFP_HELPER_TSTDG(dtstdgq, 128)
602 
603 #define DFP_HELPER_TSTEX(op, size)                                       \
604 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)     \
605 {                                                                        \
606     struct PPC_DFP dfp;                                                  \
607     int expa, expb, a_is_special, b_is_special;                          \
608                                                                          \
609     dfp_prepare_decimal##size(&dfp, a, b, env);                          \
610                                                                          \
611     expa = dfp.a.exponent;                                               \
612     expb = dfp.b.exponent;                                               \
613     a_is_special = decNumberIsSpecial(&dfp.a);                           \
614     b_is_special = decNumberIsSpecial(&dfp.b);                           \
615                                                                          \
616     if (a_is_special || b_is_special) {                                  \
617         int atype = a_is_special ? (decNumberIsNaN(&dfp.a) ? 4 : 2) : 1; \
618         int btype = b_is_special ? (decNumberIsNaN(&dfp.b) ? 4 : 2) : 1; \
619         dfp.crbf = (atype ^ btype) ? 0x1 : 0x2;                          \
620     } else if (expa < expb) {                                            \
621         dfp.crbf = 0x8;                                                  \
622     } else if (expa > expb) {                                            \
623         dfp.crbf = 0x4;                                                  \
624     } else {                                                             \
625         dfp.crbf = 0x2;                                                  \
626     }                                                                    \
627                                                                          \
628     dfp_set_FPCC_from_CRBF(&dfp);                                        \
629     return dfp.crbf;                                                     \
630 }
631 
632 DFP_HELPER_TSTEX(dtstex, 64)
633 DFP_HELPER_TSTEX(dtstexq, 128)
634 
635 #define DFP_HELPER_TSTSF(op, size)                                       \
636 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)     \
637 {                                                                        \
638     struct PPC_DFP dfp;                                                  \
639     unsigned k;                                                          \
640     uint64_t a64;                                                        \
641                                                                          \
642     dfp_prepare_decimal##size(&dfp, 0, b, env);                          \
643                                                                          \
644     get_dfp64(&a64, a);                                                  \
645     k = a64 & 0x3F;                                                      \
646                                                                          \
647     if (unlikely(decNumberIsSpecial(&dfp.b))) {                          \
648         dfp.crbf = 1;                                                    \
649     } else if (k == 0) {                                                 \
650         dfp.crbf = 4;                                                    \
651     } else if (unlikely(decNumberIsZero(&dfp.b))) {                      \
652         /* Zero has no sig digits */                                     \
653         dfp.crbf = 4;                                                    \
654     } else {                                                             \
655         unsigned nsd = dfp.b.digits;                                     \
656         if (k < nsd) {                                                   \
657             dfp.crbf = 8;                                                \
658         } else if (k > nsd) {                                            \
659             dfp.crbf = 4;                                                \
660         } else {                                                         \
661             dfp.crbf = 2;                                                \
662         }                                                                \
663     }                                                                    \
664                                                                          \
665     dfp_set_FPCC_from_CRBF(&dfp);                                        \
666     return dfp.crbf;                                                     \
667 }
668 
669 DFP_HELPER_TSTSF(dtstsf, 64)
670 DFP_HELPER_TSTSF(dtstsfq, 128)
671 
672 #define DFP_HELPER_TSTSFI(op, size)                                     \
673 uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b)       \
674 {                                                                       \
675     struct PPC_DFP dfp;                                                 \
676     unsigned uim;                                                       \
677                                                                         \
678     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
679                                                                         \
680     uim = a & 0x3F;                                                     \
681                                                                         \
682     if (unlikely(decNumberIsSpecial(&dfp.b))) {                         \
683         dfp.crbf = 1;                                                   \
684     } else if (uim == 0) {                                              \
685         dfp.crbf = 4;                                                   \
686     } else if (unlikely(decNumberIsZero(&dfp.b))) {                     \
687         /* Zero has no sig digits */                                    \
688         dfp.crbf = 4;                                                   \
689     } else {                                                            \
690         unsigned nsd = dfp.b.digits;                                    \
691         if (uim < nsd) {                                                \
692             dfp.crbf = 8;                                               \
693         } else if (uim > nsd) {                                         \
694             dfp.crbf = 4;                                               \
695         } else {                                                        \
696             dfp.crbf = 2;                                               \
697         }                                                               \
698     }                                                                   \
699                                                                         \
700     dfp_set_FPCC_from_CRBF(&dfp);                                       \
701     return dfp.crbf;                                                    \
702 }
703 
704 DFP_HELPER_TSTSFI(dtstsfi, 64)
705 DFP_HELPER_TSTSFI(dtstsfiq, 128)
706 
707 static void QUA_PPs(struct PPC_DFP *dfp)
708 {
709     dfp_set_FPRF_from_FRT(dfp);
710     dfp_check_for_XX(dfp);
711     dfp_check_for_VXSNAN(dfp);
712     dfp_check_for_VXCVI(dfp);
713 }
714 
715 static void dfp_quantize(uint8_t rmc, struct PPC_DFP *dfp)
716 {
717     dfp_set_round_mode_from_immediate(0, rmc, dfp);
718     decNumberQuantize(&dfp->t, &dfp->b, &dfp->a, &dfp->context);
719     if (decNumberIsSNaN(&dfp->a)) {
720         dfp->t = dfp->a;
721         dfp_makeQNaN(&dfp->t);
722     } else if (decNumberIsSNaN(&dfp->b)) {
723         dfp->t = dfp->b;
724         dfp_makeQNaN(&dfp->t);
725     } else if (decNumberIsQNaN(&dfp->a)) {
726         dfp->t = dfp->a;
727     } else if (decNumberIsQNaN(&dfp->b)) {
728         dfp->t = dfp->b;
729     }
730 }
731 
732 #define DFP_HELPER_QUAI(op, size)                                       \
733 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,        \
734                  uint32_t te, uint32_t rmc)                             \
735 {                                                                       \
736     struct PPC_DFP dfp;                                                 \
737                                                                         \
738     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
739                                                                         \
740     decNumberFromUInt32(&dfp.a, 1);                                     \
741     dfp.a.exponent = (int32_t)((int8_t)(te << 3) >> 3);                 \
742                                                                         \
743     dfp_quantize(rmc, &dfp);                                            \
744     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
745                               &dfp.context);                            \
746     QUA_PPs(&dfp);                                                      \
747                                                                         \
748     if (size == 64) {                                                   \
749         set_dfp64(t, dfp.t64);                                          \
750     } else if (size == 128) {                                           \
751         set_dfp128(t, dfp.t64);                                         \
752     }                                                                   \
753 }
754 
755 DFP_HELPER_QUAI(dquai, 64)
756 DFP_HELPER_QUAI(dquaiq, 128)
757 
758 #define DFP_HELPER_QUA(op, size)                                        \
759 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
760                  ppc_fprp_t *b, uint32_t rmc)                           \
761 {                                                                       \
762     struct PPC_DFP dfp;                                                 \
763                                                                         \
764     dfp_prepare_decimal##size(&dfp, a, b, env);                         \
765                                                                         \
766     dfp_quantize(rmc, &dfp);                                            \
767     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
768                               &dfp.context);                            \
769     QUA_PPs(&dfp);                                                      \
770                                                                         \
771     if (size == 64) {                                                   \
772         set_dfp64(t, dfp.t64);                                          \
773     } else if (size == 128) {                                           \
774         set_dfp128(t, dfp.t64);                                         \
775     }                                                                   \
776 }
777 
778 DFP_HELPER_QUA(dqua, 64)
779 DFP_HELPER_QUA(dquaq, 128)
780 
781 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
782                              struct PPC_DFP *dfp)
783 {
784     int msd_orig, msd_rslt;
785 
786     if (unlikely((ref_sig == 0) || (dfp->b.digits <= ref_sig))) {
787         dfp->t = dfp->b;
788         if (decNumberIsSNaN(&dfp->b)) {
789             dfp_makeQNaN(&dfp->t);
790             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FPSCR_VE);
791         }
792         return;
793     }
794 
795     /* Reround is equivalent to quantizing b with 1**E(n) where */
796     /* n = exp(b) + numDigits(b) - reference_significance.      */
797 
798     decNumberFromUInt32(&dfp->a, 1);
799     dfp->a.exponent = dfp->b.exponent + dfp->b.digits - ref_sig;
800 
801     if (unlikely(dfp->a.exponent > xmax)) {
802         dfp->t.digits = 0;
803         dfp->t.bits &= ~DECNEG;
804         dfp_makeQNaN(&dfp->t);
805         dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);
806         return;
807     }
808 
809     dfp_quantize(rmc, dfp);
810 
811     msd_orig = dfp_get_digit(&dfp->b, dfp->b.digits-1);
812     msd_rslt = dfp_get_digit(&dfp->t, dfp->t.digits-1);
813 
814     /* If the quantization resulted in rounding up to the next magnitude, */
815     /* then we need to shift the significand and adjust the exponent.     */
816 
817     if (unlikely((msd_orig == 9) && (msd_rslt == 1))) {
818 
819         decNumber negone;
820 
821         decNumberFromInt32(&negone, -1);
822         decNumberShift(&dfp->t, &dfp->t, &negone, &dfp->context);
823         dfp->t.exponent++;
824 
825         if (unlikely(dfp->t.exponent > xmax)) {
826             dfp_makeQNaN(&dfp->t);
827             dfp->t.digits = 0;
828             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE);
829             /* Inhibit XX in this case */
830             decContextClearStatus(&dfp->context, DEC_Inexact);
831         }
832     }
833 }
834 
835 #define DFP_HELPER_RRND(op, size)                                       \
836 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,        \
837                  ppc_fprp_t *b, uint32_t rmc)                           \
838 {                                                                       \
839     struct PPC_DFP dfp;                                                 \
840     uint64_t a64;                                                       \
841     int32_t ref_sig;                                                    \
842     int32_t xmax = ((size) == 64) ? 369 : 6111;                         \
843                                                                         \
844     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
845                                                                         \
846     get_dfp64(&a64, a);                                                 \
847     ref_sig = a64 & 0x3f;                                               \
848                                                                         \
849     _dfp_reround(rmc, ref_sig, xmax, &dfp);                             \
850     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
851                               &dfp.context);                            \
852     QUA_PPs(&dfp);                                                      \
853                                                                         \
854     if (size == 64) {                                                   \
855         set_dfp64(t, dfp.t64);                                          \
856     } else if (size == 128) {                                           \
857         set_dfp128(t, dfp.t64);                                         \
858     }                                                                   \
859 }
860 
861 DFP_HELPER_RRND(drrnd, 64)
862 DFP_HELPER_RRND(drrndq, 128)
863 
864 #define DFP_HELPER_RINT(op, postprocs, size)                                   \
865 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,               \
866              uint32_t r, uint32_t rmc)                                         \
867 {                                                                              \
868     struct PPC_DFP dfp;                                                        \
869                                                                                \
870     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
871                                                                                \
872     dfp_set_round_mode_from_immediate(r, rmc, &dfp);                           \
873     decNumberToIntegralExact(&dfp.t, &dfp.b, &dfp.context);                    \
874     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
875     postprocs(&dfp);                                                           \
876                                                                                \
877     if (size == 64) {                                                          \
878         set_dfp64(t, dfp.t64);                                                 \
879     } else if (size == 128) {                                                  \
880         set_dfp128(t, dfp.t64);                                                \
881     }                                                                          \
882 }
883 
884 static void RINTX_PPs(struct PPC_DFP *dfp)
885 {
886     dfp_set_FPRF_from_FRT(dfp);
887     dfp_check_for_XX(dfp);
888     dfp_check_for_VXSNAN(dfp);
889 }
890 
891 DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
892 DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
893 
894 static void RINTN_PPs(struct PPC_DFP *dfp)
895 {
896     dfp_set_FPRF_from_FRT(dfp);
897     dfp_check_for_VXSNAN(dfp);
898 }
899 
900 DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
901 DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
902 
903 void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
904 {
905     struct PPC_DFP dfp;
906     uint64_t b64;
907     uint32_t b_short;
908 
909     get_dfp64(&b64, b);
910     b_short = (uint32_t)b64;
911 
912     dfp_prepare_decimal64(&dfp, 0, 0, env);
913     decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
914     decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.t, &dfp.context);
915     set_dfp64(t, dfp.t64);
916     dfp_set_FPRF_from_FRT(&dfp);
917 }
918 
919 void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
920 {
921     struct PPC_DFP dfp;
922     uint64_t b64;
923     dfp_prepare_decimal128(&dfp, 0, 0, env);
924     get_dfp64(&b64, b);
925     decimal64ToNumber((decimal64 *)&b64, &dfp.t);
926 
927     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
928     dfp_set_FPRF_from_FRT(&dfp);
929 
930     decimal128FromNumber((decimal128 *)&dfp.t64, &dfp.t, &dfp.context);
931     set_dfp128(t, dfp.t64);
932 }
933 
934 void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
935 {
936     struct PPC_DFP dfp;
937     uint32_t t_short = 0;
938     uint64_t t64;
939     dfp_prepare_decimal64(&dfp, 0, b, env);
940     decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context);
941     decimal32ToNumber((decimal32 *)&t_short, &dfp.t);
942 
943     dfp_set_FPRF_from_FRT_short(&dfp);
944     dfp_check_for_OX(&dfp);
945     dfp_check_for_UX(&dfp);
946     dfp_check_for_XX(&dfp);
947 
948     t64 = (uint64_t)t_short;
949     set_dfp64(t, &t64);
950 }
951 
952 void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
953 {
954     struct PPC_DFP dfp;
955     dfp_prepare_decimal128(&dfp, 0, b, env);
956     decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.b, &dfp.context);
957     decimal64ToNumber((decimal64 *)&dfp.t64, &dfp.t);
958 
959     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
960     dfp_set_FPRF_from_FRT_long(&dfp);
961     dfp_check_for_OX(&dfp);
962     dfp_check_for_UX(&dfp);
963     dfp_check_for_XX(&dfp);
964 
965     dfp.t64[0] = dfp.t64[1] = 0;
966     decimal64FromNumber((decimal64 *)dfp.t64, &dfp.t, &dfp.context);
967     set_dfp128(t, dfp.t64);
968 }
969 
970 #define DFP_HELPER_CFFIX(op, size)                                             \
971 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)               \
972 {                                                                              \
973     struct PPC_DFP dfp;                                                        \
974     uint64_t b64;                                                              \
975     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
976     get_dfp64(&b64, b);                                                        \
977     decNumberFromInt64(&dfp.t, (int64_t)b64);                                  \
978     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
979     CFFIX_PPs(&dfp);                                                           \
980                                                                                \
981     if (size == 64) {                                                          \
982         set_dfp64(t, dfp.t64);                                                 \
983     } else if (size == 128) {                                                  \
984         set_dfp128(t, dfp.t64);                                                \
985     }                                                                          \
986 }
987 
988 static void CFFIX_PPs(struct PPC_DFP *dfp)
989 {
990     dfp_set_FPRF_from_FRT(dfp);
991     dfp_check_for_XX(dfp);
992 }
993 
994 DFP_HELPER_CFFIX(dcffix, 64)
995 DFP_HELPER_CFFIX(dcffixq, 128)
996 
997 #define DFP_HELPER_CTFIX(op, size)                                            \
998 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)              \
999 {                                                                             \
1000     struct PPC_DFP dfp;                                                       \
1001     dfp_prepare_decimal##size(&dfp, 0, b, env);                               \
1002                                                                               \
1003     if (unlikely(decNumberIsSpecial(&dfp.b))) {                               \
1004         uint64_t invalid_flags = FP_VX | FP_VXCVI;                            \
1005         if (decNumberIsInfinite(&dfp.b)) {                                    \
1006             dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
1007         } else { /* NaN */                                                    \
1008             dfp.t64[0] = INT64_MIN;                                           \
1009             if (decNumberIsSNaN(&dfp.b)) {                                    \
1010                 invalid_flags |= FP_VXSNAN;                                   \
1011             }                                                                 \
1012         }                                                                     \
1013         dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);                       \
1014     } else if (unlikely(decNumberIsZero(&dfp.b))) {                           \
1015         dfp.t64[0] = 0;                                                       \
1016     } else {                                                                  \
1017         decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);               \
1018         dfp.t64[0] = decNumberIntegralToInt64(&dfp.b, &dfp.context);          \
1019         if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {      \
1020             dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
1021             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);                \
1022         } else {                                                              \
1023             dfp_check_for_XX(&dfp);                                           \
1024         }                                                                     \
1025     }                                                                         \
1026                                                                               \
1027     set_dfp64(t, dfp.t64);                                                    \
1028 }
1029 
1030 DFP_HELPER_CTFIX(dctfix, 64)
1031 DFP_HELPER_CTFIX(dctfixq, 128)
1032 
1033 static inline void dfp_set_bcd_digit_64(uint64_t *t, uint8_t digit,
1034                                             unsigned n)
1035 {
1036     *t |= ((uint64_t)(digit & 0xF) << (n << 2));
1037 }
1038 
1039 static inline void dfp_set_bcd_digit_128(uint64_t *t, uint8_t digit,
1040                                              unsigned n)
1041 {
1042     t[(n & 0x10) ? HI_IDX : LO_IDX] |=
1043         ((uint64_t)(digit & 0xF) << ((n & 15) << 2));
1044 }
1045 
1046 static inline void dfp_set_sign_64(uint64_t *t, uint8_t sgn)
1047 {
1048     *t <<= 4;
1049     *t |= (sgn & 0xF);
1050 }
1051 
1052 static inline void dfp_set_sign_128(uint64_t *t, uint8_t sgn)
1053 {
1054     t[HI_IDX] <<= 4;
1055     t[HI_IDX] |= (t[LO_IDX] >> 60);
1056     t[LO_IDX] <<= 4;
1057     t[LO_IDX] |= (sgn & 0xF);
1058 }
1059 
1060 #define DFP_HELPER_DEDPD(op, size)                                        \
1061 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,          \
1062                  uint32_t sp)                                             \
1063 {                                                                         \
1064     struct PPC_DFP dfp;                                                   \
1065     uint8_t digits[34];                                                   \
1066     int i, N;                                                             \
1067                                                                           \
1068     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
1069                                                                           \
1070     decNumberGetBCD(&dfp.b, digits);                                      \
1071     dfp.t64[0] = dfp.t64[1] = 0;                                          \
1072     N = dfp.b.digits;                                                     \
1073                                                                           \
1074     for (i = 0; (i < N) && (i < (size)/4); i++) {                         \
1075         dfp_set_bcd_digit_##size(dfp.t64, digits[N-i-1], i);              \
1076     }                                                                     \
1077                                                                           \
1078     if (sp & 2) {                                                         \
1079         uint8_t sgn;                                                      \
1080                                                                           \
1081         if (decNumberIsNegative(&dfp.b)) {                                \
1082             sgn = 0xD;                                                    \
1083         } else {                                                          \
1084             sgn = ((sp & 1) ? 0xF : 0xC);                                 \
1085         }                                                                 \
1086         dfp_set_sign_##size(dfp.t64, sgn);                                \
1087     }                                                                     \
1088                                                                           \
1089     if (size == 64) {                                                     \
1090         set_dfp64(t, dfp.t64);                                            \
1091     } else if (size == 128) {                                             \
1092         set_dfp128(t, dfp.t64);                                           \
1093     }                                                                     \
1094 }
1095 
1096 DFP_HELPER_DEDPD(ddedpd, 64)
1097 DFP_HELPER_DEDPD(ddedpdq, 128)
1098 
1099 static inline uint8_t dfp_get_bcd_digit_64(uint64_t *t, unsigned n)
1100 {
1101     return *t >> ((n << 2) & 63) & 15;
1102 }
1103 
1104 static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n)
1105 {
1106     return t[(n & 0x10) ? HI_IDX : LO_IDX] >> ((n << 2) & 63) & 15;
1107 }
1108 
1109 #define DFP_HELPER_ENBCD(op, size)                                           \
1110 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,             \
1111                  uint32_t s)                                                 \
1112 {                                                                            \
1113     struct PPC_DFP dfp;                                                      \
1114     uint8_t digits[32];                                                      \
1115     int n = 0, offset = 0, sgn = 0, nonzero = 0;                             \
1116                                                                              \
1117     dfp_prepare_decimal##size(&dfp, 0, b, env);                              \
1118                                                                              \
1119     decNumberZero(&dfp.t);                                                   \
1120                                                                              \
1121     if (s) {                                                                 \
1122         uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++);     \
1123         switch (sgnNibble) {                                                 \
1124         case 0xD:                                                            \
1125         case 0xB:                                                            \
1126             sgn = 1;                                                         \
1127             break;                                                           \
1128         case 0xC:                                                            \
1129         case 0xF:                                                            \
1130         case 0xA:                                                            \
1131         case 0xE:                                                            \
1132             sgn = 0;                                                         \
1133             break;                                                           \
1134         default:                                                             \
1135             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);            \
1136             return;                                                          \
1137         }                                                                    \
1138         }                                                                    \
1139                                                                              \
1140     while (offset < (size) / 4) {                                            \
1141         n++;                                                                 \
1142         digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
1143         if (digits[(size) / 4 - n] > 10) {                                   \
1144             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);            \
1145             return;                                                          \
1146         } else {                                                             \
1147             nonzero |= (digits[(size) / 4 - n] > 0);                         \
1148         }                                                                    \
1149     }                                                                        \
1150                                                                              \
1151     if (nonzero) {                                                           \
1152         decNumberSetBCD(&dfp.t, digits + ((size) / 4) - n, n);               \
1153     }                                                                        \
1154                                                                              \
1155     if (s && sgn)  {                                                         \
1156         dfp.t.bits |= DECNEG;                                                \
1157     }                                                                        \
1158     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,              \
1159                               &dfp.context);                                 \
1160     dfp_set_FPRF_from_FRT(&dfp);                                             \
1161     if ((size) == 64) {                                                      \
1162         set_dfp64(t, dfp.t64);                                               \
1163     } else if ((size) == 128) {                                              \
1164         set_dfp128(t, dfp.t64);                                              \
1165     }                                                                        \
1166 }
1167 
1168 DFP_HELPER_ENBCD(denbcd, 64)
1169 DFP_HELPER_ENBCD(denbcdq, 128)
1170 
1171 #define DFP_HELPER_XEX(op, size)                               \
1172 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
1173 {                                                              \
1174     struct PPC_DFP dfp;                                        \
1175     uint64_t t64;                                              \
1176                                                                \
1177     dfp_prepare_decimal##size(&dfp, 0, b, env);                \
1178                                                                \
1179     if (unlikely(decNumberIsSpecial(&dfp.b))) {                \
1180         if (decNumberIsInfinite(&dfp.b)) {                     \
1181             t64 = -1;                                          \
1182         } else if (decNumberIsSNaN(&dfp.b)) {                  \
1183             t64 = -3;                                          \
1184         } else if (decNumberIsQNaN(&dfp.b)) {                  \
1185             t64 = -2;                                          \
1186         } else {                                               \
1187             assert(0);                                         \
1188         }                                                      \
1189         set_dfp64(t, &t64);                                    \
1190     } else {                                                   \
1191         if ((size) == 64) {                                    \
1192             t64 = dfp.b.exponent + 398;                        \
1193         } else if ((size) == 128) {                            \
1194             t64 = dfp.b.exponent + 6176;                       \
1195         } else {                                               \
1196             assert(0);                                         \
1197         }                                                      \
1198         set_dfp64(t, &t64);                                    \
1199     }                                                          \
1200 }
1201 
1202 DFP_HELPER_XEX(dxex, 64)
1203 DFP_HELPER_XEX(dxexq, 128)
1204 
1205 static void dfp_set_raw_exp_64(uint64_t *t, uint64_t raw)
1206 {
1207     *t &= 0x8003ffffffffffffULL;
1208     *t |= (raw << (63 - 13));
1209 }
1210 
1211 static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
1212 {
1213     t[HI_IDX] &= 0x80003fffffffffffULL;
1214     t[HI_IDX] |= (raw << (63 - 17));
1215 }
1216 
1217 #define DFP_HELPER_IEX(op, size)                                          \
1218 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,          \
1219                  ppc_fprp_t *b)                                           \
1220 {                                                                         \
1221     struct PPC_DFP dfp;                                                   \
1222     uint64_t raw_qnan, raw_snan, raw_inf, max_exp, a64;                   \
1223     int bias;                                                             \
1224     int64_t exp;                                                          \
1225                                                                           \
1226     get_dfp64(&a64, a);                                                   \
1227     exp = (int64_t)a64;                                                   \
1228     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
1229                                                                           \
1230     if ((size) == 64) {                                                   \
1231         max_exp = 767;                                                    \
1232         raw_qnan = 0x1F00;                                                \
1233         raw_snan = 0x1F80;                                                \
1234         raw_inf = 0x1E00;                                                 \
1235         bias = 398;                                                       \
1236     } else if ((size) == 128) {                                           \
1237         max_exp = 12287;                                                  \
1238         raw_qnan = 0x1f000;                                               \
1239         raw_snan = 0x1f800;                                               \
1240         raw_inf = 0x1e000;                                                \
1241         bias = 6176;                                                      \
1242     } else {                                                              \
1243         assert(0);                                                        \
1244     }                                                                     \
1245                                                                           \
1246     if (unlikely((exp < 0) || (exp > max_exp))) {                         \
1247         dfp.t64[0] = dfp.b64[0];                                          \
1248         dfp.t64[1] = dfp.b64[1];                                          \
1249         if (exp == -1) {                                                  \
1250             dfp_set_raw_exp_##size(dfp.t64, raw_inf);                     \
1251         } else if (exp == -3) {                                           \
1252             dfp_set_raw_exp_##size(dfp.t64, raw_snan);                    \
1253         } else {                                                          \
1254             dfp_set_raw_exp_##size(dfp.t64, raw_qnan);                    \
1255         }                                                                 \
1256     } else {                                                              \
1257         dfp.t = dfp.b;                                                    \
1258         if (unlikely(decNumberIsSpecial(&dfp.t))) {                       \
1259             dfp.t.bits &= ~DECSPECIAL;                                    \
1260         }                                                                 \
1261         dfp.t.exponent = exp - bias;                                      \
1262         decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,       \
1263                                   &dfp.context);                          \
1264     }                                                                     \
1265     if (size == 64) {                                                     \
1266         set_dfp64(t, dfp.t64);                                            \
1267     } else if (size == 128) {                                             \
1268         set_dfp128(t, dfp.t64);                                           \
1269     }                                                                     \
1270 }
1271 
1272 DFP_HELPER_IEX(diex, 64)
1273 DFP_HELPER_IEX(diexq, 128)
1274 
1275 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
1276 {
1277 
1278     /* The most significant 5 bits of the PowerPC DFP format combine bits  */
1279     /* from the left-most decimal digit (LMD) and the biased exponent.     */
1280     /* This  routine clears the LMD bits while preserving the exponent     */
1281     /*  bits.  See "Figure 80: Encoding of bits 0:4 of the G field for     */
1282     /*  Finite Numbers" in the Power ISA for additional details.           */
1283 
1284     uint64_t g5msb = (*t >> 58) & 0x1F;
1285 
1286     if ((g5msb >> 3) < 3) { /* LMD in [0-7] ? */
1287        *t &= ~(7ULL << 58);
1288     } else {
1289        switch (g5msb & 7) {
1290        case 0:
1291        case 1:
1292            g5msb = 0;
1293            break;
1294        case 2:
1295        case 3:
1296            g5msb = 0x8;
1297            break;
1298        case 4:
1299        case 5:
1300            g5msb = 0x10;
1301            break;
1302        case 6:
1303            g5msb = 0x1E;
1304            break;
1305        case 7:
1306            g5msb = 0x1F;
1307            break;
1308        }
1309 
1310         *t &= ~(0x1fULL << 58);
1311         *t |= (g5msb << 58);
1312     }
1313 }
1314 
1315 #define DFP_HELPER_SHIFT(op, size, shift_left)                      \
1316 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,    \
1317                  uint32_t sh)                                       \
1318 {                                                                   \
1319     struct PPC_DFP dfp;                                             \
1320     unsigned max_digits = ((size) == 64) ? 16 : 34;                 \
1321                                                                     \
1322     dfp_prepare_decimal##size(&dfp, a, 0, env);                     \
1323                                                                     \
1324     if (sh <= max_digits) {                                         \
1325                                                                     \
1326         decNumber shd;                                              \
1327         unsigned special = dfp.a.bits & DECSPECIAL;                 \
1328                                                                     \
1329         if (shift_left) {                                           \
1330             decNumberFromUInt32(&shd, sh);                          \
1331         } else {                                                    \
1332             decNumberFromInt32(&shd, -((int32_t)sh));               \
1333         }                                                           \
1334                                                                     \
1335         dfp.a.bits &= ~DECSPECIAL;                                  \
1336         decNumberShift(&dfp.t, &dfp.a, &shd, &dfp.context);         \
1337                                                                     \
1338         dfp.t.bits |= special;                                      \
1339         if (special && (dfp.t.digits >= max_digits)) {              \
1340             dfp.t.digits = max_digits - 1;                          \
1341         }                                                           \
1342                                                                     \
1343         decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
1344                                   &dfp.context);                    \
1345     } else {                                                        \
1346         if ((size) == 64) {                                         \
1347             dfp.t64[0] = dfp.a64[0] & 0xFFFC000000000000ULL;        \
1348             dfp_clear_lmd_from_g5msb(dfp.t64);                      \
1349         } else {                                                    \
1350             dfp.t64[HI_IDX] = dfp.a64[HI_IDX] &                     \
1351                               0xFFFFC00000000000ULL;                \
1352             dfp_clear_lmd_from_g5msb(dfp.t64 + HI_IDX);             \
1353             dfp.t64[LO_IDX] = 0;                                    \
1354         }                                                           \
1355     }                                                               \
1356                                                                     \
1357     if ((size) == 64) {                                             \
1358         set_dfp64(t, dfp.t64);                                      \
1359     } else {                                                        \
1360         set_dfp128(t, dfp.t64);                                     \
1361     }                                                               \
1362 }
1363 
1364 DFP_HELPER_SHIFT(dscli, 64, 1)
1365 DFP_HELPER_SHIFT(dscliq, 128, 1)
1366 DFP_HELPER_SHIFT(dscri, 64, 0)
1367 DFP_HELPER_SHIFT(dscriq, 128, 0)
1368