//===--- Builtins.def - Builtins Macro Metaprogramming Database -*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the database of builtin functions.
//
// BUILTIN(Id, Name, Attrs)
//   - Id is an identifier suitable for use in C++
//   - Name is a string literal for the name to which the builtin should be
//     bound in Swift
//   - Attrs specifies information about attributes of the function:
//     n -> readnone
//
//===----------------------------------------------------------------------===//

/// Cast operations have type T1 -> T2.
#ifndef BUILTIN_CAST_OPERATION
#define BUILTIN_CAST_OPERATION(Id, Name, Attrs) BUILTIN(Id, Name, Attrs)
#endif
BUILTIN_CAST_OPERATION(Trunc   , "trunc",    "n")
BUILTIN_CAST_OPERATION(ZExt    , "zext",     "n")
BUILTIN_CAST_OPERATION(SExt    , "sext",     "n")
BUILTIN_CAST_OPERATION(FPToUI  , "fptoui",   "n")
BUILTIN_CAST_OPERATION(FPToSI  , "fptosi",   "n")
BUILTIN_CAST_OPERATION(UIToFP  , "uitofp",   "n")
BUILTIN_CAST_OPERATION(SIToFP  , "sitofp",   "n")
BUILTIN_CAST_OPERATION(FPTrunc , "fptrunc",  "n")
BUILTIN_CAST_OPERATION(FPExt   , "fpext",    "n")
BUILTIN_CAST_OPERATION(PtrToInt, "ptrtoint", "n")
BUILTIN_CAST_OPERATION(IntToPtr, "inttoptr", "n")
BUILTIN_CAST_OPERATION(BitCast , "bitcast",  "n")

#undef BUILTIN_CAST_OPERATION

/// Binary operations have type (T,T) -> T.
#ifndef BUILTIN_BINARY_OPERATION
#define BUILTIN_BINARY_OPERATION(Id, Name, Attrs, Overload) \
          BUILTIN(Id, Name, Attrs)
