linux/arch/sparc/lib/atomic_64.S
<<
>>
Prefs
   1/* atomic.S: These things are too big to do inline.
   2 *
   3 * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
   4 */
   5
   6#include <asm/asi.h>
   7#include <asm/backoff.h>
   8
   9        .text
  10
  11        /* Two versions of the atomic routines, one that
  12         * does not return a value and does not perform
  13         * memory barriers, and a second which returns
  14         * a value and does the barriers.
  15         */
  16        .globl  atomic_add
  17        .type   atomic_add,#function
  18atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
  19        BACKOFF_SETUP(%o2)
  201:      lduw    [%o1], %g1
  21        add     %g1, %o0, %g7
  22        cas     [%o1], %g1, %g7
  23        cmp     %g1, %g7
  24        bne,pn  %icc, 2f
  25         nop
  26        retl
  27         nop
  282:      BACKOFF_SPIN(%o2, %o3, 1b)
  29        .size   atomic_add, .-atomic_add
  30
  31        .globl  atomic_sub
  32        .type   atomic_sub,#function
  33atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
  34        BACKOFF_SETUP(%o2)
  351:      lduw    [%o1], %g1
  36        sub     %g1, %o0, %g7
  37        cas     [%o1], %g1, %g7
  38        cmp     %g1, %g7
  39        bne,pn  %icc, 2f
  40         nop
  41        retl
  42         nop
  432:      BACKOFF_SPIN(%o2, %o3, 1b)
  44        .size   atomic_sub, .-atomic_sub
  45
  46        .globl  atomic_add_ret
  47        .type   atomic_add_ret,#function
  48atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
  49        BACKOFF_SETUP(%o2)
  501:      lduw    [%o1], %g1
  51        add     %g1, %o0, %g7
  52        cas     [%o1], %g1, %g7
  53        cmp     %g1, %g7
  54        bne,pn  %icc, 2f
  55         add    %g7, %o0, %g7
  56        sra     %g7, 0, %o0
  57        retl
  58         nop
  592:      BACKOFF_SPIN(%o2, %o3, 1b)
  60        .size   atomic_add_ret, .-atomic_add_ret
  61
  62        .globl  atomic_sub_ret
  63        .type   atomic_sub_ret,#function
  64atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
  65        BACKOFF_SETUP(%o2)
  661:      lduw    [%o1], %g1
  67        sub     %g1, %o0, %g7
  68        cas     [%o1], %g1, %g7
  69        cmp     %g1, %g7
  70        bne,pn  %icc, 2f
  71         sub    %g7, %o0, %g7
  72        sra     %g7, 0, %o0
  73        retl
  74         nop
  752:      BACKOFF_SPIN(%o2, %o3, 1b)
  76        .size   atomic_sub_ret, .-atomic_sub_ret
  77
  78        .globl  atomic64_add
  79        .type   atomic64_add,#function
  80atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
  81        BACKOFF_SETUP(%o2)
  821:      ldx     [%o1], %g1
  83        add     %g1, %o0, %g7
  84        casx    [%o1], %g1, %g7
  85        cmp     %g1, %g7
  86        bne,pn  %xcc, 2f
  87         nop
  88        retl
  89         nop
  902:      BACKOFF_SPIN(%o2, %o3, 1b)
  91        .size   atomic64_add, .-atomic64_add
  92
  93        .globl  atomic64_sub
  94        .type   atomic64_sub,#function
  95atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
  96        BACKOFF_SETUP(%o2)
  971:      ldx     [%o1], %g1
  98        sub     %g1, %o0, %g7
  99        casx    [%o1], %g1, %g7
 100        cmp     %g1, %g7
 101        bne,pn  %xcc, 2f
 102         nop
 103        retl
 104         nop
 1052:      BACKOFF_SPIN(%o2, %o3, 1b)
 106        .size   atomic64_sub, .-atomic64_sub
 107
 108        .globl  atomic64_add_ret
 109        .type   atomic64_add_ret,#function
 110atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
 111        BACKOFF_SETUP(%o2)
 1121:      ldx     [%o1], %g1
 113        add     %g1, %o0, %g7
 114        casx    [%o1], %g1, %g7
 115        cmp     %g1, %g7
 116        bne,pn  %xcc, 2f
 117         add    %g7, %o0, %g7
 118        mov     %g7, %o0
 119        retl
 120         nop
 1212:      BACKOFF_SPIN(%o2, %o3, 1b)
 122        .size   atomic64_add_ret, .-atomic64_add_ret
 123
 124        .globl  atomic64_sub_ret
 125        .type   atomic64_sub_ret,#function
 126atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
 127        BACKOFF_SETUP(%o2)
 1281:      ldx     [%o1], %g1
 129        sub     %g1, %o0, %g7
 130        casx    [%o1], %g1, %g7
 131        cmp     %g1, %g7
 132        bne,pn  %xcc, 2f
 133         sub    %g7, %o0, %g7
 134        mov     %g7, %o0
 135        retl
 136         nop
 1372:      BACKOFF_SPIN(%o2, %o3, 1b)
 138        .size   atomic64_sub_ret, .-atomic64_sub_ret
 139