2010-02-24 12:54:25 +03:00
/ *
* atomic6 4 _ t f o r 3 8 6 / 4 8 6
*
* Copyright © 2 0 1 0 L u c a B a r b i e r i
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e a s p u b l i s h e d b y
* the F r e e S o f t w a r e F o u n d a t i o n ; either version 2 of the License, or
* ( at y o u r o p t i o n ) a n y l a t e r v e r s i o n .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a l t e r n a t i v e - a s m . h >
# include < a s m / d w a r f2 . h >
/* if you want SMP support, implement these with real spinlocks */
.macro LOCK reg
2011-02-28 18:54:40 +03:00
pushfl_ c f i
2010-02-24 12:54:25 +03:00
cli
.endm
.macro UNLOCK reg
2011-02-28 18:54:40 +03:00
popfl_ c f i
2010-02-24 12:54:25 +03:00
.endm
2010-08-06 06:04:38 +04:00
# define B E G I N ( o p ) \
2010-08-12 18:00:35 +04:00
.macro endp; \
2010-08-06 06:04:38 +04:00
CFI_ E N D P R O C ; \
ENDPROC( a t o m i c64 _ ## o p # # _ 386 ) ; \
2010-08-12 18:00:35 +04:00
.purgem endp; \
2010-08-06 06:04:38 +04:00
.endm ; \
ENTRY( a t o m i c64 _ ## o p # # _ 386 ) ; \
CFI_ S T A R T P R O C ; \
LOCK v ;
2010-08-12 18:00:35 +04:00
# define E N D P e n d p
2010-08-06 06:04:38 +04:00
# define R E T \
UNLOCK v ; \
2010-02-24 12:54:25 +03:00
ret
2010-08-12 18:00:35 +04:00
# define R E T _ E N D P \
2010-08-06 06:04:38 +04:00
RET; \
2010-08-12 18:00:35 +04:00
ENDP
2010-08-06 06:04:38 +04:00
# define v % e c x
BEGIN( r e a d )
movl ( v ) , % e a x
movl 4 ( v ) , % e d x
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e s i
BEGIN( s e t )
movl % e b x , ( v )
movl % e c x , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e s i
BEGIN( x c h g )
movl ( v ) , % e a x
movl 4 ( v ) , % e d x
movl % e b x , ( v )
movl % e c x , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e c x
BEGIN( a d d )
addl % e a x , ( v )
adcl % e d x , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e c x
BEGIN( a d d _ r e t u r n )
addl ( v ) , % e a x
adcl 4 ( v ) , % e d x
movl % e a x , ( v )
movl % e d x , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e c x
BEGIN( s u b )
subl % e a x , ( v )
sbbl % e d x , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e c x
BEGIN( s u b _ r e t u r n )
2010-02-24 12:54:25 +03:00
negl % e d x
negl % e a x
sbbl $ 0 , % e d x
2010-08-06 06:04:38 +04:00
addl ( v ) , % e a x
adcl 4 ( v ) , % e d x
movl % e a x , ( v )
movl % e d x , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e s i
BEGIN( i n c )
addl $ 1 , ( v )
adcl $ 0 , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e s i
BEGIN( i n c _ r e t u r n )
movl ( v ) , % e a x
movl 4 ( v ) , % e d x
2010-02-24 12:54:25 +03:00
addl $ 1 , % e a x
adcl $ 0 , % e d x
2010-08-06 06:04:38 +04:00
movl % e a x , ( v )
movl % e d x , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e s i
BEGIN( d e c )
subl $ 1 , ( v )
sbbl $ 0 , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
# define v % e s i
BEGIN( d e c _ r e t u r n )
movl ( v ) , % e a x
movl 4 ( v ) , % e d x
2010-02-24 12:54:25 +03:00
subl $ 1 , % e a x
sbbl $ 0 , % e d x
2010-08-06 06:04:38 +04:00
movl % e a x , ( v )
movl % e d x , 4 ( v )
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v
2010-02-24 12:54:25 +03:00
2012-01-20 20:22:04 +04:00
# define v % e s i
2010-08-06 06:04:38 +04:00
BEGIN( a d d _ u n l e s s )
2012-01-20 20:22:04 +04:00
addl % e a x , % e c x
2010-02-24 12:54:25 +03:00
adcl % e d x , % e d i
2010-08-06 06:04:38 +04:00
addl ( v ) , % e a x
adcl 4 ( v ) , % e d x
2012-01-20 20:22:04 +04:00
cmpl % e a x , % e c x
2010-02-24 12:54:25 +03:00
je 3 f
1 :
2010-08-06 06:04:38 +04:00
movl % e a x , ( v )
movl % e d x , 4 ( v )
2010-03-01 21:55:46 +03:00
movl $ 1 , % e a x
2010-02-24 12:54:25 +03:00
2 :
2010-08-06 06:04:38 +04:00
RET
2010-02-24 12:54:25 +03:00
3 :
cmpl % e d x , % e d i
jne 1 b
2010-03-01 21:55:46 +03:00
xorl % e a x , % e a x
2010-02-24 12:54:25 +03:00
jmp 2 b
2010-08-12 18:00:35 +04:00
ENDP
2010-08-06 06:04:38 +04:00
# undef v
2010-02-24 12:54:25 +03:00
2010-08-06 06:04:38 +04:00
# define v % e s i
BEGIN( i n c _ n o t _ z e r o )
movl ( v ) , % e a x
movl 4 ( v ) , % e d x
2010-02-24 12:54:25 +03:00
testl % e a x , % e a x
je 3 f
1 :
addl $ 1 , % e a x
adcl $ 0 , % e d x
2010-08-06 06:04:38 +04:00
movl % e a x , ( v )
movl % e d x , 4 ( v )
2010-03-01 21:55:49 +03:00
movl $ 1 , % e a x
2010-02-24 12:54:25 +03:00
2 :
2010-08-06 06:04:38 +04:00
RET
2010-02-24 12:54:25 +03:00
3 :
testl % e d x , % e d x
jne 1 b
jmp 2 b
2010-08-12 18:00:35 +04:00
ENDP
2010-08-06 06:04:38 +04:00
# undef v
2010-02-24 12:54:25 +03:00
2010-08-06 06:04:38 +04:00
# define v % e s i
BEGIN( d e c _ i f _ p o s i t i v e )
movl ( v ) , % e a x
movl 4 ( v ) , % e d x
2010-02-24 12:54:25 +03:00
subl $ 1 , % e a x
sbbl $ 0 , % e d x
js 1 f
2010-08-06 06:04:38 +04:00
movl % e a x , ( v )
movl % e d x , 4 ( v )
2010-02-24 12:54:25 +03:00
1 :
2010-08-12 18:00:35 +04:00
RET_ E N D P
2010-08-06 06:04:38 +04:00
# undef v