Skip to content

Commit ba4024f

Browse files
authored
Merge pull request #38408 from al45tair/callconvs
[Docs] Added a calling convention summary document.
2 parents 69a8e24 + 2dab086 commit ba4024f

File tree

4 files changed

+217
-16
lines changed

4 files changed

+217
-16
lines changed

docs/ABI/CallConvSummary.rst

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
Calling Convention Summary
2+
==========================
3+
4+
Below is a summary of the calling conventions used on macOS and iOS.
5+
6+
The `ABI stability manifesto <../ABIStabilityManifesto.md>`_ gives more details
7+
on the use of the Swift error return and ``self`` registers, while `The Swift
8+
Calling Convention <CallingConvention.rst>`_ covers the specifics in more
9+
details. (The Swift ``self`` register is known in other documents as the
10+
"Context register".)
11+
12+
x86-64
13+
------
14+
15+
See `Apple x86-64 Documentation`_, `System V ABI AMD64 Processor Supplement`_.
16+
17+
.. _Apple x86-64 Documentation: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html
18+
.. _System V ABI AMD64 Processor Supplement: https://www.uclibc.org/docs/psABI-x86_64.pdf
19+
20+
Register usage
21+
^^^^^^^^^^^^^^
22+
23+
+-----------+----------------------------------+----------+----------+----------+
24+
| Register | Purpose | C++ | ObjC | Swift |
25+
+===========+==================================+==========+==========+==========+
26+
| ``rax`` | Return value; also, for varargs, | | | |
27+
| | number of ``xmm`` registers used | | | |
28+
+-----------+----------------------------------+----------+----------+----------+
29+
| ``rbx`` | Callee-saved register | | | |
30+
+-----------+----------------------------------+----------+----------+----------+
31+
| ``rdi`` | Integer argument 1 | ``this`` | ``self`` | |
32+
+-----------+----------------------------------+----------+----------+----------+
33+
| ``rsi`` | Integer argument 2 | | ``_cmd`` | |
34+
+-----------+----------------------------------+----------+----------+----------+
35+
| ``rdx`` | Integer argument 3 | | | |
36+
| | (2nd return value) | | | |
37+
+-----------+----------------------------------+----------+----------+----------+
38+
| ``rcx`` | Integer argument 4 | | | |
39+
| | (3rd return value) | | | |
40+
+-----------+----------------------------------+----------+----------+----------+
41+
| ``r8`` | Integer argument 5 | | | |
42+
| | (4th return value) | | | |
43+
+-----------+----------------------------------+----------+----------+----------+
44+
| ``r9`` | Integer argument 6 | | | |
45+
+-----------+----------------------------------+----------+----------+----------+
46+
| ``r12`` | Callee-saved register | | | Error |
47+
| | | | | return |
48+
+-----------+----------------------------------+----------+----------+----------+
49+
| ``r13`` | Callee-saved register | | | ``self`` |
50+
+-----------+----------------------------------+----------+----------+----------+
51+
| ``r14`` | Callee-saved register | | | |
52+
+-----------+----------------------------------+----------+----------+----------+
53+
| ``r15`` | Callee-saved register | | | |
54+
| | (other platforms use as GOT ptr) | | | |
55+
+-----------+----------------------------------+----------+----------+----------+
56+
| ``st0`` | Used to return ``long double`` | | | |
57+
| | values | | | |
58+
+-----------+----------------------------------+----------+----------+----------+
59+
| ``st1`` | Used to return ``long double`` | | | |
60+
| | values | | | |
61+
+-----------+----------------------------------+----------+----------+----------+
62+
| ``xmm0``- | Floating point arguments 1-8 | | | |
63+
| ``xmm7`` | (``xmm0``-``xmm3`` also used | | | |
64+
| | for return) | | | |
65+
+-----------+----------------------------------+----------+----------+----------+
66+
| ``rsp`` | Stack pointer | | | |
67+
+-----------+----------------------------------+----------+----------+----------+
68+
| ``rbp`` | Callee-saved register, | | | |
69+
| | used as frame pointer | | | |
70+
+-----------+----------------------------------+----------+----------+----------+
71+
72+
Stack frame
73+
^^^^^^^^^^^
74+
75+
On function entry, ``rsp+8`` is **16-byte aligned**, i.e. the start of the memory
76+
arguments is 16-byte aligned; the initial stack pointer is shown below as "entry
77+
``rsp``", but a typical non-leaf function will start by doing::
78+
79+
push %rbp
80+
mov %rsp, %rbp
81+
sub <local-size>, %rsp
82+
83+
Frameless leaf functions, however, will often not set up the frame pointer,
84+
``rbp``, in which case they may refer to arguments relative to ``rsp`` instead.
85+
86+
+---------------+---------------+------------------------+
87+
| | ``rbp+8n+16`` | memory argument *n* |
88+
| | | |
89+
| | ... | ... |
90+
| | | |
91+
| | ``rbp+16`` | memory argument 0 |
92+
+---------------+-----------+---+------------------------+
93+
| ↓ Current Frame | ↑ Previous Frame |
94+
+---------------+-----------+---+------------------------+
95+
| | ``rbp+8`` | return address |
96+
| | | |
97+
+---------------+---------------+------------------------+
98+
| entry ``rsp`` | ``rbp`` | previous ``rbp`` value |
99+
+---------------+---------------+------------------------+
100+
| | ``rbp-8`` | |
101+
| | | |
102+
| | ... | local storage |
103+
| | | |
104+
| | ``rsp`` | |
105+
+---------------+---------------+------------------------+
106+
| | ``rsp-8`` | |
107+
| | | |
108+
| | ... | red zone |
109+
| | | |
110+
| | ``rsp-128`` | |
111+
+---------------+---------------+------------------------+
112+
113+
114+
ARM64
115+
-----
116+
117+
See `Apple ARM64 Documentation`_, `Procedure Call Standard for the Arm 64-bit Architecture`_.
118+
119+
.. _Apple ARM64 Documentation: https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
120+
.. _Procedure Call Standard for the Arm 64-bit Architecture: https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
121+
122+
Register usage
123+
^^^^^^^^^^^^^^
124+
125+
+----------+---------+-------------------------+----------+----------+----------+
126+
| Register | Special | Purpose | C++ | ObjC | Swift |
127+
+==========+=========+=========================+==========+==========+==========+
128+
| ``x0`` | | Integer argument 1 | ``this`` | ``self`` | |
129+
| | | (1st return value) | | | |
130+
+----------+---------+-------------------------+----------+----------+----------+
131+
| ``x1`` | | Integer argument 2 | | ``_cmd`` | |
132+
| | | (2nd return value) | | | |
133+
+----------+---------+-------------------------+----------+----------+----------+
134+
| ``x2``- | | Integer arguments 3-8 | | | |
135+
| ``x7`` | | (3rd-8th return values) | | | |
136+
+----------+---------+-------------------------+----------+----------+----------+
137+
| ``x8`` | | Indirect result | | | |
138+
| | | location register | | | |
139+
+----------+---------+-------------------------+----------+----------+----------+
140+
| ``x16`` | ``ip0`` | Scratch registers (used | | | |
141+
+----------+---------+ by dyld, can be used | | | |
142+
| ``x17`` | ``ip1`` | freely otherwise) | | | |
143+
+----------+---------+-------------------------+----------+----------+----------+
144+
| ``x18`` | | RESERVED **DO NOT USE** | | | |
145+
+----------+---------+-------------------------+----------+----------+----------+
146+
| ``x19`` | | Callee-saved register | | | |
147+
+----------+---------+-------------------------+----------+----------+----------+
148+
| ``x20`` | | Callee-saved register | | | ``self`` |
149+
+----------+---------+-------------------------+----------+----------+----------+
150+
| ``x21`` | | Callee-saved register | | | Error |
151+
| | | | | | return |
152+
+----------+---------+-------------------------+----------+----------+----------+
153+
| ``x22``- | | Callee-saved registers | | | |
154+
| ``x28`` | | | | | |
155+
+----------+---------+-------------------------+----------+----------+----------+
156+
| ``x29`` | ``fp`` | Frame pointer | | | |
157+
+----------+---------+-------------------------+----------+----------+----------+
158+
| ``x30`` | ``lr`` | Link register | | | |
159+
+----------+---------+-------------------------+----------+----------+----------+
160+
| ``sp`` | | Stack pointer | | | |
161+
+----------+---------+-------------------------+----------+----------+----------+
162+
| ``v0``- | | Floating point/SIMD | | | |
163+
| ``v7`` | | arguments 1-8 | | | |
164+
| | | (also for return) | | | |
165+
+----------+---------+-------------------------+----------+----------+----------+
166+
| ``v8``- | | Callee-saved registers | | | |
167+
| ``v15`` | | (**lower 64-bits only**)| | | |
168+
+----------+---------+-------------------------+----------+----------+----------+
169+
170+
Stack frame
171+
^^^^^^^^^^^
172+
173+
The stack pointer is **16-byte aligned**; on function entry, ``sp`` points at
174+
the location shown by "entry ``sp``" below. As with x86, frameless leaf
175+
functions may not set up ``fp``, in which case they will use ``sp`` relative
176+
accesses.
177+
178+
+--------------+---------------+------------------------+
179+
| | ``fp+8n+16`` | last memory argument |
180+
| | | |
181+
| | ... | ... |
182+
| | | |
183+
| | ``fp+16`` | memory argument 0 [1]_ |
184+
+--------------+------------+--+------------------------+
185+
| ↓ Current Frame | ↑ Previous Frame |
186+
+--------------+------------+--+------------------------+
187+
| entry ``sp`` | ``fp+8`` | saved ``lr`` |
188+
| | | (return address) |
189+
+--------------+---------------+------------------------+
190+
| | ``fp`` | previous ``fp`` value |
191+
+--------------+---------------+------------------------+
192+
| | ``fp-8`` | |
193+
| | | |
194+
| | ... | local storage |
195+
| | | |
196+
| | ``sp`` | |
197+
+--------------+---------------+------------------------+
198+
| | ``sp-8`` | |
199+
| | | |
200+
| | ... | red zone |
201+
| | | |
202+
| | ``sp-128`` | |
203+
+--------------+---------------+------------------------+
204+
205+
.. [1] See Apple documentation, however. Unlike the official ARM64 ABI, we pack
206+
arguments, so this might also hold argument 1, argument 2 and so on.

