9#ifndef FORTRAN_EVALUATE_ROUNDING_BITS_H_
10#define FORTRAN_EVALUATE_ROUNDING_BITS_H_
12#include "flang/Evaluate/target.h"
18namespace Fortran::evaluate::value {
23 bool guard =
false,
bool round =
false,
bool sticky =
false)
24 : guard_{guard}, round_{round}, sticky_{sticky} {}
26 template <
typename FRACTION>
27 constexpr RoundingBits(
const FRACTION &fraction,
int rshift) {
28 if (rshift > 0 && rshift < fraction.bits + 1) {
29 guard_ = fraction.BTEST(rshift - 1);
31 if (rshift > 1 && rshift < fraction.bits + 2) {
32 round_ = fraction.BTEST(rshift - 2);
35 if (rshift >= fraction.bits + 2) {
36 sticky_ = !fraction.IsZero();
38 auto mask{fraction.MASKR(rshift - 2)};
39 sticky_ = !fraction.IAND(mask).IsZero();
44 constexpr bool guard()
const {
return guard_; }
45 constexpr bool round()
const {
return round_; }
46 constexpr bool sticky()
const {
return sticky_; }
47 constexpr bool empty()
const {
return !(guard_ | round_ | sticky_); }
64 constexpr bool ShiftLeft() {
65 bool oldGuard{guard_};
71 constexpr void ShiftRight(
bool newGuard) {
79 constexpr bool MustRound(
80 Rounding rounding,
bool isNegative,
bool isOdd)
const {
82 switch (rounding.mode) {
83 case common::RoundingMode::TiesToEven:
84 round = guard_ && (round_ | sticky_ | isOdd);
86 case common::RoundingMode::ToZero:
88 case common::RoundingMode::Down:
89 round = isNegative && !empty();
91 case common::RoundingMode::Up:
92 round = !isNegative && !empty();
94 case common::RoundingMode::TiesAwayFromZero:
Definition: rounding-bits.h:20
Definition: target-rounding.h:18
Definition: expression.h:247