]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/sparc64/include/asmacros.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / sparc64 / include / asmacros.h
1 /*-
2  * Copyright (c) 2001 Jake Burkholder.
3  * Copyright (c) 2011 Marius Strobl <marius@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29
30 #ifndef _MACHINE_ASMACROS_H_
31 #define _MACHINE_ASMACROS_H_
32
33 #ifdef _KERNEL
34
35 /*
36  * Normal and alternate %g6 point to the pcb of the current process.  Normal,
37  * alternate and interrupt %g7 point to per-cpu data.
38  */
39 #define PCB_REG         %g6
40 #define PCPU_REG        %g7
41
42 /*
43  * Alternate %g5 points to a per-cpu panic stack, which is used as a last
44  * resort, and for temporarily saving alternate globals.
45  */
46 #define ASP_REG         %g5
47
48 #ifdef LOCORE
49
50 /*
51  * Atomically decrement an integer in memory.
52  */
53 #define ATOMIC_DEC_INT(r1, r2, r3)                                      \
54         lduw    [r1], r2 ;                                              \
55 9:      sub     r2, 1, r3 ;                                             \
56         casa    [r1] ASI_N, r2, r3 ;                                    \
57         cmp     r2, r3 ;                                                \
58         bne,pn  %icc, 9b ;                                              \
59          mov    r3, r2
60
61 /*
62  * Atomically increment an integer in memory.
63  */
64 #define ATOMIC_INC_INT(r1, r2, r3)                                      \
65         lduw    [r1], r2 ;                                              \
66 9:      add     r2, 1, r3 ;                                             \
67         casa    [r1] ASI_N, r2, r3 ;                                    \
68         cmp     r2, r3 ;                                                \
69         bne,pn  %icc, 9b ;                                              \
70          mov    r3, r2
71
72 /*
73  * Atomically increment a long in memory.
74  */
75 #define ATOMIC_INC_LONG(r1, r2, r3)                                     \
76         ldx     [r1], r2 ;                                              \
77 9:      add     r2, 1, r3 ;                                             \
78         casxa   [r1] ASI_N, r2, r3 ;                                    \
79         cmp     r2, r3 ;                                                \
80         bne,pn  %xcc, 9b ;                                              \
81          mov    r3, r2
82
83 /*
84  * Atomically clear a number of bits of an integer in memory.
85  */
86 #define ATOMIC_CLEAR_INT(r1, r2, r3, bits)                              \
87         lduw    [r1], r2 ;                                              \
88 9:      andn    r2, bits, r3 ;                                          \
89         casa    [r1] ASI_N, r2, r3 ;                                    \
90         cmp     r2, r3 ;                                                \
91         bne,pn  %icc, 9b ;                                              \
92          mov    r3, r2
93
94 /*
95  * Atomically clear a number of bits of a long in memory.
96  */
97 #define ATOMIC_CLEAR_LONG(r1, r2, r3, bits)                             \
98         ldx     [r1], r2 ;                                              \
99 9:      andn    r2, bits, r3 ;                                          \
100         casxa   [r1] ASI_N, r2, r3 ;                                    \
101         cmp     r2, r3 ;                                                \
102         bne,pn  %xcc, 9b ;                                              \
103          mov    r3, r2
104
105 /*
106  * Atomically load an integer from memory.
107  */
108 #define ATOMIC_LOAD_INT(r1, val)                                        \
109         clr     val ;                                                   \
110         casa    [r1] ASI_N, %g0, val
111
112 /*
113  * Atomically load a long from memory.
114  */
115 #define ATOMIC_LOAD_LONG(r1, val)                                       \
116         clr     val ;                                                   \
117         casxa   [r1] ASI_N, %g0, val
118
119 /*
120  * Atomically set a number of bits of an integer in memory.
121  */
122 #define ATOMIC_SET_INT(r1, r2, r3, bits)                                \
123         lduw    [r1], r2 ;                                              \
124 9:      or      r2, bits, r3 ;                                          \
125         casa    [r1] ASI_N, r2, r3 ;                                    \
126         cmp     r2, r3 ;                                                \
127         bne,pn  %icc, 9b ;                                              \
128          mov    r3, r2
129
130 /*
131  * Atomically set a number of bits of a long in memory.
132  */
133 #define ATOMIC_SET_LONG(r1, r2, r3, bits)                               \
134         ldx     [r1], r2 ;                                              \
135 9:      or      r2, bits, r3 ;                                          \
136         casxa   [r1] ASI_N, r2, r3 ;                                    \
137         cmp     r2, r3 ;                                                \
138         bne,pn  %xcc, 9b ;                                              \
139          mov    r3, r2
140
141 /*
142  * Atomically store an integer in memory.
143  */
144 #define ATOMIC_STORE_INT(r1, r2, r3, val)                               \
145         lduw    [r1], r2 ;                                              \
146 9:      mov     val, r3 ;                                               \
147         casa    [r1] ASI_N, r2, r3 ;                                    \
148         cmp     r2, r3 ;                                                \
149         bne,pn  %icc, 9b ;                                              \
150          mov    r3, r2
151
152 /*
153  * Atomically store a long in memory.
154  */
155 #define ATOMIC_STORE_LONG(r1, r2, r3, val)                              \
156         ldx     [r1], r2 ;                                              \
157 9:      mov     val, r3 ;                                               \
158         casxa   [r1] ASI_N, r2, r3 ;                                    \
159         cmp     r2, r3 ;                                                \
160         bne,pn  %xcc, 9b ;                                              \
161          mov    r3, r2
162
163 #define PCPU(member)    PCPU_REG + PC_ ## member
164 #define PCPU_ADDR(member, reg)                                          \
165         add     PCPU_REG, PC_ ## member, reg
166
167 #define DEBUGGER()                                                      \
168         ta      %xcc, 1
169
170 #define PANIC(msg, r1)                                                  \
171         .sect   .rodata ;                                               \
172 9:      .asciz  msg ;                                                   \
173         .previous ;                                                     \
174         SET(9b, r1, %o0) ;                                              \
175         call    panic ;                                                 \
176          nop
177
178 #ifdef INVARIANTS
179 #define KASSERT(r1, msg)                                                \
180         brnz,pt r1, 8f ;                                                \
181          nop ;                                                          \
182         PANIC(msg, r1) ;                                                \
183 8:
184 #else
185 #define KASSERT(r1, msg)
186 #endif
187
188 #define PUTS(msg, r1)                                                   \
189         .sect   .rodata ;                                               \
190 9:      .asciz  msg ;                                                   \
191         .previous ;                                                     \
192         SET(9b, r1, %o0) ;                                              \
193         call    printf ;                                                \
194          nop
195
196 #define _ALIGN_DATA     .align 8
197
198 #define DATA(name)                                                      \
199         .data ;                                                         \
200         _ALIGN_DATA ;                                                   \
201         .globl  name ;                                                  \
202         .type   name, @object ;                                         \
203 name:
204
205 #define EMPTY
206
207 /*
208  * Generate atomic compare and swap, load and store instructions for the
209  * corresponding width and ASI (or not).  Note that we want to evaluate the
210  * macro args before concatenating, so that EMPTY really turns into nothing.
211  */
212 #define         _LD(w, a)       ld ## w ## a
213 #define         _ST(w, a)       st ## w ## a
214 #define         _CAS(w, a)      cas ## w ## a
215
216 #define         LD(w, a)        _LD(w, a)
217 #define         ST(w, a)        _ST(w, a)
218 #define         CAS(w, a)       _CAS(w, a)
219
220 #endif /* LOCORE */
221
222 #endif /* _KERNEL */
223
224 #endif /* !_MACHINE_ASMACROS_H_ */