docs/ABI/RegisterUsage.md

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
## 64-Bit Architecture Register Usage
22

3-
From Swift 5, the calling convention register allocation for 64-bit architectures is largely based on [existing](https://developer.apple.com/library/content/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html) [standards](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html), with the addition of the context and error return registers discussed in the [ABI stability manifesto](https://github.com/apple/swift/blob/main/docs/ABIStabilityManifesto.md):
4-
5-
| Register Purpose | ARM64 | x86_64 |
6-
| ------------- |:-------------:| ----- |
7-
| Context register (self) | x20 | r13 |
8-
| Error return register | x21 | r12 |
9-
| Struct return pointer | x8 | rax |
10-
| Float call arguments | v0 … v7 | xmm0 … xmm7 |
11-
| Integer call arguments | x0 … x7 | rdi, rsi, rdx, rcx, r8, r9 |
12-
| Float return | v0 … v3 | xmm0 … xmm3 |
13-
| Integer return | x0 … x3 | rax, rdx, rcx, r8 |
3+
This file has been replaced by [CallConvSummary.rst](CallConvSummary.rst),
4+
which gives information about register usage and also shows the stack frame
5+
layouts for the 64-bit architectures.

docs/ABIStabilityManifesto.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ Having the call context register be callee-saved is advantageous. It keeps the r
337337

338338
Throwing functions communicate error values to their callers through the *error* register on some platforms. The error register holds a pointer to the error value if an error occurred, otherwise 0. The caller of a throwing function is expected to quickly check for 0 before continuing on with non-error code, otherwise branching to code to handle or propagate the error. Using a callee-saved register for the error register enables free conversion from non-throwing to throwing functions, which is required to honor the subtyping relationship.
339339

340-
The specific registers used in these roles are documented in [another document on register usage](https://github.com/apple/swift/blob/main/docs/ABI/RegisterUsage.md).
340+
The specific registers used in these roles are documented in [the calling convention summary document](ABI/CallConvSummary.rst).
341341

342342
### <a name="function-signature-lowering"></a>Function Signature Lowering
343343

docs/README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,15 @@ documentation, please create a thread on the Swift forums under the
177177
<!-- NOTE: Outdated -->
178178
- [Lexicon.md](/docs/Lexicon.md):
179179
Canonical reference for terminology used throughout the project.
180-
180+
181181
### ABI
182182

183+
- [CallConvSummary.rst](/docs/ABI/CallConvSummary.rst):
184+
A concise summary of the calling conventions used for C/C++, Objective-C
185+
and Swift on Apple platforms. Contains references to source documents,
186+
where further detail is required.
187+
- [CallingConvention.rst](/docs/ABI/CallingConvention.rst):
188+
Describes in detail the Swift calling convention.
183189
- [GenericSignature.md](/docs/ABI/GenericSignature.md):
184190
Describes what generic signatures are and how they are used in the ABI,
185191
including the algorithms for minimization and canonicalization.
@@ -191,9 +197,6 @@ documentation, please create a thread on the Swift forums under the
191197
- [Mangling.rst](/docs/ABI/Mangling.rst):
192198
Describes the stable mangling scheme, which produces unique symbols for
193199
ABI-public declarations.
194-
- [RegisterUsage.md](/docs/ABI/RegisterUsage.md):
195-
Summarizes the register allocation for ARM64 and x86_64 calling conventions,
196-
including the context register (self) and error return register.
197200
- [TypeLayout.rst](/docs/ABI/TypeLayout.rst):
198201
Describes the algorithms/strategies for fragile struct and tuple layout;
199202
class layout; fragile enum layout; and existential container layout.

0 commit comments

Comments
 (0)