//===--- Builtins.def - Builtin function info database ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the standard builtin function database.  Users of this file
// must define the BUILTIN macro to make use of this information.
//
//===----------------------------------------------------------------------===//

// FIXME: this needs to be the full list supported by GCC.  Right now, I'm just
// adding stuff on demand.
//
// FIXME: This should really be a .td file, but that requires modifying tblgen.
// Perhaps tblgen should have plugins.

// The first value provided to the macro specifies the function name of the
// builtin, and results in a clang::builtin::BIXX enum value for XX.

// The second value provided to the macro specifies the type of the function
// (result value, then each argument) as follows:
//  v -> void
//  b -> boolean
//  c -> char
//  s -> short
//  i -> int
//  f -> float
//  d -> double
//  z -> size_t
//  F -> constant CFString
//  a -> __builtin_va_list
//  A -> "reference" to __builtin_va_list
//  V -> Vector, following num elements and a base type.
//  P -> FILE
//  . -> "...".  This may only occur at the end of the function list.
//
// Types maybe prefixed with the following modifiers:
//  L  -> long (e.g. Li for 'long int')
//  LL -> long long
//  S  -> signed
//  U  -> unsigned
//
// Types may be postfixed with the following modifiers:
// * -> pointer
// & -> reference
// C -> const

// The third value provided to the macro specifies information about attributes
// of the function.  These must be kept in sync with the predicates in the
// Builtin::Context class.  Currently we have:
//  n -> nothrow
//  c -> const
//  F -> this is a libc/libm function with a '__builtin_' prefix added.
//  f -> this is a libc/libm function without the '__builtin_' prefix. It can
//       be followed by ':headername:' to state which header this function
//       comes from.
//  p:N: -> this is a printf-like function whose Nth argument is the format 
//          string.
//  P:N: -> similar to the p:N: attribute, but the function is like vprintf
//          in that it accepts its arguments as a va_list rather than 
//          through an ellipsis
//  e -> const, but only when -fmath-errno=0
//  FIXME: gcc has nonnull

#if defined(BUILTIN) && !defined(LIBBUILTIN)
#  define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) BUILTIN(ID, TYPE, ATTRS)
#endif

// Standard libc/libm functions:
BUILTIN(__builtin_huge_val, "d", "nc")
BUILTIN(__builtin_huge_valf, "f", "nc")
BUILTIN(__builtin_huge_vall, "Ld", "nc")
BUILTIN(__builtin_inf  , "d"   , "nc")
BUILTIN(__builtin_inff , "f"   , "nc")
BUILTIN(__builtin_infl , "Ld"  , "nc")
BUILTIN(__builtin_nan,  "dcC*" , "ncF")
BUILTIN(__builtin_nanf, "fcC*" , "ncF")
BUILTIN(__builtin_nanl, "LdcC*", "ncF")
BUILTIN(__builtin_nans,  "dcC*" , "ncF")
BUILTIN(__builtin_nansf, "fcC*" , "ncF")
BUILTIN(__builtin_nansl, "LdcC*", "ncF")
BUILTIN(__builtin_abs  , "ii"  , "ncF")
BUILTIN(__builtin_fabs , "dd"  , "ncF")
BUILTIN(__builtin_fabsf, "ff"  , "ncF")
BUILTIN(__builtin_fabsl, "LdLd", "ncF")
BUILTIN(__builtin_copysign, "ddd", "ncF")
BUILTIN(__builtin_copysignf, "fff", "ncF")
BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
BUILTIN(__builtin_powi , "ddi"  , "nc")
BUILTIN(__builtin_powif, "ffi"  , "nc")
BUILTIN(__builtin_powil, "LdLdi", "nc")

// FP Comparisons.
BUILTIN(__builtin_isgreater     , "i.", "nc")
BUILTIN(__builtin_isgreaterequal, "i.", "nc")
BUILTIN(__builtin_isless        , "i.", "nc")
BUILTIN(__builtin_islessequal   , "i.", "nc")
BUILTIN(__builtin_islessgreater , "i.", "nc")
BUILTIN(__builtin_isunordered   , "i.", "nc")

