message(FATAL_ERROR "`add_entrypoint_object` rule requires HDRS to be specified.")
endif()
- set(objects_target_name "${fq_target_name}_objects")
+ set(common_compile_options -fpie ${LLVM_CXX_STD_default} -ffreestanding ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS})
+ set(internal_target_name ${fq_target_name}.__internal__)
+ set(include_dirs ${LIBC_BUILD_DIR}/include ${LIBC_SOURCE_DIR} ${LIBC_BUILD_DIR})
+ get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
+ set(full_deps_list ${fq_deps_list} libc.src.__support.common)
+
+ add_library(
+ ${internal_target_name}
+ # TODO: We don't need an object library for internal consumption.
+ # A future change should switch this to a normal static library.
+ OBJECT
+ ${ADD_ENTRYPOINT_OBJ_SRCS}
+ ${ADD_ENTRYPOINT_OBJ_HDRS}
+ )
+ target_compile_options(${internal_target_name} BEFORE PRIVATE ${common_compile_options})
+ target_include_directories(${internal_target_name} PRIVATE ${include_dirs})
+ add_dependencies(${internal_target_name} ${full_deps_list})
add_library(
- ${objects_target_name}
+ ${fq_target_name}
# We want an object library as the objects will eventually get packaged into
# an archive (like libc.a).
OBJECT
${ADD_ENTRYPOINT_OBJ_HDRS}
)
target_compile_options(
- ${objects_target_name}
- BEFORE
- PRIVATE
- -fpie ${LLVM_CXX_STD_default} -ffreestanding
- )
- target_include_directories(
- ${objects_target_name}
- PRIVATE
- ${LIBC_BUILD_DIR}/include
- ${LIBC_SOURCE_DIR}
- ${LIBC_BUILD_DIR}
+ ${fq_target_name} BEFORE PRIVATE ${common_compile_options} -DLLVM_LIBC_PUBLIC_PACKAGING
)
- get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
- add_dependencies(
- ${objects_target_name}
- libc.src.__support.common
- ${fq_deps_list}
- )
-
- if(ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS)
- target_compile_options(
- ${objects_target_name}
- PRIVATE ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS}
- )
- endif()
+ target_include_directories(${fq_target_name} PRIVATE ${include_dirs})
+ add_dependencies(${fq_target_name} ${full_deps_list})
- set(object_file_raw "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_raw.o")
- set(object_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.o")
-
- set(input_objects $<TARGET_OBJECTS:${objects_target_name}>)
- add_custom_command(
- OUTPUT ${object_file_raw}
- DEPENDS ${input_objects}
- COMMAND ${CMAKE_LINKER} -r ${input_objects} -o ${object_file_raw}
- )
-
- set(alias_attributes "0,function,global")
- if(ADD_ENTRYPOINT_OBJ_REDIRECTED)
- set(alias_attributes "${alias_attributes},hidden")
- endif()
-
- add_custom_command(
- OUTPUT ${object_file}
- # We llvm-objcopy here as GNU-binutils objcopy does not support the 'hidden' flag.
- DEPENDS ${object_file_raw} ${llvm-objcopy}
- COMMAND $<TARGET_FILE:llvm-objcopy> --add-symbol
- "${entrypoint_name}=.llvm.libc.entrypoint.${entrypoint_name}:${alias_attributes}"
- ${object_file_raw} ${object_file}
- )
-
- add_custom_target(
- ${fq_target_name}
- ALL
- DEPENDS ${object_file}
- )
set_target_properties(
${fq_target_name}
PROPERTIES
"ENTRYPOINT_NAME" ${entrypoint_name}
"TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
- "OBJECT_FILE" "${object_file}"
- "OBJECT_FILE_RAW" "${object_file_raw}"
+ "OBJECT_FILE" $<TARGET_OBJECTS:${fq_target_name}>
+ # TODO: We don't need to list internal object files if the internal
+ # target is a normal static library.
+ "OBJECT_FILE_RAW" $<TARGET_OBJECTS:${internal_target_name}>
"DEPS" "${fq_deps_list}"
)
# crossplatform touch.
COMMAND "${CMAKE_COMMAND}" -E touch ${lint_timestamp}
COMMENT "Linting... ${target_name}"
- DEPENDS clang-tidy ${objects_target_name} ${ADD_ENTRYPOINT_OBJ_SRCS}
+ DEPENDS clang-tidy ${internal_target_name} ${ADD_ENTRYPOINT_OBJ_SRCS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
#define unlikely(x) __builtin_expect (x, 0)
#define UNUSED __attribute__((unused))
-<!> Include the platform specific definitions at build time. For example, that
-<!> of entrypoint macro.
-%%include_file(${platform_defs})
+#ifndef LLVM_LIBC_FUNCTION_ATTR
+ #define LLVM_LIBC_FUNCTION_ATTR
+#endif
+
+#ifdef LLVM_LIBC_PUBLIC_PACKAGING
+#define LLVM_LIBC_FUNCTION(type, name, arglist) \
+ type name arglist; \
+ LLVM_LIBC_FUNCTION_ATTR decltype(__llvm_libc::name) __##name##_impl__ __asm__(#name); \
+ decltype(__llvm_libc::name) name [[gnu::alias(#name)]]; \
+ type __##name##_impl__ arglist
+#else
+#define LLVM_LIBC_FUNCTION(type, name, arglist)\
+ type name arglist
+#endif
#endif // LLVM_LIBC_SUPPORT_COMMON_H
__llvm_libc::syscall(SYS_write, 2, s, length);
}
-void LLVM_LIBC_ENTRYPOINT(__assert_fail)(const char *assertion, const char *file,
- unsigned line, const char *function) {
+LLVM_LIBC_FUNCTION(void, __assert_fail,
+ (const char *assertion, const char *file, unsigned line,
+ const char *function)) {
writeToStderr(file);
writeToStderr(": Assertion failed: '");
writeToStderr(assertion);
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isalnum)(int c) { return internal::isalnum(c); }
+LLVM_LIBC_FUNCTION(int, isalnum, (int c)) { return internal::isalnum(c); }
} // namespace __llvm_libc
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isalpha)(int c) { return internal::isalpha(c); }
+LLVM_LIBC_FUNCTION(int, isalpha, (int c)) { return internal::isalpha(c); }
} // namespace __llvm_libc
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isblank)(int c) {
+LLVM_LIBC_FUNCTION(int, isblank, (int c)) {
const unsigned char ch = c;
return ch == ' ' || ch == '\t';
}
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(iscntrl)(int c) {
+LLVM_LIBC_FUNCTION(int, iscntrl, (int c)) {
const unsigned char ch = c;
return ch < 0x20 || ch == 0x7f;
}
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isdigit)(int c) { return internal::isdigit(c); }
+LLVM_LIBC_FUNCTION(int, isdigit, (int c)) { return internal::isdigit(c); }
} // namespace __llvm_libc
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isgraph)(int c) { return internal::isgraph(c); }
+LLVM_LIBC_FUNCTION(int, isgraph, (int c)) { return internal::isgraph(c); }
} // namespace __llvm_libc
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(islower)(int c) { return internal::islower(c); }
+LLVM_LIBC_FUNCTION(int, islower, (int c)) { return internal::islower(c); }
} // namespace __llvm_libc
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isprint)(int c) {
+LLVM_LIBC_FUNCTION(int, isprint, (int c)) {
const unsigned ch = c;
return (ch - ' ') < 95;
}
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(ispunct)(int c) {
+LLVM_LIBC_FUNCTION(int, ispunct, (int c)) {
return !internal::isalnum(c) && internal::isgraph(c);
}
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isspace)(int c) {
+LLVM_LIBC_FUNCTION(int, isspace, (int c)) {
const unsigned ch = c;
return ch == ' ' || (ch - '\t') < 5;
}
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isupper)(int c) { return internal::isupper(c); }
+LLVM_LIBC_FUNCTION(int, isupper, (int c)) { return internal::isupper(c); }
} // namespace __llvm_libc
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(isxdigit)(int c) {
+LLVM_LIBC_FUNCTION(int, isxdigit, (int c)) {
const unsigned ch = c;
return internal::isdigit(ch) || (ch | 32) - 'a' < 6;
}
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(tolower)(int c) {
+LLVM_LIBC_FUNCTION(int, tolower, (int c)) {
if (internal::isupper(c))
return c + 'a' - 'A';
return c;
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-int LLVM_LIBC_ENTRYPOINT(toupper)(int c) {
+LLVM_LIBC_FUNCTION(int, toupper, (int c)) {
if (internal::islower(c))
return c + 'A' - 'a';
return c;
// __errno_location is not really an entry point but we still want it to behave
// like an entry point because the errno macro resolves to the C symbol
// "__errno_location".
-int *LLVM_LIBC_ENTRYPOINT(__errno_location)() { return &__errno; }
+LLVM_LIBC_FUNCTION(int *, __errno_location, ()) { return &__errno; }
} // namespace __llvm_libc
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(feclearexcept)(int e) {
+LLVM_LIBC_FUNCTION(int, feclearexcept, (int e)) {
return fputil::clearExcept(e);
}
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(fegetround)() { return fputil::getRound(); }
+LLVM_LIBC_FUNCTION(int, fegetround, ()) { return fputil::getRound(); }
} // namespace __llvm_libc
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(feraiseexcept)(int e) {
+LLVM_LIBC_FUNCTION(int, feraiseexcept, (int e)) {
return fputil::raiseExcept(e);
}
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(fesetround)(int m) { return fputil::setRound(m); }
+LLVM_LIBC_FUNCTION(int, fesetround, (int m)) { return fputil::setRound(m); }
} // namespace __llvm_libc
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(fetestexcept)(int e) { return fputil::testExcept(e); }
+LLVM_LIBC_FUNCTION(int, fetestexcept, (int e)) { return fputil::testExcept(e); }
} // namespace __llvm_libc
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(ceil)(double x) { return fputil::ceil(x); }
+LLVM_LIBC_FUNCTION(double, ceil, (double x)) { return fputil::ceil(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(ceilf)(float x) { return fputil::ceil(x); }
+LLVM_LIBC_FUNCTION(float, ceilf, (float x)) { return fputil::ceil(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(ceill)(long double x) {
+LLVM_LIBC_FUNCTION(long double, ceill, (long double x)) {
return fputil::ceil(x);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(copysign)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, copysign, (double x, double y)) {
return fputil::copysign(x, y);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(copysignf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, copysignf, (float x, float y)) {
return fputil::copysign(x, y);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(copysignl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, copysignl, (long double x, long double y)) {
return fputil::copysign(x, y);
}
// error is 0.5303 * 2^-23. A single-step range reduction is used for
// small values. Large inputs have their range reduced using fast integer
// arithmetic.
-float LLVM_LIBC_ENTRYPOINT(cosf)(float y) {
+LLVM_LIBC_FUNCTION(float, cosf, (float y)) {
double x = y;
double s;
int n;
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(exp2f)(float x) {
+LLVM_LIBC_FUNCTION(float, exp2f, (float x)) {
uint32_t abstop;
uint64_t ki, t;
// double_t for better performance on targets with FLT_EVAL_METHOD==2.
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(expf)(float x) {
+LLVM_LIBC_FUNCTION(float, expf, (float x)) {
uint32_t abstop;
uint64_t ki, t;
// double_t for better performance on targets with FLT_EVAL_METHOD == 2.
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(fabs)(double x) { return fputil::abs(x); }
+LLVM_LIBC_FUNCTION(double, fabs, (double x)) { return fputil::abs(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(fabsf)(float x) { return fputil::abs(x); }
+LLVM_LIBC_FUNCTION(float, fabsf, (float x)) { return fputil::abs(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(fabsl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, fabsl, (long double x)) {
return fputil::abs(x);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(fdim)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, fdim, (double x, double y)) {
return fputil::fdim(x, y);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(fdimf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, fdimf, (float x, float y)) {
return fputil::fdim(x, y);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(fdiml)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, fdiml, (long double x, long double y)) {
return fputil::fdim(x, y);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(floor)(double x) { return fputil::floor(x); }
+LLVM_LIBC_FUNCTION(double, floor, (double x)) { return fputil::floor(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(floorf)(float x) { return fputil::floor(x); }
+LLVM_LIBC_FUNCTION(float, floorf, (float x)) { return fputil::floor(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(floorl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, floorl, (long double x)) {
return fputil::floor(x);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(fmaf)(float x, float y, float z) {
+LLVM_LIBC_FUNCTION(float, fmaf, (float x, float y, float z)){
// Product is exact.
double prod = static_cast<double>(x) * static_cast<double>(y);
double z_d = static_cast<double>(z);
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(fmax)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, fmax, (double x, double y)) {
return fputil::fmax(x, y);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(fmaxf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, fmaxf, (float x, float y)) {
return fputil::fmax(x, y);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(fmaxl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, fmaxl, (long double x, long double y)) {
return fputil::fmax(x, y);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(fmin)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, fmin, (double x, double y)) {
return fputil::fmin(x, y);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(fminf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, fminf, (float x, float y)) {
return fputil::fmin(x, y);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(fminl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, fminl, (long double x, long double y)) {
return fputil::fmin(x, y);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(frexp)(double x, int *exp) {
+LLVM_LIBC_FUNCTION(double, frexp, (double x, int *exp)) {
return fputil::frexp(x, *exp);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(frexpf)(float x, int *exp) {
+LLVM_LIBC_FUNCTION(float, frexpf, (float x, int *exp)) {
return fputil::frexp(x, *exp);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(frexpl)(long double x, int *exp) {
+LLVM_LIBC_FUNCTION(long double, frexpl, (long double x, int *exp)) {
return fputil::frexp(x, *exp);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(hypot)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, hypot, (double x, double y)) {
return __llvm_libc::fputil::hypot(x, y);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(hypotf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
return __llvm_libc::fputil::hypot(x, y);
}
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(ilogb)(double x) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return fputil::ilogb(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(ilogbf)(float x) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return fputil::ilogb(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(ilogbl)(long double x) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogbl, (long double x)) { return fputil::ilogb(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(ldexp)(double x, int exp) {
+LLVM_LIBC_FUNCTION(double, ldexp, (double x, int exp)) {
return fputil::ldexp(x, exp);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(ldexpf)(float x, int exp) {
+LLVM_LIBC_FUNCTION(float, ldexpf, (float x, int exp)) {
return fputil::ldexp(x, exp);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(ldexpl)(long double x, int exp) {
+LLVM_LIBC_FUNCTION(long double, ldexpl, (long double x, int exp)) {
return fputil::ldexp(x, exp);
}
namespace __llvm_libc {
-long long LLVM_LIBC_ENTRYPOINT(llrint)(double x) {
+LLVM_LIBC_FUNCTION(long long, llrint, (double x)) {
return fputil::roundToSignedIntegerUsingCurrentRoundingMode<double,
long long>(x);
}
namespace __llvm_libc {
-long long LLVM_LIBC_ENTRYPOINT(llrintf)(float x) {
+LLVM_LIBC_FUNCTION(long long, llrintf, (float x)) {
return fputil::roundToSignedIntegerUsingCurrentRoundingMode<float, long long>(
x);
}
namespace __llvm_libc {
-long long LLVM_LIBC_ENTRYPOINT(llrintl)(long double x) {
+LLVM_LIBC_FUNCTION(long long, llrintl, (long double x)) {
return fputil::roundToSignedIntegerUsingCurrentRoundingMode<long double,
long long>(x);
}
namespace __llvm_libc {
-long long LLVM_LIBC_ENTRYPOINT(llround)(double x) {
+LLVM_LIBC_FUNCTION(long long, llround, (double x)) {
return fputil::roundToSignedInteger<double, long long>(x);
}
namespace __llvm_libc {
-long long LLVM_LIBC_ENTRYPOINT(llroundf)(float x) {
+LLVM_LIBC_FUNCTION(long long, llroundf, (float x)) {
return fputil::roundToSignedInteger<float, long long>(x);
}
namespace __llvm_libc {
-long long LLVM_LIBC_ENTRYPOINT(llroundl)(long double x) {
+LLVM_LIBC_FUNCTION(long long, llroundl, (long double x)) {
return fputil::roundToSignedInteger<long double, long long>(x);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(logb)(double x) { return fputil::logb(x); }
+LLVM_LIBC_FUNCTION(double, logb, (double x)) { return fputil::logb(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(logbf)(float x) { return fputil::logb(x); }
+LLVM_LIBC_FUNCTION(float, logbf, (float x)) { return fputil::logb(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(logbl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, logbl, (long double x)) {
return fputil::logb(x);
}
namespace __llvm_libc {
-long LLVM_LIBC_ENTRYPOINT(lrint)(double x) {
+LLVM_LIBC_FUNCTION(long, lrint, (double x)) {
return fputil::roundToSignedIntegerUsingCurrentRoundingMode<double, long>(x);
}
namespace __llvm_libc {
-long LLVM_LIBC_ENTRYPOINT(lrintf)(float x) {
+LLVM_LIBC_FUNCTION(long, lrintf, (float x)) {
return fputil::roundToSignedIntegerUsingCurrentRoundingMode<float, long>(x);
}
namespace __llvm_libc {
-long LLVM_LIBC_ENTRYPOINT(lrintl)(long double x) {
+LLVM_LIBC_FUNCTION(long, lrintl, (long double x)) {
return fputil::roundToSignedIntegerUsingCurrentRoundingMode<long double,
long>(x);
}
namespace __llvm_libc {
-long LLVM_LIBC_ENTRYPOINT(lround)(double x) {
+LLVM_LIBC_FUNCTION(long, lround, (double x)) {
return fputil::roundToSignedInteger<double, long>(x);
}
namespace __llvm_libc {
-long LLVM_LIBC_ENTRYPOINT(lroundf)(float x) {
+LLVM_LIBC_FUNCTION(long, lroundf, (float x)) {
return fputil::roundToSignedInteger<float, long>(x);
}
namespace __llvm_libc {
-long LLVM_LIBC_ENTRYPOINT(lroundl)(long double x) {
+LLVM_LIBC_FUNCTION(long, lroundl, (long double x)) {
return fputil::roundToSignedInteger<long double, long>(x);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(modf)(double x, double *iptr) {
+LLVM_LIBC_FUNCTION(double, modf, (double x, double *iptr)) {
return fputil::modf(x, *iptr);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(modff)(float x, float *iptr) {
+LLVM_LIBC_FUNCTION(float, modff, (float x, float *iptr)) {
return fputil::modf(x, *iptr);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(modfl)(long double x, long double *iptr) {
+LLVM_LIBC_FUNCTION(long double, modfl, (long double x, long double *iptr)) {
return fputil::modf(x, *iptr);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(nearbyint)(double x) {
+LLVM_LIBC_FUNCTION(double, nearbyint, (double x)) {
return fputil::roundUsingCurrentRoundingMode(x);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(nearbyintf)(float x) {
+LLVM_LIBC_FUNCTION(float, nearbyintf, (float x)) {
return fputil::roundUsingCurrentRoundingMode(x);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(nearbyintl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, nearbyintl, (long double x)) {
return fputil::roundUsingCurrentRoundingMode(x);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(nextafter)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, nextafter, (double x, double y)) {
return fputil::nextafter(x, y);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(nextafterf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, nextafterf, (float x, float y)) {
return fputil::nextafter(x, y);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(nextafterl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, nextafterl, (long double x, long double y)) {
return fputil::nextafter(x, y);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(remainder)(double x, double y) {
+LLVM_LIBC_FUNCTION(double, remainder, (double x, double y)) {
int quotient;
return fputil::remquo(x, y, quotient);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(remainderf)(float x, float y) {
+LLVM_LIBC_FUNCTION(float, remainderf, (float x, float y)) {
int quotient;
return fputil::remquo(x, y, quotient);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(remainderl)(long double x, long double y) {
+LLVM_LIBC_FUNCTION(long double, remainderl, (long double x, long double y)) {
int quotient;
return fputil::remquo(x, y, quotient);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(remquo)(double x, double y, int *exp) {
+LLVM_LIBC_FUNCTION(double, remquo, (double x, double y, int *exp)) {
return fputil::remquo(x, y, *exp);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(remquof)(float x, float y, int *exp) {
+LLVM_LIBC_FUNCTION(float, remquof, (float x, float y, int *exp)) {
return fputil::remquo(x, y, *exp);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(remquol)(long double x, long double y,
- int *exp) {
+LLVM_LIBC_FUNCTION(long double, remquol,
+ (long double x, long double y, int *exp)) {
return fputil::remquo(x, y, *exp);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(rint)(double x) {
+LLVM_LIBC_FUNCTION(double, rint, (double x)) {
return fputil::roundUsingCurrentRoundingMode(x);
}
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(rintf)(float x) {
+LLVM_LIBC_FUNCTION(float, rintf, (float x)) {
return fputil::roundUsingCurrentRoundingMode(x);
}
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(rintl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, rintl, (long double x)) {
return fputil::roundUsingCurrentRoundingMode(x);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(round)(double x) { return fputil::round(x); }
+LLVM_LIBC_FUNCTION(double, round, (double x)) { return fputil::round(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(roundf)(float x) { return fputil::round(x); }
+LLVM_LIBC_FUNCTION(float, roundf, (float x)) { return fputil::round(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(roundl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, roundl, (long double x)) {
return fputil::round(x);
}
// error is 0.5303 * 2^-23. A single-step range reduction is used for
// small values. Large inputs have their range reduced using fast integer
// arithmetic.
-void LLVM_LIBC_ENTRYPOINT(sincosf)(float y, float *sinp, float *cosp) {
+LLVM_LIBC_FUNCTION(void, sincosf, (float y, float *sinp, float *cosp)) {
double x = y;
double s;
int n;
// error is 0.5303 * 2^-23. A single-step range reduction is used for
// small values. Large inputs have their range reduced using fast integer
// arithmetic.
-float LLVM_LIBC_ENTRYPOINT(sinf)(float y) {
+LLVM_LIBC_FUNCTION(float, sinf, (float y)) {
double x = y;
double s;
int n;
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(sqrt)(double x) { return fputil::sqrt(x); }
+LLVM_LIBC_FUNCTION(double, sqrt, (double x)) { return fputil::sqrt(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(sqrtf)(float x) { return fputil::sqrt(x); }
+LLVM_LIBC_FUNCTION(float, sqrtf, (float x)) { return fputil::sqrt(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(sqrtl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, sqrtl, (long double x)) {
return fputil::sqrt(x);
}
namespace __llvm_libc {
-double LLVM_LIBC_ENTRYPOINT(trunc)(double x) { return fputil::trunc(x); }
+LLVM_LIBC_FUNCTION(double, trunc, (double x)) { return fputil::trunc(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-float LLVM_LIBC_ENTRYPOINT(truncf)(float x) { return fputil::trunc(x); }
+LLVM_LIBC_FUNCTION(float, truncf, (float x)) { return fputil::trunc(x); }
} // namespace __llvm_libc
namespace __llvm_libc {
-long double LLVM_LIBC_ENTRYPOINT(truncl)(long double x) {
+LLVM_LIBC_FUNCTION(long double, truncl, (long double x)) {
return fputil::trunc(x);
}
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(raise)(int sig) {
+LLVM_LIBC_FUNCTION(int, raise, (int sig)) {
__llvm_libc::Sigset sigset;
__llvm_libc::block_all_signals(sigset);
long pid = __llvm_libc::syscall(SYS_getpid);
dest.sa_restorer = source.sa_restorer;
}
-int LLVM_LIBC_ENTRYPOINT(sigaction)(
- int signal, const struct __sigaction *__restrict libc_new,
- struct __sigaction *__restrict libc_old) {
+LLVM_LIBC_FUNCTION(int, sigaction,
+ (int signal, const struct __sigaction *__restrict libc_new,
+ struct __sigaction *__restrict libc_old)) {
struct sigaction kernel_new;
if (libc_new) {
copySigaction(kernel_new, *libc_new);
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(sigaddset)(sigset_t *set, int signum) {
+LLVM_LIBC_FUNCTION(int, sigaddset, (sigset_t * set, int signum)) {
if (!set || (unsigned)(signum - 1) >= (8 * sizeof(sigset_t))) {
llvmlibc_errno = EINVAL;
return -1;
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(sigdelset)(sigset_t *set, int signum) {
+LLVM_LIBC_FUNCTION(int, sigdelset, (sigset_t * set, int signum)) {
if (!set || (unsigned)(signum - 1) >= (8 * sizeof(sigset_t))) {
llvmlibc_errno = EINVAL;
return -1;
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(sigemptyset)(sigset_t *set) {
+LLVM_LIBC_FUNCTION(int, sigemptyset, (sigset_t * set)) {
if (!set) {
llvmlibc_errno = EINVAL;
return -1;
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(sigfillset)(sigset_t *set) {
+LLVM_LIBC_FUNCTION(int, sigfillset, (sigset_t * set)) {
if (!set) {
llvmlibc_errno = EINVAL;
return -1;
namespace __llvm_libc {
-sighandler_t LLVM_LIBC_ENTRYPOINT(signal)(int signum, sighandler_t handler) {
+LLVM_LIBC_FUNCTION(sighandler_t, signal, (int signum, sighandler_t handler)) {
struct __sigaction action, old;
action.sa_handler = handler;
action.sa_flags = SA_RESTART;
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(sigprocmask)(int how, const sigset_t *__restrict set,
- sigset_t *__restrict oldset) {
+LLVM_LIBC_FUNCTION(int, sigprocmask,
+ (int how, const sigset_t *__restrict set,
+ sigset_t *__restrict oldset)) {
int ret = __llvm_libc::syscall(SYS_rt_sigprocmask, how, set, oldset,
sizeof(sigset_t));
if (!ret)
namespace __llvm_libc {
-void LLVM_LIBC_ENTRYPOINT(abort)() {
+LLVM_LIBC_FUNCTION(void, abort, ()) {
// TODO: When sigprocmask and sigaction land:
// Unblock SIGABRT, raise it, if it was ignored or the handler returned,
// change its action to SIG_DFL, raise it again.
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(abs)(int n) {
+LLVM_LIBC_FUNCTION(int, abs, (int n)) {
// integer_abs from abs_utils.h.
return integer_abs(n);
}
namespace __llvm_libc {
-long LLVM_LIBC_ENTRYPOINT(labs)(long n) {
+LLVM_LIBC_FUNCTION(long, labs, (long n)) {
// integer_abs from abs_utils.h.
return integer_abs(n);
}
namespace __llvm_libc {
-void LLVM_LIBC_ENTRYPOINT(_Exit)(int status) {
+LLVM_LIBC_FUNCTION(void, _Exit, (int status)) {
for (;;) {
__llvm_libc::syscall(SYS_exit_group, status);
__llvm_libc::syscall(SYS_exit, status);
namespace __llvm_libc {
-long long LLVM_LIBC_ENTRYPOINT(llabs)(long long n) {
+LLVM_LIBC_FUNCTION(long long, llabs, (long long n)) {
// integer_abs from abs_utils.h.
return integer_abs(n);
}
namespace __llvm_libc {
-void LLVM_LIBC_ENTRYPOINT(bzero)(void *ptr, size_t count) {
+LLVM_LIBC_FUNCTION(void, bzero, (void *ptr, size_t count)) {
GeneralPurposeMemset(reinterpret_cast<char *>(ptr), 0, count);
}
namespace __llvm_libc {
// TODO: Look at performance benefits of comparing words.
-void *LLVM_LIBC_ENTRYPOINT(memchr)(const void *src, int c, size_t n) {
+LLVM_LIBC_FUNCTION(void *, memchr, (const void *src, int c, size_t n)) {
return internal::find_first_character(
reinterpret_cast<const unsigned char *>(src), c, n);
}
namespace __llvm_libc {
// TODO: It is a simple implementation, an optimized version is preparing.
-int LLVM_LIBC_ENTRYPOINT(memcmp)(const void *lhs, const void *rhs,
- size_t count) {
+LLVM_LIBC_FUNCTION(int, memcmp,
+ (const void *lhs, const void *rhs, size_t count)) {
const unsigned char *_lhs = reinterpret_cast<const unsigned char *>(lhs);
const unsigned char *_rhs = reinterpret_cast<const unsigned char *>(rhs);
for (size_t i = 0; i < count; ++i)
return CopyAlignedBlocks<32>(dst, src, count);
}
-void *LLVM_LIBC_ENTRYPOINT(memcpy)(void *__restrict dst,
- const void *__restrict src, size_t size) {
+LLVM_LIBC_FUNCTION(void *, memcpy,
+ (void *__restrict dst, const void *__restrict src,
+ size_t size)) {
memcpy_impl(reinterpret_cast<char *>(dst),
reinterpret_cast<const char *>(src), size);
return dst;
namespace __llvm_libc {
-void *LLVM_LIBC_ENTRYPOINT(memrchr)(const void *src, int c, size_t n) {
+LLVM_LIBC_FUNCTION(void *, memrchr, (const void *src, int c, size_t n)) {
const unsigned char *str = reinterpret_cast<const unsigned char *>(src);
const unsigned char ch = c;
for (; n != 0; --n) {
namespace __llvm_libc {
-void *LLVM_LIBC_ENTRYPOINT(memset)(void *dst, int value, size_t count) {
+LLVM_LIBC_FUNCTION(void *, memset, (void *dst, int value, size_t count)) {
GeneralPurposeMemset(reinterpret_cast<char *>(dst),
static_cast<unsigned char>(value), count);
return dst;
namespace __llvm_libc {
-char *LLVM_LIBC_ENTRYPOINT(strcat)(char *__restrict dest,
- const char *__restrict src) {
+LLVM_LIBC_FUNCTION(char *, strcat,
+ (char *__restrict dest, const char *__restrict src)) {
__llvm_libc::strcpy(dest + internal::string_length(dest), src);
return dest;
}
namespace __llvm_libc {
// TODO: Look at performance benefits of comparing words.
-char *LLVM_LIBC_ENTRYPOINT(strchr)(const char *src, int c) {
+LLVM_LIBC_FUNCTION(char *, strchr, (const char *src, int c)) {
unsigned char *str =
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(src));
const unsigned char ch = c;
namespace __llvm_libc {
// TODO: Look at benefits for comparing words at a time.
-int LLVM_LIBC_ENTRYPOINT(strcmp)(const char *left, const char *right) {
+LLVM_LIBC_FUNCTION(int, strcmp, (const char *left, const char *right)) {
for (; *left && *left == *right; ++left, ++right)
;
return *reinterpret_cast<const unsigned char *>(left) -
namespace __llvm_libc {
-char *LLVM_LIBC_ENTRYPOINT(strcpy)(char *__restrict dest,
- const char *__restrict src) {
+LLVM_LIBC_FUNCTION(char *, strcpy,
+ (char *__restrict dest, const char *__restrict src)) {
return reinterpret_cast<char *>(
__llvm_libc::memcpy(dest, src, internal::string_length(src) + 1));
}
namespace __llvm_libc {
-size_t LLVM_LIBC_ENTRYPOINT(strcspn)(const char *src, const char *segment) {
+LLVM_LIBC_FUNCTION(size_t, strcspn, (const char *src, const char *segment)) {
return internal::complementary_span(src, segment);
}
// TODO: investigate the performance of this function.
// There might be potential for compiler optimization.
-size_t LLVM_LIBC_ENTRYPOINT(strlen)(const char *src) {
+LLVM_LIBC_FUNCTION(size_t, strlen, (const char *src)) {
return internal::string_length(src);
}
namespace __llvm_libc {
-char *LLVM_LIBC_ENTRYPOINT(strncpy)(char *__restrict dest,
- const char *__restrict src, size_t n) {
+LLVM_LIBC_FUNCTION(char *, strncpy,
+ (char *__restrict dest, const char *__restrict src,
+ size_t n)) {
size_t i = 0;
// Copy up until \0 is found.
for (; i < n && src[i] != '\0'; ++i)
namespace __llvm_libc {
-size_t LLVM_LIBC_ENTRYPOINT(strnlen)(const char *src, size_t n) {
+LLVM_LIBC_FUNCTION(size_t, strnlen, (const char *src, size_t n)) {
const void *temp = internal::find_first_character(
reinterpret_cast<const unsigned char *>(src), '\0', n);
return temp ? reinterpret_cast<const char *>(temp) - src : n;
namespace __llvm_libc {
-char *LLVM_LIBC_ENTRYPOINT(strpbrk)(const char *src, const char *breakset) {
+LLVM_LIBC_FUNCTION(char *, strpbrk, (const char *src, const char *breakset)) {
src += internal::complementary_span(src, breakset);
return *src ? const_cast<char *>(src) : nullptr;
}
namespace __llvm_libc {
-char *LLVM_LIBC_ENTRYPOINT(strrchr)(const char *src, int c) {
+LLVM_LIBC_FUNCTION(char *, strrchr, (const char *src, int c)) {
const char ch = c;
char *last_occurrence = nullptr;
do {
namespace __llvm_libc {
-size_t LLVM_LIBC_ENTRYPOINT(strspn)(const char *src, const char *segment) {
+LLVM_LIBC_FUNCTION(size_t, strspn, (const char *src, const char *segment)) {
const char *initial = src;
cpp::Bitset<256> bitset;
// TODO: This is a simple brute force implementation. This can be
// improved upon using well known string matching algorithms.
-char *LLVM_LIBC_ENTRYPOINT(strstr)(const char *haystack, const char *needle) {
+LLVM_LIBC_FUNCTION(char *, strstr, (const char *haystack, const char *needle)) {
for (size_t i = 0; haystack[i]; ++i) {
size_t j;
for (j = 0; haystack[i + j] && haystack[i + j] == needle[j]; ++j)
static char *strtok_str = nullptr;
-char *LLVM_LIBC_ENTRYPOINT(strtok)(char *__restrict src,
- const char *__restrict delimiter_string) {
+LLVM_LIBC_FUNCTION(char *, strtok,
+ (char *__restrict src,
+ const char *__restrict delimiter_string)) {
return internal::string_token(src, delimiter_string, &strtok_str);
}
namespace __llvm_libc {
-char *LLVM_LIBC_ENTRYPOINT(strtok_r)(char *__restrict src,
- const char *__restrict delimiter_string,
- char **__restrict saveptr) {
+LLVM_LIBC_FUNCTION(char *, strtok_r,
+ (char *__restrict src,
+ const char *__restrict delimiter_string,
+ char **__restrict saveptr)) {
return internal::string_token(src, delimiter_string, saveptr);
}
return CopyRepMovsb(dst, src, count);
}
-void *LLVM_LIBC_ENTRYPOINT(memcpy)(void *__restrict dst,
- const void *__restrict src, size_t size) {
+LLVM_LIBC_FUNCTION(void *, memcpy,
+ (void *__restrict dst, const void *__restrict src,
+ size_t size)) {
memcpy_x86(reinterpret_cast<char *>(dst), reinterpret_cast<const char *>(src),
size);
return dst;
// This function is currently linux only. It has to be refactored suitably if
// mmap is to be supported on non-linux operating systems also.
-void *LLVM_LIBC_ENTRYPOINT(mmap)(void *addr, size_t size, int prot, int flags,
- int fd, off_t offset) {
+LLVM_LIBC_FUNCTION(void *, mmap,
+ (void *addr, size_t size, int prot, int flags, int fd,
+ off_t offset)) {
// A lot of POSIX standard prescribed validation of the parameters is not
// done in this function as modern linux versions do it in the syscall.
// TODO: Perform argument validation not done by the linux syscall.
// This function is currently linux only. It has to be refactored suitably if
// mmap is to be supported on non-linux operating systems also.
-int LLVM_LIBC_ENTRYPOINT(munmap)(void *addr, size_t size) {
+LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) {
long ret_val =
__llvm_libc::syscall(SYS_munmap, reinterpret_cast<long>(addr), size);
static constexpr unsigned WAITING = 0x22;
static constexpr unsigned FINISH = 0x33;
-void LLVM_LIBC_ENTRYPOINT(call_once)(once_flag *flag, __call_once_func_t func) {
+LLVM_LIBC_FUNCTION(void, call_once,
+ (once_flag * flag, __call_once_func_t func)) {
FutexData *futex_word = reinterpret_cast<FutexData *>(flag);
unsigned int not_called = ONCE_FLAG_INIT;
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(mtx_init)(mtx_t *mutex, int type) {
+LLVM_LIBC_FUNCTION(int, mtx_init, (mtx_t * mutex, int type)) {
*(reinterpret_cast<uint32_t *>(mutex->__internal_data)) = MS_Free;
mutex->__mtx_type = type;
return thrd_success;
namespace __llvm_libc {
// The implementation currently handles only plain mutexes.
-int LLVM_LIBC_ENTRYPOINT(mtx_lock)(mtx_t *mutex) {
+LLVM_LIBC_FUNCTION(int, mtx_lock, (mtx_t * mutex)) {
FutexData *futex_data = reinterpret_cast<FutexData *>(mutex->__internal_data);
while (true) {
uint32_t mutex_status = MS_Free;
namespace __llvm_libc {
// The implementation currently handles only plain mutexes.
-int LLVM_LIBC_ENTRYPOINT(mtx_unlock)(mtx_t *mutex) {
+LLVM_LIBC_FUNCTION(int, mtx_unlock, (mtx_t * mutex)) {
FutexData *futex_word = reinterpret_cast<FutexData *>(mutex->__internal_data);
while (true) {
uint32_t mutex_status = MS_Waiting;
start_args->func(start_args->arg));
}
-int LLVM_LIBC_ENTRYPOINT(thrd_create)(thrd_t *thread, thrd_start_t func,
- void *arg) {
+LLVM_LIBC_FUNCTION(int, thrd_create,
+ (thrd_t * thread, thrd_start_t func, void *arg)) {
unsigned clone_flags =
CLONE_VM // Share the memory space with the parent.
| CLONE_FS // Share the file system with the parent.
namespace __llvm_libc {
-int LLVM_LIBC_ENTRYPOINT(thrd_join)(thrd_t *thread, int *retval) {
+LLVM_LIBC_FUNCTION(int, thrd_join, (thrd_t * thread, int *retval)) {
FutexData *clear_tid_address =
reinterpret_cast<FutexData *>(thread->__clear_tid);
return static_cast<time_t>(-1);
}
-time_t LLVM_LIBC_ENTRYPOINT(mktime)(struct tm *t1) {
+LLVM_LIBC_FUNCTION(time_t, mktime, (struct tm * t1)) {
// Unlike most C Library functions, mktime doesn't just die on bad input.
// TODO(rtenneti); Handle leap seconds. Handle out of range time and date
// values that don't overflow or underflow.
namespace __llvm_libc {
-ssize_t LLVM_LIBC_ENTRYPOINT(write)(int fd, const void *buf, size_t count) {
+LLVM_LIBC_FUNCTION(ssize_t, write, (int fd, const void *buf, size_t count)) {
long ret = __llvm_libc::syscall(SYS_write, fd, buf, count);
if (ret < 0) {
llvmlibc_errno = -ret;