#include "flang/Evaluate/real.h"
#include "flang/Evaluate/traverse.h"
#include "flang/Lower/AbstractConverter.h"
+#include "flang/Lower/ConvertType.h"
#include "flang/Lower/IntrinsicCall.h"
#include "flang/Lower/SymbolMap.h"
#include "flang/Lower/Todo.h"
return builder.createBool(getLoc(), value);
}
+ /// Generate a real constant with a value `value`.
+ template <int KIND>
+ mlir::Value genRealConstant(mlir::MLIRContext *context,
+ const llvm::APFloat &value) {
+ mlir::Type fltTy = Fortran::lower::convertReal(context, KIND);
+ return builder.createRealConstant(getLoc(), fltTy, value);
+ }
+
/// Returns a reference to a symbol or its box/boxChar descriptor if it has
/// one.
ExtValue gen(Fortran::semantics::SymbolRef sym) {
} else if constexpr (TC == Fortran::common::TypeCategory::Logical) {
return genBoolConstant(value.IsTrue());
} else if constexpr (TC == Fortran::common::TypeCategory::Real) {
- TODO(getLoc(), "genval real constant");
+ std::string str = value.DumpHexadecimal();
+ if constexpr (KIND == 2) {
+ llvm::APFloat floatVal{llvm::APFloatBase::IEEEhalf(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else if constexpr (KIND == 3) {
+ llvm::APFloat floatVal{llvm::APFloatBase::BFloat(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else if constexpr (KIND == 4) {
+ llvm::APFloat floatVal{llvm::APFloatBase::IEEEsingle(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else if constexpr (KIND == 10) {
+ llvm::APFloat floatVal{llvm::APFloatBase::x87DoubleExtended(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else if constexpr (KIND == 16) {
+ llvm::APFloat floatVal{llvm::APFloatBase::IEEEquad(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else {
+ // convert everything else to double
+ llvm::APFloat floatVal{llvm::APFloatBase::IEEEdouble(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ }
} else if constexpr (TC == Fortran::common::TypeCategory::Complex) {
TODO(getLoc(), "genval complex constant");
} else /*constexpr*/ {
! CHECK: fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref<!fir.complex<4>>
! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<!fir.complex<4>>
! CHECK: return %[[RET]] : !fir.complex<4>
+
+subroutine real_constant()
+ real(2) :: a
+ real(4) :: b
+ real(8) :: c
+ real(10) :: d
+ real(16) :: e
+ a = 2.0_2
+ b = 4.0_4
+ c = 8.0_8
+ d = 10.0_10
+ e = 16.0_16
+end
+
+! CHECK: %[[A:.*]] = fir.alloca f16
+! CHECK: %[[B:.*]] = fir.alloca f32
+! CHECK: %[[C:.*]] = fir.alloca f64
+! CHECK: %[[D:.*]] = fir.alloca f80
+! CHECK: %[[E:.*]] = fir.alloca f128
+! CHECK: %[[C2:.*]] = arith.constant 2.000000e+00 : f16
+! CHECK: fir.store %[[C2]] to %[[A]] : !fir.ref<f16>
+! CHECK: %[[C4:.*]] = arith.constant 4.000000e+00 : f32
+! CHECK: fir.store %[[C4]] to %[[B]] : !fir.ref<f32>
+! CHECK: %[[C8:.*]] = arith.constant 8.000000e+00 : f64
+! CHECK: fir.store %[[C8]] to %[[C]] : !fir.ref<f64>
+! CHECK: %[[C10:.*]] = arith.constant 1.000000e+01 : f80
+! CHECK: fir.store %[[C10]] to %[[D]] : !fir.ref<f80>
+! CHECK: %[[C16:.*]] = arith.constant 1.600000e+01 : f128
+! CHECK: fir.store %[[C16]] to %[[E]] : !fir.ref<f128>