Skip to content
44 changes: 44 additions & 0 deletions flang/include/flang/Common/Fortran-consts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===-- include/flang/Common/Fortran-consts.h -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_COMMON_FORTRAN_CONSTS_H_
#define FORTRAN_COMMON_FORTRAN_CONSTS_H_

#include "flang/Common/enum-class.h"
#include <cstdint>

namespace Fortran::common {

// Fortran has five kinds of intrinsic data types, plus the derived types.
ENUM_CLASS(TypeCategory, Integer, Real, Complex, Character, Logical, Derived)
ENUM_CLASS(VectorElementCategory, Integer, Unsigned, Real)

ENUM_CLASS(IoStmtKind, None, Backspace, Close, Endfile, Flush, Inquire, Open,
Print, Read, Rewind, Wait, Write)

// Defined I/O variants
ENUM_CLASS(
DefinedIo, ReadFormatted, ReadUnformatted, WriteFormatted, WriteUnformatted)

// Fortran arrays may have up to 15 dimensions (See Fortran 2018 section 5.4.6).
static constexpr int maxRank{15};

// Floating-point rounding modes; these are packed into a byte to save
// room in the runtime's format processing context structure. These
// enumerators are defined with the corresponding values returned from
// llvm.get.rounding.
enum class RoundingMode : std::uint8_t {
ToZero, // ROUND=ZERO, RZ - truncation
TiesToEven, // ROUND=NEAREST, RN - default IEEE rounding
Up, // ROUND=UP, RU
Down, // ROUND=DOWN, RD
TiesAwayFromZero, // ROUND=COMPATIBLE, RC - ties round away from zero
};

} // namespace Fortran::common
#endif /* FORTRAN_COMMON_FORTRAN_CONSTS_H_ */
26 changes: 1 addition & 25 deletions flang/include/flang/Common/Fortran.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@

#include "enum-set.h"
#include "idioms.h"
#include "flang/Common/Fortran-consts.h"
#include <cinttypes>
#include <optional>
#include <string>

