blob: 78ee8e0fa278889b1b509141789478156a329e68 [file] [log] [blame]
Luca Barbieria7e926a2010-02-24 10:54:25 +01001/*
2 * atomic64_t for 386/486
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/* if you want SMP support, implement these with real spinlocks */
17.macro LOCK reg
18 pushfl
19 CFI_ADJUST_CFA_OFFSET 4
20 cli
21.endm
22
23.macro UNLOCK reg
24 popfl
25 CFI_ADJUST_CFA_OFFSET -4
26.endm
27
Luca Barbieri30246552010-08-06 04:04:38 +020028#define BEGIN(op) \
29.macro END; \
30 CFI_ENDPROC; \
31ENDPROC(atomic64_##op##_386); \
32.purgem END; \
33.endm; \
34ENTRY(atomic64_##op##_386); \
35 CFI_STARTPROC; \
36 LOCK v;
Luca Barbieria7e926a2010-02-24 10:54:25 +010037
Luca Barbieri30246552010-08-06 04:04:38 +020038#define RET \
39 UNLOCK v; \
Luca Barbieria7e926a2010-02-24 10:54:25 +010040 ret
Luca Barbieria7e926a2010-02-24 10:54:25 +010041
Luca Barbieri30246552010-08-06 04:04:38 +020042#define RET_END \
43 RET; \
44 END
Luca Barbieria7e926a2010-02-24 10:54:25 +010045
Luca Barbieri30246552010-08-06 04:04:38 +020046#define v %ecx
47BEGIN(read)
48 movl (v), %eax
49 movl 4(v), %edx
50RET_END
51#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010052
Luca Barbieri30246552010-08-06 04:04:38 +020053#define v %esi
54BEGIN(set)
55 movl %ebx, (v)
56 movl %ecx, 4(v)
57RET_END
58#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010059
Luca Barbieri30246552010-08-06 04:04:38 +020060#define v %esi
61BEGIN(xchg)
62 movl (v), %eax
63 movl 4(v), %edx
64 movl %ebx, (v)
65 movl %ecx, 4(v)
66RET_END
67#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010068
Luca Barbieri30246552010-08-06 04:04:38 +020069#define v %ecx
70BEGIN(add)
71 addl %eax, (v)
72 adcl %edx, 4(v)
73RET_END
74#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010075
Luca Barbieri30246552010-08-06 04:04:38 +020076#define v %ecx
77BEGIN(add_return)
78 addl (v), %eax
79 adcl 4(v), %edx
80 movl %eax, (v)
81 movl %edx, 4(v)
82RET_END
83#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010084
Luca Barbieri30246552010-08-06 04:04:38 +020085#define v %ecx
86BEGIN(sub)
87 subl %eax, (v)
88 sbbl %edx, 4(v)
89RET_END
90#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010091
Luca Barbieri30246552010-08-06 04:04:38 +020092#define v %ecx
93BEGIN(sub_return)
Luca Barbieria7e926a2010-02-24 10:54:25 +010094 negl %edx
95 negl %eax
96 sbbl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +020097 addl (v), %eax
98 adcl 4(v), %edx
99 movl %eax, (v)
100 movl %edx, 4(v)
101RET_END
102#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100103
Luca Barbieri30246552010-08-06 04:04:38 +0200104#define v %esi
105BEGIN(inc)
106 addl $1, (v)
107 adcl $0, 4(v)
108RET_END
109#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100110
Luca Barbieri30246552010-08-06 04:04:38 +0200111#define v %esi
112BEGIN(inc_return)
113 movl (v), %eax
114 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100115 addl $1, %eax
116 adcl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200117 movl %eax, (v)
118 movl %edx, 4(v)
119RET_END
120#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100121
Luca Barbieri30246552010-08-06 04:04:38 +0200122#define v %esi
123BEGIN(dec)
124 subl $1, (v)
125 sbbl $0, 4(v)
126RET_END
127#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100128
Luca Barbieri30246552010-08-06 04:04:38 +0200129#define v %esi
130BEGIN(dec_return)
131 movl (v), %eax
132 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100133 subl $1, %eax
134 sbbl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200135 movl %eax, (v)
136 movl %edx, 4(v)
137RET_END
138#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100139
Luca Barbieri30246552010-08-06 04:04:38 +0200140#define v %ecx
141BEGIN(add_unless)
Luca Barbieria7e926a2010-02-24 10:54:25 +0100142 addl %eax, %esi
143 adcl %edx, %edi
Luca Barbieri30246552010-08-06 04:04:38 +0200144 addl (v), %eax
145 adcl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100146 cmpl %eax, %esi
147 je 3f
1481:
Luca Barbieri30246552010-08-06 04:04:38 +0200149 movl %eax, (v)
150 movl %edx, 4(v)
Luca Barbieri6e6104f2010-03-01 19:55:46 +0100151 movl $1, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +01001522:
Luca Barbieri30246552010-08-06 04:04:38 +0200153 RET
Luca Barbieria7e926a2010-02-24 10:54:25 +01001543:
155 cmpl %edx, %edi
156 jne 1b
Luca Barbieri6e6104f2010-03-01 19:55:46 +0100157 xorl %eax, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +0100158 jmp 2b
Luca Barbieri30246552010-08-06 04:04:38 +0200159END
160#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100161
Luca Barbieri30246552010-08-06 04:04:38 +0200162#define v %esi
163BEGIN(inc_not_zero)
164 movl (v), %eax
165 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100166 testl %eax, %eax
167 je 3f
1681:
169 addl $1, %eax
170 adcl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200171 movl %eax, (v)
172 movl %edx, 4(v)
Luca Barbierif3e83132010-03-01 19:55:49 +0100173 movl $1, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +01001742:
Luca Barbieri30246552010-08-06 04:04:38 +0200175 RET
Luca Barbieria7e926a2010-02-24 10:54:25 +01001763:
177 testl %edx, %edx
178 jne 1b
Luca Barbieria7e926a2010-02-24 10:54:25 +0100179 jmp 2b
Luca Barbieri30246552010-08-06 04:04:38 +0200180END
181#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100182
Luca Barbieri30246552010-08-06 04:04:38 +0200183#define v %esi
184BEGIN(dec_if_positive)
185 movl (v), %eax
186 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100187 subl $1, %eax
188 sbbl $0, %edx
189 js 1f
Luca Barbieri30246552010-08-06 04:04:38 +0200190 movl %eax, (v)
191 movl %edx, 4(v)
Luca Barbieria7e926a2010-02-24 10:54:25 +01001921:
Luca Barbieri30246552010-08-06 04:04:38 +0200193RET_END
194#undef v