vfp.hh (7385:493aea5e1006) vfp.hh (7386:23065556d48e)
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 161 unchanged lines hidden (view full) ---

170 uint64_t bits;
171 } val;
172 val.bits = bits;
173 return val.fp;
174}
175
176template <class fpType>
177static inline fpType
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 161 unchanged lines hidden (view full) ---

170 uint64_t bits;
171 } val;
172 val.bits = bits;
173 return val.fp;
174}
175
176template <class fpType>
177static inline fpType
178fixDest(FPSCR fpscr, fpType val, fpType op1)
179{
180 int fpClass = std::fpclassify(val);
181 fpType junk = 0.0;
182 if (fpClass == FP_NAN) {
183 const bool single = (sizeof(val) == sizeof(float));
184 const uint64_t qnan = single ? 0x7fc00000 : ULL(0x7ff8000000000000);
185 const bool nan = std::isnan(op1);
186 if (!nan || (fpscr.dn == 1)) {
187 val = bitsToFp(qnan, junk);
188 } else if (nan) {
189 val = bitsToFp(fpToBits(op1) | qnan, junk);
190 }
191 } else if (fpClass == FP_SUBNORMAL && fpscr.fz == 1) {
192 // Turn val into a zero with the correct sign;
193 uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1);
194 val = bitsToFp(fpToBits(val) & bitMask, junk);
195 feraiseexcept(FeUnderflow);
196 }
197 return val;
198}
199
200template <class fpType>
201static inline fpType
178fixDest(FPSCR fpscr, fpType val, fpType op1, fpType op2)
179{
180 int fpClass = std::fpclassify(val);
181 fpType junk = 0.0;
182 if (fpClass == FP_NAN) {
183 const bool single = (sizeof(val) == sizeof(float));
184 const uint64_t qnan = single ? 0x7fc00000 : ULL(0x7ff8000000000000);
185 const bool nan1 = std::isnan(op1);

--- 15 unchanged lines hidden (view full) ---

201 // Turn val into a zero with the correct sign;
202 uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1);
203 val = bitsToFp(fpToBits(val) & bitMask, junk);
204 feraiseexcept(FeUnderflow);
205 }
206 return val;
207}
208
202fixDest(FPSCR fpscr, fpType val, fpType op1, fpType op2)
203{
204 int fpClass = std::fpclassify(val);
205 fpType junk = 0.0;
206 if (fpClass == FP_NAN) {
207 const bool single = (sizeof(val) == sizeof(float));
208 const uint64_t qnan = single ? 0x7fc00000 : ULL(0x7ff8000000000000);
209 const bool nan1 = std::isnan(op1);

--- 15 unchanged lines hidden (view full) ---

225 // Turn val into a zero with the correct sign;
226 uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1);
227 val = bitsToFp(fpToBits(val) & bitMask, junk);
228 feraiseexcept(FeUnderflow);
229 }
230 return val;
231}
232
233template <class fpType>
234static inline fpType
235fixMultDest(FPSCR fpscr, fpType val, fpType op1, fpType op2)
236{
237 fpType mid = fixDest(fpscr, val, op1, op2);
238 const bool single = (sizeof(fpType) == sizeof(float));
239 const fpType junk = 0.0;
240 if ((single && (val == bitsToFp(0x00800000, junk) ||
241 val == bitsToFp(0x80800000, junk))) ||
242 (!single && (val == bitsToFp(ULL(0x0010000000000000), junk) ||
243 val == bitsToFp(ULL(0x8010000000000000), junk)))
244 ) {
245 __asm__ __volatile__("" : "=m" (op1) : "m" (op1));
246 fesetround(FeRoundZero);
247 fpType temp = 0.0;
248 __asm__ __volatile__("" : "=m" (temp) : "m" (temp));
249 temp = op1 * op2;
250 if (!std::isnormal(temp)) {
251 feraiseexcept(FeUnderflow);
252 }
253 __asm__ __volatile__("" :: "m" (temp));
254 }
255 return mid;
256}
257
258template <class fpType>
259static inline fpType
260fixDivDest(FPSCR fpscr, fpType val, fpType op1, fpType op2)
261{
262 fpType mid = fixDest(fpscr, val, op1, op2);
263 const bool single = (sizeof(fpType) == sizeof(float));
264 const fpType junk = 0.0;
265 if ((single && (val == bitsToFp(0x00800000, junk) ||
266 val == bitsToFp(0x80800000, junk))) ||
267 (!single && (val == bitsToFp(ULL(0x0010000000000000), junk) ||
268 val == bitsToFp(ULL(0x8010000000000000), junk)))
269 ) {
270 __asm__ __volatile__("" : "=m" (op1) : "m" (op1));
271 fesetround(FeRoundZero);
272 fpType temp = 0.0;
273 __asm__ __volatile__("" : "=m" (temp) : "m" (temp));
274 temp = op1 / op2;
275 if (!std::isnormal(temp)) {
276 feraiseexcept(FeUnderflow);
277 }
278 __asm__ __volatile__("" :: "m" (temp));
279 }
280 return mid;
281}
282
283static inline float
284fixFpDFpSDest(FPSCR fpscr, double val)
285{
286 const float junk = 0.0;
287 float op1 = 0.0;
288 if (std::isnan(val)) {
289 uint64_t valBits = fpToBits(val);
290 uint32_t op1Bits = bits(valBits, 50, 29) |
291 (mask(9) << 22) |
292 (bits(valBits, 63) << 31);
293 op1 = bitsToFp(op1Bits, junk);
294 }
295 float mid = fixDest(fpscr, (float)val, op1);
296 if (mid == bitsToFp(0x00800000, junk) ||
297 mid == bitsToFp(0x80800000, junk)) {
298 __asm__ __volatile__("" : "=m" (val) : "m" (val));
299 fesetround(FeRoundZero);
300 float temp = 0.0;
301 __asm__ __volatile__("" : "=m" (temp) : "m" (temp));
302 temp = val;
303 if (!std::isnormal(temp)) {
304 feraiseexcept(FeUnderflow);
305 }
306 __asm__ __volatile__("" :: "m" (temp));
307 }
308 return mid;
309}
310
209static inline uint64_t
210vfpFpSToFixed(float val, bool isSigned, bool half, uint8_t imm)
211{
212 fesetround(FeRoundZero);
213 val = val * powf(2.0, imm);
214 __asm__ __volatile__("" : "=m" (val) : "m" (val));
215 feclearexcept(FeAllExceptions);
216 __asm__ __volatile__("" : "=m" (val) : "m" (val));

--- 60 unchanged lines hidden (view full) ---

277 return mask(32);
278 }
279 return (uint32_t)val;
280 }
281 }
282}
283
284static inline float
311static inline uint64_t
312vfpFpSToFixed(float val, bool isSigned, bool half, uint8_t imm)
313{
314 fesetround(FeRoundZero);
315 val = val * powf(2.0, imm);
316 __asm__ __volatile__("" : "=m" (val) : "m" (val));
317 feclearexcept(FeAllExceptions);
318 __asm__ __volatile__("" : "=m" (val) : "m" (val));

--- 60 unchanged lines hidden (view full) ---

379 return mask(32);
380 }
381 return (uint32_t)val;
382 }
383 }
384}
385
386static inline float
285vfpUFixedToFpS(uint32_t val, bool half, uint8_t imm)
387vfpUFixedToFpS(FPSCR fpscr, uint32_t val, bool half, uint8_t imm)
286{
287 fesetround(FeRoundNearest);
288 if (half)
289 val = (uint16_t)val;
290 float scale = powf(2.0, imm);
291 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
292 feclearexcept(FeAllExceptions);
293 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
388{
389 fesetround(FeRoundNearest);
390 if (half)
391 val = (uint16_t)val;
392 float scale = powf(2.0, imm);
393 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
394 feclearexcept(FeAllExceptions);
395 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
294 return val / scale;
396 return fixDivDest(fpscr, val / scale, (float)val, scale);
295}
296
297static inline float
397}
398
399static inline float
298vfpSFixedToFpS(int32_t val, bool half, uint8_t imm)
400vfpSFixedToFpS(FPSCR fpscr, int32_t val, bool half, uint8_t imm)
299{
300 fesetround(FeRoundNearest);
301 if (half)
302 val = sext<16>(val & mask(16));
303 float scale = powf(2.0, imm);
304 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
305 feclearexcept(FeAllExceptions);
306 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
401{
402 fesetround(FeRoundNearest);
403 if (half)
404 val = sext<16>(val & mask(16));
405 float scale = powf(2.0, imm);
406 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
407 feclearexcept(FeAllExceptions);
408 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
307 return val / scale;
409 return fixDivDest(fpscr, val / scale, (float)val, scale);
308}
309
310static inline uint64_t
311vfpFpDToFixed(double val, bool isSigned, bool half, uint8_t imm)
312{
313 fesetround(FeRoundNearest);
314 val = val * pow(2.0, imm);
315 __asm__ __volatile__("" : "=m" (val) : "m" (val));

--- 62 unchanged lines hidden (view full) ---

378 return mask(32);
379 }
380 return (uint32_t)val;
381 }
382 }
383}
384
385static inline double
410}
411
412static inline uint64_t
413vfpFpDToFixed(double val, bool isSigned, bool half, uint8_t imm)
414{
415 fesetround(FeRoundNearest);
416 val = val * pow(2.0, imm);
417 __asm__ __volatile__("" : "=m" (val) : "m" (val));

--- 62 unchanged lines hidden (view full) ---

480 return mask(32);
481 }
482 return (uint32_t)val;
483 }
484 }
485}
486
487static inline double
386vfpUFixedToFpD(uint32_t val, bool half, uint8_t imm)
488vfpUFixedToFpD(FPSCR fpscr, uint32_t val, bool half, uint8_t imm)
387{
388 fesetround(FeRoundNearest);
389 if (half)
390 val = (uint16_t)val;
391 double scale = pow(2.0, imm);
392 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
393 feclearexcept(FeAllExceptions);
394 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
489{
490 fesetround(FeRoundNearest);
491 if (half)
492 val = (uint16_t)val;
493 double scale = pow(2.0, imm);
494 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
495 feclearexcept(FeAllExceptions);
496 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
395 return val / scale;
497 return fixDivDest(fpscr, val / scale, (double)val, scale);
396}
397
398static inline double
498}
499
500static inline double
399vfpSFixedToFpD(int32_t val, bool half, uint8_t imm)
501vfpSFixedToFpD(FPSCR fpscr, int32_t val, bool half, uint8_t imm)
400{
401 fesetround(FeRoundNearest);
402 if (half)
403 val = sext<16>(val & mask(16));
404 double scale = pow(2.0, imm);
405 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
406 feclearexcept(FeAllExceptions);
407 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
502{
503 fesetround(FeRoundNearest);
504 if (half)
505 val = sext<16>(val & mask(16));
506 double scale = pow(2.0, imm);
507 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
508 feclearexcept(FeAllExceptions);
509 __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
408 return val / scale;
510 return fixDivDest(fpscr, val / scale, (double)val, scale);
409}
410
411typedef int VfpSavedState;
412
413static inline VfpSavedState
414prepVfpFpscr(FPSCR fpscr)
415{
416 int roundingMode = fegetround();

--- 154 unchanged lines hidden ---
511}
512
513typedef int VfpSavedState;
514
515static inline VfpSavedState
516prepVfpFpscr(FPSCR fpscr)
517{
518 int roundingMode = fegetround();

--- 154 unchanged lines hidden ---