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