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 |
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 |
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 |
387vfpUFixedToFpS(FPSCR fpscr, uint32_t val, bool half, uint8_t imm) |
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)); |
396 return fixDivDest(fpscr, val / scale, (float)val, scale); |
397} 398 399static inline float |
400vfpSFixedToFpS(FPSCR fpscr, int32_t val, bool half, uint8_t imm) |
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)); |
409 return fixDivDest(fpscr, val / scale, (float)val, scale); |
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 |
488vfpUFixedToFpD(FPSCR fpscr, uint32_t val, bool half, uint8_t imm) |
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)); |
497 return fixDivDest(fpscr, val / scale, (double)val, scale); |
498} 499 500static inline double |
501vfpSFixedToFpD(FPSCR fpscr, int32_t val, bool half, uint8_t imm) |
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)); |
510 return fixDivDest(fpscr, val / scale, (double)val, scale); |
511} 512 513typedef int VfpSavedState; 514 515static inline VfpSavedState 516prepVfpFpscr(FPSCR fpscr) 517{ 518 int roundingMode = fegetround(); --- 154 unchanged lines hidden --- |