diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp_helper.h | 5 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpdouble.cpp | 171 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpsingle.cpp | 40 |
3 files changed, 1 insertions, 215 deletions
diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h index 6e63d59ec..b68090b80 100644 --- a/src/core/arm/skyeye_common/vfp/vfp_helper.h +++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h | |||
| @@ -381,8 +381,6 @@ static inline int vfp_double_type(vfp_double* s) | |||
| 381 | return type; | 381 | return type; |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | u32 vfp_double_normaliseround(ARMul_State* state, int dd, vfp_double* vd, u32 fpscr, u32 exceptions, const char* func); | ||
| 385 | |||
| 386 | u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); | 384 | u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); |
| 387 | 385 | ||
| 388 | // A special flag to tell the normalisation code not to normalise. | 386 | // A special flag to tell the normalisation code not to normalise. |
| @@ -441,7 +439,6 @@ static inline u32 fls(ARMword x) | |||
| 441 | 439 | ||
| 442 | } | 440 | } |
| 443 | 441 | ||
| 444 | u32 vfp_double_normaliseroundintern(ARMul_State* state, vfp_double* vd, u32 fpscr, u32 exceptions, const char* func); | ||
| 445 | u32 vfp_double_multiply(vfp_double* vdd, vfp_double* vdn, vfp_double* vdm, u32 fpscr); | 442 | u32 vfp_double_multiply(vfp_double* vdd, vfp_double* vdn, vfp_double* vdm, u32 fpscr); |
| 446 | u32 vfp_double_add(vfp_double* vdd, vfp_double* vdn, vfp_double *vdm, u32 fpscr); | 443 | u32 vfp_double_add(vfp_double* vdd, vfp_double* vdn, vfp_double *vdm, u32 fpscr); |
| 447 | u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, vfp_double* dm, u32 fpscr); | 444 | u32 vfp_double_normaliseround(ARMul_State* state, int dd, vfp_double* vd, u32 fpscr, u32 exceptions, const char* func); |
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp index a05db0a45..d6d21db2f 100644 --- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp | |||
| @@ -83,134 +83,6 @@ static void vfp_double_normalise_denormal(struct vfp_double *vd) | |||
| 83 | vfp_double_dump("normalise_denormal: out", vd); | 83 | vfp_double_dump("normalise_denormal: out", vd); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | u32 vfp_double_normaliseroundintern(ARMul_State* state, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func) | ||
| 87 | { | ||
| 88 | u64 significand, incr; | ||
| 89 | int exponent, shift, underflow; | ||
| 90 | u32 rmode; | ||
| 91 | |||
| 92 | vfp_double_dump("pack: in", vd); | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Infinities and NaNs are a special case. | ||
| 96 | */ | ||
| 97 | if (vd->exponent == 2047 && (vd->significand == 0 || exceptions)) | ||
| 98 | goto pack; | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Special-case zero. | ||
| 102 | */ | ||
| 103 | if (vd->significand == 0) { | ||
| 104 | vd->exponent = 0; | ||
| 105 | goto pack; | ||
| 106 | } | ||
| 107 | |||
| 108 | exponent = vd->exponent; | ||
| 109 | significand = vd->significand; | ||
| 110 | |||
| 111 | shift = 32 - fls((ARMword)(significand >> 32)); | ||
| 112 | if (shift == 32) | ||
| 113 | shift = 64 - fls((ARMword)significand); | ||
| 114 | if (shift) { | ||
| 115 | exponent -= shift; | ||
| 116 | significand <<= shift; | ||
| 117 | } | ||
| 118 | |||
| 119 | #if 1 | ||
| 120 | vd->exponent = exponent; | ||
| 121 | vd->significand = significand; | ||
| 122 | vfp_double_dump("pack: normalised", vd); | ||
| 123 | #endif | ||
| 124 | |||
| 125 | /* | ||
| 126 | * Tiny number? | ||
| 127 | */ | ||
| 128 | underflow = exponent < 0; | ||
| 129 | if (underflow) { | ||
| 130 | significand = vfp_shiftright64jamming(significand, -exponent); | ||
| 131 | exponent = 0; | ||
| 132 | #if 1 | ||
| 133 | vd->exponent = exponent; | ||
| 134 | vd->significand = significand; | ||
| 135 | vfp_double_dump("pack: tiny number", vd); | ||
| 136 | #endif | ||
| 137 | if (!(significand & ((1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1))) | ||
| 138 | underflow = 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | /* | ||
| 142 | * Select rounding increment. | ||
| 143 | */ | ||
| 144 | incr = 0; | ||
| 145 | rmode = fpscr & FPSCR_RMODE_MASK; | ||
| 146 | |||
| 147 | if (rmode == FPSCR_ROUND_NEAREST) { | ||
| 148 | incr = 1ULL << VFP_DOUBLE_LOW_BITS; | ||
| 149 | if ((significand & (1ULL << (VFP_DOUBLE_LOW_BITS + 1))) == 0) | ||
| 150 | incr -= 1; | ||
| 151 | } | ||
| 152 | else if (rmode == FPSCR_ROUND_TOZERO) { | ||
| 153 | incr = 0; | ||
| 154 | } | ||
| 155 | else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0)) | ||
| 156 | incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1; | ||
| 157 | |||
| 158 | LOG_TRACE(Core_ARM11, "VFP: rounding increment = 0x%08llx\n", incr); | ||
| 159 | |||
| 160 | /* | ||
| 161 | * Is our rounding going to overflow? | ||
| 162 | */ | ||
| 163 | if ((significand + incr) < significand) { | ||
| 164 | exponent += 1; | ||
| 165 | significand = (significand >> 1) | (significand & 1); | ||
| 166 | incr >>= 1; | ||
| 167 | #if 1 | ||
| 168 | vd->exponent = exponent; | ||
| 169 | vd->significand = significand; | ||
| 170 | vfp_double_dump("pack: overflow", vd); | ||
| 171 | #endif | ||
| 172 | } | ||
| 173 | |||
| 174 | /* | ||
| 175 | * If any of the low bits (which will be shifted out of the | ||
| 176 | * number) are non-zero, the result is inexact. | ||
| 177 | */ | ||
| 178 | if (significand & ((1 << (VFP_DOUBLE_LOW_BITS + 1)) - 1)) | ||
| 179 | exceptions |= FPSCR_IXC; | ||
| 180 | |||
| 181 | /* | ||
| 182 | * Do our rounding. | ||
| 183 | */ | ||
| 184 | significand += incr; | ||
| 185 | |||
| 186 | /* | ||
| 187 | * Infinity? | ||
| 188 | */ | ||
| 189 | if (exponent >= 2046) { | ||
| 190 | exceptions |= FPSCR_OFC | FPSCR_IXC; | ||
| 191 | if (incr == 0) { | ||
| 192 | vd->exponent = 2045; | ||
| 193 | vd->significand = 0x7fffffffffffffffULL; | ||
| 194 | } | ||
| 195 | else { | ||
| 196 | vd->exponent = 2047; /* infinity */ | ||
| 197 | vd->significand = 0; | ||
| 198 | } | ||
| 199 | } | ||
| 200 | else { | ||
| 201 | if (significand >> (VFP_DOUBLE_LOW_BITS + 1) == 0) | ||
| 202 | exponent = 0; | ||
| 203 | if (exponent || significand > 0x8000000000000000ULL) | ||
| 204 | underflow = 0; | ||
| 205 | if (underflow) | ||
| 206 | exceptions |= FPSCR_UFC; | ||
| 207 | vd->exponent = exponent; | ||
| 208 | vd->significand = significand >> 1; | ||
| 209 | } | ||
| 210 | pack: | ||
| 211 | return 0; | ||
| 212 | } | ||
| 213 | |||
| 214 | u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func) | 86 | u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func) |
| 215 | { | 87 | { |
| 216 | u64 significand, incr; | 88 | u64 significand, incr; |
| @@ -592,49 +464,6 @@ static u32 vfp_double_fcmpez(ARMul_State* state, int dd, int unused, int dm, u32 | |||
| 592 | return vfp_compare(state, dd, 1, VFP_REG_ZERO, fpscr); | 464 | return vfp_compare(state, dd, 1, VFP_REG_ZERO, fpscr); |
| 593 | } | 465 | } |
| 594 | 466 | ||
| 595 | u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, struct vfp_double* dm, u32 fpscr) //ichfly for internal use only | ||
| 596 | { | ||
| 597 | struct vfp_single vsd; | ||
| 598 | int tm; | ||
| 599 | u32 exceptions = 0; | ||
| 600 | |||
| 601 | LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); | ||
| 602 | |||
| 603 | tm = vfp_double_type(dm); | ||
| 604 | |||
| 605 | /* | ||
| 606 | * If we have a signalling NaN, signal invalid operation. | ||
| 607 | */ | ||
| 608 | if (tm == VFP_SNAN) | ||
| 609 | exceptions = FPSCR_IOC; | ||
| 610 | |||
| 611 | if (tm & VFP_DENORMAL) | ||
| 612 | vfp_double_normalise_denormal(dm); | ||
| 613 | |||
| 614 | vsd.sign = dm->sign; | ||
| 615 | vsd.significand = vfp_hi64to32jamming(dm->significand); | ||
| 616 | |||
| 617 | /* | ||
| 618 | * If we have an infinity or a NaN, the exponent must be 255 | ||
| 619 | */ | ||
| 620 | if (tm & (VFP_INFINITY | VFP_NAN)) { | ||
| 621 | vsd.exponent = 255; | ||
| 622 | if (tm == VFP_QNAN) | ||
| 623 | vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN; | ||
| 624 | goto pack_nan; | ||
| 625 | } | ||
| 626 | else if (tm & VFP_ZERO) | ||
| 627 | vsd.exponent = 0; | ||
| 628 | else | ||
| 629 | vsd.exponent = dm->exponent - (1023 - 127); | ||
| 630 | |||
| 631 | return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, "fcvts"); | ||
| 632 | |||
| 633 | pack_nan: | ||
| 634 | vfp_put_float(state, vfp_single_pack(&vsd), sd); | ||
| 635 | return exceptions; | ||
| 636 | } | ||
| 637 | |||
| 638 | static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) | 467 | static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) |
| 639 | { | 468 | { |
| 640 | struct vfp_double vdm; | 469 | struct vfp_double vdm; |
diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp index da4d2d384..678b63f51 100644 --- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp | |||
| @@ -491,46 +491,6 @@ static u32 vfp_single_fcmpez(ARMul_State* state, int sd, int unused, s32 m, u32 | |||
| 491 | return vfp_compare(state, sd, 1, 0, fpscr); | 491 | return vfp_compare(state, sd, 1, 0, fpscr); |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | static s64 vfp_single_to_doubleintern(ARMul_State* state, s32 m, u32 fpscr) //ichfly for internal use only | ||
| 495 | { | ||
| 496 | struct vfp_single vsm; | ||
| 497 | struct vfp_double vdd; | ||
| 498 | int tm; | ||
| 499 | u32 exceptions = 0; | ||
| 500 | |||
| 501 | vfp_single_unpack(&vsm, m); | ||
| 502 | |||
| 503 | tm = vfp_single_type(&vsm); | ||
| 504 | |||
| 505 | /* | ||
| 506 | * If we have a signalling NaN, signal invalid operation. | ||
| 507 | */ | ||
| 508 | if (tm == VFP_SNAN) | ||
| 509 | exceptions = FPSCR_IOC; | ||
| 510 | |||
| 511 | if (tm & VFP_DENORMAL) | ||
| 512 | vfp_single_normalise_denormal(&vsm); | ||
| 513 | |||
| 514 | vdd.sign = vsm.sign; | ||
| 515 | vdd.significand = (u64)vsm.significand << 32; | ||
| 516 | |||
| 517 | /* | ||
| 518 | * If we have an infinity or NaN, the exponent must be 2047. | ||
| 519 | */ | ||
| 520 | if (tm & (VFP_INFINITY | VFP_NAN)) { | ||
| 521 | vdd.exponent = 2047; | ||
| 522 | if (tm == VFP_QNAN) | ||
| 523 | vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; | ||
| 524 | goto pack_nan; | ||
| 525 | } else if (tm & VFP_ZERO) | ||
| 526 | vdd.exponent = 0; | ||
| 527 | else | ||
| 528 | vdd.exponent = vsm.exponent + (1023 - 127); | ||
| 529 | pack_nan: | ||
| 530 | vfp_double_normaliseroundintern(state, &vdd, fpscr, exceptions, "fcvtd"); | ||
| 531 | return vfp_double_pack(&vdd); | ||
| 532 | } | ||
| 533 | |||
| 534 | static u32 vfp_single_fcvtd(ARMul_State* state, int dd, int unused, s32 m, u32 fpscr) | 494 | static u32 vfp_single_fcvtd(ARMul_State* state, int dd, int unused, s32 m, u32 fpscr) |
| 535 | { | 495 | { |
| 536 | struct vfp_single vsm; | 496 | struct vfp_single vsm; |