| 673 | } |
| 674 | |
| 675 | static expr handle_subnormal(const State &s, FPDenormalAttrs::Type attr, |
| 676 | expr &&v) { |
| 677 | auto posz = [&]() { |
| 678 | return expr::mkIf(v.isFPSubNormal(), expr::mkNumber("0", v), v); |
| 679 | }; |
| 680 | auto sign = [&]() { |
| 681 | return expr::mkIf(v.isFPSubNormal(), |
| 682 | expr::mkIf(v.isFPNegative(), |
| 683 | expr::mkNumber("-0", v), |
| 684 | expr::mkNumber("0", v)), |
| 685 | v); |
| 686 | }; |
| 687 | |
| 688 | switch (attr) { |
| 689 | case FPDenormalAttrs::IEEE: |
| 690 | break; |
| 691 | case FPDenormalAttrs::PositiveZero: |
| 692 | v = posz(); |
| 693 | break; |
| 694 | case FPDenormalAttrs::PreserveSign: |
| 695 | v = sign(); |
| 696 | break; |
| 697 | case FPDenormalAttrs::Dynamic: { |
| 698 | auto &mode = s.getFpDenormalMode(); |
| 699 | v = expr::mkIf(mode == FPDenormalAttrs::IEEE, |
| 700 | v, |
| 701 | expr::mkIf(mode == FPDenormalAttrs::PositiveZero, |
| 702 | posz(), |
| 703 | sign())); |
| 704 | break; |
| 705 | } |
| 706 | } |
| 707 | return std::move(v); |
| 708 | } |
| 709 | |
| 710 | template <typename T> |
| 711 | static T round_value(const State &s, FpRoundingMode rm, AndExpr &non_poison, |
no test coverage detected