0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/linkage.h>
0009 #include <asm/alternative.h>
0010
0011
0012 .macro IRQ_SAVE reg
0013 pushfl
0014 cli
0015 .endm
0016
0017 .macro IRQ_RESTORE reg
0018 popfl
0019 .endm
0020
0021 #define BEGIN_IRQ_SAVE(op) \
0022 .macro endp; \
0023 SYM_FUNC_END(atomic64_##op##_386); \
0024 .purgem endp; \
0025 .endm; \
0026 SYM_FUNC_START(atomic64_##op##_386); \
0027 IRQ_SAVE v;
0028
0029 #define ENDP endp
0030
0031 #define RET_IRQ_RESTORE \
0032 IRQ_RESTORE v; \
0033 RET
0034
0035 #define v %ecx
0036 BEGIN_IRQ_SAVE(read)
0037 movl (v), %eax
0038 movl 4(v), %edx
0039 RET_IRQ_RESTORE
0040 ENDP
0041 #undef v
0042
0043 #define v %esi
0044 BEGIN_IRQ_SAVE(set)
0045 movl %ebx, (v)
0046 movl %ecx, 4(v)
0047 RET_IRQ_RESTORE
0048 ENDP
0049 #undef v
0050
0051 #define v %esi
0052 BEGIN_IRQ_SAVE(xchg)
0053 movl (v), %eax
0054 movl 4(v), %edx
0055 movl %ebx, (v)
0056 movl %ecx, 4(v)
0057 RET_IRQ_RESTORE
0058 ENDP
0059 #undef v
0060
0061 #define v %ecx
0062 BEGIN_IRQ_SAVE(add)
0063 addl %eax, (v)
0064 adcl %edx, 4(v)
0065 RET_IRQ_RESTORE
0066 ENDP
0067 #undef v
0068
0069 #define v %ecx
0070 BEGIN_IRQ_SAVE(add_return)
0071 addl (v), %eax
0072 adcl 4(v), %edx
0073 movl %eax, (v)
0074 movl %edx, 4(v)
0075 RET_IRQ_RESTORE
0076 ENDP
0077 #undef v
0078
0079 #define v %ecx
0080 BEGIN_IRQ_SAVE(sub)
0081 subl %eax, (v)
0082 sbbl %edx, 4(v)
0083 RET_IRQ_RESTORE
0084 ENDP
0085 #undef v
0086
0087 #define v %ecx
0088 BEGIN_IRQ_SAVE(sub_return)
0089 negl %edx
0090 negl %eax
0091 sbbl $0, %edx
0092 addl (v), %eax
0093 adcl 4(v), %edx
0094 movl %eax, (v)
0095 movl %edx, 4(v)
0096 RET_IRQ_RESTORE
0097 ENDP
0098 #undef v
0099
0100 #define v %esi
0101 BEGIN_IRQ_SAVE(inc)
0102 addl $1, (v)
0103 adcl $0, 4(v)
0104 RET_IRQ_RESTORE
0105 ENDP
0106 #undef v
0107
0108 #define v %esi
0109 BEGIN_IRQ_SAVE(inc_return)
0110 movl (v), %eax
0111 movl 4(v), %edx
0112 addl $1, %eax
0113 adcl $0, %edx
0114 movl %eax, (v)
0115 movl %edx, 4(v)
0116 RET_IRQ_RESTORE
0117 ENDP
0118 #undef v
0119
0120 #define v %esi
0121 BEGIN_IRQ_SAVE(dec)
0122 subl $1, (v)
0123 sbbl $0, 4(v)
0124 RET_IRQ_RESTORE
0125 ENDP
0126 #undef v
0127
0128 #define v %esi
0129 BEGIN_IRQ_SAVE(dec_return)
0130 movl (v), %eax
0131 movl 4(v), %edx
0132 subl $1, %eax
0133 sbbl $0, %edx
0134 movl %eax, (v)
0135 movl %edx, 4(v)
0136 RET_IRQ_RESTORE
0137 ENDP
0138 #undef v
0139
0140 #define v %esi
0141 BEGIN_IRQ_SAVE(add_unless)
0142 addl %eax, %ecx
0143 adcl %edx, %edi
0144 addl (v), %eax
0145 adcl 4(v), %edx
0146 cmpl %eax, %ecx
0147 je 3f
0148 1:
0149 movl %eax, (v)
0150 movl %edx, 4(v)
0151 movl $1, %eax
0152 2:
0153 RET_IRQ_RESTORE
0154 3:
0155 cmpl %edx, %edi
0156 jne 1b
0157 xorl %eax, %eax
0158 jmp 2b
0159 ENDP
0160 #undef v
0161
0162 #define v %esi
0163 BEGIN_IRQ_SAVE(inc_not_zero)
0164 movl (v), %eax
0165 movl 4(v), %edx
0166 testl %eax, %eax
0167 je 3f
0168 1:
0169 addl $1, %eax
0170 adcl $0, %edx
0171 movl %eax, (v)
0172 movl %edx, 4(v)
0173 movl $1, %eax
0174 2:
0175 RET_IRQ_RESTORE
0176 3:
0177 testl %edx, %edx
0178 jne 1b
0179 jmp 2b
0180 ENDP
0181 #undef v
0182
0183 #define v %esi
0184 BEGIN_IRQ_SAVE(dec_if_positive)
0185 movl (v), %eax
0186 movl 4(v), %edx
0187 subl $1, %eax
0188 sbbl $0, %edx
0189 js 1f
0190 movl %eax, (v)
0191 movl %edx, 4(v)
0192 1:
0193 RET_IRQ_RESTORE
0194 ENDP
0195 #undef v