blob: e8e7e0d06f4210daeec66f198b13a79a025eac6c [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
Jan Beulich60cf6372011-02-28 15:54:40 +000018 pushfl_cfi
Luca Barbieria7e926a2010-02-24 10:54:25 +010019 cli
20.endm
21
22.macro UNLOCK reg
Jan Beulich60cf6372011-02-28 15:54:40 +000023 popfl_cfi
Luca Barbieria7e926a2010-02-24 10:54:25 +010024.endm
25
Luca Barbieri30246552010-08-06 04:04:38 +020026#define BEGIN(op) \
Luca Barbieri417484d2010-08-12 07:00:35 -070027.macro endp; \
Luca Barbieri30246552010-08-06 04:04:38 +020028 CFI_ENDPROC; \
29ENDPROC(atomic64_##op##_386); \
Luca Barbieri417484d2010-08-12 07:00:35 -070030.purgem endp; \
Luca Barbieri30246552010-08-06 04:04:38 +020031.endm; \
32ENTRY(atomic64_##op##_386); \
33 CFI_STARTPROC; \
34 LOCK v;
Luca Barbieria7e926a2010-02-24 10:54:25 +010035
Luca Barbieri417484d2010-08-12 07:00:35 -070036#define ENDP endp
37
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 Barbieri417484d2010-08-12 07:00:35 -070042#define RET_ENDP \
Luca Barbieri30246552010-08-06 04:04:38 +020043 RET; \
Luca Barbieri417484d2010-08-12 07:00:35 -070044 ENDP
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
Luca Barbieri417484d2010-08-12 07:00:35 -070050RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020051#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)
Luca Barbieri417484d2010-08-12 07:00:35 -070057RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020058#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)
Luca Barbieri417484d2010-08-12 07:00:35 -070066RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020067#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)
Luca Barbieri417484d2010-08-12 07:00:35 -070073RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020074#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)
Luca Barbieri417484d2010-08-12 07:00:35 -070082RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020083#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)
Luca Barbieri417484d2010-08-12 07:00:35 -070089RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020090#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)
Luca Barbieri417484d2010-08-12 07:00:35 -0700101RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200102#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)
Luca Barbieri417484d2010-08-12 07:00:35 -0700108RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200109#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)
Luca Barbieri417484d2010-08-12 07:00:35 -0700119RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200120#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)
Luca Barbieri417484d2010-08-12 07:00:35 -0700126RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200127#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)
Luca Barbieri417484d2010-08-12 07:00:35 -0700137RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200138#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 Barbieri417484d2010-08-12 07:00:35 -0700159ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200160#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 Barbieri417484d2010-08-12 07:00:35 -0700180ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200181#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 Barbieri417484d2010-08-12 07:00:35 -0700193RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200194#undef v