]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/powerpc/powerpc/atomic.S
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / powerpc / powerpc / atomic.S
1 /*-
2  * Copyright (c) 2000, 2001 Benno Rice
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #include <machine/asm.h>
30         
31         .text
32         
33 ASENTRY_NOPROF(atomic_set_8)
34 0:      lwarx   0, 0, 3         /* load old value */
35         slwi    4, 4, 24        /* shift the byte so it's in the right place */
36         or      0, 0, 4         /* generate new value */
37         stwcx.  0, 0, 3         /* attempt to store */
38         bne-    0               /* loop if failed */
39         eieio                   /* synchronise */
40         sync
41         blr                     /* return */
42
43 ASENTRY_NOPROF(atomic_clear_8)
44 0:      lwarx   0, 0, 3         /* load old value */
45         slwi    4, 4, 24        /* shift the byte so it's in the right place */
46         andc    0, 0, 4         /* generate new value */
47         stwcx.  0, 0, 3         /* attempt to store */
48         bne-    0               /* loop if failed */
49         eieio                   /* synchronise */
50         sync
51         blr                     /* return */
52
53 ASENTRY_NOPROF(atomic_add_8)
54 0:      lwarx   9, 0, 3         /* load old value */
55         srwi    0, 9, 24        /* byte alignment */
56         add     0, 4, 0         /* calculate new value */
57         slwi    0, 9, 24        /* byte alignment */
58         clrlwi  9, 9, 8         /* clear the byte in the original word */
59         or      9, 9, 0         /* copy back in to the original word */
60         stwcx.  9, 0, 3         /* attempt to store */
61         bne-    0               /* loop if failed */
62         eieio                   /* synchronise */
63         sync
64         blr                     /* return */
65
66 ASENTRY_NOPROF(atomic_subtract_8)
67 0:      lwarx   9, 0, 3         /* load old value */
68         srwi    0, 9, 24        /* byte alignment */
69         subf    0, 4, 0         /* calculate new value */
70         slwi    0, 9, 24        /* byte alignment */
71         clrlwi  9, 9, 8         /* clear the byte in the original word */
72         or      9, 9, 0         /* copy back in to the original word */
73         stwcx.  9, 0, 3         /* attempt to store */
74         bne-    0               /* loop if failed */
75         eieio                   /* synchronise */
76         sync
77         blr                     /* return */
78
79 ASENTRY_NOPROF(atomic_set_16)
80         li      11, 3           /* mask to test for alignment */
81         andc.   11, 3, 11       /* force address to be word-aligned */
82 0:      lwarx   12, 0, 11       /* load old value */
83         bne     1f              /* no realignment needed if it's aligned */
84         slwi    4, 4, 16        /* realign operand */
85 1:      or      12, 12, 4       /* calculate new value */
86         stwcx.  12, 0, 11       /* attempt to store */
87         bne-    0b              /* loop if failed */
88         eieio                   /* synchronise */
89         sync
90         blr                     /* return */
91
92 ASENTRY_NOPROF(atomic_clear_16)
93         li      11, 3           /* mask to test for alignment */
94         andc.   11, 3, 11       /* force address to be word-aligned */
95 0:      lwarx   12, 0, 11       /* load old value */
96         bne     1f              /* no realignment needed if it's aligned */
97         slwi    4, 4, 16        /* realign operand */
98 1:      andc    12, 12, 4       /* calculate new value */
99         stwcx.  12, 0, 11       /* attempt to store */
100         bne-    0b              /* loop if failed */
101         eieio                   /* synchronise */
102         sync
103         blr                     /* return */
104
105 ASENTRY_NOPROF(atomic_add_16)
106         li      11, 3           /* mask to test for alignment */
107         andc.   11, 3, 11       /* force address to be word-aligned */
108 0:      lwarx   12, 0, 11       /* load old value */
109         bne     1f              /* no realignment needed if it's aligned */
110         srwi    12, 9, 16       /* realign */
111 1:      add     12, 4, 12       /* calculate new value */
112         bne     2f              /* no realignment needed if it's aligned */
113         slwi    12, 12, 16      /* realign */
114 2:      clrlwi  9, 9, 16        /* clear old value */
115         or      9, 9, 12        /* copy in new value */
116         stwcx.  12, 0, 11       /* attempt to store */
117         bne-    0b              /* loop if failed */
118         eieio                   /* synchronise */
119         sync
120         blr                     /* return */
121
122 ASENTRY_NOPROF(atomic_subtract_16)
123         li      11, 3           /* mask to test for alignment */
124         andc.   11, 3, 11       /* force address to be word-aligned */
125 0:      lwarx   12, 0, 11       /* load old value */
126         bne     1f              /* no realignment needed if it's aligned */
127         srwi    12, 9, 16       /* realign */
128 1:      subf    12, 4, 12       /* calculate new value */
129         bne     2f              /* no realignment needed if it's aligned */
130         slwi    12, 12, 16      /* realign */
131 2:      clrlwi  9, 9, 16        /* clear old value */
132         or      9, 9, 12        /* copy in new value */
133         stwcx.  12, 0, 11       /* attempt to store */
134         bne-    0               /* loop if failed */
135         eieio                   /* synchronise */
136         sync
137         blr                     /* return */