diff options
Diffstat (limited to 'arch/x86/include/asm/calling.h')
| -rw-r--r-- | arch/x86/include/asm/calling.h | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 2bc162e0ec6e..0e63c9a2a8d0 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h | |||
| @@ -1,5 +1,55 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Some macros to handle stack frames in assembly. | 2 | |
| 3 | x86 function call convention, 64-bit: | ||
| 4 | ------------------------------------- | ||
| 5 | arguments | callee-saved | extra caller-saved | return | ||
| 6 | [callee-clobbered] | | [callee-clobbered] | | ||
| 7 | --------------------------------------------------------------------------- | ||
| 8 | rdi rsi rdx rcx r8-9 | rbx rbp [*] r12-15 | r10-11 | rax, rdx [**] | ||
| 9 | |||
| 10 | ( rsp is obviously invariant across normal function calls. (gcc can 'merge' | ||
| 11 | functions when it sees tail-call optimization possibilities) rflags is | ||
| 12 | clobbered. Leftover arguments are passed over the stack frame.) | ||
| 13 | |||
| 14 | [*] In the frame-pointers case rbp is fixed to the stack frame. | ||
| 15 | |||
| 16 | [**] for struct return values wider than 64 bits the return convention is a | ||
| 17 | bit more complex: up to 128 bits width we return small structures | ||
| 18 | straight in rax, rdx. For structures larger than that (3 words or | ||
| 19 | larger) the caller puts a pointer to an on-stack return struct | ||
| 20 | [allocated in the caller's stack frame] into the first argument - i.e. | ||
| 21 | into rdi. All other arguments shift up by one in this case. | ||
| 22 | Fortunately this case is rare in the kernel. | ||
| 23 | |||
| 24 | For 32-bit we have the following conventions - kernel is built with | ||
| 25 | -mregparm=3 and -freg-struct-return: | ||
| 26 | |||
| 27 | x86 function calling convention, 32-bit: | ||
| 28 | ---------------------------------------- | ||
| 29 | arguments | callee-saved | extra caller-saved | return | ||
| 30 | [callee-clobbered] | | [callee-clobbered] | | ||
| 31 | ------------------------------------------------------------------------- | ||
| 32 | eax edx ecx | ebx edi esi ebp [*] | <none> | eax, edx [**] | ||
| 33 | |||
| 34 | ( here too esp is obviously invariant across normal function calls. eflags | ||
| 35 | is clobbered. Leftover arguments are passed over the stack frame. ) | ||
| 36 | |||
| 37 | [*] In the frame-pointers case ebp is fixed to the stack frame. | ||
| 38 | |||
| 39 | [**] We build with -freg-struct-return, which on 32-bit means similar | ||
| 40 | semantics as on 64-bit: edx can be used for a second return value | ||
| 41 | (i.e. covering integer and structure sizes up to 64 bits) - after that | ||
| 42 | it gets more complex and more expensive: 3-word or larger struct returns | ||
| 43 | get done in the caller's frame and the pointer to the return struct goes | ||
| 44 | into regparm0, i.e. eax - the other arguments shift up and the | ||
| 45 | function's register parameters degenerate to regparm=2 in essence. | ||
| 46 | |||
| 47 | */ | ||
| 48 | |||
| 49 | |||
| 50 | /* | ||
| 51 | * 64-bit system call stack frame layout defines and helpers, | ||
| 52 | * for assembly code: | ||
| 3 | */ | 53 | */ |
| 4 | 54 | ||
| 5 | #define R15 0 | 55 | #define R15 0 |
| @@ -9,7 +59,7 @@ | |||
| 9 | #define RBP 32 | 59 | #define RBP 32 |
| 10 | #define RBX 40 | 60 | #define RBX 40 |
| 11 | 61 | ||
| 12 | /* arguments: interrupts/non tracing syscalls only save upto here*/ | 62 | /* arguments: interrupts/non tracing syscalls only save up to here: */ |
| 13 | #define R11 48 | 63 | #define R11 48 |
| 14 | #define R10 56 | 64 | #define R10 56 |
| 15 | #define R9 64 | 65 | #define R9 64 |
| @@ -22,7 +72,7 @@ | |||
| 22 | #define ORIG_RAX 120 /* + error_code */ | 72 | #define ORIG_RAX 120 /* + error_code */ |
| 23 | /* end of arguments */ | 73 | /* end of arguments */ |
| 24 | 74 | ||
| 25 | /* cpu exception frame or undefined in case of fast syscall. */ | 75 | /* cpu exception frame or undefined in case of fast syscall: */ |
| 26 | #define RIP 128 | 76 | #define RIP 128 |
| 27 | #define CS 136 | 77 | #define CS 136 |
| 28 | #define EFLAGS 144 | 78 | #define EFLAGS 144 |
