linux/arch/arm/lib/bitops.h
<<
>>
Prefs
   1#include <asm/unwind.h>
   2
   3#if __LINUX_ARM_ARCH__ >= 6
   4        .macro  bitop, name, instr
   5ENTRY(  \name           )
   6UNWIND( .fnstart        )
   7        ands    ip, r1, #3
   8        strneb  r1, [ip]                @ assert word-aligned
   9        mov     r2, #1
  10        and     r3, r0, #31             @ Get bit offset
  11        mov     r0, r0, lsr #5
  12        add     r1, r1, r0, lsl #2      @ Get word offset
  13        mov     r3, r2, lsl r3
  141:      ldrex   r2, [r1]
  15        \instr  r2, r2, r3
  16        strex   r0, r2, [r1]
  17        cmp     r0, #0
  18        bne     1b
  19        bx      lr
  20UNWIND( .fnend          )
  21ENDPROC(\name           )
  22        .endm
  23
  24        .macro  testop, name, instr, store
  25ENTRY(  \name           )
  26UNWIND( .fnstart        )
  27        ands    ip, r1, #3
  28        strneb  r1, [ip]                @ assert word-aligned
  29        mov     r2, #1
  30        and     r3, r0, #31             @ Get bit offset
  31        mov     r0, r0, lsr #5
  32        add     r1, r1, r0, lsl #2      @ Get word offset
  33        mov     r3, r2, lsl r3          @ create mask
  34        smp_dmb
  351:      ldrex   r2, [r1]
  36        ands    r0, r2, r3              @ save old value of bit
  37        \instr  r2, r2, r3              @ toggle bit
  38        strex   ip, r2, [r1]
  39        cmp     ip, #0
  40        bne     1b
  41        smp_dmb
  42        cmp     r0, #0
  43        movne   r0, #1
  442:      bx      lr
  45UNWIND( .fnend          )
  46ENDPROC(\name           )
  47        .endm
  48#else
  49        .macro  bitop, name, instr
  50ENTRY(  \name           )
  51UNWIND( .fnstart        )
  52        ands    ip, r1, #3
  53        strneb  r1, [ip]                @ assert word-aligned
  54        and     r2, r0, #31
  55        mov     r0, r0, lsr #5
  56        mov     r3, #1
  57        mov     r3, r3, lsl r2
  58        save_and_disable_irqs ip
  59        ldr     r2, [r1, r0, lsl #2]
  60        \instr  r2, r2, r3
  61        str     r2, [r1, r0, lsl #2]
  62        restore_irqs ip
  63        mov     pc, lr
  64UNWIND( .fnend          )
  65ENDPROC(\name           )
  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
  74 * to avoid dirtying the data cache.
  75 */
  76        .macro  testop, name, instr, store
  77ENTRY(  \name           )
  78UNWIND( .fnstart        )
  79        ands    ip, r1, #3
  80        strneb  r1, [ip]                @ assert word-aligned
  81        and     r3, r0, #31
  82        mov     r0, r0, lsr #5
  83        save_and_disable_irqs ip
  84        ldr     r2, [r1, r0, lsl #2]!
  85        mov     r0, #1
  86        tst     r2, r0, lsl r3
  87        \instr  r2, r2, r0, lsl r3
  88        \store  r2, [r1]
  89        moveq   r0, #0
  90        restore_irqs ip
  91        mov     pc, lr
  92UNWIND( .fnend          )
  93ENDPROC(\name           )
  94        .endm
  95#endif
  96