// Builtins for arithmetic.
BUILTIN(__builtin_clz  , "iUi"  , "nc")
BUILTIN(__builtin_clzl , "iULi" , "nc")
BUILTIN(__builtin_clzll, "iULLi", "nc")
// TODO: int clzimax(uintmax_t)
BUILTIN(__builtin_ctz  , "iUi"  , "nc")
BUILTIN(__builtin_ctzl , "iULi" , "nc")
BUILTIN(__builtin_ctzll, "iULLi", "nc")
// TODO: int ctzimax(uintmax_t)
BUILTIN(__builtin_ffs  , "iUi"  , "nc")
BUILTIN(__builtin_ffsl , "iULi" , "nc")
BUILTIN(__builtin_ffsll, "iULLi", "nc")
BUILTIN(__builtin_parity  , "iUi"  , "nc")
BUILTIN(__builtin_parityl , "iULi" , "nc")
BUILTIN(__builtin_parityll, "iULLi", "nc")
BUILTIN(__builtin_popcount  , "iUi"  , "nc")
BUILTIN(__builtin_popcountl , "iULi" , "nc")
BUILTIN(__builtin_popcountll, "iULLi", "nc")

// FIXME: These type signatures are not correct for targets with int != 32-bits
// or with ULL != 64-bits.
BUILTIN(__builtin_bswap32, "UiUi", "nc")
BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")

// Random GCC builtins
BUILTIN(__builtin_constant_p, "Us.", "nc")
BUILTIN(__builtin_classify_type, "i.", "nc")
BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
BUILTIN(__builtin_va_start, "vA.", "n")
BUILTIN(__builtin_va_end, "vA", "n")
BUILTIN(__builtin_va_copy, "vAA", "n")
BUILTIN(__builtin_stdarg_start, "vA.", "n")
BUILTIN(__builtin_bcmp, "iv*v*z", "n")
BUILTIN(__builtin_bcopy, "vv*v*z", "n")
BUILTIN(__builtin_bzero, "vv*z", "n")
BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
BUILTIN(__builtin_memmove, "v*v*vC*z", "nF")
BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF")
BUILTIN(__builtin_memset, "v*v*iz", "nF")
BUILTIN(__builtin_stpcpy, "c*c*cC*", "nF")
BUILTIN(__builtin_stpncpy, "c*c*cC*z", "nF")
BUILTIN(__builtin_strcasecmp, "icC*cC*", "nF")
BUILTIN(__builtin_strcat, "c*c*cC*", "nF")
BUILTIN(__builtin_strchr, "c*cC*i", "nF")
BUILTIN(__builtin_strcmp, "icC*cC*", "nF")
BUILTIN(__builtin_strcpy, "c*c*cC*", "nF")
BUILTIN(__builtin_strcspn, "zcC*cC*", "nF")
BUILTIN(__builtin_strdup, "c*cC*", "nF")
BUILTIN(__builtin_strlen, "zcC*", "nF")
BUILTIN(__builtin_strncasecmp, "icC*cC*z", "nF")
BUILTIN(__builtin_strncat, "c*c*cC*z", "nF")
BUILTIN(__builtin_strncmp, "icC*cC*z", "nF")
BUILTIN(__builtin_strncpy, "c*c*cC*z", "nF")
BUILTIN(__builtin_strndup, "c*cC*z", "nF")
BUILTIN(__builtin_strpbrk, "c*cC*cC*", "nF")
BUILTIN(__builtin_strrchr, "c*cC*i", "nF")
BUILTIN(__builtin_strspn, "zcC*cC*", "nF")
BUILTIN(__builtin_strstr, "c*cC*cC*", "nF")
BUILTIN(__builtin_return_address, "v*Ui", "n")
BUILTIN(__builtin_frame_address, "v*Ui", "n")
BUILTIN(__builtin_flt_rounds, "i", "nc")

// GCC Object size checking builtins
BUILTIN(__builtin_object_size, "zv*i", "n")
BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___memset_chk, "v*v*izz", "nF")
BUILTIN(__builtin___stpcpy_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___snprintf_chk, "ic*zizcC*.", "Fp:4:")
BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "Fp:3:")
BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "FP:4:")
BUILTIN(__builtin___vsprintf_chk, "ic*izcC*a", "FP:3:")
BUILTIN(__builtin___fprintf_chk, "iP*icC*.", "Fp:2:")
BUILTIN(__builtin___printf_chk, "iicC*.", "Fp:1:")
BUILTIN(__builtin___vfprintf_chk, "iP*icC*a", "FP:2:")
BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")

BUILTIN(__builtin_expect, "iii"   , "nc")
BUILTIN(__builtin_prefetch, "vCv*.", "nc")
BUILTIN(__builtin_trap, "v", "n")

BUILTIN(__builtin_shufflevector, "v."   , "nc")

BUILTIN(__builtin_alloca, "v*z"   , "n")

// Atomic operators builtin.

