| 2491 | } |
| 2492 | |
| 2493 | Expected<IEEEFloat::opStatus> |
| 2494 | IEEEFloat::convertFromHexadecimalString(StringRef s, |
| 2495 | roundingMode rounding_mode) { |
| 2496 | lostFraction lost_fraction = lfExactlyZero; |
| 2497 | |
| 2498 | category = fcNormal; |
| 2499 | zeroSignificand(); |
| 2500 | exponent = 0; |
| 2501 | |
| 2502 | integerPart *significand = significandParts(); |
| 2503 | unsigned partsCount = partCount(); |
| 2504 | unsigned bitPos = partsCount * integerPartWidth; |
| 2505 | bool computedTrailingFraction = false; |
| 2506 | |
| 2507 | // Skip leading zeroes and any (hexa)decimal point. |
| 2508 | StringRef::iterator begin = s.begin(); |
| 2509 | StringRef::iterator end = s.end(); |
| 2510 | StringRef::iterator dot; |
| 2511 | auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot); |
| 2512 | if (!PtrOrErr) |
| 2513 | return PtrOrErr.takeError(); |
| 2514 | StringRef::iterator p = *PtrOrErr; |
| 2515 | StringRef::iterator firstSignificantDigit = p; |
| 2516 | |
| 2517 | while (p != end) { |
| 2518 | integerPart hex_value; |
| 2519 | |
| 2520 | if (*p == '.') { |
| 2521 | if (dot != end) |
| 2522 | return createError("String contains multiple dots"); |
| 2523 | dot = p++; |
| 2524 | continue; |
| 2525 | } |
| 2526 | |
| 2527 | hex_value = hexDigitValue(*p); |
| 2528 | if (hex_value == -1U) |
| 2529 | break; |
| 2530 | |
| 2531 | p++; |
| 2532 | |
| 2533 | // Store the number while we have space. |
| 2534 | if (bitPos) { |
| 2535 | bitPos -= 4; |
| 2536 | hex_value <<= bitPos % integerPartWidth; |
| 2537 | significand[bitPos / integerPartWidth] |= hex_value; |
| 2538 | } else if (!computedTrailingFraction) { |
| 2539 | auto FractOrErr = trailingHexadecimalFraction(p, end, hex_value); |
| 2540 | if (!FractOrErr) |
| 2541 | return FractOrErr.takeError(); |
| 2542 | lost_fraction = *FractOrErr; |
| 2543 | computedTrailingFraction = true; |
| 2544 | } |
| 2545 | } |
| 2546 | |
| 2547 | /* Hex floats require an exponent but not a hexadecimal point. */ |
| 2548 | if (p == end) |
| 2549 | return createError("Hex strings require an exponent"); |
| 2550 | if (*p != 'p' && *p != 'P') |
nothing calls this directly
no test coverage detected