1/* $Id: bitops.S,v 1.1.1.1 2007-08-03 18:52:18 $ 2 * bitops.S: Sparc64 atomic bit operations. 3 * 4 * Copyright (C) 2000 David S. Miller (davem@redhat.com) 5 */ 6 7#include <asm/asi.h> 8 9 .text 10 11 /* On SMP we need to use memory barriers to ensure 12 * correct memory operation ordering, nop these out 13 * for uniprocessor. 14 */ 15 16#ifdef CONFIG_SMP 17#define BITOP_PRE_BARRIER membar #StoreLoad | #LoadLoad 18#define BITOP_POST_BARRIER \ 19 ba,pt %xcc, 80b; \ 20 membar #StoreLoad | #StoreStore 21 2280: retl 23 nop 24#else 25#define BITOP_PRE_BARRIER 26#define BITOP_POST_BARRIER 27#endif 28 29 .globl test_and_set_bit 30 .type test_and_set_bit,#function 31test_and_set_bit: /* %o0=nr, %o1=addr */ 32 BITOP_PRE_BARRIER 33 srlx %o0, 6, %g1 34 mov 1, %o2 35 sllx %g1, 3, %g3 36 and %o0, 63, %g2 37 sllx %o2, %g2, %o2 38 add %o1, %g3, %o1 391: ldx [%o1], %g7 40 or %g7, %o2, %g1 41 casx [%o1], %g7, %g1 42 cmp %g7, %g1 43 bne,pn %xcc, 1b 44 and %g7, %o2, %g2 45 clr %o0 46 movrne %g2, 1, %o0 47 BITOP_POST_BARRIER 48 retl 49 nop 50 .size test_and_set_bit, .-test_and_set_bit 51 52 .globl test_and_clear_bit 53 .type test_and_clear_bit,#function 54test_and_clear_bit: /* %o0=nr, %o1=addr */ 55 BITOP_PRE_BARRIER 56 srlx %o0, 6, %g1 57 mov 1, %o2 58 sllx %g1, 3, %g3 59 and %o0, 63, %g2 60 sllx %o2, %g2, %o2 61 add %o1, %g3, %o1 621: ldx [%o1], %g7 63 andn %g7, %o2, %g1 64 casx [%o1], %g7, %g1 65 cmp %g7, %g1 66 bne,pn %xcc, 1b 67 and %g7, %o2, %g2 68 clr %o0 69 movrne %g2, 1, %o0 70 BITOP_POST_BARRIER 71 retl 72 nop 73 .size test_and_clear_bit, .-test_and_clear_bit 74 75 .globl test_and_change_bit 76 .type test_and_change_bit,#function 77test_and_change_bit: /* %o0=nr, %o1=addr */ 78 BITOP_PRE_BARRIER 79 srlx %o0, 6, %g1 80 mov 1, %o2 81 sllx %g1, 3, %g3 82 and %o0, 63, %g2 83 sllx %o2, %g2, %o2 84 add %o1, %g3, %o1 851: ldx [%o1], %g7 86 xor %g7, %o2, %g1 87 casx [%o1], %g7, %g1 88 cmp %g7, %g1 89 bne,pn %xcc, 1b 90 and %g7, %o2, %g2 91 clr %o0 92 movrne %g2, 1, %o0 93 BITOP_POST_BARRIER 94 retl 95 nop 96 .size test_and_change_bit, .-test_and_change_bit 97 98 .globl set_bit 99 .type set_bit,#function 100set_bit: /* %o0=nr, %o1=addr */ 101 srlx %o0, 6, %g1 102 mov 1, %o2 103 sllx %g1, 3, %g3 104 and %o0, 63, %g2 105 sllx %o2, %g2, %o2 106 add %o1, %g3, %o1 1071: ldx [%o1], %g7 108 or %g7, %o2, %g1 109 casx [%o1], %g7, %g1 110 cmp %g7, %g1 111 bne,pn %xcc, 1b 112 nop 113 retl 114 nop 115 .size set_bit, .-set_bit 116 117 .globl clear_bit 118 .type clear_bit,#function 119clear_bit: /* %o0=nr, %o1=addr */ 120 srlx %o0, 6, %g1 121 mov 1, %o2 122 sllx %g1, 3, %g3 123 and %o0, 63, %g2 124 sllx %o2, %g2, %o2 125 add %o1, %g3, %o1 1261: ldx [%o1], %g7 127 andn %g7, %o2, %g1 128 casx [%o1], %g7, %g1 129 cmp %g7, %g1 130 bne,pn %xcc, 1b 131 nop 132 retl 133 nop 134 .size clear_bit, .-clear_bit 135 136 .globl change_bit 137 .type change_bit,#function 138change_bit: /* %o0=nr, %o1=addr */ 139 srlx %o0, 6, %g1 140 mov 1, %o2 141 sllx %g1, 3, %g3 142 and %o0, 63, %g2 143 sllx %o2, %g2, %o2 144 add %o1, %g3, %o1 1451: ldx [%o1], %g7 146 xor %g7, %o2, %g1 147 casx [%o1], %g7, %g1 148 cmp %g7, %g1 149 bne,pn %xcc, 1b 150 nop 151 retl 152 nop 153 .size change_bit, .-change_bit 154