Add qemu 2.4.0
[kvmfornfv.git] / qemu / target-ppc / dfp_helper.c
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 "cpu.h"
21 #include "exec/helper-proto.h"
22
23 #define DECNUMDIGITS 34
24 #include "libdecnumber/decContext.h"
25 #include "libdecnumber/decNumber.h"
26 #include "libdecnumber/dpd/decimal32.h"
27 #include "libdecnumber/dpd/decimal64.h"
28 #include "libdecnumber/dpd/decimal128.h"
29
30 #if defined(HOST_WORDS_BIGENDIAN)
31 #define HI_IDX 0
32 #define LO_IDX 1
33 #else
34 #define HI_IDX 1
35 #define LO_IDX 0
36 #endif
37
38 struct PPC_DFP {
39     CPUPPCState *env;
40     uint64_t t64[2], a64[2], b64[2];
41     decNumber t, a, b;
42     decContext context;
43     uint8_t crbf;
44 };
45
46 static void dfp_prepare_rounding_mode(decContext *context, uint64_t fpscr)
47 {
48     enum rounding rnd;
49
50     switch ((fpscr >> 32) & 0x7) {
51     case 0:
52         rnd = DEC_ROUND_HALF_EVEN;
53         break;
54     case 1:
55         rnd = DEC_ROUND_DOWN;
56         break;
57     case 2:
58          rnd = DEC_ROUND_CEILING;
59          break;
60     case 3:
61          rnd = DEC_ROUND_FLOOR;
62          break;
63     case 4:
64          rnd = DEC_ROUND_HALF_UP;
65          break;
66     case 5:
67          rnd = DEC_ROUND_HALF_DOWN;
68          break;
69     case 6:
70          rnd = DEC_ROUND_UP;
71          break;
72     case 7:
73          rnd = DEC_ROUND_05UP;
74          break;
75     default:
76         g_assert_not_reached();
77     }
78
79     decContextSetRounding(context, rnd);
80 }
81
82 static void dfp_set_round_mode_from_immediate(uint8_t r, uint8_t rmc,
83                                                   struct PPC_DFP *dfp)
84 {
85     enum rounding rnd;
86     if (r == 0) {
87         switch (rmc & 3) {
88         case 0:
89             rnd = DEC_ROUND_HALF_EVEN;
90             break;
91         case 1:
92             rnd = DEC_ROUND_DOWN;
93             break;
94         case 2:
95             rnd = DEC_ROUND_HALF_UP;
96             break;
97         case 3: /* use FPSCR rounding mode */
98             return;
99         default:
100             assert(0); /* cannot get here */
101         }
102     } else { /* r == 1 */
103         switch (rmc & 3) {
104         case 0:
105             rnd = DEC_ROUND_CEILING;
106             break;
107         case 1:
108             rnd = DEC_ROUND_FLOOR;
109             break;
110         case 2:
111             rnd = DEC_ROUND_UP;
112             break;
113         case 3:
114             rnd = DEC_ROUND_HALF_DOWN;
115             break;
116         default:
117             assert(0); /* cannot get here */
118         }
119     }
120     decContextSetRounding(&dfp->context, rnd);
121 }
122
123 static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
124                 uint64_t *b, CPUPPCState *env)
125 {
126     decContextDefault(&dfp->context, DEC_INIT_DECIMAL64);
127     dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
128     dfp->env = env;
129
130     if (a) {
131         dfp->a64[0] = *a;
132         decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a);
133     } else {
134         dfp->a64[0] = 0;
135         decNumberZero(&dfp->a);
136     }
137
138     if (b) {
139         dfp->b64[0] = *b;
140         decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b);
141     } else {
142         dfp->b64[0] = 0;
143         decNumberZero(&dfp->b);
144     }
145 }
146
147 static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
148                 uint64_t *b, CPUPPCState *env)
149 {
150     decContextDefault(&dfp->context, DEC_INIT_DECIMAL128);
151     dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
152     dfp->env = env;
153
154     if (a) {
155         dfp->a64[0] = a[HI_IDX];
156         dfp->a64[1] = a[LO_IDX];
157         decimal128ToNumber((decimal128 *)dfp->a64, &dfp->a);
158     } else {
159         dfp->a64[0] = dfp->a64[1] = 0;
160         decNumberZero(&dfp->a);
161     }
162
163     if (b) {
164         dfp->b64[0] = b[HI_IDX];
165         dfp->b64[1] = b[LO_IDX];
166         decimal128ToNumber((decimal128 *)dfp->b64, &dfp->b);
167     } else {
168         dfp->b64[0] = dfp->b64[1] = 0;
169         decNumberZero(&dfp->b);
170     }
171 }
172
173 #define FP_FX       (1ull << FPSCR_FX)
174 #define FP_FEX      (1ull << FPSCR_FEX)
175 #define FP_OX       (1ull << FPSCR_OX)
176 #define FP_OE       (1ull << FPSCR_OE)
177 #define FP_UX       (1ull << FPSCR_UX)
178 #define FP_UE       (1ull << FPSCR_UE)
179 #define FP_XX       (1ull << FPSCR_XX)
180 #define FP_XE       (1ull << FPSCR_XE)
181 #define FP_ZX       (1ull << FPSCR_ZX)
182 #define FP_ZE       (1ull << FPSCR_ZE)
183 #define FP_VX       (1ull << FPSCR_VX)
184 #define FP_VXSNAN   (1ull << FPSCR_VXSNAN)
185 #define FP_VXISI    (1ull << FPSCR_VXISI)
186 #define FP_VXIMZ    (1ull << FPSCR_VXIMZ)
187 #define FP_VXZDZ    (1ull << FPSCR_VXZDZ)
188 #define FP_VXIDI    (1ull << FPSCR_VXIDI)
189 #define FP_VXVC     (1ull << FPSCR_VXVC)
190 #define FP_VXCVI    (1ull << FPSCR_VXCVI)
191 #define FP_VE       (1ull << FPSCR_VE)
192 #define FP_FI       (1ull << FPSCR_FI)
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 &= ~(0x1F << 12);
244     dfp->env->fpscr |= (fprf << 12);
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 &= ~(0xF << 12);
393     dfp->env->fpscr |= (dfp->crbf << 12);
394 }
395
396 static inline void dfp_makeQNaN(decNumber *dn)
397 {
398     dn->bits &= ~DECSPECIAL;
399     dn->bits |= DECNAN;
400 }
401
402 static inline int dfp_get_digit(decNumber *dn, int n)
403 {
404     assert(DECDPUN == 3);
405     int unit = n / DECDPUN;
406     int dig = n % DECDPUN;
407     switch (dig) {
408     case 0:
409         return dn->lsu[unit] % 10;
410     case 1:
411         return (dn->lsu[unit] / 10) % 10;
412     case 2:
413         return dn->lsu[unit] / 100;
414     }
415     g_assert_not_reached();
416 }
417
418 #define DFP_HELPER_TAB(op, dnop, postprocs, size)                              \
419 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b)      \
420 {                                                                              \
421     struct PPC_DFP dfp;                                                        \
422     dfp_prepare_decimal##size(&dfp, a, b, env);                                \
423     dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context);                                \
424     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
425     postprocs(&dfp);                                                           \
426     if (size == 64) {                                                          \
427         t[0] = dfp.t64[0];                                                     \
428     } else if (size == 128) {                                                  \
429         t[0] = dfp.t64[HI_IDX];                                                \
430         t[1] = dfp.t64[LO_IDX];                                                \
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, uint64_t *a, uint64_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, uint64_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, uint64_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, uint64_t *a, uint64_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, uint64_t *a, uint64_t *b)         \
637 {                                                                        \
638     struct PPC_DFP dfp;                                                  \
639     unsigned k;                                                          \
640                                                                          \
641     dfp_prepare_decimal##size(&dfp, 0, b, env);                          \
642                                                                          \
643     k = *a & 0x3F;                                                       \
644                                                                          \
645     if (unlikely(decNumberIsSpecial(&dfp.b))) {                          \
646         dfp.crbf = 1;                                                    \
647     } else if (k == 0) {                                                 \
648         dfp.crbf = 4;                                                    \
649     } else if (unlikely(decNumberIsZero(&dfp.b))) {                      \
650         /* Zero has no sig digits */                                     \
651         dfp.crbf = 4;                                                    \
652     } else {                                                             \
653         unsigned nsd = dfp.b.digits;                                     \
654         if (k < nsd) {                                                   \
655             dfp.crbf = 8;                                                \
656         } else if (k > nsd) {                                            \
657             dfp.crbf = 4;                                                \
658         } else {                                                         \
659             dfp.crbf = 2;                                                \
660         }                                                                \
661     }                                                                    \
662                                                                          \
663     dfp_set_FPCC_from_CRBF(&dfp);                                        \
664     return dfp.crbf;                                                     \
665 }
666
667 DFP_HELPER_TSTSF(dtstsf, 64)
668 DFP_HELPER_TSTSF(dtstsfq, 128)
669
670 static void QUA_PPs(struct PPC_DFP *dfp)
671 {
672     dfp_set_FPRF_from_FRT(dfp);
673     dfp_check_for_XX(dfp);
674     dfp_check_for_VXSNAN(dfp);
675     dfp_check_for_VXCVI(dfp);
676 }
677
678 static void dfp_quantize(uint8_t rmc, struct PPC_DFP *dfp)
679 {
680     dfp_set_round_mode_from_immediate(0, rmc, dfp);
681     decNumberQuantize(&dfp->t, &dfp->b, &dfp->a, &dfp->context);
682     if (decNumberIsSNaN(&dfp->a)) {
683         dfp->t = dfp->a;
684         dfp_makeQNaN(&dfp->t);
685     } else if (decNumberIsSNaN(&dfp->b)) {
686         dfp->t = dfp->b;
687         dfp_makeQNaN(&dfp->t);
688     } else if (decNumberIsQNaN(&dfp->a)) {
689         dfp->t = dfp->a;
690     } else if (decNumberIsQNaN(&dfp->b)) {
691         dfp->t = dfp->b;
692     }
693 }
694
695 #define DFP_HELPER_QUAI(op, size)                                       \
696 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,            \
697                  uint32_t te, uint32_t rmc)                             \
698 {                                                                       \
699     struct PPC_DFP dfp;                                                 \
700                                                                         \
701     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
702                                                                         \
703     decNumberFromUInt32(&dfp.a, 1);                                     \
704     dfp.a.exponent = (int32_t)((int8_t)(te << 3) >> 3);                 \
705                                                                         \
706     dfp_quantize(rmc, &dfp);                                            \
707     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
708                               &dfp.context);                            \
709     QUA_PPs(&dfp);                                                      \
710                                                                         \
711     if (size == 64) {                                                   \
712         t[0] = dfp.t64[0];                                              \
713     } else if (size == 128) {                                           \
714         t[0] = dfp.t64[HI_IDX];                                         \
715         t[1] = dfp.t64[LO_IDX];                                         \
716     }                                                                   \
717 }
718
719 DFP_HELPER_QUAI(dquai, 64)
720 DFP_HELPER_QUAI(dquaiq, 128)
721
722 #define DFP_HELPER_QUA(op, size)                                        \
723 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
724                  uint64_t *b, uint32_t rmc)                             \
725 {                                                                       \
726     struct PPC_DFP dfp;                                                 \
727                                                                         \
728     dfp_prepare_decimal##size(&dfp, a, b, env);                         \
729                                                                         \
730     dfp_quantize(rmc, &dfp);                                            \
731     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
732                               &dfp.context);                            \
733     QUA_PPs(&dfp);                                                      \
734                                                                         \
735     if (size == 64) {                                                   \
736         t[0] = dfp.t64[0];                                              \
737     } else if (size == 128) {                                           \
738         t[0] = dfp.t64[HI_IDX];                                         \
739         t[1] = dfp.t64[LO_IDX];                                         \
740     }                                                                   \
741 }
742
743 DFP_HELPER_QUA(dqua, 64)
744 DFP_HELPER_QUA(dquaq, 128)
745
746 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
747                              struct PPC_DFP *dfp)
748 {
749     int msd_orig, msd_rslt;
750
751     if (unlikely((ref_sig == 0) || (dfp->b.digits <= ref_sig))) {
752         dfp->t = dfp->b;
753         if (decNumberIsSNaN(&dfp->b)) {
754             dfp_makeQNaN(&dfp->t);
755             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FPSCR_VE);
756         }
757         return;
758     }
759
760     /* Reround is equivalent to quantizing b with 1**E(n) where */
761     /* n = exp(b) + numDigits(b) - reference_significance.      */
762
763     decNumberFromUInt32(&dfp->a, 1);
764     dfp->a.exponent = dfp->b.exponent + dfp->b.digits - ref_sig;
765
766     if (unlikely(dfp->a.exponent > xmax)) {
767         dfp->t.digits = 0;
768         dfp->t.bits &= ~DECNEG;
769         dfp_makeQNaN(&dfp->t);
770         dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);
771         return;
772     }
773
774     dfp_quantize(rmc, dfp);
775
776     msd_orig = dfp_get_digit(&dfp->b, dfp->b.digits-1);
777     msd_rslt = dfp_get_digit(&dfp->t, dfp->t.digits-1);
778
779     /* If the quantization resulted in rounding up to the next magnitude, */
780     /* then we need to shift the significand and adjust the exponent.     */
781
782     if (unlikely((msd_orig == 9) && (msd_rslt == 1))) {
783
784         decNumber negone;
785
786         decNumberFromInt32(&negone, -1);
787         decNumberShift(&dfp->t, &dfp->t, &negone, &dfp->context);
788         dfp->t.exponent++;
789
790         if (unlikely(dfp->t.exponent > xmax)) {
791             dfp_makeQNaN(&dfp->t);
792             dfp->t.digits = 0;
793             dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE);
794             /* Inhibit XX in this case */
795             decContextClearStatus(&dfp->context, DEC_Inexact);
796         }
797     }
798 }
799
800 #define DFP_HELPER_RRND(op, size)                                       \
801 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,            \
802                  uint64_t *b, uint32_t rmc)                             \
803 {                                                                       \
804     struct PPC_DFP dfp;                                                 \
805     int32_t ref_sig = *a & 0x3F;                                        \
806     int32_t xmax = ((size) == 64) ? 369 : 6111;                         \
807                                                                         \
808     dfp_prepare_decimal##size(&dfp, 0, b, env);                         \
809                                                                         \
810     _dfp_reround(rmc, ref_sig, xmax, &dfp);                             \
811     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,         \
812                               &dfp.context);                            \
813     QUA_PPs(&dfp);                                                      \
814                                                                         \
815     if (size == 64) {                                                   \
816         t[0] = dfp.t64[0];                                              \
817     } else if (size == 128) {                                           \
818         t[0] = dfp.t64[HI_IDX];                                         \
819         t[1] = dfp.t64[LO_IDX];                                         \
820     }                                                                   \
821 }
822
823 DFP_HELPER_RRND(drrnd, 64)
824 DFP_HELPER_RRND(drrndq, 128)
825
826 #define DFP_HELPER_RINT(op, postprocs, size)                                   \
827 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b,                   \
828              uint32_t r, uint32_t rmc)                                         \
829 {                                                                              \
830     struct PPC_DFP dfp;                                                        \
831                                                                                \
832     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
833                                                                                \
834     dfp_set_round_mode_from_immediate(r, rmc, &dfp);                           \
835     decNumberToIntegralExact(&dfp.t, &dfp.b, &dfp.context);                    \
836     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
837     postprocs(&dfp);                                                           \
838                                                                                \
839     if (size == 64) {                                                          \
840         t[0] = dfp.t64[0];                                                     \
841     } else if (size == 128) {                                                  \
842         t[0] = dfp.t64[HI_IDX];                                                \
843         t[1] = dfp.t64[LO_IDX];                                                \
844     }                                                                          \
845 }
846
847 static void RINTX_PPs(struct PPC_DFP *dfp)
848 {
849     dfp_set_FPRF_from_FRT(dfp);
850     dfp_check_for_XX(dfp);
851     dfp_check_for_VXSNAN(dfp);
852 }
853
854 DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
855 DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
856
857 static void RINTN_PPs(struct PPC_DFP *dfp)
858 {
859     dfp_set_FPRF_from_FRT(dfp);
860     dfp_check_for_VXSNAN(dfp);
861 }
862
863 DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
864 DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
865
866 void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
867 {
868     struct PPC_DFP dfp;
869     uint32_t b_short = *b;
870     dfp_prepare_decimal64(&dfp, 0, 0, env);
871     decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
872     decimal64FromNumber((decimal64 *)t, &dfp.t, &dfp.context);
873     dfp_set_FPRF_from_FRT(&dfp);
874 }
875
876 void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
877 {
878     struct PPC_DFP dfp;
879     dfp_prepare_decimal128(&dfp, 0, 0, env);
880     decimal64ToNumber((decimal64 *)b, &dfp.t);
881
882     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
883     dfp_set_FPRF_from_FRT(&dfp);
884
885     decimal128FromNumber((decimal128 *)&dfp.t64, &dfp.t, &dfp.context);
886     t[0] = dfp.t64[HI_IDX];
887     t[1] = dfp.t64[LO_IDX];
888 }
889
890 void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
891 {
892     struct PPC_DFP dfp;
893     uint32_t t_short = 0;
894     dfp_prepare_decimal64(&dfp, 0, b, env);
895     decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context);
896     decimal32ToNumber((decimal32 *)&t_short, &dfp.t);
897
898     dfp_set_FPRF_from_FRT_short(&dfp);
899     dfp_check_for_OX(&dfp);
900     dfp_check_for_UX(&dfp);
901     dfp_check_for_XX(&dfp);
902
903     *t = t_short;
904 }
905
906 void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
907 {
908     struct PPC_DFP dfp;
909     dfp_prepare_decimal128(&dfp, 0, b, env);
910     decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.b, &dfp.context);
911     decimal64ToNumber((decimal64 *)&dfp.t64, &dfp.t);
912
913     dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
914     dfp_set_FPRF_from_FRT_long(&dfp);
915     dfp_check_for_OX(&dfp);
916     dfp_check_for_UX(&dfp);
917     dfp_check_for_XX(&dfp);
918
919     decimal64FromNumber((decimal64 *)dfp.t64, &dfp.t, &dfp.context);
920     t[0] = dfp.t64[0];
921     t[1] = 0;
922 }
923
924 #define DFP_HELPER_CFFIX(op, size)                                             \
925 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                   \
926 {                                                                              \
927     struct PPC_DFP dfp;                                                        \
928     dfp_prepare_decimal##size(&dfp, 0, b, env);                                \
929     decNumberFromInt64(&dfp.t, (int64_t)(*b));                                 \
930     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
931     CFFIX_PPs(&dfp);                                                           \
932                                                                                \
933     if (size == 64) {                                                          \
934         t[0] = dfp.t64[0];                                                     \
935     } else if (size == 128) {                                                  \
936         t[0] = dfp.t64[HI_IDX];                                                \
937         t[1] = dfp.t64[LO_IDX];                                                \
938     }                                                                          \
939 }
940
941 static void CFFIX_PPs(struct PPC_DFP *dfp)
942 {
943     dfp_set_FPRF_from_FRT(dfp);
944     dfp_check_for_XX(dfp);
945 }
946
947 DFP_HELPER_CFFIX(dcffix, 64)
948 DFP_HELPER_CFFIX(dcffixq, 128)
949
950 #define DFP_HELPER_CTFIX(op, size)                                            \
951 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)                  \
952 {                                                                             \
953     struct PPC_DFP dfp;                                                       \
954     dfp_prepare_decimal##size(&dfp, 0, b, env);                               \
955                                                                               \
956     if (unlikely(decNumberIsSpecial(&dfp.b))) {                               \
957         uint64_t invalid_flags = FP_VX | FP_VXCVI;                            \
958         if (decNumberIsInfinite(&dfp.b)) {                                    \
959             dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
960         } else { /* NaN */                                                    \
961             dfp.t64[0] = INT64_MIN;                                           \
962             if (decNumberIsSNaN(&dfp.b)) {                                    \
963                 invalid_flags |= FP_VXSNAN;                                   \
964             }                                                                 \
965         }                                                                     \
966         dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);                       \
967     } else if (unlikely(decNumberIsZero(&dfp.b))) {                           \
968         dfp.t64[0] = 0;                                                       \
969     } else {                                                                  \
970         decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);               \
971         dfp.t64[0] = decNumberIntegralToInt64(&dfp.b, &dfp.context);          \
972         if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {      \
973             dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
974             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);                \
975         } else {                                                              \
976             dfp_check_for_XX(&dfp);                                           \
977         }                                                                     \
978     }                                                                         \
979                                                                               \
980     *t = dfp.t64[0];                                                          \
981 }
982
983 DFP_HELPER_CTFIX(dctfix, 64)
984 DFP_HELPER_CTFIX(dctfixq, 128)
985
986 static inline void dfp_set_bcd_digit_64(uint64_t *t, uint8_t digit,
987                                             unsigned n)
988 {
989     *t |= ((uint64_t)(digit & 0xF) << (n << 2));
990 }
991
992 static inline void dfp_set_bcd_digit_128(uint64_t *t, uint8_t digit,
993                                              unsigned n)
994 {
995     t[(n & 0x10) ? HI_IDX : LO_IDX] |=
996         ((uint64_t)(digit & 0xF) << ((n & 15) << 2));
997 }
998
999 static inline void dfp_set_sign_64(uint64_t *t, uint8_t sgn)
1000 {
1001     *t <<= 4;
1002     *t |= (sgn & 0xF);
1003 }
1004
1005 static inline void dfp_set_sign_128(uint64_t *t, uint8_t sgn)
1006 {
1007     t[HI_IDX] <<= 4;
1008     t[HI_IDX] |= (t[LO_IDX] >> 60);
1009     t[LO_IDX] <<= 4;
1010     t[LO_IDX] |= (sgn & 0xF);
1011 }
1012
1013 #define DFP_HELPER_DEDPD(op, size)                                        \
1014 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \
1015 {                                                                         \
1016     struct PPC_DFP dfp;                                                   \
1017     uint8_t digits[34];                                                   \
1018     int i, N;                                                             \
1019                                                                           \
1020     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
1021                                                                           \
1022     decNumberGetBCD(&dfp.b, digits);                                      \
1023     dfp.t64[0] = dfp.t64[1] = 0;                                          \
1024     N = dfp.b.digits;                                                     \
1025                                                                           \
1026     for (i = 0; (i < N) && (i < (size)/4); i++) {                         \
1027         dfp_set_bcd_digit_##size(dfp.t64, digits[N-i-1], i);              \
1028     }                                                                     \
1029                                                                           \
1030     if (sp & 2) {                                                         \
1031         uint8_t sgn;                                                      \
1032                                                                           \
1033         if (decNumberIsNegative(&dfp.b)) {                                \
1034             sgn = 0xD;                                                    \
1035         } else {                                                          \
1036             sgn = ((sp & 1) ? 0xF : 0xC);                                 \
1037         }                                                                 \
1038         dfp_set_sign_##size(dfp.t64, sgn);                                \
1039     }                                                                     \
1040                                                                           \
1041     if (size == 64) {                                                     \
1042         t[0] = dfp.t64[0];                                                \
1043     } else if (size == 128) {                                             \
1044         t[0] = dfp.t64[HI_IDX];                                           \
1045         t[1] = dfp.t64[LO_IDX];                                           \
1046     }                                                                     \
1047 }
1048
1049 DFP_HELPER_DEDPD(ddedpd, 64)
1050 DFP_HELPER_DEDPD(ddedpdq, 128)
1051
1052 static inline uint8_t dfp_get_bcd_digit_64(uint64_t *t, unsigned n)
1053 {
1054     return *t >> ((n << 2) & 63) & 15;
1055 }
1056
1057 static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n)
1058 {
1059     return t[(n & 0x10) ? HI_IDX : LO_IDX] >> ((n << 2) & 63) & 15;
1060 }
1061
1062 #define DFP_HELPER_ENBCD(op, size)                                           \
1063 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s)     \
1064 {                                                                            \
1065     struct PPC_DFP dfp;                                                      \
1066     uint8_t digits[32];                                                      \
1067     int n = 0, offset = 0, sgn = 0, nonzero = 0;                             \
1068                                                                              \
1069     dfp_prepare_decimal##size(&dfp, 0, b, env);                              \
1070                                                                              \
1071     decNumberZero(&dfp.t);                                                   \
1072                                                                              \
1073     if (s) {                                                                 \
1074         uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++);     \
1075         switch (sgnNibble) {                                                 \
1076         case 0xD:                                                            \
1077         case 0xB:                                                            \
1078             sgn = 1;                                                         \
1079             break;                                                           \
1080         case 0xC:                                                            \
1081         case 0xF:                                                            \
1082         case 0xA:                                                            \
1083         case 0xE:                                                            \
1084             sgn = 0;                                                         \
1085             break;                                                           \
1086         default:                                                             \
1087             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);            \
1088             return;                                                          \
1089         }                                                                    \
1090         }                                                                    \
1091                                                                              \
1092     while (offset < (size)/4) {                                              \
1093         n++;                                                                 \
1094         digits[(size)/4-n] = dfp_get_bcd_digit_##size(dfp.b64, offset++);    \
1095         if (digits[(size)/4-n] > 10) {                                       \
1096             dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);            \
1097             return;                                                          \
1098         } else {                                                             \
1099             nonzero |= (digits[(size)/4-n] > 0);                             \
1100         }                                                                    \
1101     }                                                                        \
1102                                                                              \
1103     if (nonzero) {                                                           \
1104         decNumberSetBCD(&dfp.t, digits+((size)/4)-n, n);                     \
1105     }                                                                        \
1106                                                                              \
1107     if (s && sgn)  {                                                         \
1108         dfp.t.bits |= DECNEG;                                                \
1109     }                                                                        \
1110     decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,              \
1111                               &dfp.context);                                 \
1112     dfp_set_FPRF_from_FRT(&dfp);                                             \
1113     if ((size) == 64) {                                                      \
1114         t[0] = dfp.t64[0];                                                   \
1115     } else if ((size) == 128) {                                              \
1116         t[0] = dfp.t64[HI_IDX];                                              \
1117         t[1] = dfp.t64[LO_IDX];                                              \
1118     }                                                                        \
1119 }
1120
1121 DFP_HELPER_ENBCD(denbcd, 64)
1122 DFP_HELPER_ENBCD(denbcdq, 128)
1123
1124 #define DFP_HELPER_XEX(op, size)                               \
1125 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b)   \
1126 {                                                              \
1127     struct PPC_DFP dfp;                                        \
1128                                                                \
1129     dfp_prepare_decimal##size(&dfp, 0, b, env);                \
1130                                                                \
1131     if (unlikely(decNumberIsSpecial(&dfp.b))) {                \
1132         if (decNumberIsInfinite(&dfp.b)) {                     \
1133             *t = -1;                                           \
1134         } else if (decNumberIsSNaN(&dfp.b)) {                  \
1135             *t = -3;                                           \
1136         } else if (decNumberIsQNaN(&dfp.b)) {                  \
1137             *t = -2;                                           \
1138         } else {                                               \
1139             assert(0);                                         \
1140         }                                                      \
1141     } else {                                                   \
1142         if ((size) == 64) {                                    \
1143             *t = dfp.b.exponent + 398;                         \
1144         } else if ((size) == 128) {                            \
1145             *t = dfp.b.exponent + 6176;                        \
1146         } else {                                               \
1147             assert(0);                                         \
1148         }                                                      \
1149     }                                                          \
1150 }
1151
1152 DFP_HELPER_XEX(dxex, 64)
1153 DFP_HELPER_XEX(dxexq, 128)
1154
1155 static void dfp_set_raw_exp_64(uint64_t *t, uint64_t raw)
1156 {
1157     *t &= 0x8003ffffffffffffULL;
1158     *t |= (raw << (63-13));
1159 }
1160
1161 static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
1162 {
1163     t[HI_IDX] &= 0x80003fffffffffffULL;
1164     t[HI_IDX] |= (raw << (63-17));
1165 }
1166
1167 #define DFP_HELPER_IEX(op, size)                                          \
1168 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
1169 {                                                                         \
1170     struct PPC_DFP dfp;                                                   \
1171     uint64_t raw_qnan, raw_snan, raw_inf, max_exp;                        \
1172     int bias;                                                             \
1173     int64_t exp = *((int64_t *)a);                                        \
1174                                                                           \
1175     dfp_prepare_decimal##size(&dfp, 0, b, env);                           \
1176                                                                           \
1177     if ((size) == 64) {                                                   \
1178         max_exp = 767;                                                    \
1179         raw_qnan = 0x1F00;                                                \
1180         raw_snan = 0x1F80;                                                \
1181         raw_inf = 0x1E00;                                                 \
1182         bias = 398;                                                       \
1183     } else if ((size) == 128) {                                           \
1184         max_exp = 12287;                                                  \
1185         raw_qnan = 0x1f000;                                               \
1186         raw_snan = 0x1f800;                                               \
1187         raw_inf = 0x1e000;                                                \
1188         bias = 6176;                                                      \
1189     } else {                                                              \
1190         assert(0);                                                        \
1191     }                                                                     \
1192                                                                           \
1193     if (unlikely((exp < 0) || (exp > max_exp))) {                         \
1194         dfp.t64[0] = dfp.b64[0];                                          \
1195         dfp.t64[1] = dfp.b64[1];                                          \
1196         if (exp == -1) {                                                  \
1197             dfp_set_raw_exp_##size(dfp.t64, raw_inf);                     \
1198         } else if (exp == -3) {                                           \
1199             dfp_set_raw_exp_##size(dfp.t64, raw_snan);                    \
1200         } else {                                                          \
1201             dfp_set_raw_exp_##size(dfp.t64, raw_qnan);                    \
1202         }                                                                 \
1203     } else {                                                              \
1204         dfp.t = dfp.b;                                                    \
1205         if (unlikely(decNumberIsSpecial(&dfp.t))) {                       \
1206             dfp.t.bits &= ~DECSPECIAL;                                    \
1207         }                                                                 \
1208         dfp.t.exponent = exp - bias;                                      \
1209         decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t,       \
1210                                   &dfp.context);                          \
1211     }                                                                     \
1212     if (size == 64) {                                                     \
1213         t[0] = dfp.t64[0];                                                \
1214     } else if (size == 128) {                                             \
1215         t[0] = dfp.t64[HI_IDX];                                           \
1216         t[1] = dfp.t64[LO_IDX];                                           \
1217     }                                                                     \
1218 }
1219
1220 DFP_HELPER_IEX(diex, 64)
1221 DFP_HELPER_IEX(diexq, 128)
1222
1223 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
1224 {
1225
1226     /* The most significant 5 bits of the PowerPC DFP format combine bits  */
1227     /* from the left-most decimal digit (LMD) and the biased exponent.     */
1228     /* This  routine clears the LMD bits while preserving the exponent     */
1229     /*  bits.  See "Figure 80: Encoding of bits 0:4 of the G field for     */
1230     /*  Finite Numbers" in the Power ISA for additional details.           */
1231
1232     uint64_t g5msb = (*t >> 58) & 0x1F;
1233
1234     if ((g5msb >> 3) < 3) { /* LMD in [0-7] ? */
1235        *t &= ~(7ULL << 58);
1236     } else {
1237        switch (g5msb & 7) {
1238        case 0:
1239        case 1:
1240            g5msb = 0;
1241            break;
1242        case 2:
1243        case 3:
1244            g5msb = 0x8;
1245            break;
1246        case 4:
1247        case 5:
1248            g5msb = 0x10;
1249            break;
1250        case 6:
1251            g5msb = 0x1E;
1252            break;
1253        case 7:
1254            g5msb = 0x1F;
1255            break;
1256        }
1257
1258         *t &= ~(0x1fULL << 58);
1259         *t |= (g5msb << 58);
1260     }
1261 }
1262
1263 #define DFP_HELPER_SHIFT(op, size, shift_left)                      \
1264 void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a,        \
1265                  uint32_t sh)                                       \
1266 {                                                                   \
1267     struct PPC_DFP dfp;                                             \
1268     unsigned max_digits = ((size) == 64) ? 16 : 34;                 \
1269                                                                     \
1270     dfp_prepare_decimal##size(&dfp, a, 0, env);                     \
1271                                                                     \
1272     if (sh <= max_digits) {                                         \
1273                                                                     \
1274         decNumber shd;                                              \
1275         unsigned special = dfp.a.bits & DECSPECIAL;                 \
1276                                                                     \
1277         if (shift_left) {                                           \
1278             decNumberFromUInt32(&shd, sh);                          \
1279         } else {                                                    \
1280             decNumberFromInt32(&shd, -((int32_t)sh));               \
1281         }                                                           \
1282                                                                     \
1283         dfp.a.bits &= ~DECSPECIAL;                                  \
1284         decNumberShift(&dfp.t, &dfp.a, &shd, &dfp.context);         \
1285                                                                     \
1286         dfp.t.bits |= special;                                      \
1287         if (special && (dfp.t.digits >= max_digits)) {              \
1288             dfp.t.digits = max_digits - 1;                          \
1289         }                                                           \
1290                                                                     \
1291         decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
1292                                   &dfp.context);                    \
1293     } else {                                                        \
1294         if ((size) == 64) {                                         \
1295             dfp.t64[0] = dfp.a64[0] & 0xFFFC000000000000ULL;        \
1296             dfp_clear_lmd_from_g5msb(dfp.t64);                      \
1297         } else {                                                    \
1298             dfp.t64[HI_IDX] = dfp.a64[HI_IDX] &                     \
1299                               0xFFFFC00000000000ULL;                \
1300             dfp_clear_lmd_from_g5msb(dfp.t64 + HI_IDX);             \
1301             dfp.t64[LO_IDX] = 0;                                    \
1302         }                                                           \
1303     }                                                               \
1304                                                                     \
1305     if ((size) == 64) {                                             \
1306         t[0] = dfp.t64[0];                                          \
1307     } else {                                                        \
1308         t[0] = dfp.t64[HI_IDX];                                     \
1309         t[1] = dfp.t64[LO_IDX];                                     \
1310     }                                                               \
1311 }
1312
1313 DFP_HELPER_SHIFT(dscli, 64, 1)
1314 DFP_HELPER_SHIFT(dscliq, 128, 1)
1315 DFP_HELPER_SHIFT(dscri, 64, 0)
1316 DFP_HELPER_SHIFT(dscriq, 128, 0)