//===--- 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
//  c -> char
//  s -> short
//  i -> int
//  f -> float
//  d -> double
//  z -> size_t
//  F -> constant CFString
//  a -> __builtin_va_list
//  V -> Vector, following num elements and a base type.
//  . -> "...".  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.
//  FIXME: gcc has nonnull

// 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, "UsUs", "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, "va&a", "n")
BUILTIN(__builtin_stdarg_start, "va&a", "n")
BUILTIN(__builtin_bzero, "vv*z", "n")
BUILTIN(__builtin_memcpy, "v*v*vC*z", "n")
BUILTIN(__builtin_memmove, "v*v*vC*z", "n")
BUILTIN(__builtin_memset, "v*v*cz", "n")
BUILTIN(__builtin_return_address, "v*Ui", "n")
BUILTIN(__builtin_frame_address, "v*Ui", "n")
// 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*.", "F") // FIXME: format printf attribute
BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "F") // FIXME: format printf attribute
BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "F") // FIXME: format printf attribute
BUILTIN(__builtin___vsprintf_chk, "ic*izcC*a", "F") // FIXME: format printf attribute
//BUILTIN(__builtin___fprintf_chk, "i(FIXME:FILEPTR)icC*.", "F") // FIXME: format printf attribute
BUILTIN(__builtin___printf_chk, "iicC*.", "F")
//BUILTIN(__builtin___vfprintf_chk, "i(FIXME:FILEPTR)icC*a", "F") // FIXME: format printf attribute
BUILTIN(__builtin___vprintf_chk, "iicC*a", "F") // FIXME: format printf attribute

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.                                                  
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_lock_test_and_set,"ii*i", "n")
BUILTIN(__sync_val_compare_and_swap,"ii*ii", "n")

#undef BUILTIN
