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