mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
It is a hint to the optimizer that the code, where this builtin is called, is on the fast path. Specifically, the inliner takes it into account and increases the assumed benefit for code where the builtin is located. Compared to the fastPath/slowPath builtins, this builtin can be placed into plain linear code and doesn't need to be used in conditions. Compared to the @inline(__always) attribute, this builtin has also an effect on the caller function. Let's assume foo() calls bar() contains onFastPath and both foo and bar are small functions. Then if bar gets inlined into foo, the builtin also increases the chances that foo gets inlined. This would not be the case if @inline(__always) is used just for bar.
463 lines
20 KiB
C++
463 lines
20 KiB
C++
//===--- 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<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
|
|
|
|
/// 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 : <T> (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 : <T> (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 : <T> (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)
|
|
|
|
/// onFastPath has type () -> ().
|
|
BUILTIN_MISC_OPERATION(OnFastPath, "onFastPath", "n", 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<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)
|
|
|
|
/// 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> () -> 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)
|
|
|
|
// unsafeGuaranteed has type <T: AnyObject> T -> (T, Builtin.Int8)
|
|
BUILTIN_MISC_OPERATION(UnsafeGuaranteed, "unsafeGuaranteed", "", Special)
|
|
|
|
// unsafeGuaranteedEnd has type (Builtin.Int8) -> ()
|
|
BUILTIN_MISC_OPERATION(UnsafeGuaranteedEnd, "unsafeGuaranteedEnd", "", 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
|