summary refs log tree commit diff
path: root/doc/abi.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/abi.txt')
-rw-r--r--doc/abi.txt52
1 files changed, 52 insertions, 0 deletions
diff --git a/doc/abi.txt b/doc/abi.txt
new file mode 100644
index 0000000..0eaa7c7
--- /dev/null
+++ b/doc/abi.txt
@@ -0,0 +1,52 @@
+System V ABI for calls on x64
+=============================
+
+Data classes of interest as defined by the ABI:
+ - INTEGER
+ - SSE
+ - MEMORY
+
+Unions are treated like structures with the alignment
+of their most demanding member, and the size of their
+largest member.
+
+Classification:
+1. The size of each argument gets rounded up to eightbytes.
+   (It keeps the stack always 8 bytes aligned.)
+2. _Bool, char, short, int, long, long long and pointers
+   are in the INTEGER class.
+3. float and double are in the SSE class.
+4. If the size of an object is larger than two eightbytes
+   or if contains unaligned fields, it has class MEMORY.
+5. Otherwise, recursively classify fields and determine
+   the class of the two eightbytes using the classes of
+   their components.  If any of them is MEMORY the result
+   is MEMORY (but I don't think it can happen), if any is
+   INTEGER the result is INTEGER, otherwise the result
+   is SSE.
+
+Passing:
+ - Classify arguments in order.
+ - INTEGER arguments use in order %rdi %rsi %rdx %rcx
+   %r8 %r9.
+ - SSE arguments use in order %xmm0 - %xmm7.
+ - MEMORY gets passed on the stack.
+ - When we run out of registers for an aggregate, revert
+   the assignment for the first eightbytes and pass it
+   on the stack.
+ - When all registers are taken, write arguments on the
+   stack from right to left.
+ - When calling a variadic function, %al stores the number
+   of vector registers used to pass arguments (it must be
+   an upper bound and does not have to be exact).
+ - Registers %rbx, %r12 - %r15 are callee-save.
+
+Returning:
+ - Classify the return type.
+ - Use %rax and %rdx in order for INTEGER return values.
+ - Use %xmm0 and %xmm1 in order for SSE return values.
+ - I the return value's class is MEMORY, the first
+   argument of the function %rdi was a pointer to an
+   area big enough to fit the return value.  The function
+   writes the return value there and returns the address
+   (that was in %rdi) in %rax.