0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/linkage.h>
0009 #include <asm/alternative.h>
0010
0011 .macro read64 reg
0012 movl %ebx, %eax
0013 movl %ecx, %edx
0014
0015 LOCK_PREFIX
0016 cmpxchg8b (\reg)
0017 .endm
0018
0019 SYM_FUNC_START(atomic64_read_cx8)
0020 read64 %ecx
0021 RET
0022 SYM_FUNC_END(atomic64_read_cx8)
0023
0024 SYM_FUNC_START(atomic64_set_cx8)
0025 1:
0026
0027
0028 cmpxchg8b (%esi)
0029 jne 1b
0030
0031 RET
0032 SYM_FUNC_END(atomic64_set_cx8)
0033
0034 SYM_FUNC_START(atomic64_xchg_cx8)
0035 1:
0036 LOCK_PREFIX
0037 cmpxchg8b (%esi)
0038 jne 1b
0039
0040 RET
0041 SYM_FUNC_END(atomic64_xchg_cx8)
0042
0043 .macro addsub_return func ins insc
0044 SYM_FUNC_START(atomic64_\func\()_return_cx8)
0045 pushl %ebp
0046 pushl %ebx
0047 pushl %esi
0048 pushl %edi
0049
0050 movl %eax, %esi
0051 movl %edx, %edi
0052 movl %ecx, %ebp
0053
0054 read64 %ecx
0055 1:
0056 movl %eax, %ebx
0057 movl %edx, %ecx
0058 \ins\()l %esi, %ebx
0059 \insc\()l %edi, %ecx
0060 LOCK_PREFIX
0061 cmpxchg8b (%ebp)
0062 jne 1b
0063
0064 10:
0065 movl %ebx, %eax
0066 movl %ecx, %edx
0067 popl %edi
0068 popl %esi
0069 popl %ebx
0070 popl %ebp
0071 RET
0072 SYM_FUNC_END(atomic64_\func\()_return_cx8)
0073 .endm
0074
0075 addsub_return add add adc
0076 addsub_return sub sub sbb
0077
0078 .macro incdec_return func ins insc
0079 SYM_FUNC_START(atomic64_\func\()_return_cx8)
0080 pushl %ebx
0081
0082 read64 %esi
0083 1:
0084 movl %eax, %ebx
0085 movl %edx, %ecx
0086 \ins\()l $1, %ebx
0087 \insc\()l $0, %ecx
0088 LOCK_PREFIX
0089 cmpxchg8b (%esi)
0090 jne 1b
0091
0092 10:
0093 movl %ebx, %eax
0094 movl %ecx, %edx
0095 popl %ebx
0096 RET
0097 SYM_FUNC_END(atomic64_\func\()_return_cx8)
0098 .endm
0099
0100 incdec_return inc add adc
0101 incdec_return dec sub sbb
0102
0103 SYM_FUNC_START(atomic64_dec_if_positive_cx8)
0104 pushl %ebx
0105
0106 read64 %esi
0107 1:
0108 movl %eax, %ebx
0109 movl %edx, %ecx
0110 subl $1, %ebx
0111 sbb $0, %ecx
0112 js 2f
0113 LOCK_PREFIX
0114 cmpxchg8b (%esi)
0115 jne 1b
0116
0117 2:
0118 movl %ebx, %eax
0119 movl %ecx, %edx
0120 popl %ebx
0121 RET
0122 SYM_FUNC_END(atomic64_dec_if_positive_cx8)
0123
0124 SYM_FUNC_START(atomic64_add_unless_cx8)
0125 pushl %ebp
0126 pushl %ebx
0127
0128 pushl %edi
0129 pushl %ecx
0130
0131 movl %eax, %ebp
0132 movl %edx, %edi
0133
0134 read64 %esi
0135 1:
0136 cmpl %eax, 0(%esp)
0137 je 4f
0138 2:
0139 movl %eax, %ebx
0140 movl %edx, %ecx
0141 addl %ebp, %ebx
0142 adcl %edi, %ecx
0143 LOCK_PREFIX
0144 cmpxchg8b (%esi)
0145 jne 1b
0146
0147 movl $1, %eax
0148 3:
0149 addl $8, %esp
0150 popl %ebx
0151 popl %ebp
0152 RET
0153 4:
0154 cmpl %edx, 4(%esp)
0155 jne 2b
0156 xorl %eax, %eax
0157 jmp 3b
0158 SYM_FUNC_END(atomic64_add_unless_cx8)
0159
0160 SYM_FUNC_START(atomic64_inc_not_zero_cx8)
0161 pushl %ebx
0162
0163 read64 %esi
0164 1:
0165 movl %eax, %ecx
0166 orl %edx, %ecx
0167 jz 3f
0168 movl %eax, %ebx
0169 xorl %ecx, %ecx
0170 addl $1, %ebx
0171 adcl %edx, %ecx
0172 LOCK_PREFIX
0173 cmpxchg8b (%esi)
0174 jne 1b
0175
0176 movl $1, %eax
0177 3:
0178 popl %ebx
0179 RET
0180 SYM_FUNC_END(atomic64_inc_not_zero_cx8)