10da5ac1aSSiva Chandra Reddy //===-- Unittests for feenableexcept -------------------------------------===//
20da5ac1aSSiva Chandra Reddy //
30da5ac1aSSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40da5ac1aSSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
50da5ac1aSSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60da5ac1aSSiva Chandra Reddy //
70da5ac1aSSiva Chandra Reddy //===----------------------------------------------------------------------===//
80da5ac1aSSiva Chandra Reddy
9*0aea170bSGuillaume Chatelet #include "src/__support/architectures.h"
10a72e2499SGuillaume Chatelet #include "src/fenv/fedisableexcept.h"
11fe953b15SGuillaume Chatelet #include "src/fenv/feenableexcept.h"
120da5ac1aSSiva Chandra Reddy #include "src/fenv/fegetexcept.h"
130da5ac1aSSiva Chandra Reddy
140da5ac1aSSiva Chandra Reddy #include "utils/UnitTest/Test.h"
150da5ac1aSSiva Chandra Reddy
160da5ac1aSSiva Chandra Reddy #include <fenv.h>
170da5ac1aSSiva Chandra Reddy
TEST(LlvmLibcFEnvTest,EnableTest)180da5ac1aSSiva Chandra Reddy TEST(LlvmLibcFEnvTest, EnableTest) {
19*0aea170bSGuillaume Chatelet #if defined(LLVM_LIBC_ARCH_AARCH64)
200da5ac1aSSiva Chandra Reddy // Few aarch64 HW implementations do not trap exceptions. We skip this test
210da5ac1aSSiva Chandra Reddy // completely on such HW.
220da5ac1aSSiva Chandra Reddy //
230da5ac1aSSiva Chandra Reddy // Whether HW supports trapping exceptions or not is deduced by enabling an
240da5ac1aSSiva Chandra Reddy // exception and reading back to see if the exception got enabled. If the
250da5ac1aSSiva Chandra Reddy // exception did not get enabled, then it means that the HW does not support
260da5ac1aSSiva Chandra Reddy // trapping exceptions.
270da5ac1aSSiva Chandra Reddy __llvm_libc::fedisableexcept(FE_ALL_EXCEPT);
280da5ac1aSSiva Chandra Reddy __llvm_libc::feenableexcept(FE_DIVBYZERO);
290da5ac1aSSiva Chandra Reddy if (__llvm_libc::fegetexcept() == 0)
300da5ac1aSSiva Chandra Reddy return;
31*0aea170bSGuillaume Chatelet #endif // defined(LLVM_LIBC_ARCH_AARCH64)
320da5ac1aSSiva Chandra Reddy
330da5ac1aSSiva Chandra Reddy int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
340da5ac1aSSiva Chandra Reddy FE_UNDERFLOW};
350da5ac1aSSiva Chandra Reddy __llvm_libc::fedisableexcept(FE_ALL_EXCEPT);
360da5ac1aSSiva Chandra Reddy ASSERT_EQ(0, __llvm_libc::fegetexcept());
370da5ac1aSSiva Chandra Reddy
380da5ac1aSSiva Chandra Reddy for (int e : excepts) {
390da5ac1aSSiva Chandra Reddy __llvm_libc::feenableexcept(e);
400da5ac1aSSiva Chandra Reddy ASSERT_EQ(e, __llvm_libc::fegetexcept());
410da5ac1aSSiva Chandra Reddy __llvm_libc::fedisableexcept(e);
420da5ac1aSSiva Chandra Reddy }
430da5ac1aSSiva Chandra Reddy
440da5ac1aSSiva Chandra Reddy for (int e1 : excepts) {
450da5ac1aSSiva Chandra Reddy for (int e2 : excepts) {
460da5ac1aSSiva Chandra Reddy __llvm_libc::feenableexcept(e1 | e2);
470da5ac1aSSiva Chandra Reddy ASSERT_EQ(e1 | e2, __llvm_libc::fegetexcept());
480da5ac1aSSiva Chandra Reddy __llvm_libc::fedisableexcept(e1 | e2);
490da5ac1aSSiva Chandra Reddy }
500da5ac1aSSiva Chandra Reddy }
510da5ac1aSSiva Chandra Reddy
520da5ac1aSSiva Chandra Reddy for (int e1 : excepts) {
530da5ac1aSSiva Chandra Reddy for (int e2 : excepts) {
540da5ac1aSSiva Chandra Reddy for (int e3 : excepts) {
550da5ac1aSSiva Chandra Reddy __llvm_libc::feenableexcept(e1 | e2 | e3);
560da5ac1aSSiva Chandra Reddy ASSERT_EQ(e1 | e2 | e3, __llvm_libc::fegetexcept());
570da5ac1aSSiva Chandra Reddy __llvm_libc::fedisableexcept(e1 | e2 | e3);
580da5ac1aSSiva Chandra Reddy }
590da5ac1aSSiva Chandra Reddy }
600da5ac1aSSiva Chandra Reddy }
610da5ac1aSSiva Chandra Reddy
620da5ac1aSSiva Chandra Reddy for (int e1 : excepts) {
630da5ac1aSSiva Chandra Reddy for (int e2 : excepts) {
640da5ac1aSSiva Chandra Reddy for (int e3 : excepts) {
650da5ac1aSSiva Chandra Reddy for (int e4 : excepts) {
660da5ac1aSSiva Chandra Reddy __llvm_libc::feenableexcept(e1 | e2 | e3 | e4);
670da5ac1aSSiva Chandra Reddy ASSERT_EQ(e1 | e2 | e3 | e4, __llvm_libc::fegetexcept());
680da5ac1aSSiva Chandra Reddy __llvm_libc::fedisableexcept(e1 | e2 | e3 | e4);
690da5ac1aSSiva Chandra Reddy }
700da5ac1aSSiva Chandra Reddy }
710da5ac1aSSiva Chandra Reddy }
720da5ac1aSSiva Chandra Reddy }
730da5ac1aSSiva Chandra Reddy
740da5ac1aSSiva Chandra Reddy for (int e1 : excepts) {
750da5ac1aSSiva Chandra Reddy for (int e2 : excepts) {
760da5ac1aSSiva Chandra Reddy for (int e3 : excepts) {
770da5ac1aSSiva Chandra Reddy for (int e4 : excepts) {
780da5ac1aSSiva Chandra Reddy for (int e5 : excepts) {
790da5ac1aSSiva Chandra Reddy __llvm_libc::feenableexcept(e1 | e2 | e3 | e4 | e5);
800da5ac1aSSiva Chandra Reddy ASSERT_EQ(e1 | e2 | e3 | e4 | e5, __llvm_libc::fegetexcept());
810da5ac1aSSiva Chandra Reddy __llvm_libc::fedisableexcept(e1 | e2 | e3 | e4 | e5);
820da5ac1aSSiva Chandra Reddy }
830da5ac1aSSiva Chandra Reddy }
840da5ac1aSSiva Chandra Reddy }
850da5ac1aSSiva Chandra Reddy }
860da5ac1aSSiva Chandra Reddy }
870da5ac1aSSiva Chandra Reddy }
88