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