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