mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
466 lines
20 KiB
C++
466 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 - 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
|
||
|
||
/// 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)
|
||
|
||
/// MarkDependence has type (T, U) -> T
|
||
BUILTIN_SIL_OPERATION(MarkDependence, "markDependence", Special)
|
||
|
||
/// allocValueBuffer : <T> (inout Builtin.UnsafeValueBuffer, T.Type)
|
||
/// -> Builtin.RawPointer
|
||
BUILTIN_SIL_OPERATION(AllocValueBuffer, "allocValueBuffer", Special)
|
||
|
||
/// projectValueBuffer : <T> (inout Builtin.UnsafeValueBuffer, T.Type)
|
||
/// -> Builtin.RawPointer
|
||
BUILTIN_SIL_OPERATION(ProjectValueBuffer, "projectValueBuffer", Special)
|
||
|
||
/// deallocValueBuffer : <T> (inout Builtin.UnsafeValueBuffer, T.Type)
|
||
/// -> ()
|
||
BUILTIN_SIL_OPERATION(DeallocValueBuffer, "deallocValueBuffer", Special)
|
||
|
||
/// MakeMaterializeForSetCallback has type
|
||
/// ((Builtin.RawPointer,
|
||
/// inout Builtin.UnsafeValueBuffer,
|
||
/// inout T,
|
||
/// T.Type) -> ())
|
||
/// -> Builtin.RawPointer
|
||
///
|
||
/// The first argument is the address returned from materializeForSet.
|
||
/// The second argument is the same Builtin.UnsafeValueBuffer
|
||
/// that was passed to materializeForSet.
|
||
/// The third argument is self.
|
||
/// The last argument is the metatype for self.
|
||
BUILTIN_SIL_OPERATION(MakeMaterializeForSetCallback,
|
||
"makeMaterializeForSetCallback", 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)
|
||
|
||
/// 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 dymanic 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: ErrorType -> ()
|
||
BUILTIN_RUNTIME_CALL(WillThrow, "willThrow", "n")
|
||
|
||
/// unexpectedError: ErrorType -> ()
|
||
BUILTIN_RUNTIME_CALL(UnexpectedError, "unexpectedError", "n")
|
||
|
||
/// errorInMain: ErrorType -> ()
|
||
BUILTIN_RUNTIME_CALL(ErrorInMain, "errorInMain", "n")
|
||
|
||
#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)
|
||
|
||
/// 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)
|
||
|
||
/// 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)
|
||
|
||
#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
|