blob: d6408d1ee543fe5e3ceabbcda01b25efb07676ba [file] [log] [blame]
Will Deaconc36ef4b2011-11-23 11:28:25 +01001#include <asm/unwind.h>
2
Russell King6323f0c2011-01-16 18:02:17 +00003#if __LINUX_ARM_ARCH__ >= 6
Will Deaconc36ef4b2011-11-23 11:28:25 +01004 .macro bitop, name, instr
5ENTRY( \name )
6UNWIND( .fnstart )
Russell Kinga16ede32011-01-16 17:59:44 +00007 ands ip, r1, #3
8 strneb r1, [ip] @ assert word-aligned
Russell King54ea06f2005-07-16 15:21:51 +01009 mov r2, #1
Russell King6323f0c2011-01-16 18:02:17 +000010 and r3, r0, #31 @ Get bit offset
11 mov r0, r0, lsr #5
12 add r1, r1, r0, lsl #2 @ Get word offset
Russell King54ea06f2005-07-16 15:21:51 +010013 mov r3, r2, lsl r3
Russell King6323f0c2011-01-16 18:02:17 +0000141: ldrex r2, [r1]
Russell King54ea06f2005-07-16 15:21:51 +010015 \instr r2, r2, r3
Russell King6323f0c2011-01-16 18:02:17 +000016 strex r0, r2, [r1]
Russell Kinge7ec0292005-07-28 20:36:26 +010017 cmp r0, #0
Russell King54ea06f2005-07-16 15:21:51 +010018 bne 1b
Dave Martin3ba6e692011-02-08 12:09:52 +010019 bx lr
Will Deaconc36ef4b2011-11-23 11:28:25 +010020UNWIND( .fnend )
21ENDPROC(\name )
Russell King54ea06f2005-07-16 15:21:51 +010022 .endm
23
Will Deaconc36ef4b2011-11-23 11:28:25 +010024 .macro testop, name, instr, store
25ENTRY( \name )
26UNWIND( .fnstart )
Russell Kinga16ede32011-01-16 17:59:44 +000027 ands ip, r1, #3
28 strneb r1, [ip] @ assert word-aligned
Russell King54ea06f2005-07-16 15:21:51 +010029 mov r2, #1
Russell King6323f0c2011-01-16 18:02:17 +000030 and r3, r0, #31 @ Get bit offset
31 mov r0, r0, lsr #5
32 add r1, r1, r0, lsl #2 @ Get word offset
Russell King54ea06f2005-07-16 15:21:51 +010033 mov r3, r2, lsl r3 @ create mask
Russell Kingbac4e962009-05-25 20:58:00 +010034 smp_dmb
Russell King6323f0c2011-01-16 18:02:17 +0000351: ldrex r2, [r1]
Russell King54ea06f2005-07-16 15:21:51 +010036 ands r0, r2, r3 @ save old value of bit
Russell King6323f0c2011-01-16 18:02:17 +000037 \instr r2, r2, r3 @ toggle bit
38 strex ip, r2, [r1]
Russell King614d73e2005-07-27 23:00:05 +010039 cmp ip, #0
Russell King54ea06f2005-07-16 15:21:51 +010040 bne 1b
Russell Kingbac4e962009-05-25 20:58:00 +010041 smp_dmb
Russell King54ea06f2005-07-16 15:21:51 +010042 cmp r0, #0
43 movne r0, #1
Dave Martin3ba6e692011-02-08 12:09:52 +0100442: bx lr
Will Deaconc36ef4b2011-11-23 11:28:25 +010045UNWIND( .fnend )
46ENDPROC(\name )
Russell King54ea06f2005-07-16 15:21:51 +010047 .endm
48#else
Will Deaconc36ef4b2011-11-23 11:28:25 +010049 .macro bitop, name, instr
50ENTRY( \name )
51UNWIND( .fnstart )
Russell Kinga16ede32011-01-16 17:59:44 +000052 ands ip, r1, #3
53 strneb r1, [ip] @ assert word-aligned
Russell King6323f0c2011-01-16 18:02:17 +000054 and r2, r0, #31
55 mov r0, r0, lsr #5
Russell King7a55fd02005-04-18 22:50:01 +010056 mov r3, #1
57 mov r3, r3, lsl r2
Russell King59d1ff32005-11-09 15:04:22 +000058 save_and_disable_irqs ip
Russell King6323f0c2011-01-16 18:02:17 +000059 ldr r2, [r1, r0, lsl #2]
Russell King7a55fd02005-04-18 22:50:01 +010060 \instr r2, r2, r3
Russell King6323f0c2011-01-16 18:02:17 +000061 str r2, [r1, r0, lsl #2]
Russell King7a55fd02005-04-18 22:50:01 +010062 restore_irqs ip
63 mov pc, lr
Will Deaconc36ef4b2011-11-23 11:28:25 +010064UNWIND( .fnend )
65ENDPROC(\name )
Russell King7a55fd02005-04-18 22:50:01 +010066 .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
Simon Arlott6cbdc8c2007-05-11 20:40:30 +010074 * to avoid dirtying the data cache.
Russell King7a55fd02005-04-18 22:50:01 +010075 */
Will Deaconc36ef4b2011-11-23 11:28:25 +010076 .macro testop, name, instr, store
77ENTRY( \name )
78UNWIND( .fnstart )
Russell Kinga16ede32011-01-16 17:59:44 +000079 ands ip, r1, #3
80 strneb r1, [ip] @ assert word-aligned
Russell King6323f0c2011-01-16 18:02:17 +000081 and r3, r0, #31
82 mov r0, r0, lsr #5
Russell King59d1ff32005-11-09 15:04:22 +000083 save_and_disable_irqs ip
Russell King6323f0c2011-01-16 18:02:17 +000084 ldr r2, [r1, r0, lsl #2]!
85 mov r0, #1
Russell King7a55fd02005-04-18 22:50:01 +010086 tst r2, r0, lsl r3
87 \instr r2, r2, r0, lsl r3
88 \store r2, [r1]
Russell King7a55fd02005-04-18 22:50:01 +010089 moveq r0, #0
Uwe Kleine-König0d928b02009-08-13 20:38:17 +020090 restore_irqs ip
Russell King7a55fd02005-04-18 22:50:01 +010091 mov pc, lr
Will Deaconc36ef4b2011-11-23 11:28:25 +010092UNWIND( .fnend )
93ENDPROC(\name )
Russell King7a55fd02005-04-18 22:50:01 +010094 .endm
Russell King54ea06f2005-07-16 15:21:51 +010095#endif