macros.h revision 1.23 1 1.23 ragge /* $NetBSD: macros.h,v 1.23 2001/06/03 15:08:32 ragge Exp $ */
2 1.2 cgd
3 1.1 ragge /*
4 1.18 ragge * Copyright (c) 1994, 1998, 2000 Ludd, University of Lule}, Sweden.
5 1.1 ragge * All rights reserved.
6 1.1 ragge *
7 1.1 ragge * Redistribution and use in source and binary forms, with or without
8 1.1 ragge * modification, are permitted provided that the following conditions
9 1.1 ragge * are met:
10 1.1 ragge * 1. Redistributions of source code must retain the above copyright
11 1.1 ragge * notice, this list of conditions and the following disclaimer.
12 1.1 ragge * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 ragge * notice, this list of conditions and the following disclaimer in the
14 1.1 ragge * documentation and/or other materials provided with the distribution.
15 1.1 ragge * 3. All advertising materials mentioning features or use of this software
16 1.1 ragge * must display the following acknowledgement:
17 1.1 ragge * This product includes software developed at Ludd, University of Lule}.
18 1.1 ragge * 4. The name of the author may not be used to endorse or promote products
19 1.1 ragge * derived from this software without specific prior written permission
20 1.1 ragge *
21 1.1 ragge * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.1 ragge * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.1 ragge * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.1 ragge * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.1 ragge * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.1 ragge * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.1 ragge * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.1 ragge * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.1 ragge * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 1.1 ragge * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.1 ragge */
32 1.1 ragge
33 1.1 ragge /* All bugs are subject to removal without further notice */
34 1.3 ragge
35 1.17 ragge #if !defined(_VAX_MACROS_H_) && !defined(lint)
36 1.15 ragge #define _VAX_MACROS_H_
37 1.1 ragge
38 1.1 ragge /* Here general macros are supposed to be stored */
39 1.1 ragge
40 1.16 ragge static __inline__ int
41 1.16 ragge ffs(int reg)
42 1.16 ragge {
43 1.3 ragge register int val;
44 1.3 ragge
45 1.22 matt __asm__ __volatile ("ffs $0,$32,%1,%0
46 1.22 matt bneq 1f
47 1.22 matt mnegl $1,%0
48 1.22 matt 1: incl %0"
49 1.19 matt : "=&r" (val)
50 1.3 ragge : "r" (reg) );
51 1.3 ragge return val;
52 1.3 ragge }
53 1.3 ragge
54 1.16 ragge static __inline__ void
55 1.16 ragge _remque(void *p)
56 1.16 ragge {
57 1.13 thorpej __asm__ __volatile ("remque (%0),%0;clrl 4(%0)"
58 1.3 ragge :
59 1.3 ragge : "r" (p)
60 1.3 ragge : "memory" );
61 1.3 ragge }
62 1.3 ragge
63 1.16 ragge static __inline__ void
64 1.16 ragge _insque(void *p, void *q)
65 1.16 ragge {
66 1.22 matt __asm__ __volatile ("insque (%0),(%1)"
67 1.15 ragge :
68 1.15 ragge : "r" (p),"r" (q)
69 1.15 ragge : "memory" );
70 1.3 ragge }
71 1.3 ragge
72 1.16 ragge static __inline__ void *
73 1.22 matt memcpy(void *to, const void *from, size_t len)
74 1.16 ragge {
75 1.22 matt __asm__ __volatile ("movc3 %0,%1,%2"
76 1.16 ragge :
77 1.22 matt : "g" (len), "m" (*(char *)from), "m" (*(char *)to)
78 1.16 ragge :"r0","r1","r2","r3","r4","r5","memory","cc");
79 1.22 matt return to;
80 1.16 ragge }
81 1.16 ragge static __inline__ void *
82 1.22 matt memmove(void *to, const void *from, size_t len)
83 1.16 ragge {
84 1.22 matt __asm__ __volatile ("movc3 %0,%1,%2"
85 1.3 ragge :
86 1.22 matt : "g" (len), "m" (*(char *)from), "m" (*(char *)to)
87 1.16 ragge :"r0","r1","r2","r3","r4","r5","memory","cc");
88 1.22 matt return to;
89 1.16 ragge }
90 1.16 ragge
91 1.16 ragge static __inline__ void
92 1.22 matt bcopy(const void *from, void *to, size_t len)
93 1.16 ragge {
94 1.22 matt __asm__ __volatile ("movc3 %0,%1,%2"
95 1.16 ragge :
96 1.22 matt : "g" (len), "m" (*(char *)from), "m" (*(char *)to)
97 1.16 ragge :"r0","r1","r2","r3","r4","r5","memory","cc");
98 1.3 ragge }
99 1.3 ragge
100 1.20 matt void blkclr __P((void *, size_t));
101 1.15 ragge
102 1.16 ragge static __inline__ void *
103 1.16 ragge memset(void *block, int c, size_t len)
104 1.16 ragge {
105 1.16 ragge if (len > 65535)
106 1.16 ragge blkclr(block, len);
107 1.16 ragge else {
108 1.22 matt __asm__ __volatile ("movc5 $0,(sp),%2,%1,%0"
109 1.16 ragge :
110 1.22 matt : "m" (*(char *)block), "g" (len), "g" (c)
111 1.16 ragge :"r0","r1","r2","r3","r4","r5","memory","cc");
112 1.16 ragge }
113 1.16 ragge return block;
114 1.16 ragge }
115 1.16 ragge
116 1.16 ragge static __inline__ void
117 1.20 matt bzero(void *block, size_t len)
118 1.16 ragge {
119 1.15 ragge if (len > 65535)
120 1.15 ragge blkclr(block, len);
121 1.15 ragge else {
122 1.22 matt __asm__ __volatile ("movc5 $0,(sp),$0,%1,%0"
123 1.3 ragge :
124 1.22 matt : "m" (*(char *)block), "g" (len)
125 1.16 ragge :"r0","r1","r2","r3","r4","r5","memory","cc");
126 1.15 ragge }
127 1.3 ragge }
128 1.3 ragge
129 1.16 ragge /* XXX - the return syntax of memcmp is wrong */
130 1.16 ragge static __inline__ int
131 1.16 ragge memcmp(const void *b1, const void *b2, size_t len)
132 1.16 ragge {
133 1.17 ragge register int ret;
134 1.16 ragge
135 1.16 ragge __asm__ __volatile("cmpc3 %3,(%1),(%2);movl r0,%0"
136 1.16 ragge : "=r" (ret)
137 1.16 ragge : "r" (b1), "r" (b2), "r" (len)
138 1.16 ragge : "r0","r1","r2","r3" );
139 1.16 ragge return ret;
140 1.16 ragge }
141 1.16 ragge
142 1.16 ragge static __inline__ int
143 1.16 ragge bcmp(const void *b1, const void *b2, size_t len)
144 1.16 ragge {
145 1.17 ragge register int ret;
146 1.3 ragge
147 1.13 thorpej __asm__ __volatile("cmpc3 %3,(%1),(%2);movl r0,%0"
148 1.3 ragge : "=r" (ret)
149 1.3 ragge : "r" (b1), "r" (b2), "r" (len)
150 1.3 ragge : "r0","r1","r2","r3" );
151 1.3 ragge return ret;
152 1.3 ragge }
153 1.3 ragge
154 1.16 ragge /* Begin nya */
155 1.16 ragge static __inline__ size_t
156 1.16 ragge strlen(const char *cp)
157 1.16 ragge {
158 1.17 ragge register size_t ret;
159 1.16 ragge
160 1.16 ragge __asm__ __volatile("locc $0,$65535,(%1);subl3 r0,$65535,%0"
161 1.16 ragge : "=r" (ret)
162 1.16 ragge : "r" (cp)
163 1.16 ragge : "r0","r1","cc" );
164 1.16 ragge return ret;
165 1.16 ragge }
166 1.16 ragge
167 1.16 ragge static __inline__ char *
168 1.16 ragge strcat(char *cp, const char *c2)
169 1.16 ragge {
170 1.16 ragge __asm__ __volatile("locc $0,$65535,(%1);subl3 r0,$65535,r2;incl r2;
171 1.16 ragge locc $0,$65535,(%0);movc3 r2,(%1),(r1)"
172 1.16 ragge :
173 1.16 ragge : "r" (cp), "r" (c2)
174 1.16 ragge : "r0","r1","r2","r3","r4","r5","memory","cc");
175 1.16 ragge return cp;
176 1.16 ragge }
177 1.16 ragge
178 1.16 ragge static __inline__ char *
179 1.16 ragge strncat(char *cp, const char *c2, size_t count)
180 1.16 ragge {
181 1.16 ragge __asm__ __volatile("locc $0,%2,(%1);subl3 r0,%2,r2;
182 1.16 ragge locc $0,$65535,(%0);movc3 r2,(%1),(r1);movb $0,(r3)"
183 1.16 ragge :
184 1.16 ragge : "r" (cp), "r" (c2), "g"(count)
185 1.16 ragge : "r0","r1","r2","r3","r4","r5","memory","cc");
186 1.16 ragge return cp;
187 1.16 ragge }
188 1.16 ragge
189 1.16 ragge static __inline__ char *
190 1.16 ragge strcpy(char *cp, const char *c2)
191 1.16 ragge {
192 1.16 ragge __asm__ __volatile("locc $0,$65535,(%1);subl3 r0,$65535,r2;
193 1.16 ragge movc3 r2,(%1),(%0);movb $0,(r3)"
194 1.16 ragge :
195 1.16 ragge : "r" (cp), "r" (c2)
196 1.16 ragge : "r0","r1","r2","r3","r4","r5","memory","cc");
197 1.16 ragge return cp;
198 1.16 ragge }
199 1.16 ragge
200 1.16 ragge static __inline__ char *
201 1.16 ragge strncpy(char *cp, const char *c2, size_t len)
202 1.16 ragge {
203 1.16 ragge __asm__ __volatile("movl %2,r2;locc $0,r2,(%1);beql 1f;subl3 r0,%2,r2;
204 1.16 ragge clrb (%0)[r2];1:;movc3 r2,(%1),(%0)"
205 1.16 ragge :
206 1.16 ragge : "r" (cp), "r" (c2), "g"(len)
207 1.16 ragge : "r0","r1","r2","r3","r4","r5","memory","cc");
208 1.16 ragge return cp;
209 1.16 ragge }
210 1.16 ragge
211 1.16 ragge static __inline__ void *
212 1.16 ragge memchr(const void *cp, int c, size_t len)
213 1.16 ragge {
214 1.16 ragge void *ret;
215 1.16 ragge __asm__ __volatile("locc %2,%3,(%1);bneq 1f;clrl r1;1:movl r1,%0"
216 1.16 ragge : "=g"(ret)
217 1.16 ragge : "r" (cp), "r" (c), "g"(len)
218 1.16 ragge : "r0","r1","cc");
219 1.16 ragge return ret;
220 1.16 ragge }
221 1.16 ragge
222 1.16 ragge static __inline__ int
223 1.16 ragge strcmp(const char *cp, const char *c2)
224 1.16 ragge {
225 1.17 ragge register int ret;
226 1.16 ragge __asm__ __volatile("locc $0,$65535,(%1);subl3 r0,$65535,r0;incl r0;
227 1.16 ragge cmpc3 r0,(%1),(%2);beql 1f;movl $1,r2;
228 1.16 ragge cmpb (r1),(r3);bcc 1f;movl $-1,r2;1:movl r2,%0"
229 1.16 ragge : "=g"(ret)
230 1.16 ragge : "r" (cp), "r" (c2)
231 1.16 ragge : "r0","r1","r2","r3","cc");
232 1.16 ragge return ret;
233 1.16 ragge }
234 1.16 ragge /* End nya */
235 1.16 ragge
236 1.9 cgd #if 0 /* unused, but no point in deleting it since it _is_ an instruction */
237 1.20 matt static __inline__ int locc(int mask, char *cp, size_t size){
238 1.3 ragge register ret;
239 1.3 ragge
240 1.13 thorpej __asm__ __volatile("locc %1,%2,(%3);movl r0,%0"
241 1.3 ragge : "=r" (ret)
242 1.3 ragge : "r" (mask),"r"(size),"r"(cp)
243 1.3 ragge : "r0","r1" );
244 1.3 ragge return ret;
245 1.3 ragge }
246 1.9 cgd #endif
247 1.3 ragge
248 1.10 ragge static __inline__ int
249 1.16 ragge scanc(u_int size, const u_char *cp, const u_char *table, int mask)
250 1.16 ragge {
251 1.17 ragge register int ret;
252 1.3 ragge
253 1.13 thorpej __asm__ __volatile("scanc %1,(%2),(%3),%4;movl r0,%0"
254 1.3 ragge : "=g"(ret)
255 1.3 ragge : "r"(size),"r"(cp),"r"(table),"r"(mask)
256 1.3 ragge : "r0","r1","r2","r3" );
257 1.3 ragge return ret;
258 1.3 ragge }
259 1.3 ragge
260 1.16 ragge static __inline__ int
261 1.16 ragge skpc(int mask, size_t size, u_char *cp)
262 1.16 ragge {
263 1.17 ragge register int ret;
264 1.3 ragge
265 1.13 thorpej __asm__ __volatile("skpc %1,%2,(%3);movl r0,%0"
266 1.3 ragge : "=g"(ret)
267 1.3 ragge : "r"(mask),"r"(size),"r"(cp)
268 1.3 ragge : "r0","r1" );
269 1.3 ragge return ret;
270 1.23 ragge }
271 1.23 ragge
272 1.23 ragge /*
273 1.23 ragge * Set/clear a bit at a memory position; interlocked.
274 1.23 ragge * Return 0 if already set, 1 otherwise.
275 1.23 ragge */
276 1.23 ragge static __inline__ int
277 1.23 ragge bbssi(int bitnr, long *addr)
278 1.23 ragge {
279 1.23 ragge register int ret;
280 1.23 ragge
281 1.23 ragge __asm__ __volatile("clrl r0;bbssi %1,%2,1f;incl r0;1:movl r0,%0"
282 1.23 ragge : "=&r"(ret)
283 1.23 ragge : "g"(bitnr),"m"(*addr)
284 1.23 ragge : "r0","cc","memory");
285 1.23 ragge return ret;
286 1.23 ragge }
287 1.23 ragge
288 1.23 ragge static __inline__ int
289 1.23 ragge bbcci(int bitnr, long *addr)
290 1.23 ragge {
291 1.23 ragge register int ret;
292 1.23 ragge
293 1.23 ragge __asm__ __volatile("clrl r0;bbcci %1,%2,1f;incl r0;1:movl r0,%0"
294 1.23 ragge : "=&r"(ret)
295 1.23 ragge : "g"(bitnr),"m"(*addr)
296 1.23 ragge : "r0","cc","memory");
297 1.23 ragge return ret;
298 1.3 ragge }
299 1.3 ragge
300 1.15 ragge #define setrunqueue(p) \
301 1.13 thorpej __asm__ __volatile("movl %0,r0;jsb Setrq":: "g"(p):"r0","r1","r2");
302 1.12 ragge
303 1.15 ragge #define remrunqueue(p) \
304 1.13 thorpej __asm__ __volatile("movl %0,r0;jsb Remrq":: "g"(p):"r0","r1","r2");
305 1.12 ragge
306 1.15 ragge #define cpu_switch(p) \
307 1.21 matt __asm__ __volatile("movl %0,r6;movpsl -(sp);jsb Swtch" \
308 1.21 matt ::"g"(p):"r0","r1","r2","r3","r4","r5","r6");
309 1.18 ragge
310 1.18 ragge /*
311 1.18 ragge * Interlock instructions. Used both in multiprocessor environments to
312 1.18 ragge * lock between CPUs and in uniprocessor systems when locking is required
313 1.18 ragge * between I/O devices and the master CPU.
314 1.18 ragge */
315 1.18 ragge /*
316 1.18 ragge * Insqti() locks and inserts an element into the end of a queue.
317 1.18 ragge * Returns -1 if interlock failed, 1 if inserted OK and 0 if first in queue.
318 1.18 ragge */
319 1.18 ragge static __inline__ int
320 1.18 ragge insqti(void *entry, void *header) {
321 1.18 ragge register int ret;
322 1.18 ragge
323 1.18 ragge __asm__ __volatile("
324 1.18 ragge mnegl $1,%0;
325 1.18 ragge insqti (%1),(%2);
326 1.18 ragge bcs 1f; # failed insert
327 1.18 ragge beql 2f; # jump if first entry
328 1.18 ragge movl $1,%0;
329 1.18 ragge brb 1f;
330 1.18 ragge 2: clrl %0;
331 1.18 ragge 1:;"
332 1.19 matt : "=&g"(ret)
333 1.18 ragge : "r"(entry), "r"(header)
334 1.18 ragge : "memory");
335 1.18 ragge
336 1.18 ragge return ret;
337 1.18 ragge }
338 1.18 ragge
339 1.18 ragge /*
340 1.18 ragge * Remqhi() removes an element from the head of the queue.
341 1.18 ragge * Returns -1 if interlock failed, 0 if queue empty, address of the
342 1.18 ragge * removed element otherwise.
343 1.18 ragge */
344 1.18 ragge static __inline__ void *
345 1.18 ragge remqhi(void *header) {
346 1.18 ragge register void *ret;
347 1.18 ragge
348 1.18 ragge __asm__ __volatile("
349 1.18 ragge remqhi (%1),%0;
350 1.18 ragge bcs 1f; # failed interlock
351 1.18 ragge bvs 2f; # nothing was removed
352 1.18 ragge brb 3f;
353 1.18 ragge 1: mnegl $1,%0;
354 1.18 ragge brb 3f;
355 1.18 ragge 2: clrl %0;
356 1.18 ragge 3:;"
357 1.19 matt : "=&g"(ret)
358 1.18 ragge : "r"(header)
359 1.18 ragge : "memory");
360 1.18 ragge
361 1.18 ragge return ret;
362 1.18 ragge }
363 1.18 ragge #define ILCK_FAILED -1 /* Interlock failed */
364 1.18 ragge #define Q_EMPTY 0 /* Queue is/was empty */
365 1.18 ragge #define Q_OK 1 /* Inserted OK */
366 1.18 ragge
367 1.3 ragge #endif /* _VAX_MACROS_H_ */
368