// FIXME: These should be overloaded for i8, i16, i32, and i64.
BUILTIN(__sync_fetch_and_add,"ii*i", "n")
BUILTIN(__sync_fetch_and_sub,"ii*i", "n")
BUILTIN(__sync_fetch_and_min,"ii*i", "n")
BUILTIN(__sync_fetch_and_max,"ii*i", "n")
BUILTIN(__sync_fetch_and_umin,"UiUi*Ui", "n")
BUILTIN(__sync_fetch_and_umax,"UiUi*Ui", "n")
BUILTIN(__sync_fetch_and_and,"ii*i", "n")
BUILTIN(__sync_fetch_and_or,"ii*i", "n")
BUILTIN(__sync_fetch_and_xor,"ii*i", "n")
BUILTIN(__sync_add_and_fetch,"ii*i", "n")
BUILTIN(__sync_sub_and_fetch,"ii*i", "n")
BUILTIN(__sync_min_and_fetch,"ii*i", "n")
BUILTIN(__sync_max_and_fetch,"ii*i", "n")
BUILTIN(__sync_umin_and_fetch,"UiUi*Ui", "n")
BUILTIN(__sync_umax_and_fetch,"UiUi*Ui", "n")
BUILTIN(__sync_and_and_fetch,"ii*i", "n")
BUILTIN(__sync_or_and_fetch,"ii*i", "n")
BUILTIN(__sync_xor_and_fetch,"ii*i", "n")
BUILTIN(__sync_lock_test_and_set,"ii*i", "n")
BUILTIN(__sync_bool_compare_and_swap,"ii*ii", "n")
BUILTIN(__sync_val_compare_and_swap,"ii*ii", "n")

// LLVM instruction builtin
BUILTIN(__builtin_llvm_memory_barrier,"vbbbbb", "n")

// Builtin library functions
LIBBUILTIN(alloca, "v*z",         "f",     "stdlib.h")
LIBBUILTIN(calloc, "v*zz",        "f",     "stdlib.h")
LIBBUILTIN(malloc, "v*z",         "f",     "stdlib.h")
LIBBUILTIN(realloc, "v*v*z",      "f",     "stdlib.h")
LIBBUILTIN(memcpy, "v*v*vC*z",    "f",     "string.h")
LIBBUILTIN(memmove, "v*v*vC*z",   "f",     "string.h")
LIBBUILTIN(memset, "v*v*iz",      "f",     "string.h")
LIBBUILTIN(strcat, "c*c*cC*",     "f",     "string.h")
LIBBUILTIN(strchr, "c*cC*i",      "f",     "string.h")
LIBBUILTIN(strcpy, "c*c*cC*",     "f",     "string.h")
LIBBUILTIN(strcspn, "zcC*cC*",    "f",     "string.h")
LIBBUILTIN(strlen, "zcC*",        "f",     "string.h")
LIBBUILTIN(strncat, "c*c*cC*z",   "f",     "string.h")
LIBBUILTIN(strncpy, "c*c*cC*z",   "f",     "string.h")
LIBBUILTIN(strpbrk, "c*cC*cC*",   "f",     "string.h")
LIBBUILTIN(strrchr, "c*cC*i",     "f",     "string.h")
LIBBUILTIN(strspn, "zcC*cC*",     "f",     "string.h")
LIBBUILTIN(strstr, "c*cC*cC*",    "f",     "string.h")
LIBBUILTIN(printf, "icC*.",       "fp:0:", "stdio.h")
LIBBUILTIN(fprintf, "iP*cC*.",    "fp:1:", "stdio.h")
LIBBUILTIN(snprintf, "ic*zcC*.",  "fp:2:", "stdio.h")
LIBBUILTIN(sprintf, "ic*cC*.",    "fp:1:", "stdio.h")
LIBBUILTIN(vprintf, "icC*a",      "fP:0:", "stdio.h")
LIBBUILTIN(vfprintf, "iP*cC*a",   "fP:1:", "stdio.h")
LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h")
LIBBUILTIN(vsprintf, "ic*cC*a",   "fP:1:", "stdio.h")

// FIXME: asprintf and vasprintf aren't C99 functions. Should they be
// target-specific builtins, perhaps? 

// Builtin math library functions
LIBBUILTIN(pow, "ddd", "fe", "math.h")
LIBBUILTIN(powl, "LdLdLd", "fe", "math.h")
LIBBUILTIN(powf, "fff", "fe", "math.h")

LIBBUILTIN(sqrt, "dd", "fe", "math.h")
LIBBUILTIN(sqrtl, "LdLd", "fe", "math.h")
LIBBUILTIN(sqrtf, "ff", "fe", "math.h")

#undef BUILTIN
#undef LIBBUILTIN
