Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * atomic64_t for 386/486
0004  *
0005  * Copyright © 2010  Luca Barbieri
0006  */
0007 
0008 #include <linux/linkage.h>
0009 #include <asm/alternative.h>
0010 
0011 /* if you want SMP support, implement these with real spinlocks */
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