2005-08-10 14:41:45 +01:00
2005-11-03 15:48:21 +00:00
# if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
2005-07-16 15:21:51 +01:00
. macro bitop , instr
mov r2 , # 1
and r3 , r0 , # 7 @ Get bit offset
add r1 , r1 , r0 , lsr # 3 @ Get byte offset
mov r3 , r2 , lsl r3
1 : ldrexb r2 , [ r1 ]
\ instr r2 , r2 , r3
strexb 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
mov pc , lr
. endm
. macro testop , instr , store
and r3 , r0 , # 7 @ Get bit offset
mov r2 , # 1
add r1 , r1 , r0 , lsr # 3 @ Get byte offset
mov r3 , r2 , lsl r3 @ create mask
2009-05-25 20:58:00 +01:00
smp_dmb
2005-07-16 15:21:51 +01:00
1 : ldrexb r2 , [ r1 ]
ands r0 , r2 , r3 @ save old value of bit
2005-07-27 23:00:05 +01:00
\ instr r2 , r2 , r3 @ toggle bit
strexb ip , r2 , [ r1 ]
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
2 : mov pc , lr
. endm
# else
2005-04-18 22:50:01 +01:00
. macro bitop , instr
and r2 , r0 , # 7
mov r3 , # 1
mov r3 , r3 , lsl r2
2005-11-09 15:04:22 +00:00
save_and_disable_irqs ip
2005-04-18 22:50:01 +01:00
ldrb r2 , [ r1 , r0 , lsr # 3 ]
\ instr r2 , r2 , r3
strb r2 , [ r1 , r0 , lsr # 3 ]
restore_irqs ip
mov pc , lr
. 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
*/
. macro testop , instr , store
add r1 , r1 , r0 , lsr # 3
and r3 , r0 , # 7
mov r0 , # 1
2005-11-09 15:04:22 +00:00
save_and_disable_irqs ip
2005-04-18 22:50:01 +01:00
ldrb r2 , [ r1 ]
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
2005-04-18 22:50:01 +01:00
mov pc , lr
. endm
2005-07-16 15:21:51 +01:00
# endif