/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include "utils.h"

#include <fenv.h>
#include <stdint.h>
#include <sys/cdefs.h>

static void TestRounding(float expectation1, float expectation2) {
  // Volatile to prevent compile-time evaluation.
  volatile float f = 1.968750f;
  volatile float m = 0x1.0p23f;
  float x;
  DoNotOptimize(x = f + m);
  ASSERT_FLOAT_EQ(expectation1, x);
  DoNotOptimize(x = x - m);
  ASSERT_EQ(expectation2, x);
}

static void DivideByZero() {
  // Volatile to prevent compile-time evaluation.
  volatile float zero = 0.0f;
  DoNotOptimize(123.0f / zero);
}

TEST(fenv, fesetround_fegetround_FE_TONEAREST) {
  fesetround(FE_TONEAREST);
  ASSERT_EQ(FE_TONEAREST, fegetround());
  TestRounding(8388610.0f, 2.0f);
}

TEST(fenv, fesetround_fegetround_FE_TOWARDZERO) {
  fesetround(FE_TOWARDZERO);
  ASSERT_EQ(FE_TOWARDZERO, fegetround());
  TestRounding(8388609.0f, 1.0f);
}

TEST(fenv, fesetround_fegetround_FE_UPWARD) {
  fesetround(FE_UPWARD);
  ASSERT_EQ(FE_UPWARD, fegetround());
  TestRounding(8388610.0f, 2.0f);
}

TEST(fenv, fesetround_fegetround_FE_DOWNWARD) {
  fesetround(FE_DOWNWARD);
  ASSERT_EQ(FE_DOWNWARD, fegetround());
  TestRounding(8388609.0f, 1.0f);
}

TEST(fenv, feclearexcept_fetestexcept) {
  // Clearing clears.
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));

  // Dividing by zero sets FE_DIVBYZERO.
  DivideByZero();
  int raised = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW);
  ASSERT_TRUE((raised & FE_OVERFLOW) == 0);
  ASSERT_TRUE((raised & FE_DIVBYZERO) != 0);

  // Clearing an unset bit is a no-op.
  feclearexcept(FE_OVERFLOW);
  ASSERT_TRUE((raised & FE_OVERFLOW) == 0);
  ASSERT_TRUE((raised & FE_DIVBYZERO) != 0);

  // Clearing a set bit works.
  feclearexcept(FE_DIVBYZERO);
  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
}

TEST(fenv, FE_DFL_ENV_macro) {
  ASSERT_EQ(0, fesetenv(FE_DFL_ENV));
}

TEST(fenv, feraiseexcept) {
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));

  ASSERT_EQ(0, feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW));
  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
}

TEST(fenv, fegetenv_fesetenv) {
  // Set FE_OVERFLOW only.
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
  ASSERT_EQ(0, feraiseexcept(FE_OVERFLOW));

  // fegetenv (unlike feholdexcept) leaves the current state untouched...
  fenv_t state;
  ASSERT_EQ(0, fegetenv(&state));
  ASSERT_EQ(FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));

  // Dividing by zero sets the appropriate flag...
  DivideByZero();
  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));

  // And fesetenv (unlike feupdateenv) clobbers that to return to where
  // we started.
  ASSERT_EQ(0, fesetenv(&state));
  ASSERT_EQ(FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
}

TEST(fenv, fegetenv_fesetenv_rounding_mode) {
  // Test that fegetenv()/fesetenv() includes the rounding mode.
  fesetround(FE_DOWNWARD);
  ASSERT_EQ(FE_DOWNWARD, fegetround());

  fenv_t env;
  fegetenv(&env);

  fesetround(FE_UPWARD);
  ASSERT_EQ(FE_UPWARD, fegetround());

  fesetenv(&env);
  ASSERT_EQ(FE_DOWNWARD, fegetround());
}

