Merge branch 'drm-next-4.6' of git://people.freedesktop.org/~agd5f/linux into drm...
[deliverable/linux.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
15 .macro read64 reg
16 movl %ebx, %eax
17 movl %ecx, %edx
18 /* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
19 LOCK_PREFIX
20 cmpxchg8b (\reg)
21 .endm
22
23 ENTRY(atomic64_read_cx8)
24 read64 %ecx
25 ret
26 ENDPROC(atomic64_read_cx8)
27
28 ENTRY(atomic64_set_cx8)
29 1:
30 /* we don't need LOCK_PREFIX since aligned 64-bit writes
31 * are atomic on 586 and newer */
32 cmpxchg8b (%esi)
33 jne 1b
34
35 ret
36 ENDPROC(atomic64_set_cx8)
37
38 ENTRY(atomic64_xchg_cx8)
39 1:
40 LOCK_PREFIX
41 cmpxchg8b (%esi)
42 jne 1b
43
44 ret
45 ENDPROC(atomic64_xchg_cx8)
46
47 .macro addsub_return func ins insc
48 ENTRY(atomic64_\func\()_return_cx8)
49 pushl %ebp
50 pushl %ebx
51 pushl %esi
52 pushl %edi
53
54 movl %eax, %esi
55 movl %edx, %edi
56 movl %ecx, %ebp
57
58 read64 %ecx
59 1:
60 movl %eax, %ebx
61 movl %edx, %ecx
62 \ins\()l %esi, %ebx
63 \insc\()l %edi, %ecx
64 LOCK_PREFIX
65 cmpxchg8b (%ebp)
66 jne 1b
67
68 10:
69 movl %ebx, %eax
70 movl %ecx, %edx
71 popl %edi
72 popl %esi
73 popl %ebx
74 popl %ebp
75 ret
76 ENDPROC(atomic64_\func\()_return_cx8)
77 .endm
78
79 addsub_return add add adc
80 addsub_return sub sub sbb
81
82 .macro incdec_return func ins insc
83 ENTRY(atomic64_\func\()_return_cx8)
84 pushl %ebx
85
86 read64 %esi
87 1:
88 movl %eax, %ebx
89 movl %edx, %ecx
90 \ins\()l $1, %ebx
91 \insc\()l $0, %ecx
92 LOCK_PREFIX
93 cmpxchg8b (%esi)
94 jne 1b
95
96 10:
97 movl %ebx, %eax
98 movl %ecx, %edx
99 popl %ebx
100 ret
101 ENDPROC(atomic64_\func\()_return_cx8)
102 .endm
103
104 incdec_return inc add adc
105 incdec_return dec sub sbb
106
107 ENTRY(atomic64_dec_if_positive_cx8)
108 pushl %ebx
109
110 read64 %esi
111 1:
112 movl %eax, %ebx
113 movl %edx, %ecx
114 subl $1, %ebx
115 sbb $0, %ecx
116 js 2f
117 LOCK_PREFIX
118 cmpxchg8b (%esi)
119 jne 1b
120
121 2:
122 movl %ebx, %eax
123 movl %ecx, %edx
124 popl %ebx
125 ret
126 ENDPROC(atomic64_dec_if_positive_cx8)
127
128 ENTRY(atomic64_add_unless_cx8)
129 pushl %ebp
130 pushl %ebx
131 /* these just push these two parameters on the stack */
132 pushl %edi
133 pushl %ecx
134
135 movl %eax, %ebp
136 movl %edx, %edi
137
138 read64 %esi
139 1:
140 cmpl %eax, 0(%esp)
141 je 4f
142 2:
143 movl %eax, %ebx
144 movl %edx, %ecx
145 addl %ebp, %ebx
146 adcl %edi, %ecx
147 LOCK_PREFIX
148 cmpxchg8b (%esi)
149 jne 1b
150
151 movl $1, %eax
152 3:
153 addl $8, %esp
154 popl %ebx
155 popl %ebp
156 ret
157 4:
158 cmpl %edx, 4(%esp)
159 jne 2b
160 xorl %eax, %eax
161 jmp 3b
162 ENDPROC(atomic64_add_unless_cx8)
163
164 ENTRY(atomic64_inc_not_zero_cx8)
165 pushl %ebx
166
167 read64 %esi
168 1:
169 movl %eax, %ecx
170 orl %edx, %ecx
171 jz 3f
172 movl %eax, %ebx
173 xorl %ecx, %ecx
174 addl $1, %ebx
175 adcl %edx, %ecx
176 LOCK_PREFIX
177 cmpxchg8b (%esi)
178 jne 1b
179
180 movl $1, %eax
181 3:
182 popl %ebx
183 ret
184 ENDPROC(atomic64_inc_not_zero_cx8)
This page took 0.034474 seconds and 5 git commands to generate.