1 //===-- runtime/exceptions.cpp --------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Runtime exception support.
11 #include "flang/Runtime/exceptions.h"
12 #include "terminator.h"
15 // When not supported, these macro are undefined in cfenv.h,
16 // set them to zero in that case.
21 #define __FE_DENORM 0 // denorm is nonstandard
24 #define FE_DIVBYZERO 0
30 #define FE_UNDERFLOW 0
36 namespace Fortran::runtime
{
40 // Map a set of Fortran ieee_arithmetic module exceptions to a libm fenv.h
42 uint32_t RTNAME(MapException
)(uint32_t excepts
) {
43 Terminator terminator
{__FILE__
, __LINE__
};
45 static constexpr uint32_t v
{FE_INVALID
};
46 static constexpr uint32_t s
{__FE_DENORM
}; // subnormal
47 static constexpr uint32_t z
{FE_DIVBYZERO
};
48 static constexpr uint32_t o
{FE_OVERFLOW
};
49 static constexpr uint32_t u
{FE_UNDERFLOW
};
50 static constexpr uint32_t x
{FE_INEXACT
};
52 #define vm(p) p, p | v
53 #define sm(p) vm(p), vm(p | s)
54 #define zm(p) sm(p), sm(p | z)
55 #define om(p) zm(p), zm(p | o)
56 #define um(p) om(p), om(p | u)
57 #define xm um(0), um(x)
59 static constexpr uint32_t map
[]{xm
};
60 static constexpr uint32_t mapSize
{sizeof(map
) / sizeof(uint32_t)};
61 static_assert(mapSize
== 64);
62 if (excepts
== 0 || excepts
>= mapSize
) {
63 terminator
.Crash("Invalid excepts value: %d", excepts
);
65 uint32_t except_value
= map
[excepts
];
66 if (except_value
== 0) {
68 "Excepts value %d not supported by flang runtime", excepts
);
73 // Verify that the size of ieee_modes_type and ieee_status_type objects from
74 // intrinsic module file __fortran_ieee_exceptions.f90 are large enough to
75 // hold fenv_t object.
76 // TODO: fenv_t can be way larger than
77 // sizeof(int) * _FORTRAN_RUNTIME_IEEE_FENV_T_EXTENT
78 // on some systems, e.g. Solaris, so omit object size comparison for now.
79 // TODO: consider femode_t object size comparison once its more mature.
82 } // namespace Fortran::runtime