#endif
BUILTIN_BINARY_OPERATION(Add,     "add",      "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(FAdd,    "fadd",     "n", FloatOrVector)
BUILTIN_BINARY_OPERATION(And,     "and",      "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(AShr,    "ashr",     "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(LShr,    "lshr",     "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(Or,      "or",       "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(FDiv,    "fdiv",     "n", FloatOrVector)
BUILTIN_BINARY_OPERATION(Mul,     "mul",      "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(FMul,    "fmul",     "n", FloatOrVector)
BUILTIN_BINARY_OPERATION(SDiv,    "sdiv",     "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(ExactSDiv, "sdiv_exact", "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(Shl,     "shl",      "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(SRem,    "srem",     "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(Sub,     "sub",      "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(FSub,    "fsub",     "n", FloatOrVector)
BUILTIN_BINARY_OPERATION(UDiv,    "udiv",     "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(ExactUDiv, "udiv_exact", "n", IntegerOrVector)
BUILTIN_BINARY_OPERATION(URem,    "urem",     "n", Integer)
BUILTIN_BINARY_OPERATION(Xor,     "xor",      "n", IntegerOrVector)
#undef BUILTIN_BINARY_OPERATION

/// Unary operations have type (T) -> T.
#ifndef BUILTIN_UNARY_OPERATION
#define BUILTIN_UNARY_OPERATION(Id, Name, Attrs, Overload) \
          BUILTIN(Id, Name, Attrs)
#endif

// "fneg" is a separate builtin because its LLVM representation is
// 'fsub -0.0, %x', but defining it in swift as
// 'func [prefix] -(x) { -0.0 - x }' would be infinitely recursive.
BUILTIN_UNARY_OPERATION(FNeg, "fneg", "n", FloatOrVector)
#undef BUILTIN_UNARY_OPERATION

// Binary predicates have type (T,T) -> i1 or (T, T) -> Vector<i1> for scalars
// and vectors, respectively.
#ifndef BUILTIN_BINARY_PREDICATE
#define BUILTIN_BINARY_PREDICATE(Id, Name, Attrs, Overload) \
          BUILTIN(Id, Name, Attrs)
#endif
BUILTIN_BINARY_PREDICATE(ICMP_EQ,  "cmp_eq",   "n", IntegerOrRawPointerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_NE,  "cmp_ne",   "n", IntegerOrRawPointerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_SLE, "cmp_sle",  "n", IntegerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_SLT, "cmp_slt",  "n", IntegerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_SGE, "cmp_sge",  "n", IntegerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_SGT, "cmp_sgt",  "n", IntegerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_ULE, "cmp_ule",  "n", IntegerOrRawPointerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_ULT, "cmp_ult",  "n", IntegerOrRawPointerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_UGE, "cmp_uge",  "n", IntegerOrRawPointerOrVector)
BUILTIN_BINARY_PREDICATE(ICMP_UGT, "cmp_ugt",  "n", IntegerOrRawPointerOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_OEQ, "fcmp_oeq", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_OGT, "fcmp_ogt", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_OGE, "fcmp_oge", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_OLT, "fcmp_olt", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_OLE, "fcmp_ole", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_ONE, "fcmp_one", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_ORD, "fcmp_ord", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_UEQ, "fcmp_ueq", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_UGT, "fcmp_ugt", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_UGE, "fcmp_uge", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_ULT, "fcmp_ult", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_ULE, "fcmp_ule", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_UNE, "fcmp_une", "n", FloatOrVector)
BUILTIN_BINARY_PREDICATE(FCMP_UNO, "fcmp_uno", "n", FloatOrVector)
#undef BUILTIN_BINARY_PREDICATE

// BUILTIN_SIL_OPERATION - Operations that can be lowered to SIL instructions.
// These have various types.
// Since these operations will be lowered to SIL Instructions, we do not 
// assign any attributes on them.
#ifndef BUILTIN_SIL_OPERATION
#define BUILTIN_SIL_OPERATION(Id, Name, Overload) BUILTIN(Id, Name, "")
#endif

/// Load has type (Builtin.RawPointer) -> T
BUILTIN_SIL_OPERATION(Load, "load", Special)

/// Move has type (Builtin.RawPointer) -> T
BUILTIN_SIL_OPERATION(Move, "move", Special)

/// Destroy has type (metatype<T>, Builtin.RawPointer) -> ()
BUILTIN_SIL_OPERATION(Destroy, "destroy", Special)

/// Assign has type (T, Builtin.RawPointer) -> ()
BUILTIN_SIL_OPERATION(Assign, "assign", Special)

/// Init has type (T, Builtin.RawPointer) -> ()
BUILTIN_SIL_OPERATION(Init, "initialize", Special)

/// CastToObjectPointer has type (T) -> Builtin.ObjectPointer.
BUILTIN_SIL_OPERATION(CastToObjectPointer, "castToObjectPointer", Special)

/// CastFromObjectPointer has type (Builtin.ObjectPointer) -> T.
BUILTIN_SIL_OPERATION(CastFromObjectPointer, "castFromObjectPointer", Special)

/// BridgeToRawPointer has type (T) -> Builtin.RawPointer.
BUILTIN_SIL_OPERATION(BridgeToRawPointer, "bridgeToRawPointer", Special)

/// BridgeFromRawPointer (Builtin.RawPointer) -> T.
/// SILGen requires that T is a single retainable pointer.
/// Bridging to/from a raw pointer does not imply a retain.
BUILTIN_SIL_OPERATION(BridgeFromRawPointer, "bridgeFromRawPointer", Special)

/// addressof ([byref] T) -> Builtin.RawPointer.
/// Returns a RawPointer pointing to an lvalue. The returned pointer is only
/// valid within the scope of the statement for logical lvalues.
BUILTIN_SIL_OPERATION(AddressOf, "addressof", Special)

/// typeof(T) -> T.metatype.
/// Returns the runtime type of a value.
BUILTIN_SIL_OPERATION(TypeOf, "typeof", Special)

/// GetElementPtr has type (Builtin.RawPointer, T) -> Builtin.RawPointer
BUILTIN_SIL_OPERATION(Gep, "gep", Integer)

#undef BUILTIN_SIL_OPERATION

// BUILTIN_MISC_OPERATION - Miscellaneous operations without a unifying class.
// These have various types.
#ifndef BUILTIN_MISC_OPERATION
#define BUILTIN_MISC_OPERATION(Id, Name, Attrs, Overload) \
          BUILTIN(Id, Name, Attrs)
#endif
                       
/// Sizeof has type (metatype<T>) -> Int64
BUILTIN_MISC_OPERATION(Sizeof, "sizeof", "n", Special)

/// Strideof has type (metatype<T>) -> Int64
BUILTIN_MISC_OPERATION(Strideof, "strideof", "n", Special)

/// Alignof has type (metatype<T>) -> Int64
BUILTIN_MISC_OPERATION(Alignof, "alignof", "n", Special)

/// AllocRaw has type (Int64, Int64) -> Builtin.RawPointer
BUILTIN_MISC_OPERATION(AllocRaw, "allocRaw", "", Special)

/// DeallocRaw has type (Builtin.RawPointer, Int64) -> ()
BUILTIN_MISC_OPERATION(DeallocRaw, "deallocRaw", "", Special)

/// Fence has type () -> ().
BUILTIN_MISC_OPERATION(Fence, "fence", "", None)

/// CmpXChg has type (Builtin.RawPointer, T, T) -> T.
BUILTIN_MISC_OPERATION(CmpXChg, "cmpxchg", "", Special)

/// AtomicRMW has type (Builtin.RawPointer, T) -> T.
BUILTIN_MISC_OPERATION(AtomicRMW, "atomicrmw", "", IntegerOrRawPointer)

/// ExtractElement has type (Vector<N, T>, Int32) -> T
BUILTIN_MISC_OPERATION(ExtractElement, "extractelement", "n", Special)

/// InsertElement has type (Vector<N, T>, T, Int32) -> Vector<N, T>.
BUILTIN_MISC_OPERATION(InsertElement, "insertelement", "n", Special)

// FIXME: shufflevector

#undef BUILTIN_MISC_OPERATION

#undef BUILTIN
