qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

dfp_helper.c (62333B)


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