summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp_helper.h5
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpdouble.cpp171
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpsingle.cpp40
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
384u32 vfp_double_normaliseround(ARMul_State* state, int dd, vfp_double* vd, u32 fpscr, u32 exceptions, const char* func);
385
386u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); 384u32 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
444u32 vfp_double_normaliseroundintern(ARMul_State* state, vfp_double* vd, u32 fpscr, u32 exceptions, const char* func);
445u32 vfp_double_multiply(vfp_double* vdd, vfp_double* vdn, vfp_double* vdm, u32 fpscr); 442u32 vfp_double_multiply(vfp_double* vdd, vfp_double* vdn, vfp_double* vdm, u32 fpscr);
446u32 vfp_double_add(vfp_double* vdd, vfp_double* vdn, vfp_double *vdm, u32 fpscr); 443u32 vfp_double_add(vfp_double* vdd, vfp_double* vdn, vfp_double *vdm, u32 fpscr);
447u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, vfp_double* dm, u32 fpscr); 444u32 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
86u32 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
214u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func) 86u32 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
595u32 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
633pack_nan:
634 vfp_put_float(state, vfp_single_pack(&vsd), sd);
635 return exceptions;
636}
637
638static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) 467static 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
494static 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);
529pack_nan:
530 vfp_double_normaliseroundintern(state, &vdd, fpscr, exceptions, "fcvtd");
531 return vfp_double_pack(&vdd);
532}
533
534static u32 vfp_single_fcvtd(ARMul_State* state, int dd, int unused, s32 m, u32 fpscr) 494static 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;