]> Pileus Git - ~andy/linux/blob - arch/x86/lib/atomic64_cx8_32.S
Merge tag 'omap-dt-for-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[~andy/linux] / arch / x86 / lib / atomic64_cx8_32.S
1 /*
2  * atomic64_t for 586+
3  *
4  * Copyright © 2010  Luca Barbieri
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <linux/linkage.h>
13 #include <asm/alternative-asm.h>
14 #include <asm/dwarf2.h>
15
16 .macro SAVE reg
17         pushl_cfi %\reg
18         CFI_REL_OFFSET \reg, 0
19 .endm
20
21 .macro RESTORE reg
22         popl_cfi %\reg
23         CFI_RESTORE \reg
24 .endm
25
26 .macro read64 reg
27         movl %ebx, %eax
28         movl %ecx, %edx
29 /* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
30         LOCK_PREFIX
31         cmpxchg8b (\reg)
32 .endm
33
34 ENTRY(atomic64_read_cx8)
35         CFI_STARTPROC
36
37         read64 %ecx
38         ret
39         CFI_ENDPROC
40 ENDPROC(atomic64_read_cx8)
41
42 ENTRY(atomic64_set_cx8)
43         CFI_STARTPROC
44
45 1:
46 /* we don't need LOCK_PREFIX since aligned 64-bit writes
47  * are atomic on 586 and newer */
48         cmpxchg8b (%esi)
49         jne 1b
50
51         ret
52         CFI_ENDPROC
53 ENDPROC(atomic64_set_cx8)
54
55 ENTRY(atomic64_xchg_cx8)
56         CFI_STARTPROC
57
58 1:
59         LOCK_PREFIX
60         cmpxchg8b (%esi)
61         jne 1b
62
63         ret
64         CFI_ENDPROC
65 ENDPROC(atomic64_xchg_cx8)
66
67 .macro addsub_return func ins insc
68 ENTRY(atomic64_\func\()_return_cx8)
69         CFI_STARTPROC
70         SAVE ebp
71         SAVE ebx
72         SAVE esi
73         SAVE edi
74
75         movl %eax, %esi
76         movl %edx, %edi
77         movl %ecx, %ebp
78
79         read64 %ecx
80 1:
81         movl %eax, %ebx
82         movl %edx, %ecx
83         \ins\()l %esi, %ebx
84         \insc\()l %edi, %ecx
85         LOCK_PREFIX
86         cmpxchg8b (%ebp)
87         jne 1b
88
89 10:
90         movl %ebx, %eax
91         movl %ecx, %edx
92         RESTORE edi
93         RESTORE esi
94         RESTORE ebx
95         RESTORE ebp
96         ret
97         CFI_ENDPROC
98 ENDPROC(atomic64_\func\()_return_cx8)
99 .endm
100
101 addsub_return add add adc
102 addsub_return sub sub sbb
103
104 .macro incdec_return func ins insc
105 ENTRY(atomic64_\func\()_return_cx8)
106         CFI_STARTPROC
107         SAVE ebx
108
109         read64 %esi
110 1:
111         movl %eax, %ebx
112         movl %edx, %ecx
113         \ins\()l $1, %ebx
114         \insc\()l $0, %ecx
115         LOCK_PREFIX
116         cmpxchg8b (%esi)
117         jne 1b
118
119 10:
120         movl %ebx, %eax
121         movl %ecx, %edx
122         RESTORE ebx
123         ret
124         CFI_ENDPROC
125 ENDPROC(atomic64_\func\()_return_cx8)
126 .endm
127
128 incdec_return inc add adc
129 incdec_return dec sub sbb
130
131 ENTRY(atomic64_dec_if_positive_cx8)
132         CFI_STARTPROC
133         SAVE ebx
134
135         read64 %esi
136 1:
137         movl %eax, %ebx
138         movl %edx, %ecx
139         subl $1, %ebx
140         sbb $0, %ecx
141         js 2f
142         LOCK_PREFIX
143         cmpxchg8b (%esi)
144         jne 1b
145
146 2:
147         movl %ebx, %eax
148         movl %ecx, %edx
149         RESTORE ebx
150         ret
151         CFI_ENDPROC
152 ENDPROC(atomic64_dec_if_positive_cx8)
153
154 ENTRY(atomic64_add_unless_cx8)
155         CFI_STARTPROC
156         SAVE ebp
157         SAVE ebx
158 /* these just push these two parameters on the stack */
159         SAVE edi
160         SAVE ecx
161
162         movl %eax, %ebp
163         movl %edx, %edi
164
165         read64 %esi
166 1:
167         cmpl %eax, 0(%esp)
168         je 4f
169 2:
170         movl %eax, %ebx
171         movl %edx, %ecx
172         addl %ebp, %ebx
173         adcl %edi, %ecx
174         LOCK_PREFIX
175         cmpxchg8b (%esi)
176         jne 1b
177
178         movl $1, %eax
179 3:
180         addl $8, %esp
181         CFI_ADJUST_CFA_OFFSET -8
182         RESTORE ebx
183         RESTORE ebp
184         ret
185 4:
186         cmpl %edx, 4(%esp)
187         jne 2b
188         xorl %eax, %eax
189         jmp 3b
190         CFI_ENDPROC
191 ENDPROC(atomic64_add_unless_cx8)
192
193 ENTRY(atomic64_inc_not_zero_cx8)
194         CFI_STARTPROC
195         SAVE ebx
196
197         read64 %esi
198 1:
199         movl %eax, %ecx
200         orl %edx, %ecx
201         jz 3f
202         movl %eax, %ebx
203         xorl %ecx, %ecx
204         addl $1, %ebx
205         adcl %edx, %ecx
206         LOCK_PREFIX
207         cmpxchg8b (%esi)
208         jne 1b
209
210         movl $1, %eax
211 3:
212         RESTORE ebx
213         ret
214         CFI_ENDPROC
215 ENDPROC(atomic64_inc_not_zero_cx8)