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