TEST(fenv, feholdexcept_feupdateenv) {
  // Set FE_OVERFLOW only.
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
  ASSERT_EQ(0, feraiseexcept(FE_OVERFLOW));

  // feholdexcept (unlike fegetenv) clears everything...
  fenv_t state;
  ASSERT_EQ(0, feholdexcept(&state));
  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));

  // Dividing by zero sets the appropriate flag...
  DivideByZero();
  ASSERT_EQ(FE_DIVBYZERO, fetestexcept(FE_ALL_EXCEPT));

  // And feupdateenv (unlike fesetenv) merges what we started with
  // (FE_OVERFLOW) with what we now have (FE_DIVBYZERO).
  ASSERT_EQ(0, feupdateenv(&state));
  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
}

TEST(fenv, fegetexceptflag_fesetexceptflag) {
  // Set three flags.
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW));
  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT));

  fexcept_t all; // FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW
  fexcept_t two; // FE_OVERFLOW | FE_UNDERFLOW
  ASSERT_EQ(0, fegetexceptflag(&all, FE_ALL_EXCEPT));
  ASSERT_EQ(0, fegetexceptflag(&two, FE_OVERFLOW | FE_UNDERFLOW));

  // Check we can restore all.
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fesetexceptflag(&all, FE_ALL_EXCEPT));
  ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT));

  // Check that `two` only stored a subset.
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fesetexceptflag(&two, FE_ALL_EXCEPT));
  ASSERT_EQ(FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT));

  // Check that we can restore a single flag.
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fesetexceptflag(&all, FE_DIVBYZERO));
  ASSERT_EQ(FE_DIVBYZERO, fetestexcept(FE_ALL_EXCEPT));

  // Check that we can restore a subset of flags.
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fesetexceptflag(&all, FE_OVERFLOW | FE_UNDERFLOW));
  ASSERT_EQ(FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT));
}

TEST(fenv, fedisableexcept_fegetexcept) {
#if !defined(ANDROID_HOST_MUSL)
  feclearexcept(FE_ALL_EXCEPT);
  ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));

  // No SIGFPE please...
  ASSERT_EQ(0, fedisableexcept(FE_ALL_EXCEPT));
  ASSERT_EQ(0, fegetexcept());
  ASSERT_EQ(0, feraiseexcept(FE_INVALID));
  ASSERT_EQ(FE_INVALID, fetestexcept(FE_ALL_EXCEPT));
#else
  GTEST_SKIP() << "musl doesn't have fegetexcept";
#endif
}

TEST(fenv, feenableexcept_fegetexcept) {
#if !defined(ANDROID_HOST_MUSL)
#if defined(__aarch64__) || defined(__arm__) || defined(__riscv)
  // ARM and RISC-V don't support hardware trapping of floating point
  // exceptions. ARM used to if you go back far enough, but it was
  // removed in the Cortex-A8 between r3p1 and r3p2. RISC-V never has.
  ASSERT_EQ(-1, feenableexcept(FE_INVALID));
  ASSERT_EQ(0, fegetexcept());
  ASSERT_EQ(-1, feenableexcept(FE_DIVBYZERO));
  ASSERT_EQ(0, fegetexcept());
  ASSERT_EQ(-1, feenableexcept(FE_OVERFLOW));
  ASSERT_EQ(0, fegetexcept());
  ASSERT_EQ(-1, feenableexcept(FE_UNDERFLOW));
  ASSERT_EQ(0, fegetexcept());
  ASSERT_EQ(-1, feenableexcept(FE_INEXACT));
  ASSERT_EQ(0, fegetexcept());
#if defined(_FE_DENORMAL)  // riscv64 doesn't support this.
  ASSERT_EQ(-1, feenableexcept(FE_DENORMAL));
  ASSERT_EQ(0, fegetexcept());
#endif
#else
  // We can't recover from SIGFPE, so sacrifice a child...
  pid_t pid = fork();
  ASSERT_NE(-1, pid) << strerror(errno);

  if (pid == 0) {
    signal(SIGFPE, SIG_DFL);  // Disable debuggerd.
    feclearexcept(FE_ALL_EXCEPT);
    ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
    ASSERT_EQ(0, feenableexcept(FE_INVALID));
    ASSERT_EQ(FE_INVALID, fegetexcept());
    ASSERT_EQ(0, feraiseexcept(FE_INVALID));
    _exit(123);
  }

  AssertChildExited(pid, -SIGFPE);
#endif
#else
  GTEST_SKIP() << "musl doesn't have fegetexcept";
#endif
}
