aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/lib
diff options
context:
space:
mode:
authorLuca Barbieri <luca@luca-barbieri.com>2010-08-05 22:04:38 -0400
committerH. Peter Anvin <hpa@zytor.com>2010-08-12 00:03:28 -0400
commit30246557a06bb20618bed906a06d1e1e0faa8bb4 (patch)
tree26f1493097b00e1cf3fdbf40b4abced115ac219d /arch/x86/lib
parent8fd49936a8cac246fc9ed85508556c82cd44cf68 (diff)
x86, asm: Refactor atomic64_386_32.S to support old binutils and be cleaner
The old code didn't work on binutils 2.12 because setting a symbol to a register apparently requires a fairly recent version. This commit refactors the code to use the C preprocessor instead, and in the process makes the whole code a bit easier to understand. The object code produced is unchanged as expected. This fixes kernel bugzilla 16506. Reported-by: Dieter Stussy <kd6lvw+software@kd6lvw.ampr.org> Signed-off-by: Luca Barbieri <luca@luca-barbieri.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com> Cc: <stable@kernel.org> 2.6.35 LKML-Reference: <tip-*@git.kernel.org>
Diffstat (limited to 'arch/x86/lib')
-rw-r--r--arch/x86/lib/atomic64_386_32.S236
1 files changed, 128 insertions, 108 deletions
diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S
index 4a5979aa6883..78ee8e0fa278 100644
--- a/arch/x86/lib/atomic64_386_32.S
+++ b/arch/x86/lib/atomic64_386_32.S
@@ -25,150 +25,170 @@
25 CFI_ADJUST_CFA_OFFSET -4 25 CFI_ADJUST_CFA_OFFSET -4
26.endm 26.endm
27 27
28.macro BEGIN func reg 28#define BEGIN(op) \
29$v = \reg 29.macro END; \
30 30 CFI_ENDPROC; \
31ENTRY(atomic64_\func\()_386) 31ENDPROC(atomic64_##op##_386); \
32 CFI_STARTPROC 32.purgem END; \
33 LOCK $v 33.endm; \
34 34ENTRY(atomic64_##op##_386); \
35.macro RETURN 35 CFI_STARTPROC; \
36 UNLOCK $v 36 LOCK v;
37
38#define RET \
39 UNLOCK v; \
37 ret 40 ret
38.endm
39
40.macro END_
41 CFI_ENDPROC
42ENDPROC(atomic64_\func\()_386)
43.purgem RETURN
44.purgem END_
45.purgem END
46.endm
47
48.macro END
49RETURN
50END_
51.endm
52.endm
53
54BEGIN read %ecx
55 movl ($v), %eax
56 movl 4($v), %edx
57END
58
59BEGIN set %esi
60 movl %ebx, ($v)
61 movl %ecx, 4($v)
62END
63
64BEGIN xchg %esi
65 movl ($v), %eax
66 movl 4($v), %edx
67 movl %ebx, ($v)
68 movl %ecx, 4($v)
69END
70
71BEGIN add %ecx
72 addl %eax, ($v)
73 adcl %edx, 4($v)
74END
75 41
76BEGIN add_return %ecx 42#define RET_END \
77 addl ($v), %eax 43 RET; \
78 adcl 4($v), %edx 44 END
79 movl %eax, ($v) 45
80 movl %edx, 4($v) 46#define v %ecx
81END 47BEGIN(read)
82 48 movl (v), %eax
83BEGIN sub %ecx 49 movl 4(v), %edx
84 subl %eax, ($v) 50RET_END
85 sbbl %edx, 4($v) 51#undef v
86END 52
87 53#define v %esi
88BEGIN sub_return %ecx 54BEGIN(set)
55 movl %ebx, (v)
56 movl %ecx, 4(v)
57RET_END
58#undef v
59
60#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
68
69#define v %ecx
70BEGIN(add)
71 addl %eax, (v)
72 adcl %edx, 4(v)
73RET_END
74#undef v
75
76#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
84
85#define v %ecx
86BEGIN(sub)
87 subl %eax, (v)
88 sbbl %edx, 4(v)
89RET_END
90#undef v
91
92#define v %ecx
93BEGIN(sub_return)
89 negl %edx 94 negl %edx
90 negl %eax 95 negl %eax
91 sbbl $0, %edx 96 sbbl $0, %edx
92 addl ($v), %eax 97 addl (v), %eax
93 adcl 4($v), %edx 98 adcl 4(v), %edx
94 movl %eax, ($v) 99 movl %eax, (v)
95 movl %edx, 4($v) 100 movl %edx, 4(v)
96END 101RET_END
97 102#undef v
98BEGIN inc %esi 103
99 addl $1, ($v) 104#define v %esi
100 adcl $0, 4($v) 105BEGIN(inc)
101END 106 addl $1, (v)
102 107 adcl $0, 4(v)
103BEGIN inc_return %esi 108RET_END
104 movl ($v), %eax 109#undef v
105 movl 4($v), %edx 110
111#define v %esi
112BEGIN(inc_return)
113 movl (v), %eax
114 movl 4(v), %edx
106 addl $1, %eax 115 addl $1, %eax
107 adcl $0, %edx 116 adcl $0, %edx
108 movl %eax, ($v) 117 movl %eax, (v)
109 movl %edx, 4($v) 118 movl %edx, 4(v)
110END 119RET_END
111 120#undef v
112BEGIN dec %esi 121
113 subl $1, ($v) 122#define v %esi
114 sbbl $0, 4($v) 123BEGIN(dec)
115END 124 subl $1, (v)
116 125 sbbl $0, 4(v)
117BEGIN dec_return %esi 126RET_END
118 movl ($v), %eax 127#undef v
119 movl 4($v), %edx 128
129#define v %esi
130BEGIN(dec_return)
131 movl (v), %eax
132 movl 4(v), %edx
120 subl $1, %eax 133 subl $1, %eax
121 sbbl $0, %edx 134 sbbl $0, %edx
122 movl %eax, ($v) 135 movl %eax, (v)
123 movl %edx, 4($v) 136 movl %edx, 4(v)
124END 137RET_END
138#undef v
125 139
126BEGIN add_unless %ecx 140#define v %ecx
141BEGIN(add_unless)
127 addl %eax, %esi 142 addl %eax, %esi
128 adcl %edx, %edi 143 adcl %edx, %edi
129 addl ($v), %eax 144 addl (v), %eax
130 adcl 4($v), %edx 145 adcl 4(v), %edx
131 cmpl %eax, %esi 146 cmpl %eax, %esi
132 je 3f 147 je 3f
1331: 1481:
134 movl %eax, ($v) 149 movl %eax, (v)
135 movl %edx, 4($v) 150 movl %edx, 4(v)
136 movl $1, %eax 151 movl $1, %eax
1372: 1522:
138RETURN 153 RET
1393: 1543:
140 cmpl %edx, %edi 155 cmpl %edx, %edi
141 jne 1b 156 jne 1b
142 xorl %eax, %eax 157 xorl %eax, %eax
143 jmp 2b 158 jmp 2b
144END_ 159END
160#undef v
145 161
146BEGIN inc_not_zero %esi 162#define v %esi
147 movl ($v), %eax 163BEGIN(inc_not_zero)
148 movl 4($v), %edx 164 movl (v), %eax
165 movl 4(v), %edx
149 testl %eax, %eax 166 testl %eax, %eax
150 je 3f 167 je 3f
1511: 1681:
152 addl $1, %eax 169 addl $1, %eax
153 adcl $0, %edx 170 adcl $0, %edx
154 movl %eax, ($v) 171 movl %eax, (v)
155 movl %edx, 4($v) 172 movl %edx, 4(v)
156 movl $1, %eax 173 movl $1, %eax
1572: 1742:
158RETURN 175 RET
1593: 1763:
160 testl %edx, %edx 177 testl %edx, %edx
161 jne 1b 178 jne 1b
162 jmp 2b 179 jmp 2b
163END_ 180END
181#undef v
164 182
165BEGIN dec_if_positive %esi 183#define v %esi
166 movl ($v), %eax 184BEGIN(dec_if_positive)
167 movl 4($v), %edx 185 movl (v), %eax
186 movl 4(v), %edx
168 subl $1, %eax 187 subl $1, %eax
169 sbbl $0, %edx 188 sbbl $0, %edx
170 js 1f 189 js 1f
171 movl %eax, ($v) 190 movl %eax, (v)
172 movl %edx, 4($v) 191 movl %edx, 4(v)
1731: 1921:
174END 193RET_END
194#undef v