Skip to content

Commit

Permalink
[libc] Add implementations of the remaining fenv functions.
Browse files Browse the repository at this point in the history
Namely, implementations of fegetexceptfflag, fesetexceptflag,
fegetenv, fesetenv, feholdexcept and feupdateenv have been added.

Reviewed By: lntue

Differential Revision: https://reviews.llvm.org/D96935
  • Loading branch information
Siva Chandra Reddy committed Feb 18, 2021
1 parent 53e83af commit b7e05c8
Show file tree
Hide file tree
Showing 25 changed files with 707 additions and 19 deletions.
6 changes: 6 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Expand Up @@ -22,10 +22,16 @@ set(TARGET_LIBC_ENTRYPOINTS

# fenv.h entrypoints
libc.src.fenv.feclearexcept
libc.src.fenv.fegetenv
libc.src.fenv.fegetexceptflag
libc.src.fenv.fegetround
libc.src.fenv.feholdexcept
libc.src.fenv.fesetenv
libc.src.fenv.fesetexceptflag
libc.src.fenv.fesetround
libc.src.fenv.feraiseexcept
libc.src.fenv.fetestexcept
libc.src.fenv.feupdateenv

# stdlib.h entrypoints
libc.src.stdlib.abs
Expand Down
27 changes: 27 additions & 0 deletions libc/config/linux/api.td
Expand Up @@ -179,6 +179,29 @@ def MathAPI : PublicAPI<"math.h"> {
];
}

def FEnvT : TypeDecl<"fenv_t"> {
let Decl = [{
#ifdef __aarch64__
typedef struct {
unsigned char __control_word[4];
unsigned char __status_word[4];
} fenv_t;
#endif
#ifdef __x86_64__
typedef struct {
unsigned char __x86_status[28];
unsigned char __mxcsr[4];
} fenv_t;
#endif
}];
}

def FExceptT : TypeDecl<"fexcept_t"> {
let Decl = [{
typedef int fexcept_t;
}];
}

