Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / x86 / lib / rwsem_64.S
1 /*
2  * x86-64 rwsem wrappers
3  *
4  * This interfaces the inline asm code to the slow-path
5  * C routines. We need to save the call-clobbered regs
6  * that the asm does not mark as clobbered, and move the
7  * argument from %rax to %rdi.
8  *
9  * NOTE! We don't need to save %rax, because the functions
10  * will always return the semaphore pointer in %rax (which
11  * is also the input argument to these helpers)
12  *
13  * The following can clobber %rdx because the asm clobbers it:
14  *   call_rwsem_down_write_failed
15  *   call_rwsem_wake
16  * but %rdi, %rsi, %rcx, %r8-r11 always need saving.
17  */
18
19 #include <linux/linkage.h>
20 #include <asm/rwlock.h>
21 #include <asm/alternative-asm.h>
22 #include <asm/frame.h>
23 #include <asm/dwarf2.h>
24
25 #define save_common_regs \
26         pushq %rdi; \
27         pushq %rsi; \
28         pushq %rcx; \
29         pushq %r8; \
30         pushq %r9; \
31         pushq %r10; \
32         pushq %r11
33
34 #define restore_common_regs \
35         popq %r11; \
36         popq %r10; \
37         popq %r9; \
38         popq %r8; \
39         popq %rcx; \
40         popq %rsi; \
41         popq %rdi
42
43 /* Fix up special calling conventions */
44 ENTRY(call_rwsem_down_read_failed)
45         save_common_regs
46         pushq %rdx
47         movq %rax,%rdi
48         call rwsem_down_read_failed
49         popq %rdx
50         restore_common_regs
51         ret
52         ENDPROC(call_rwsem_down_read_failed)
53
54 ENTRY(call_rwsem_down_write_failed)
55         save_common_regs
56         movq %rax,%rdi
57         call rwsem_down_write_failed
58         restore_common_regs
59         ret
60         ENDPROC(call_rwsem_down_write_failed)
61
62 ENTRY(call_rwsem_wake)
63         decl %edx       /* do nothing if still outstanding active readers */
64         jnz 1f
65         save_common_regs
66         movq %rax,%rdi
67         call rwsem_wake
68         restore_common_regs
69 1:      ret
70         ENDPROC(call_rwsem_wake)
71
72 /* Fix up special calling conventions */
73 ENTRY(call_rwsem_downgrade_wake)
74         save_common_regs
75         pushq %rdx
76         movq %rax,%rdi
77         call rwsem_downgrade_wake
78         popq %rdx
79         restore_common_regs
80         ret
81         ENDPROC(call_rwsem_downgrade_wake)