diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-03-01 11:15:39 -0500 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-03-01 11:15:39 -0500 |
commit | 7e1b7fccd8a6ff99f5b2e427f550f5f7e5b51e84 (patch) | |
tree | c67a30cc0fcabd1ce8a7ec292c77114210358570 /doc | |
parent | d419274b04defd483edf1ea178a1d975f3b9f6f2 (diff) | |
download | roux-7e1b7fccd8a6ff99f5b2e427f550f5f7e5b51e84.tar.gz |
more abi docs
Diffstat (limited to 'doc')
-rw-r--r-- | doc/abi.txt | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/doc/abi.txt b/doc/abi.txt index 4158f5e..976c827 100644 --- a/doc/abi.txt +++ b/doc/abi.txt @@ -11,8 +11,7 @@ the IR description document for more information about them. -- ABI Subset Implemented ------------------------------ +:|: ABI Subset Implemented Data classes of interest as defined by the ABI: - INTEGER @@ -44,7 +43,10 @@ Passing: - INTEGER arguments use in order %rdi %rsi %rdx %rcx %r8 %r9. - SSE arguments use in order %xmm0 - %xmm7. - - MEMORY gets passed on the stack. + - MEMORY gets passed on the stack. They are "pushed" + in the right-to-left order, so from the callee's + point of view, the left-most argument appears first + 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. @@ -67,6 +69,66 @@ Returning: (that was in %rdi) in %rax. -- Various Remarks ------------------------------ +:|: Alignment on the Stack + +The ABI is unclear on the alignment requirement of the +stack. What must be ensured is that, right before +executing a 'call' instruction, the stack pointer %rsp +is aligned on 16 bytes. On entry of the called +function, the stack pointer is 8 modulo 16. Since most +functions will have a prelude pushing %rbp, the frame +pointer, upon entry of the body code of the function is +also aligned on 16 bytes (== 0 mod 16). + +Here is a diagram of the stack layout after a call from +g() to f(). + + | | + | g() locals | + +-------------+ + ^ | | \ + | | stack arg 2 | ' + | |xxxxxxxxxxxxx| | f()'s MEMORY + growing | +-------------+ | arguments + addresses | | stack arg 1 | , + | |xxxxxxxxxxxxx| / + | +-------------+ -> 0 mod 16 + | | ret addr | + +-------------+ -> f()'s %rbp + | saved %rbp | + +-------------+ -> 0 mod 16 + | f() locals | + | ... | + -> %rsp + +Legend: + - xxxxx Optional padding. + + +:|: Remarks + + - A struct can be returned in registers in one of three + ways. Either %rax, %rdx are used, or %xmm0, %xmm1, + or finally %rax, %xmm0. This should be clear from + the "Returning" section above. + + - The size of the arguments area of the stack needs to + be computed first, then arguments are packed starting + from the bottom of the argument area, respecting + alignment constraints. The ABI mentions "pushing" + arguments in right-to-left order, but I think it's a + mistaken view because of the alignment constraints. + + Example: If three 8 bytes MEMORY arguments are passed + to the callee and the caller's stack pointer is 16 bytes + algined, the layout will be like this. + + +-------------+ + |xxxxxxxxxxxxx| padding + | stack arg 3 | + | stack arg 2 | + | stack arg 1 | + +-------------+ -> 0 mod 16 + The padding must not be at the end of the stack area. + A "pushing" logic would put it at the end. |