2014-06-30 16:29:12 +01:00
# include <asm/assembler.h>
2011-11-23 11:28:25 +01:00
# include <asm/unwind.h>
2016-01-13 13:46:22 -05:00
# include <asm/export.h>
2011-11-23 11:28:25 +01:00
2011-01-16 18:02:17 +00:00
# if __LINUX_ARM_ARCH__ >= 6
2011-11-23 11:28:25 +01:00
. macro bitop , name , instr
ENTRY ( \ name )
UNWIND ( . fnstart )
2011-01-16 17:59:44 +00:00
ands ip , r1 , # 3
strneb r1 , [ ip ] @ assert word - aligned
2005-07-16 15:21:51 +01:00
mov r2 , # 1
2011-01-16 18:02:17 +00:00
and r3 , r0 , # 31 @ Get bit offset
mov r0 , r0 , lsr # 5
add r1 , r1 , r0 , lsl # 2 @ Get word offset
2013-11-19 15:46:11 +01:00
# if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
2013-06-27 12:01:51 +01:00
. arch_extension mp
ALT_SMP ( W ( pldw ) [ r1 ] )
ALT_UP ( W ( nop ) )
# endif
2005-07-16 15:21:51 +01:00
mov r3 , r2 , lsl r3
2011-01-16 18:02:17 +00:00
1 : ldrex r2 , [ r1 ]
2005-07-16 15:21:51 +01:00
\ instr r2 , r2 , r3
2011-01-16 18:02:17 +00:00
strex r0 , r2 , [ r1 ]
2005-07-28 20:36:26 +01:00
cmp r0 , # 0
2005-07-16 15:21:51 +01:00
bne 1 b
2011-02-08 12:09:52 +01:00
bx lr
2011-11-23 11:28:25 +01:00
UNWIND ( . fnend )
ENDPROC ( \ name )
2016-01-13 13:46:22 -05:00
EXPORT_SYMBOL ( \ name )
2005-07-16 15:21:51 +01:00
. endm
2011-11-23 11:28:25 +01:00
. macro testop , name , instr , store
ENTRY ( \ name )
UNWIND ( . fnstart )
2011-01-16 17:59:44 +00:00
ands ip , r1 , # 3
strneb r1 , [ ip ] @ assert word - aligned
2005-07-16 15:21:51 +01:00
mov r2 , # 1
2011-01-16 18:02:17 +00:00
and r3 , r0 , # 31 @ Get bit offset
mov r0 , r0 , lsr # 5
add r1 , r1 , r0 , lsl # 2 @ Get word offset
2005-07-16 15:21:51 +01:00
mov r3 , r2 , lsl r3 @ create mask
2009-05-25 20:58:00 +01:00
smp_dmb
2014-02-21 17:01:48 +01:00
# if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
. arch_extension mp
ALT_SMP ( W ( pldw ) [ r1 ] )
ALT_UP ( W ( nop ) )
# endif
2011-01-16 18:02:17 +00:00
1 : ldrex r2 , [ r1 ]
2005-07-16 15:21:51 +01:00
ands r0 , r2 , r3 @ save old value of bit
2011-01-16 18:02:17 +00:00
\ instr r2 , r2 , r3 @ toggle bit
strex ip , r2 , [ r1 ]
2005-07-27 23:00:05 +01:00
cmp ip , # 0
2005-07-16 15:21:51 +01:00
bne 1 b
2009-05-25 20:58:00 +01:00
smp_dmb
2005-07-16 15:21:51 +01:00
cmp r0 , # 0
movne r0 , # 1
2011-02-08 12:09:52 +01:00
2 : bx lr
2011-11-23 11:28:25 +01:00
UNWIND ( . fnend )
ENDPROC ( \ name )
2016-01-13 13:46:22 -05:00
EXPORT_SYMBOL ( \ name )
2005-07-16 15:21:51 +01:00
. endm
# else
2011-11-23 11:28:25 +01:00
. macro bitop , name , instr
ENTRY ( \ name )
UNWIND ( . fnstart )
2011-01-16 17:59:44 +00:00
ands ip , r1 , # 3
strneb r1 , [ ip ] @ assert word - aligned
2011-01-16 18:02:17 +00:00
and r2 , r0 , # 31
mov r0 , r0 , lsr # 5
2005-04-18 22:50:01 +01:00
mov r3 , # 1
mov r3 , r3 , lsl r2
2005-11-09 15:04:22 +00:00
save_and_disable_irqs ip
2011-01-16 18:02:17 +00:00
ldr r2 , [ r1 , r0 , lsl # 2 ]
2005-04-18 22:50:01 +01:00
\ instr r2 , r2 , r3
2011-01-16 18:02:17 +00:00
str r2 , [ r1 , r0 , lsl # 2 ]
2005-04-18 22:50:01 +01:00
restore_irqs ip
2014-06-30 16:29:12 +01:00
ret lr
2011-11-23 11:28:25 +01:00
UNWIND ( . fnend )
ENDPROC ( \ name )
2016-01-13 13:46:22 -05:00
EXPORT_SYMBOL ( \ name )
2005-04-18 22:50:01 +01:00
. endm
/**
* testop - implement a test_and_xxx_bit operation .
* @ instr : operational instruction
* @ store : store instruction
*
* Note : we can trivially conditionalise the store instruction
2007-05-11 20:40:30 +01:00
* to avoid dirtying the data cache .
2005-04-18 22:50:01 +01:00
*/
2011-11-23 11:28:25 +01:00
. macro testop , name , instr , store
ENTRY ( \ name )
UNWIND ( . fnstart )
2011-01-16 17:59:44 +00:00
ands ip , r1 , # 3
strneb r1 , [ ip ] @ assert word - aligned
2011-01-16 18:02:17 +00:00
and r3 , r0 , # 31
mov r0 , r0 , lsr # 5
2005-11-09 15:04:22 +00:00
save_and_disable_irqs ip
2011-01-16 18:02:17 +00:00
ldr r2 , [ r1 , r0 , lsl # 2 ] !
mov r0 , # 1
2005-04-18 22:50:01 +01:00
tst r2 , r0 , lsl r3
\ instr r2 , r2 , r0 , lsl r3
\ store r2 , [ r1 ]
moveq r0 , # 0
2009-08-13 20:38:17 +02:00
restore_irqs ip
2014-06-30 16:29:12 +01:00
ret lr
2011-11-23 11:28:25 +01:00
UNWIND ( . fnend )
ENDPROC ( \ name )
2016-01-13 13:46:22 -05:00
EXPORT_SYMBOL ( \ name )
2005-04-18 22:50:01 +01:00
. endm
2005-07-16 15:21:51 +01:00
# endif