namespace Fortran::common {
class LanguageFeatureControl;

// Fortran has five kinds of intrinsic data types, plus the derived types.
ENUM_CLASS(TypeCategory, Integer, Real, Complex, Character, Logical, Derived)
ENUM_CLASS(VectorElementCategory, Integer, Unsigned, Real)

constexpr bool IsNumericTypeCategory(TypeCategory category) {
return category == TypeCategory::Integer || category == TypeCategory::Real ||
category == TypeCategory::Complex;
Expand All @@ -47,9 +44,6 @@ const char *AsFortran(RelationalOperator);

ENUM_CLASS(Intent, Default, In, Out, InOut)

ENUM_CLASS(IoStmtKind, None, Backspace, Close, Endfile, Flush, Inquire, Open,
Print, Read, Rewind, Wait, Write)

// Union of specifiers for all I/O statements.
ENUM_CLASS(IoSpecKind, Access, Action, Advance, Asynchronous, Blank, Decimal,
Delim, Direct, Encoding, End, Eor, Err, Exist, File, Fmt, Form, Formatted,
Expand All @@ -61,29 +55,11 @@ ENUM_CLASS(IoSpecKind, Access, Action, Advance, Asynchronous, Blank, Decimal,
Dispose, // nonstandard
)

// Defined I/O variants
ENUM_CLASS(
DefinedIo, ReadFormatted, ReadUnformatted, WriteFormatted, WriteUnformatted)
const char *AsFortran(DefinedIo);

// Floating-point rounding modes; these are packed into a byte to save
// room in the runtime's format processing context structure. These
// enumerators are defined with the corresponding values returned from
// llvm.get.rounding.
enum class RoundingMode : std::uint8_t {
ToZero, // ROUND=ZERO, RZ - truncation
TiesToEven, // ROUND=NEAREST, RN - default IEEE rounding
Up, // ROUND=UP, RU
Down, // ROUND=DOWN, RD
TiesAwayFromZero, // ROUND=COMPATIBLE, RC - ties round away from zero
};

// Fortran label. Must be in [1..99999].
using Label = std::uint64_t;

// Fortran arrays may have up to 15 dimensions (See Fortran 2018 section 5.4.6).
static constexpr int maxRank{15};

// CUDA subprogram attribute combinations
ENUM_CLASS(CUDASubprogramAttrs, Host, Device, HostDevice, Global, Grid_Global)

Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Common/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#define FORTRAN_COMMON_FORMAT_H_

#include "enum-set.h"
#include "flang/Common/Fortran.h"
#include "flang/Common/Fortran-consts.h"
#include <cstring>

// Define a FormatValidator class template to validate a format expression
Expand Down
37 changes: 37 additions & 0 deletions flang/include/flang/Common/target-rounding.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===-- include/flang/Common/target-rounding.h ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_COMMON_TARGET_ROUNDING_H_
#define FORTRAN_COMMON_TARGET_ROUNDING_H_

#include "flang/Common/Fortran-consts.h"
#include "flang/Common/enum-set.h"

namespace Fortran::common {

// Floating-point rounding control
struct Rounding {
common::RoundingMode mode{common::RoundingMode::TiesToEven};
// When set, emulate status flag behavior peculiar to x86
// (viz., fail to set the Underflow flag when an inexact product of a
// multiplication is rounded up to a normal number from a subnormal
// in some rounding modes)
#if __x86_64__ || __riscv || __loongarch__
bool x86CompatibleBehavior{true};
#else
bool x86CompatibleBehavior{false};
#endif
};

// These are ordered like the bits in a common fenv.h header file.
ENUM_CLASS(RealFlag, InvalidArgument, Denorm, DivideByZero, Overflow, Underflow,
Inexact)
using RealFlags = common::EnumSet<RealFlag, RealFlag_enumSize>;

} // namespace Fortran::common
#endif /* FORTRAN_COMMON_TARGET_ROUNDING_H_ */
8 changes: 3 additions & 5 deletions flang/include/flang/Evaluate/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "flang/Common/idioms.h"
#include "flang/Common/indirection.h"
#include "flang/Common/restorer.h"
#include "flang/Common/target-rounding.h"
#include "flang/Parser/char-block.h"
#include "flang/Parser/message.h"
#include <cinttypes>
Expand All @@ -32,6 +33,8 @@ class IntrinsicProcTable;
class TargetCharacteristics;

using common::ConstantSubscript;
using common::RealFlag;
using common::RealFlags;
using common::RelationalOperator;

// Integers are always ordered; reals may not be.
Expand Down Expand Up @@ -128,11 +131,6 @@ static constexpr bool Satisfies(RelationalOperator op, Relation relation) {
return false; // silence g++ warning
}

// These are ordered like the bits in a common fenv.h header file.
ENUM_CLASS(RealFlag, InvalidArgument, Denorm, DivideByZero, Overflow, Underflow,
Inexact)
using RealFlags = common::EnumSet<RealFlag, RealFlag_enumSize>;

template <typename A> struct ValueWithRealFlags {
A AccumulateFlags(RealFlags &f) {
f |= flags;
Expand Down
15 changes: 2 additions & 13 deletions flang/include/flang/Evaluate/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,13 @@
#include "flang/Common/Fortran.h"
#include "flang/Common/enum-class.h"
#include "flang/Common/enum-set.h"
#include "flang/Common/target-rounding.h"
#include "flang/Evaluate/common.h"
#include <cstdint>

namespace Fortran::evaluate {

// Floating-point rounding control
struct Rounding {
common::RoundingMode mode{common::RoundingMode::TiesToEven};
// When set, emulate status flag behavior peculiar to x86
// (viz., fail to set the Underflow flag when an inexact product of a
// multiplication is rounded up to a normal number from a subnormal
// in some rounding modes)
#if __x86_64__ || __riscv || __loongarch__
bool x86CompatibleBehavior{true};
#else
bool x86CompatibleBehavior{false};
#endif
};
using common::Rounding;

ENUM_CLASS(IeeeFeature, Denormal, Divide, Flags, Halting, Inf, Io, NaN,
Rounding, Sqrt, Standard, Subnormal, UnderflowControl)
Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Runtime/cpp-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#ifndef FORTRAN_RUNTIME_CPP_TYPE_H_
#define FORTRAN_RUNTIME_CPP_TYPE_H_

#include "flang/Common/Fortran.h"
#include "flang/Common/Fortran-consts.h"
#include "flang/Common/float128.h"
#include "flang/Common/uint128.h"
#include <complex>
Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Runtime/type-code.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#ifndef FORTRAN_RUNTIME_TYPE_CODE_H_
#define FORTRAN_RUNTIME_TYPE_CODE_H_

#include "flang/Common/Fortran.h"
#include "flang/Common/Fortran-consts.h"
#include "flang/Common/optional.h"
#include "flang/ISO_Fortran_binding_wrapper.h"
#include <utility>
Expand Down
2 changes: 1 addition & 1 deletion flang/runtime/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#include "environment.h"
#include "io-error.h"
#include "flang/Common/Fortran.h"
#include "flang/Common/Fortran-consts.h"
#include "flang/Common/optional.h"
#include "flang/Decimal/decimal.h"
#include "flang/Runtime/freestanding-tools.h"
Expand Down
3 changes: 2 additions & 1 deletion flang/runtime/non-tbp-dio.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
#ifndef FORTRAN_RUNTIME_NON_TBP_DIO_H_
#define FORTRAN_RUNTIME_NON_TBP_DIO_H_

#include "flang/Common/Fortran.h"
#include "flang/Common/Fortran-consts.h"
#include "flang/Common/api-attrs.h"
#include <cstddef>

namespace Fortran::runtime::typeInfo {
Expand Down
2 changes: 1 addition & 1 deletion flang/runtime/type-info.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// flang/module/__fortran_type_info.f90.

#include "terminator.h"
#include "flang/Common/Fortran.h"
#include "flang/Common/Fortran-consts.h"
#include "flang/Common/bit-population-count.h"
#include "flang/Common/optional.h"
#include "flang/Runtime/descriptor.h"
Expand Down
2 changes: 1 addition & 1 deletion flang/unittests/Evaluate/fp-testing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#include <xmmintrin.h>
#endif

using Fortran::common::RealFlag;
using Fortran::common::RoundingMode;
using Fortran::evaluate::RealFlag;

ScopedHostFloatingPointEnvironment::ScopedHostFloatingPointEnvironment(
#if __x86_64__
Expand Down
6 changes: 3 additions & 3 deletions flang/unittests/Evaluate/fp-testing.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#ifndef FORTRAN_TEST_EVALUATE_FP_TESTING_H_
#define FORTRAN_TEST_EVALUATE_FP_TESTING_H_

#include "flang/Evaluate/target.h"
#include "flang/Common/target-rounding.h"
#include <fenv.h>

using Fortran::common::RealFlags;
using Fortran::common::Rounding;
using Fortran::common::RoundingMode;
using Fortran::evaluate::RealFlags;
using Fortran::evaluate::Rounding;

class ScopedHostFloatingPointEnvironment {
public:
Expand Down
2 changes: 1 addition & 1 deletion flang/unittests/Runtime/Complex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#pragma clang diagnostic ignored "-Wc99-extensions"
#endif

#include "flang/Common/Fortran.h"
#include "flang/Common/Fortran-consts.h"
#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/entry-names.h"

Expand Down
Loading