mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
CI has updated macOS and we should no longer have the issue of dyld stubs using our nonstandard argument registers. rdar://102912772
111 lines
6.9 KiB
C
111 lines
6.9 KiB
C
#define NUM_REGS 30
|
|
|
|
// Apply `macro` to "all" registers. Skip x18 since it's reserved, and x30 since
|
|
// it's the link register.
|
|
#define ALL_REGS(macro) \
|
|
macro( 0) \
|
|
macro( 1) \
|
|
macro( 2) \
|
|
macro( 3) \
|
|
macro( 4) \
|
|
macro( 5) \
|
|
macro( 6) \
|
|
macro( 7) \
|
|
macro( 8) \
|
|
macro( 9) \
|
|
macro(10) \
|
|
macro(11) \
|
|
macro(12) \
|
|
macro(13) \
|
|
macro(14) \
|
|
macro(15) \
|
|
macro(16) \
|
|
macro(17) \
|
|
macro(19) \
|
|
macro(20) \
|
|
macro(21) \
|
|
macro(22) \
|
|
macro(23) \
|
|
macro(24) \
|
|
macro(25) \
|
|
macro(26) \
|
|
macro(27) \
|
|
macro(28)
|
|
|
|
// Apply `macro` with the given parameters to all registers that have
|
|
// specialized entrypoints. That's the same as ALL_REGS, minus x0 (the standard
|
|
// entrypoint covers that), x16/x17 (temporary registers used as linker glue),
|
|
// and x29 (the link register).
|
|
#define FUNCTION_REGS(macro, ...) \
|
|
macro( 1, __VA_ARGS__) \
|
|
macro( 2, __VA_ARGS__) \
|
|
macro( 3, __VA_ARGS__) \
|
|
macro( 4, __VA_ARGS__) \
|
|
macro( 5, __VA_ARGS__) \
|
|
macro( 6, __VA_ARGS__) \
|
|
macro( 7, __VA_ARGS__) \
|
|
macro( 8, __VA_ARGS__) \
|
|
macro( 9, __VA_ARGS__) \
|
|
macro(10, __VA_ARGS__) \
|
|
macro(11, __VA_ARGS__) \
|
|
macro(12, __VA_ARGS__) \
|
|
macro(13, __VA_ARGS__) \
|
|
macro(14, __VA_ARGS__) \
|
|
macro(15, __VA_ARGS__) \
|
|
macro(19, __VA_ARGS__) \
|
|
macro(20, __VA_ARGS__) \
|
|
macro(21, __VA_ARGS__) \
|
|
macro(22, __VA_ARGS__) \
|
|
macro(23, __VA_ARGS__) \
|
|
macro(24, __VA_ARGS__) \
|
|
macro(25, __VA_ARGS__) \
|
|
macro(26, __VA_ARGS__) \
|
|
macro(27, __VA_ARGS__) \
|
|
macro(28, __VA_ARGS__)
|
|
|
|
// Apply `macro` to each function that gets specialized entrypoints. Also pass
|
|
// 1 if the function is a retain variant, and 0 if it's a release variant.
|
|
#define ALL_FUNCTIONS(macro) \
|
|
macro(swift_retain, 1) \
|
|
macro(swift_release, 0) \
|
|
macro(swift_bridgeObjectRetain, 1) \
|
|
macro(swift_bridgeObjectRelease, 0)
|
|
|
|
// Emit declarations for variables called xN stored in xN, initialized with
|
|
// regs[N].
|
|
#define PASS_REGS_HELPER(num) \
|
|
register void *x ## num asm ("x" #num) = regs[num];
|
|
#define PASS_REGS ALL_REGS(PASS_REGS_HELPER)
|
|
|
|
// Emit an entry in an asm inputs list containing "r" (xN).
|
|
#define REG_INPUTS_HELPER(num) \
|
|
"r" (x ## num),
|
|
#define REG_INPUTS ALL_REGS(REG_INPUTS_HELPER)
|
|
|
|
// Make a function called call_function_xN that calls function_xN with registers
|
|
// set to the contents of the given registers array.
|
|
#define MAKE_CALL_FUNC(reg, func) \
|
|
static inline void call_##func##_x##reg(void **regs) { \
|
|
PASS_REGS \
|
|
asm("bl _" #func "_x" #reg : : REG_INPUTS "i"(0)); \
|
|
}
|
|
|
|
// Make a call_function_xN for each specialized function and register.
|
|
#define MAKE_ALL_CALL_FUNCS(function, isRetain) \
|
|
FUNCTION_REGS(MAKE_CALL_FUNC, function)
|
|
ALL_FUNCTIONS(MAKE_ALL_CALL_FUNCS)
|
|
|
|
// Call `call` with each call_function_xN function created above, as well as the
|
|
// base function name, the register it operates on, and whether it's a retain
|
|
// function.
|
|
static inline void foreachRRFunction(void (*call)(void (*)(void **regs),
|
|
const char *name, int reg,
|
|
int isRetain)) {
|
|
#define CALL_ONE_FUNCTION(reg, function, isRetain) \
|
|
call(call_##function##_x##reg, #function, reg, isRetain);
|
|
#define CALL_WITH_FUNCTIONS(function, isRetain) \
|
|
FUNCTION_REGS(CALL_ONE_FUNCTION, function, isRetain)
|
|
|
|
ALL_FUNCTIONS(CALL_WITH_FUNCTIONS)
|
|
}
|