2010-02-24 10:54:25 +01:00
/ *
* atomic6 4 _ t f o r 5 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 >
.macro SAVE reg
2011-02-28 15:54:40 +00:00
pushl_ c f i % \ r e g
2010-02-24 10:54:25 +01:00
CFI_ R E L _ O F F S E T \ r e g , 0
.endm
.macro RESTORE reg
2011-02-28 15:54:40 +00:00
popl_ c f i % \ r e g
2010-02-24 10:54:25 +01:00
CFI_ R E S T O R E \ r e g
.endm
.macro read64 reg
movl % e b x , % e a x
movl % e c x , % e d x
/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
LOCK_ P R E F I X
cmpxchg8 b ( \ r e g )
.endm
ENTRY( a t o m i c64 _ r e a d _ c x8 )
CFI_ S T A R T P R O C
read6 4 % e c x
ret
CFI_ E N D P R O C
ENDPROC( a t o m i c64 _ r e a d _ c x8 )
ENTRY( a t o m i c64 _ s e t _ c x8 )
CFI_ S T A R T P R O C
1 :
/ * we d o n ' t n e e d L O C K _ P R E F I X s i n c e a l i g n e d 6 4 - b i t w r i t e s
* are a t o m i c o n 5 8 6 a n d n e w e r * /
cmpxchg8 b ( % e s i )
jne 1 b
ret
CFI_ E N D P R O C
ENDPROC( a t o m i c64 _ s e t _ c x8 )
ENTRY( a t o m i c64 _ x c h g _ c x8 )
CFI_ S T A R T P R O C
1 :
LOCK_ P R E F I X
cmpxchg8 b ( % e s i )
jne 1 b
ret
CFI_ E N D P R O C
ENDPROC( a t o m i c64 _ x c h g _ c x8 )
.macro addsub_return func i n s i n s c
ENTRY( a t o m i c64 _ \ f u n c \ ( ) _ r e t u r n _ c x8 )
CFI_ S T A R T P R O C
SAVE e b p
SAVE e b x
SAVE e s i
SAVE e d i
movl % e a x , % e s i
movl % e d x , % e d i
movl % e c x , % e b p
2012-01-20 16:22:04 +00:00
read6 4 % e c x
2010-02-24 10:54:25 +01:00
1 :
movl % e a x , % e b x
movl % e d x , % e c x
\ ins\ ( ) l % e s i , % e b x
\ insc\ ( ) l % e d i , % e c x
LOCK_ P R E F I X
cmpxchg8 b ( % e b p )
jne 1 b
10 :
movl % e b x , % e a x
movl % e c x , % e d x
RESTORE e d i
RESTORE e s i
RESTORE e b x
RESTORE e b p
ret
CFI_ E N D P R O C
ENDPROC( a t o m i c64 _ \ f u n c \ ( ) _ r e t u r n _ c x8 )
.endm
addsub_ r e t u r n a d d a d d a d c
addsub_ r e t u r n s u b s u b s b b
.macro incdec_return func i n s i n s c
ENTRY( a t o m i c64 _ \ f u n c \ ( ) _ r e t u r n _ c x8 )
CFI_ S T A R T P R O C
SAVE e b x
read6 4 % e s i
1 :
movl % e a x , % e b x
movl % e d x , % e c x
\ ins\ ( ) l $ 1 , % e b x
\ insc\ ( ) l $ 0 , % e c x
LOCK_ P R E F I X
cmpxchg8 b ( % e s i )
jne 1 b
10 :
movl % e b x , % e a x
movl % e c x , % e d x
RESTORE e b x
ret
CFI_ E N D P R O C
ENDPROC( a t o m i c64 _ \ f u n c \ ( ) _ r e t u r n _ c x8 )
.endm
incdec_ r e t u r n i n c a d d a d c
incdec_ r e t u r n d e c s u b s b b
ENTRY( a t o m i c64 _ d e c _ i f _ p o s i t i v e _ c x8 )
CFI_ S T A R T P R O C
SAVE e b x
read6 4 % e s i
1 :
movl % e a x , % e b x
movl % e d x , % e c x
subl $ 1 , % e b x
sbb $ 0 , % e c x
js 2 f
LOCK_ P R E F I X
cmpxchg8 b ( % e s i )
jne 1 b
2 :
movl % e b x , % e a x
movl % e c x , % e d x
RESTORE e b x
ret
CFI_ E N D P R O C
ENDPROC( a t o m i c64 _ d e c _ i f _ p o s i t i v e _ c x8 )
ENTRY( a t o m i c64 _ a d d _ u n l e s s _ c x8 )
CFI_ S T A R T P R O C
SAVE e b p
SAVE e b x
/* these just push these two parameters on the stack */
SAVE e d i
2012-01-20 16:22:04 +00:00
SAVE e c x
2010-02-24 10:54:25 +01:00
2012-01-20 16:22:04 +00:00
movl % e a x , % e b p
2010-02-24 10:54:25 +01:00
movl % e d x , % e d i
2012-01-20 16:22:04 +00:00
read6 4 % e s i
2010-02-24 10:54:25 +01:00
1 :
cmpl % e a x , 0 ( % e s p )
je 4 f
2 :
movl % e a x , % e b x
movl % e d x , % e c x
2012-01-20 16:22:04 +00:00
addl % e b p , % e b x
2010-02-24 10:54:25 +01:00
adcl % e d i , % e c x
LOCK_ P R E F I X
2012-01-20 16:22:04 +00:00
cmpxchg8 b ( % e s i )
2010-02-24 10:54:25 +01:00
jne 1 b
2010-03-01 19:55:46 +01:00
movl $ 1 , % e a x
2010-02-24 10:54:25 +01:00
3 :
addl $ 8 , % e s p
CFI_ A D J U S T _ C F A _ O F F S E T - 8
RESTORE e b x
RESTORE e b p
ret
4 :
cmpl % e d x , 4 ( % e s p )
jne 2 b
2010-03-01 19:55:46 +01:00
xorl % e a x , % e a x
2010-02-24 10:54:25 +01:00
jmp 3 b
CFI_ E N D P R O C
ENDPROC( a t o m i c64 _ a d d _ u n l e s s _ c x8 )
ENTRY( a t o m i c64 _ i n c _ n o t _ z e r o _ c x8 )
CFI_ S T A R T P R O C
SAVE e b x
read6 4 % e s i
1 :
2012-01-20 16:22:04 +00:00
movl % e a x , % e c x
orl % e d x , % e c x
jz 3 f
2010-02-24 10:54:25 +01:00
movl % e a x , % e b x
2012-01-20 16:22:04 +00:00
xorl % e c x , % e c x
2010-02-24 10:54:25 +01:00
addl $ 1 , % e b x
2012-01-20 16:22:04 +00:00
adcl % e d x , % e c x
2010-02-24 10:54:25 +01:00
LOCK_ P R E F I X
cmpxchg8 b ( % e s i )
jne 1 b
2010-03-01 19:55:49 +01:00
movl $ 1 , % e a x
2010-02-24 10:54:25 +01:00
3 :
RESTORE e b x
ret
CFI_ E N D P R O C
ENDPROC( a t o m i c64 _ i n c _ n o t _ z e r o _ c x8 )