def FenvAPI: PublicAPI<"fenv.h"> {
let Macros = [
SimpleMacroDef<"FE_DIVBYZERO", "1">,
Expand All @@ -193,6 +216,10 @@ def FenvAPI: PublicAPI<"fenv.h"> {
SimpleMacroDef<"FE_TOWARDZERO", "4">,
SimpleMacroDef<"FE_UPWARD", "8">,
];
let TypeDeclarations = [
FEnvT,
FExceptT,
];
}

def StringAPI : PublicAPI<"string.h"> {
Expand Down
6 changes: 6 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Expand Up @@ -25,10 +25,16 @@ set(TARGET_LIBC_ENTRYPOINTS

# fenv.h entrypoints
libc.src.fenv.feclearexcept
libc.src.fenv.fegetenv
libc.src.fenv.fegetexceptflag
libc.src.fenv.fegetround
libc.src.fenv.feholdexcept
libc.src.fenv.fesetenv
libc.src.fenv.fesetexceptflag
libc.src.fenv.fesetround
libc.src.fenv.feraiseexcept
libc.src.fenv.fetestexcept
libc.src.fenv.feupdateenv

# signal.h entrypoints
libc.src.signal.raise
Expand Down
41 changes: 40 additions & 1 deletion libc/spec/stdc.td
Expand Up @@ -96,6 +96,12 @@ def StdC : StandardSpec<"stdc"> {
]
>;

NamedType FEnvT = NamedType<"fenv_t">;
PtrType FEnvTPtr = PtrType<FEnvT>;
ConstType ConstFEnvTPtr = ConstType<FEnvTPtr>;
NamedType FExceptT = NamedType<"fexcept_t">;
PtrType FExceptTPtr = PtrType<FExceptT>;
ConstType ConstFExceptTPtr = ConstType<FExceptTPtr>;
HeaderSpec Fenv = HeaderSpec<
"fenv.h",
[
Expand All @@ -111,7 +117,10 @@ def StdC : StandardSpec<"stdc"> {
Macro<"FE_TOWARDZERO">,
Macro<"FE_UPWARD">
],
[], // Types
[
NamedType<"fenv_t">,
NamedType<"fexcept_t">,
], // Types
[], // Enumerations
[
FunctionSpec<
Expand Down Expand Up @@ -139,6 +148,36 @@ def StdC : StandardSpec<"stdc"> {
RetValSpec<IntType>,
[]
>,
FunctionSpec<
"fegetenv",
RetValSpec<IntType>,
[ArgSpec<FEnvTPtr>]
>,
FunctionSpec<
"fesetenv",
RetValSpec<IntType>,
[ArgSpec<ConstFEnvTPtr>]
>,
FunctionSpec<
"fegetexceptflag",
RetValSpec<IntType>,
[ArgSpec<FExceptTPtr>, ArgSpec<IntType>]
>,
FunctionSpec<
"fesetexceptflag",
RetValSpec<IntType>,
[ArgSpec<ConstFExceptTPtr>, ArgSpec<IntType>]
>,
FunctionSpec<
"feholdexcept",
RetValSpec<IntType>,
[ArgSpec<FEnvTPtr>]
>,
FunctionSpec<
"feupdateenv",
RetValSpec<IntType>,
[ArgSpec<ConstFEnvTPtr>]
>,
]
>;

Expand Down
78 changes: 78 additions & 0 deletions libc/src/fenv/CMakeLists.txt
Expand Up @@ -62,3 +62,81 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
fegetenv
SRCS
fegetenv.cpp
HDRS
fegetenv.h
DEPENDS
libc.include.fenv
libc.utils.FPUtil.fputil
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
fesetenv
SRCS
fesetenv.cpp
HDRS
fesetenv.h
DEPENDS
libc.include.fenv
libc.utils.FPUtil.fputil
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
fegetexceptflag
SRCS
fegetexceptflag.cpp
HDRS
fegetexceptflag.h
DEPENDS
libc.include.fenv
libc.utils.FPUtil.fputil
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
fesetexceptflag
SRCS
fesetexceptflag.cpp
HDRS
fesetexceptflag.h
DEPENDS
libc.include.fenv
libc.utils.FPUtil.fputil
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
feholdexcept
SRCS
feholdexcept.cpp
HDRS
feholdexcept.h
DEPENDS
libc.include.fenv
libc.utils.FPUtil.fputil
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
feupdateenv
SRCS
feupdateenv.cpp
HDRS
feupdateenv.h
DEPENDS
libc.include.fenv
libc.utils.FPUtil.fputil
COMPILE_OPTIONS
-O2
)
19 changes: 19 additions & 0 deletions libc/src/fenv/fegetenv.cpp
@@ -0,0 +1,19 @@
//===-- Implementation of fegetenv function -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/fenv/fegetenv.h"
#include "src/__support/common.h"
#include "utils/FPUtil/FEnv.h"

namespace __llvm_libc {

LLVM_LIBC_FUNCTION(int, fegetenv, (fenv_t * envp)) {
return fputil::getEnv(envp);
}

} // namespace __llvm_libc
20 changes: 20 additions & 0 deletions libc/src/fenv/fegetenv.h
@@ -0,0 +1,20 @@
//===-- Implementation header for fegetenv ----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_FENV_FEGETENV_H
#define LLVM_LIBC_SRC_FENV_FEGETENV_H

#include <fenv.h>

namespace __llvm_libc {

int fegetenv(fenv_t *);

} // namespace __llvm_libc

#endif // LLVM_LIBC_SRC_FENV_FEGETENV_H
26 changes: 26 additions & 0 deletions libc/src/fenv/fegetexceptflag.cpp
@@ -0,0 +1,26 @@
//===-- Implementation of fegetexceptflag function ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/fenv/fegetexceptflag.h"
#include "src/__support/common.h"
#include "utils/FPUtil/FEnv.h"

#include <fenv.h>

namespace __llvm_libc {

LLVM_LIBC_FUNCTION(int, fegetexceptflag, (fexcept_t * flagp, int excepts)) {
// Since the return type of fetestexcept is int, we ensure that fexcept_t
// matches in size.
static_assert(sizeof(int) == sizeof(fexcept_t),
"sizeof(fexcept_t) != sizeof(int)");
*reinterpret_cast<int *>(flagp) = fputil::testExcept(FE_ALL_EXCEPT) & excepts;
return 0;
}

} // namespace __llvm_libc
20 changes: 20 additions & 0 deletions libc/src/fenv/fegetexceptflag.h
@@ -0,0 +1,20 @@
//===-- Implementation header for fegetexceptflag ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_FENV_FEGETEXCEPTFLAG_H
#define LLVM_LIBC_SRC_FENV_FEGETEXCEPTFLAG_H

#include <fenv.h>

namespace __llvm_libc {

int fegetexceptflag(fexcept_t *, int excepts);

} // namespace __llvm_libc

#endif // LLVM_LIBC_SRC_FENV_FEGETEXCEPTFLAG_H
25 changes: 25 additions & 0 deletions libc/src/fenv/feholdexcept.cpp
@@ -0,0 +1,25 @@
//===-- Implementation of feholdexcept function ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/fenv/feholdexcept.h"
#include "src/__support/common.h"
#include "utils/FPUtil/FEnv.h"

#include <fenv.h>

namespace __llvm_libc {

LLVM_LIBC_FUNCTION(int, feholdexcept, (fenv_t * envp)) {
if (fputil::getEnv(envp) != 0)
return -1;
fputil::clearExcept(FE_ALL_EXCEPT);
fputil::disableExcept(FE_ALL_EXCEPT);
return 0;
}

} // namespace __llvm_libc
20 changes: 20 additions & 0 deletions libc/src/fenv/feholdexcept.h
@@ -0,0 +1,20 @@
//===-- Implementation header for feholdexcept ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_FENV_FEHOLDEXCEPT_H
#define LLVM_LIBC_SRC_FENV_FEHOLDEXCEPT_H

#include <fenv.h>

namespace __llvm_libc {

int feholdexcept(fenv_t *);

} // namespace __llvm_libc

#endif // LLVM_LIBC_SRC_FENV_FEHOLDEXCEPT_H
19 changes: 19 additions & 0 deletions libc/src/fenv/fesetenv.cpp
@@ -0,0 +1,19 @@
//===-- Implementation of fesetenv function -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/fenv/fesetenv.h"
#include "src/__support/common.h"
#include "utils/FPUtil/FEnv.h"

namespace __llvm_libc {

LLVM_LIBC_FUNCTION(int, fesetenv, (const fenv_t *envp)) {
return fputil::setEnv(envp);
}

} // namespace __llvm_libc
20 changes: 20 additions & 0 deletions libc/src/fenv/fesetenv.h
@@ -0,0 +1,20 @@
//===-- Implementation header for fesetenv ----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_FENV_FESETENV_H
#define LLVM_LIBC_SRC_FENV_FESETENV_H

#include <fenv.h>

namespace __llvm_libc {

int fesetenv(const fenv_t *);

} // namespace __llvm_libc

#endif // LLVM_LIBC_SRC_FENV_FESETENV_H

0 comments on commit b7e05c8

Please sign in to comment.