ARM: atomics: prefetch the destination word for write prior to strex
[linux-2.6-block.git] / arch / arm / lib / bitops.h
CommitLineData
c36ef4b1
WD
1#include <asm/unwind.h>
2
6323f0cc 3#if __LINUX_ARM_ARCH__ >= 6
c36ef4b1
WD
4 .macro bitop, name, instr
5ENTRY( \name )
6UNWIND( .fnstart )
a16ede35
RK
7 ands ip, r1, #3
8 strneb r1, [ip] @ assert word-aligned
54ea06f6 9 mov r2, #1
6323f0cc
RK
10 and r3, r0, #31 @ Get bit offset
11 mov r0, r0, lsr #5
12 add r1, r1, r0, lsl #2 @ Get word offset
54ea06f6 13 mov r3, r2, lsl r3
6323f0cc 141: ldrex r2, [r1]
54ea06f6 15 \instr r2, r2, r3
6323f0cc 16 strex r0, r2, [r1]
e7ec0293 17 cmp r0, #0
54ea06f6 18 bne 1b
3ba6e69a 19 bx lr
c36ef4b1
WD
20UNWIND( .fnend )
21ENDPROC(\name )
54ea06f6
RK
22 .endm
23
c36ef4b1
WD
24 .macro testop, name, instr, store
25ENTRY( \name )
26UNWIND( .fnstart )
a16ede35
RK
27 ands ip, r1, #3
28 strneb r1, [ip] @ assert word-aligned
54ea06f6 29 mov r2, #1
6323f0cc
RK
30 and r3, r0, #31 @ Get bit offset
31 mov r0, r0, lsr #5
32 add r1, r1, r0, lsl #2 @ Get word offset
54ea06f6 33 mov r3, r2, lsl r3 @ create mask
bac4e960 34 smp_dmb
6323f0cc 351: ldrex r2, [r1]
54ea06f6 36 ands r0, r2, r3 @ save old value of bit
6323f0cc
RK
37 \instr r2, r2, r3 @ toggle bit
38 strex ip, r2, [r1]
614d73ed 39 cmp ip, #0
54ea06f6 40 bne 1b
bac4e960 41 smp_dmb
54ea06f6
RK
42 cmp r0, #0
43 movne r0, #1
3ba6e69a 442: bx lr
c36ef4b1
WD
45UNWIND( .fnend )
46ENDPROC(\name )
54ea06f6
RK
47 .endm
48#else
c36ef4b1
WD
49 .macro bitop, name, instr
50ENTRY( \name )
51UNWIND( .fnstart )
a16ede35
RK
52 ands ip, r1, #3
53 strneb r1, [ip] @ assert word-aligned
6323f0cc
RK
54 and r2, r0, #31
55 mov r0, r0, lsr #5
7a55fd0b
RK
56 mov r3, #1
57 mov r3, r3, lsl r2
59d1ff3b 58 save_and_disable_irqs ip
6323f0cc 59 ldr r2, [r1, r0, lsl #2]
7a55fd0b 60 \instr r2, r2, r3
6323f0cc 61 str r2, [r1, r0, lsl #2]
7a55fd0b
RK
62 restore_irqs ip
63 mov pc, lr
c36ef4b1
WD
64UNWIND( .fnend )
65ENDPROC(\name )
7a55fd0b
RK
66 .endm
67
68/**
69 * testop - implement a test_and_xxx_bit operation.
70 * @instr: operational instruction
71 * @store: store instruction
72 *
73 * Note: we can trivially conditionalise the store instruction
6cbdc8c5 74 * to avoid dirtying the data cache.
7a55fd0b 75 */
c36ef4b1
WD
76 .macro testop, name, instr, store
77ENTRY( \name )
78UNWIND( .fnstart )
a16ede35
RK
79 ands ip, r1, #3
80 strneb r1, [ip] @ assert word-aligned
6323f0cc
RK
81 and r3, r0, #31
82 mov r0, r0, lsr #5
59d1ff3b 83 save_and_disable_irqs ip
6323f0cc
RK
84 ldr r2, [r1, r0, lsl #2]!
85 mov r0, #1
7a55fd0b
RK
86 tst r2, r0, lsl r3
87 \instr r2, r2, r0, lsl r3
88 \store r2, [r1]
7a55fd0b 89 moveq r0, #0
0d928b0b 90 restore_irqs ip
7a55fd0b 91 mov pc, lr
c36ef4b1
WD
92UNWIND( .fnend )
93ENDPROC(\name )
7a55fd0b 94 .endm
54ea06f6 95#endif