mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-02 18:54:10 +08:00
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>
This commit is contained in:
parent
8fd49936a8
commit
30246557a0
@ -25,150 +25,170 @@
|
|||||||
CFI_ADJUST_CFA_OFFSET -4
|
CFI_ADJUST_CFA_OFFSET -4
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro BEGIN func reg
|
#define BEGIN(op) \
|
||||||
$v = \reg
|
.macro END; \
|
||||||
|
CFI_ENDPROC; \
|
||||||
|
ENDPROC(atomic64_##op##_386); \
|
||||||
|
.purgem END; \
|
||||||
|
.endm; \
|
||||||
|
ENTRY(atomic64_##op##_386); \
|
||||||
|
CFI_STARTPROC; \
|
||||||
|
LOCK v;
|
||||||
|
|
||||||
ENTRY(atomic64_\func\()_386)
|
#define RET \
|
||||||
CFI_STARTPROC
|
UNLOCK v; \
|
||||||
LOCK $v
|
|
||||||
|
|
||||||
.macro RETURN
|
|
||||||
UNLOCK $v
|
|
||||||
ret
|
ret
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro END_
|
#define RET_END \
|
||||||
CFI_ENDPROC
|
RET; \
|
||||||
ENDPROC(atomic64_\func\()_386)
|
END
|
||||||
.purgem RETURN
|
|
||||||
.purgem END_
|
|
||||||
.purgem END
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro END
|
#define v %ecx
|
||||||
RETURN
|
BEGIN(read)
|
||||||
END_
|
movl (v), %eax
|
||||||
.endm
|
movl 4(v), %edx
|
||||||
.endm
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN read %ecx
|
#define v %esi
|
||||||
movl ($v), %eax
|
BEGIN(set)
|
||||||
movl 4($v), %edx
|
movl %ebx, (v)
|
||||||
END
|
movl %ecx, 4(v)
|
||||||
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN set %esi
|
#define v %esi
|
||||||
movl %ebx, ($v)
|
BEGIN(xchg)
|
||||||
movl %ecx, 4($v)
|
movl (v), %eax
|
||||||
END
|
movl 4(v), %edx
|
||||||
|
movl %ebx, (v)
|
||||||
|
movl %ecx, 4(v)
|
||||||
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN xchg %esi
|
#define v %ecx
|
||||||
movl ($v), %eax
|
BEGIN(add)
|
||||||
movl 4($v), %edx
|
addl %eax, (v)
|
||||||
movl %ebx, ($v)
|
adcl %edx, 4(v)
|
||||||
movl %ecx, 4($v)
|
RET_END
|
||||||
END
|
#undef v
|
||||||
|
|
||||||
BEGIN add %ecx
|
#define v %ecx
|
||||||
addl %eax, ($v)
|
BEGIN(add_return)
|
||||||
adcl %edx, 4($v)
|
addl (v), %eax
|
||||||
END
|
adcl 4(v), %edx
|
||||||
|
movl %eax, (v)
|
||||||
|
movl %edx, 4(v)
|
||||||
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN add_return %ecx
|
#define v %ecx
|
||||||
addl ($v), %eax
|
BEGIN(sub)
|
||||||
adcl 4($v), %edx
|
subl %eax, (v)
|
||||||
movl %eax, ($v)
|
sbbl %edx, 4(v)
|
||||||
movl %edx, 4($v)
|
RET_END
|
||||||
END
|
#undef v
|
||||||
|
|
||||||
BEGIN sub %ecx
|
#define v %ecx
|
||||||
subl %eax, ($v)
|
BEGIN(sub_return)
|
||||||
sbbl %edx, 4($v)
|
|
||||||
END
|
|
||||||
|
|
||||||
BEGIN sub_return %ecx
|
|
||||||
negl %edx
|
negl %edx
|
||||||
negl %eax
|
negl %eax
|
||||||
sbbl $0, %edx
|
sbbl $0, %edx
|
||||||
addl ($v), %eax
|
addl (v), %eax
|
||||||
adcl 4($v), %edx
|
adcl 4(v), %edx
|
||||||
movl %eax, ($v)
|
movl %eax, (v)
|
||||||
movl %edx, 4($v)
|
movl %edx, 4(v)
|
||||||
END
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN inc %esi
|
#define v %esi
|
||||||
addl $1, ($v)
|
BEGIN(inc)
|
||||||
adcl $0, 4($v)
|
addl $1, (v)
|
||||||
END
|
adcl $0, 4(v)
|
||||||
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN inc_return %esi
|
#define v %esi
|
||||||
movl ($v), %eax
|
BEGIN(inc_return)
|
||||||
movl 4($v), %edx
|
movl (v), %eax
|
||||||
|
movl 4(v), %edx
|
||||||
addl $1, %eax
|
addl $1, %eax
|
||||||
adcl $0, %edx
|
adcl $0, %edx
|
||||||
movl %eax, ($v)
|
movl %eax, (v)
|
||||||
movl %edx, 4($v)
|
movl %edx, 4(v)
|
||||||
END
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN dec %esi
|
#define v %esi
|
||||||
subl $1, ($v)
|
BEGIN(dec)
|
||||||
sbbl $0, 4($v)
|
subl $1, (v)
|
||||||
END
|
sbbl $0, 4(v)
|
||||||
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN dec_return %esi
|
#define v %esi
|
||||||
movl ($v), %eax
|
BEGIN(dec_return)
|
||||||
movl 4($v), %edx
|
movl (v), %eax
|
||||||
|
movl 4(v), %edx
|
||||||
subl $1, %eax
|
subl $1, %eax
|
||||||
sbbl $0, %edx
|
sbbl $0, %edx
|
||||||
movl %eax, ($v)
|
movl %eax, (v)
|
||||||
movl %edx, 4($v)
|
movl %edx, 4(v)
|
||||||
END
|
RET_END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN add_unless %ecx
|
#define v %ecx
|
||||||
|
BEGIN(add_unless)
|
||||||
addl %eax, %esi
|
addl %eax, %esi
|
||||||
adcl %edx, %edi
|
adcl %edx, %edi
|
||||||
addl ($v), %eax
|
addl (v), %eax
|
||||||
adcl 4($v), %edx
|
adcl 4(v), %edx
|
||||||
cmpl %eax, %esi
|
cmpl %eax, %esi
|
||||||
je 3f
|
je 3f
|
||||||
1:
|
1:
|
||||||
movl %eax, ($v)
|
movl %eax, (v)
|
||||||
movl %edx, 4($v)
|
movl %edx, 4(v)
|
||||||
movl $1, %eax
|
movl $1, %eax
|
||||||
2:
|
2:
|
||||||
RETURN
|
RET
|
||||||
3:
|
3:
|
||||||
cmpl %edx, %edi
|
cmpl %edx, %edi
|
||||||
jne 1b
|
jne 1b
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
jmp 2b
|
jmp 2b
|
||||||
END_
|
END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN inc_not_zero %esi
|
#define v %esi
|
||||||
movl ($v), %eax
|
BEGIN(inc_not_zero)
|
||||||
movl 4($v), %edx
|
movl (v), %eax
|
||||||
|
movl 4(v), %edx
|
||||||
testl %eax, %eax
|
testl %eax, %eax
|
||||||
je 3f
|
je 3f
|
||||||
1:
|
1:
|
||||||
addl $1, %eax
|
addl $1, %eax
|
||||||
adcl $0, %edx
|
adcl $0, %edx
|
||||||
movl %eax, ($v)
|
movl %eax, (v)
|
||||||
movl %edx, 4($v)
|
movl %edx, 4(v)
|
||||||
movl $1, %eax
|
movl $1, %eax
|
||||||
2:
|
2:
|
||||||
RETURN
|
RET
|
||||||
3:
|
3:
|
||||||
testl %edx, %edx
|
testl %edx, %edx
|
||||||
jne 1b
|
jne 1b
|
||||||
jmp 2b
|
jmp 2b
|
||||||
END_
|
END
|
||||||
|
#undef v
|
||||||
|
|
||||||
BEGIN dec_if_positive %esi
|
#define v %esi
|
||||||
movl ($v), %eax
|
BEGIN(dec_if_positive)
|
||||||
movl 4($v), %edx
|
movl (v), %eax
|
||||||
|
movl 4(v), %edx
|
||||||
subl $1, %eax
|
subl $1, %eax
|
||||||
sbbl $0, %edx
|
sbbl $0, %edx
|
||||||
js 1f
|
js 1f
|
||||||
movl %eax, ($v)
|
movl %eax, (v)
|
||||||
movl %edx, 4($v)
|
movl %edx, 4(v)
|
||||||
1:
|
1:
|
||||||
END
|
RET_END
|
||||||
|
#undef v
|
||||||
|
Loading…
Reference in New Issue
Block a user