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