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