File: custom_rr_abi_utilities.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (110 lines) | stat: -rw-r--r-- 7,017 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#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)
}