//===--- Builtins.def - Builtins Macro Metaprogramming Database -*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 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 /// Cast-or-bitcast operations have type T1 -> T2. /// T1 and T2 may be the same size, unlike the corresponding true casts. #ifndef BUILTIN_CAST_OR_BITCAST_OPERATION #define BUILTIN_CAST_OR_BITCAST_OPERATION(Id, Name, Attrs) BUILTIN(Id, Name, Attrs) #endif BUILTIN_CAST_OR_BITCAST_OPERATION(TruncOrBitCast, "truncOrBitCast", "n") BUILTIN_CAST_OR_BITCAST_OPERATION(ZExtOrBitCast, "zextOrBitCast", "n") BUILTIN_CAST_OR_BITCAST_OPERATION(SExtOrBitCast, "sextOrBitCast", "n") #undef BUILTIN_CAST_OR_BITCAST_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 /// These builtins are analogous the similarly named llvm intrinsics. The /// difference between the two is that these are not expected to overflow, /// so we should produce a compile time error if we can statically prove /// that they do. #ifndef BUILTIN_BINARY_OPERATION_WITH_OVERFLOW #define BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(Id, Name, UncheckedID, Attrs, Overload) \ BUILTIN(Id, Name, Attrs) #endif BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(SAddOver, "sadd_with_overflow", Add, "n", Integer) BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(UAddOver, "uadd_with_overflow", Add, "n", Integer) BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(SSubOver, "ssub_with_overflow", Sub, "n", Integer) BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(USubOver, "usub_with_overflow", Sub, "n", Integer) BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(SMulOver, "smul_with_overflow", Mul, "n", Integer) BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(UMulOver, "umul_with_overflow", Mul, "n", Integer) #undef BUILTIN_BINARY_OPERATION_WITH_OVERFLOW /// 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) // Returns the argument and specifies that the value is not negative. // It has only an effect if the argument is a load or call. // TODO: consider printing a warning if it is not used on a load or call. BUILTIN_UNARY_OPERATION(AssumeNonNegative, "assumeNonNegative", "n", Integer) #undef BUILTIN_UNARY_OPERATION // Binary predicates have type (T,T) -> i1 or (T, T) -> Vector 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 /// retain: T -> () BUILTIN_SIL_OPERATION(Retain, "retain", Special) /// release: T -> () BUILTIN_SIL_OPERATION(Release, "release", Special) /// autorelease: T -> () BUILTIN_SIL_OPERATION(Autorelease, "autorelease", Special) // The pin operations return T only because Optional isn't intrinsic. /// tryPin: Builtin.NativeObject -> T BUILTIN_SIL_OPERATION(TryPin, "tryPin", Special) /// unpin: T -> () BUILTIN_SIL_OPERATION(Unpin, "unpin", Special) /// Load has type (Builtin.RawPointer) -> T BUILTIN_SIL_OPERATION(Load, "load", Special) /// Take has type (Builtin.RawPointer) -> T BUILTIN_SIL_OPERATION(Take, "take", Special) /// Destroy has type (T.Type, 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) /// CastToUnknownObject has type (T) -> Builtin.UnknownObject. BUILTIN_SIL_OPERATION(CastToUnknownObject, "castToUnknownObject", Special) /// CastFromUnknownObject has type (Builtin.UnknownObject) -> T. BUILTIN_SIL_OPERATION(CastFromUnknownObject, "castFromUnknownObject", Special) /// CastToNativeObject has type (T) -> Builtin.NativeObject. BUILTIN_SIL_OPERATION(CastToNativeObject, "castToNativeObject", Special) /// CastFromNativeObject has type (Builtin.NativeObject) -> T BUILTIN_SIL_OPERATION(CastFromNativeObject, "castFromNativeObject", Special) /// CastToBridgeObject has type (T, Builtin.Word) -> Builtin.BridgeObject. /// It sets the BridgeObject to the bitwise OR of its operands. /// It is assumed that /// /// castReferenceFromBridgeObject(castToBridgeObject(ref, x)) === ref /// /// regardless of what x is. /// x thus must not have any bits set that would change the heap /// object pointer value, nor may it have the native/ObjC discriminator bit set, /// nor may it have any bits set if the first operand is an ObjC tagged pointer, /// or else undefined behavior will ensue. BUILTIN_SIL_OPERATION(CastToBridgeObject, "castToBridgeObject", Special) /// CastReferenceFromBridgeObject has type (Builtin.BridgeObject) -> T. /// It recovers the heap object reference by masking spare bits from the /// BridgeObject. BUILTIN_SIL_OPERATION(CastReferenceFromBridgeObject, "castReferenceFromBridgeObject", Special) /// CastBitPatternFromBridgeObject has type (Builtin.BridgeObject) -> Builtin.Word. /// It presents the raw bit pattern of the BridgeObject as BUILTIN_SIL_OPERATION(CastBitPatternFromBridgeObject, "castBitPatternFromBridgeObject", 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) /// castReference has type T -> U. /// T and U must be convertible to AnyObject. BUILTIN_SIL_OPERATION(CastReference, "castReference", Special) /// reinterpretCast has type T -> U. BUILTIN_SIL_OPERATION(ReinterpretCast, "reinterpretCast", Special) /// addressof ([inout] 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) /// GetElementPtr has type (Builtin.RawPointer, T) -> Builtin.RawPointer BUILTIN_SIL_OPERATION(Gep, "gep", Integer) /// condfail(Int1) -> () /// Triggers a runtime failure if the condition is true. BUILTIN_SIL_OPERATION(CondFail, "condfail", Special) /// fixLifetime(T) -> () /// Fixes the lifetime of any heap references in a value. BUILTIN_SIL_OPERATION(FixLifetime, "fixLifetime", Special) /// isUnique : (inout T[?]) -> Int1 /// /// This builtin takes an inout object reference and returns a boolean. Passing /// the reference inout forces the optimizer to preserve a retain distinct from /// what's required to maintain lifetime for any of the reference's source-level /// copies, because the called function is allowed to replace the reference, /// thereby releasing the referent. /// /// The kind of reference count checking that Builtin.isUnique performs depends /// on the argument type: /// /// - Native object types are directly checked by reading the /// strong reference count: /// (Builtin.NativeObject, known native class reference) /// /// - Objective-C object types require an additional check that the /// dynamic object type uses native swift reference counting: /// (Builtin.UnknownObject, unknown class reference, class existential) /// /// - Bridged object types allow the dynamic object type check to be /// passed based on their pointer encoding: /// (Builtin.BridgeObject) /// /// Any of the above types may also be wrapped in an optional. /// If the static argument type is optional, then a null check is also /// performed. /// /// Thus, isUnique only returns true for non-null, native swift object /// references with a strong reference count of one. BUILTIN_SIL_OPERATION(IsUnique, "isUnique", Special) /// isUniqueOrPinned : (inout T[?]) -> Int1 /// /// This builtin has the same semantics as isUnique except that it also returns /// true if the object is marked pinned regardless of the reference count. This /// allows for simultaneous non-structural modification of multiple subobjects. BUILTIN_SIL_OPERATION(IsUniqueOrPinned, "isUniqueOrPinned", Special) /// IsUnique_native : (inout T[?]) -> Int1 /// /// These variants of isUnique implicitly cast to a non-null NativeObject before /// checking uniqueness. This allows an object reference statically typed as /// BridgeObject or UnknownObject to be treated as a native object by the /// runtime. BUILTIN_SIL_OPERATION(IsUnique_native, "isUnique_native", Special) BUILTIN_SIL_OPERATION(IsUniqueOrPinned_native, "isUniqueOrPinned_native", Special) #undef BUILTIN_SIL_OPERATION // BUILTIN_RUNTIME_CALL - A call into a runtime function. // These functions accept a single argument of any type. #ifndef BUILTIN_RUNTIME_CALL #define BUILTIN_RUNTIME_CALL(Id, Name, Attrs) \ BUILTIN(Id, Name, Attrs) #endif /// willThrow: ErrorProtocol -> () BUILTIN_RUNTIME_CALL(WillThrow, "willThrow", "n") /// unexpectedError: ErrorProtocol -> () BUILTIN_RUNTIME_CALL(UnexpectedError, "unexpectedError", "") /// errorInMain: ErrorProtocol -> () BUILTIN_RUNTIME_CALL(ErrorInMain, "errorInMain", "") /// IsOptionalType : T.Type -> Bool /// This builtin takes a metatype and returns true if the metatype's /// nominal type is Optional. BUILTIN_RUNTIME_CALL(IsOptionalType, "isOptional", "") #undef BUILTIN_RUNTIME_CALL // 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 T.Type -> Int BUILTIN_MISC_OPERATION(Sizeof, "sizeof", "n", Special) /// Strideof has type T.Type -> Int BUILTIN_MISC_OPERATION(Strideof, "strideof", "n", Special) /// IsPOD has type T.Type -> Bool BUILTIN_MISC_OPERATION(IsPOD, "ispod", "n", Special) /// Alignof has type T.Type -> Int BUILTIN_MISC_OPERATION(Alignof, "alignof", "n", Special) /// Strideof has type T.Type -> Int. /// Note that this version will never return 0. It instead always returns /// at least 1 BUILTIN_MISC_OPERATION(StrideofNonZero, "strideof_nonzero", "n", Special) /// AllocRaw has type (Int, Int) -> Builtin.RawPointer BUILTIN_MISC_OPERATION(AllocRaw, "allocRaw", "", Special) /// DeallocRaw has type (Builtin.RawPointer, Int, Int) -> () BUILTIN_MISC_OPERATION(DeallocRaw, "deallocRaw", "", Special) /// Fence has type () -> (). BUILTIN_MISC_OPERATION(Fence, "fence", "", None) /// CmpXChg has type (Builtin.RawPointer, T, T) -> (T, Bool). BUILTIN_MISC_OPERATION(CmpXChg, "cmpxchg", "", Special) /// AtomicLoad has type (Builtin.RawPointer) -> T. BUILTIN_MISC_OPERATION(AtomicLoad, "atomicload", "", Special) /// AtomicStore has type (Builtin.RawPointer, T) -> (). BUILTIN_MISC_OPERATION(AtomicStore, "atomicstore", "", Special) /// AtomicRMW has type (Builtin.RawPointer, T) -> T. BUILTIN_MISC_OPERATION(AtomicRMW, "atomicrmw", "", IntegerOrRawPointer) /// ExtractElement has type (Vector, Int32) -> T BUILTIN_MISC_OPERATION(ExtractElement, "extractelement", "n", Special) /// InsertElement has type (Vector, T, Int32) -> Vector. BUILTIN_MISC_OPERATION(InsertElement, "insertelement", "n", Special) /// StaticReport has type (Builtin.Int1, Builtin.Int1, Builtin.RawPointer) -> () BUILTIN_MISC_OPERATION(StaticReport, "staticReport", "", Special) /// assert_configuration has type () -> Builtin.Int32 /// Returns the selected assertion configuration. BUILTIN_MISC_OPERATION(AssertConf, "assert_configuration", "n", Special) /// Special truncation builtins that check for sign and overflow errors. These /// take an integer as an input and return a tuple of the truncated result and /// an error bit. The name of each builtin is extended with the "from" /// (sign-agnostic) builtin integer type and the "to" integer type. /// We require the source type size to be larger than the destination type size /// (number of bits). BUILTIN_MISC_OPERATION(UToSCheckedTrunc, "u_to_s_checked_trunc", "n", Special) BUILTIN_MISC_OPERATION(SToSCheckedTrunc, "s_to_s_checked_trunc", "n", Special) BUILTIN_MISC_OPERATION(SToUCheckedTrunc, "s_to_u_checked_trunc", "n", Special) BUILTIN_MISC_OPERATION(UToUCheckedTrunc, "u_to_u_checked_trunc", "n", Special) /// Checked conversions for signed <-> unsigned integers of the same size. /// Returns a tuple containing the conversion result as well as /// the sign error / overflow bit. BUILTIN_MISC_OPERATION(SUCheckedConversion, "s_to_u_checked_conversion", "n", Special) BUILTIN_MISC_OPERATION(USCheckedConversion, "u_to_s_checked_conversion", "n", Special) /// IntToFPWithOverflow has type (Integer) -> Float BUILTIN_MISC_OPERATION(IntToFPWithOverflow, "itofp_with_overflow", "n", Special) // FIXME: shufflevector /// zeroInitializer has type () -> T BUILTIN_MISC_OPERATION(ZeroInitializer, "zeroInitializer", "n", Special) /// once has type (Builtin.RawPointer, () -> ()) BUILTIN_MISC_OPERATION(Once, "once", "", Special) /// unreachable has type @noreturn () -> () BUILTIN_MISC_OPERATION(Unreachable, "unreachable", "", Special) /// conditionallyUnreachable has type @noreturn () -> () BUILTIN_MISC_OPERATION(CondUnreachable, "conditionallyUnreachable", "", Special) /// DestroyArray has type (T.Type, Builtin.RawPointer, Builtin.Word) -> () BUILTIN_MISC_OPERATION(DestroyArray, "destroyArray", "", Special) /// CopyArray, TakeArrayFrontToBack, and TakeArrayBackToFront all have type /// (T.Type, Builtin.RawPointer, Builtin.RawPointer, Builtin.Word) -> () BUILTIN_MISC_OPERATION(CopyArray, "copyArray", "", Special) BUILTIN_MISC_OPERATION(TakeArrayFrontToBack, "takeArrayFrontToBack", "", Special) BUILTIN_MISC_OPERATION(TakeArrayBackToFront, "takeArrayBackToFront", "", Special) #undef BUILTIN_MISC_OPERATION // BUILTIN_TYPE_TRAIT_OPERATION - Compile-time type trait operations. #ifndef BUILTIN_TYPE_TRAIT_OPERATION #define BUILTIN_TYPE_TRAIT_OPERATION(Id, Name) \ BUILTIN(Id, #Name, "n") #endif /// canBeClass(T.Type) -> Builtin.Int8 /// At compile time, evaluate whether T is or can be bound to a class or /// @objc protocol type. The answer is a tri-state of 0 = No, 1 = Yes, 2 = /// Maybe. BUILTIN_TYPE_TRAIT_OPERATION(CanBeObjCClass, canBeClass) #undef BUILTIN_TYPE_TRAIT_OPERATION #undef BUILTIN