Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[sfrench/cifs-2.6.git] / 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 %\reg
18         CFI_ADJUST_CFA_OFFSET 4
19         CFI_REL_OFFSET \reg, 0
20 .endm
21
22 .macro RESTORE reg
23         popl %\reg
24         CFI_ADJUST_CFA_OFFSET -4
25         CFI_RESTORE \reg
26 .endm
27
28 .macro read64 reg
29         movl %ebx, %eax
30         movl %ecx, %edx
31 /* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
32         LOCK_PREFIX
33         cmpxchg8b (\reg)
34 .endm
35
36 ENTRY(atomic64_read_cx8)
37         CFI_STARTPROC
38
39         read64 %ecx
40         ret
41         CFI_ENDPROC
42 ENDPROC(atomic64_read_cx8)
43
44 ENTRY(atomic64_set_cx8)
45         CFI_STARTPROC
46
47 1:
48 /* we don't need LOCK_PREFIX since aligned 64-bit writes
49  * are atomic on 586 and newer */
50         cmpxchg8b (%esi)
51         jne 1b
52
53         ret
54         CFI_ENDPROC
55 ENDPROC(atomic64_set_cx8)
56
57 ENTRY(atomic64_xchg_cx8)
58         CFI_STARTPROC
59
60         movl %ebx, %eax
61         movl %ecx, %edx
62 1:
63         LOCK_PREFIX
64         cmpxchg8b (%esi)
65         jne 1b
66
67         ret
68         CFI_ENDPROC
69 ENDPROC(atomic64_xchg_cx8)
70
71 .macro addsub_return func ins insc
72 ENTRY(atomic64_\func\()_return_cx8)
73         CFI_STARTPROC
74         SAVE ebp
75         SAVE ebx
76         SAVE esi
77         SAVE edi
78
79         movl %eax, %esi
80         movl %edx, %edi
81         movl %ecx, %ebp
82
83         read64 %ebp
84 1:
85         movl %eax, %ebx
86         movl %edx, %ecx
87         \ins\()l %esi, %ebx
88         \insc\()l %edi, %ecx
89         LOCK_PREFIX
90         cmpxchg8b (%ebp)
91         jne 1b
92
93 10:
94         movl %ebx, %eax
95         movl %ecx, %edx
96         RESTORE edi
97         RESTORE esi
98         RESTORE ebx
99         RESTORE ebp
100         ret
101         CFI_ENDPROC
102 ENDPROC(atomic64_\func\()_return_cx8)
103 .endm
104
105 addsub_return add add adc
106 addsub_return sub sub sbb
107
108 .macro incdec_return func ins insc
109 ENTRY(atomic64_\func\()_return_cx8)
110         CFI_STARTPROC
111         SAVE ebx
112
113         read64 %esi
114 1:
115         movl %eax, %ebx
116         movl %edx, %ecx
117         \ins\()l $1, %ebx
118         \insc\()l $0, %ecx
119         LOCK_PREFIX
120         cmpxchg8b (%esi)
121         jne 1b
122
123 10:
124         movl %ebx, %eax
125         movl %ecx, %edx
126         RESTORE ebx
127         ret
128         CFI_ENDPROC
129 ENDPROC(atomic64_\func\()_return_cx8)
130 .endm
131
132 incdec_return inc add adc
133 incdec_return dec sub sbb
134
135 ENTRY(atomic64_dec_if_positive_cx8)
136         CFI_STARTPROC
137         SAVE ebx
138
139         read64 %esi
140 1:
141         movl %eax, %ebx
142         movl %edx, %ecx
143         subl $1, %ebx
144         sbb $0, %ecx
145         js 2f
146         LOCK_PREFIX
147         cmpxchg8b (%esi)
148         jne 1b
149
150 2:
151         movl %ebx, %eax
152         movl %ecx, %edx
153         RESTORE ebx
154         ret
155         CFI_ENDPROC
156 ENDPROC(atomic64_dec_if_positive_cx8)
157
158 ENTRY(atomic64_add_unless_cx8)
159         CFI_STARTPROC
160         SAVE ebp
161         SAVE ebx
162 /* these just push these two parameters on the stack */
163         SAVE edi
164         SAVE esi
165
166         movl %ecx, %ebp
167         movl %eax, %esi
168         movl %edx, %edi
169
170         read64 %ebp
171 1:
172         cmpl %eax, 0(%esp)
173         je 4f
174 2:
175         movl %eax, %ebx
176         movl %edx, %ecx
177         addl %esi, %ebx
178         adcl %edi, %ecx
179         LOCK_PREFIX
180         cmpxchg8b (%ebp)
181         jne 1b
182
183         movl $1, %eax
184 3:
185         addl $8, %esp
186         CFI_ADJUST_CFA_OFFSET -8
187         RESTORE ebx
188         RESTORE ebp
189         ret
190 4:
191         cmpl %edx, 4(%esp)
192         jne 2b
193         xorl %eax, %eax
194         jmp 3b
195         CFI_ENDPROC
196 ENDPROC(atomic64_add_unless_cx8)
197
198 ENTRY(atomic64_inc_not_zero_cx8)
199         CFI_STARTPROC
200         SAVE ebx
201
202         read64 %esi
203 1:
204         testl %eax, %eax
205         je 4f
206 2:
207         movl %eax, %ebx
208         movl %edx, %ecx
209         addl $1, %ebx
210         adcl $0, %ecx
211         LOCK_PREFIX
212         cmpxchg8b (%esi)
213         jne 1b
214
215         movl $1, %eax
216 3:
217         RESTORE ebx
218         ret
219 4:
220         testl %edx, %edx
221         jne 2b
222         jmp 3b
223         CFI_ENDPROC
224 ENDPROC(atomic64_inc_not_zero_cx8)