mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
In embedded mode, some things call retain/release using the C++ declarations, but the implementations are in Swift. The Swift implementations don't use preservemost, so the C++ declarations must not declare preservemost in that context. rdar://163940783
103 lines
4.9 KiB
C++
103 lines
4.9 KiB
C++
//===--- CustomRRABI.h - Custom retain/release ABI support ----------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2022 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Utilities for creating register-specific retain/release entrypoints.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_RUNTIME_CUSTOMRRABI_H
|
|
#define SWIFT_RUNTIME_CUSTOMRRABI_H
|
|
|
|
namespace swift {
|
|
|
|
#if __arm64__ || defined(_M_ARM64)
|
|
|
|
// Invoke the macro X on the number of each register we support for a custom ABI
|
|
// entrypoint, along with a custom parameter. We don't support all 31 registers:
|
|
// - x0 is already covered by the standard entrypoints.
|
|
// - x16/x17 are scratch registers that can be used by procedure call glue.
|
|
// - x18 is reserved.
|
|
// - x29 is the frame pointer.
|
|
// - x30 is the link register and gets overwritten when making a call.
|
|
#define CUSTOM_RR_ENTRYPOINTS_FOREACH_REG(X, param) \
|
|
X(1, param) \
|
|
X(2, param) \
|
|
X(3, param) \
|
|
X(4, param) \
|
|
X(5, param) \
|
|
X(6, param) \
|
|
X(7, param) \
|
|
X(8, param) \
|
|
X(9, param) \
|
|
X(10, param) \
|
|
X(11, param) \
|
|
X(12, param) \
|
|
X(13, param) \
|
|
X(14, param) \
|
|
X(15, param) \
|
|
X(19, param) \
|
|
X(20, param) \
|
|
X(21, param) \
|
|
X(22, param) \
|
|
X(23, param) \
|
|
X(24, param) \
|
|
X(25, param) \
|
|
X(26, param) \
|
|
X(27, param) \
|
|
X(28, param)
|
|
|
|
// Helper template for deducing the parameter type of a one-parameter function.
|
|
template <typename Ret, typename Param>
|
|
Param returnTypeHelper(Ret (*)(Param)) {}
|
|
|
|
#if SWIFT_REFCOUNT_CC_PRESERVEMOST
|
|
template <typename Ret, typename Param>
|
|
Param returnTypeHelper(SWIFT_REFCOUNT_CC Ret (*)(Param)) {}
|
|
#endif
|
|
|
|
#if defined(__LP64__) || defined(_LP64)
|
|
#define REGISTER_SUBSTITUTION_PREFIX ""
|
|
#define REGISTER_PREFIX "x"
|
|
#else
|
|
#define REGISTER_SUBSTITUTION_PREFIX "w"
|
|
#define REGISTER_PREFIX "w"
|
|
#endif
|
|
|
|
// Helper macro that defines one entrypoint that takes the parameter in reg and
|
|
// calls through to function.
|
|
#define CUSTOM_RR_ENTRYPOINTS_DEFINE_ONE_ENTRYPOINT(reg, function) \
|
|
SWIFT_RUNTIME_EXPORT decltype(function(nullptr)) function##_x##reg() { \
|
|
decltype(returnTypeHelper(function)) ptr; \
|
|
asm(".ifnc %" REGISTER_SUBSTITUTION_PREFIX "0, " REGISTER_PREFIX #reg "\n" \
|
|
"mov %" REGISTER_SUBSTITUTION_PREFIX "0, " REGISTER_PREFIX #reg "\n" \
|
|
".endif" \
|
|
: "=r"(ptr)); \
|
|
return function(ptr); \
|
|
}
|
|
|
|
// A macro that defines all register-specific entrypoints for the given
|
|
// retain/release function.
|
|
#define CUSTOM_RR_ENTRYPOINTS_DEFINE_ENTRYPOINTS(function) \
|
|
CUSTOM_RR_ENTRYPOINTS_FOREACH_REG( \
|
|
CUSTOM_RR_ENTRYPOINTS_DEFINE_ONE_ENTRYPOINT, function)
|
|
|
|
#else
|
|
|
|
// No custom entrypoints on other architectures.
|
|
#define CUSTOM_RR_ENTRYPOINTS_DEFINE_ENTRYPOINTS(function)
|
|
|
|
#endif
|
|
|
|
} // namespace swift
|
|
|
|
#endif // SWIFT_RUNTIME_CUSTOMRRABI_H
|