Merge master.kernel.org:/home/rmk/linux-2.6-serial
[linux-2.6] / arch / x86_64 / lib / thunk.S
1         /*
2          * Save registers before calling assembly functions. This avoids
3          * disturbance of register allocation in some inline assembly constructs.
4          * Copyright 2001,2002 by Andi Kleen, SuSE Labs.
5          * Subject to the GNU public license, v.2. No warranty of any kind.
6          * $Id: thunk.S,v 1.2 2002/03/13 20:06:58 ak Exp $
7          */
8
9         #include <linux/config.h>
10         #include <linux/linkage.h>
11         #include <asm/dwarf2.h>
12         #include <asm/calling.h>                        
13         #include <asm/rwlock.h>
14                 
15         /* rdi: arg1 ... normal C conventions. rax is saved/restored. */        
16         .macro thunk name,func
17         .globl \name
18 \name:  
19         CFI_STARTPROC
20         SAVE_ARGS
21         call \func
22         jmp  restore
23         CFI_ENDPROC
24         .endm
25
26         /* rdi: arg1 ... normal C conventions. rax is passed from C. */         
27         .macro thunk_retrax name,func
28         .globl \name
29 \name:  
30         CFI_STARTPROC
31         SAVE_ARGS
32         call \func
33         jmp  restore_norax
34         CFI_ENDPROC
35         .endm
36         
37
38         .section .sched.text
39 #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
40         thunk rwsem_down_read_failed_thunk,rwsem_down_read_failed
41         thunk rwsem_down_write_failed_thunk,rwsem_down_write_failed
42         thunk rwsem_wake_thunk,rwsem_wake
43         thunk rwsem_downgrade_thunk,rwsem_downgrade_wake
44 #endif  
45         
46         thunk __down_failed,__down
47         thunk_retrax __down_failed_interruptible,__down_interruptible
48         thunk_retrax __down_failed_trylock,__down_trylock
49         thunk __up_wakeup,__up
50
51 #ifdef CONFIG_TRACE_IRQFLAGS
52         thunk trace_hardirqs_on_thunk,trace_hardirqs_on
53         thunk trace_hardirqs_off_thunk,trace_hardirqs_off
54 #endif
55         
56         /* SAVE_ARGS below is used only for the .cfi directives it contains. */
57         CFI_STARTPROC
58         SAVE_ARGS
59 restore:
60         RESTORE_ARGS
61         ret     
62         CFI_ENDPROC
63         
64         CFI_STARTPROC
65         SAVE_ARGS
66 restore_norax:  
67         RESTORE_ARGS 1
68         ret
69         CFI_ENDPROC
70
71 #ifdef CONFIG_SMP
72 /* Support for read/write spinlocks. */
73         .text
74 /* rax: pointer to rwlock_t */  
75 ENTRY(__write_lock_failed)
76         lock
77         addl $RW_LOCK_BIAS,(%rax)
78 1:      rep
79         nop
80         cmpl $RW_LOCK_BIAS,(%rax)
81         jne 1b
82         lock 
83         subl $RW_LOCK_BIAS,(%rax)
84         jnz  __write_lock_failed
85         ret
86
87 /* rax: pointer to rwlock_t */  
88 ENTRY(__read_lock_failed)
89         lock
90         incl (%rax)
91 1:      rep
92         nop
93         cmpl $1,(%rax)
94         js 1b
95         lock
96         decl (%rax)
97         js __read_lock_failed
98         ret
99 #endif