macros.h revision 1.18 1 1.18 ragge /* $NetBSD: macros.h,v 1.18 2000/04/09 16:37:09 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.13 thorpej __asm__ __volatile ("ffs $0,$32,%1,%0
46 1.3 ragge bneq 1f
47 1.3 ragge mnegl $1,%0
48 1.15 ragge 1: incl %0"
49 1.3 ragge : "&=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.15 ragge __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.16 ragge memcpy(void *toe, const void *from, u_int len)
74 1.16 ragge {
75 1.16 ragge __asm__ __volatile ("movc3 %0,(%1),(%2)"
76 1.16 ragge :
77 1.16 ragge : "r" (len),"r" (from),"r"(toe)
78 1.16 ragge :"r0","r1","r2","r3","r4","r5","memory","cc");
79 1.16 ragge return toe;
80 1.16 ragge }
81 1.16 ragge static __inline__ void *
82 1.16 ragge memmove(void *toe, const void *from, u_int len)
83 1.16 ragge {
84 1.13 thorpej __asm__ __volatile ("movc3 %0,(%1),(%2)"
85 1.3 ragge :
86 1.3 ragge : "r" (len),"r" (from),"r"(toe)
87 1.16 ragge :"r0","r1","r2","r3","r4","r5","memory","cc");
88 1.16 ragge return toe;
89 1.16 ragge }
90 1.16 ragge
91 1.16 ragge static __inline__ void
92 1.16 ragge bcopy(const void *from, void *toe, u_int len)
93 1.16 ragge {
94 1.16 ragge __asm__ __volatile ("movc3 %0,(%1),(%2)"
95 1.16 ragge :
96 1.16 ragge : "r" (len),"r" (from),"r"(toe)
97 1.16 ragge :"r0","r1","r2","r3","r4","r5","memory","cc");
98 1.3 ragge }
99 1.3 ragge
100 1.15 ragge void blkclr __P((void *, u_int));
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.16 ragge __asm__ __volatile ("movc5 $0,(%0),%2,%1,(%0)"
109 1.16 ragge :
110 1.16 ragge : "r" (block), "r" (len), "r"(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.16 ragge bzero(void *block, u_int 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.15 ragge __asm__ __volatile ("movc5 $0,(%0),$0,%1,(%0)"
123 1.3 ragge :
124 1.3 ragge : "r" (block), "r" (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.3 ragge static __inline__ int locc(int mask, char *cp,u_int 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.3 ragge }
271 1.3 ragge
272 1.15 ragge #define setrunqueue(p) \
273 1.13 thorpej __asm__ __volatile("movl %0,r0;jsb Setrq":: "g"(p):"r0","r1","r2");
274 1.12 ragge
275 1.15 ragge #define remrunqueue(p) \
276 1.13 thorpej __asm__ __volatile("movl %0,r0;jsb Remrq":: "g"(p):"r0","r1","r2");
277 1.12 ragge
278 1.15 ragge #define cpu_switch(p) \
279 1.13 thorpej __asm__ __volatile("movl %0,r0;movpsl -(sp);jsb Swtch" \
280 1.12 ragge ::"g"(p):"r0","r1","r2","r3");
281 1.18 ragge
282 1.18 ragge /*
283 1.18 ragge * Interlock instructions. Used both in multiprocessor environments to
284 1.18 ragge * lock between CPUs and in uniprocessor systems when locking is required
285 1.18 ragge * between I/O devices and the master CPU.
286 1.18 ragge */
287 1.18 ragge /*
288 1.18 ragge * Insqti() locks and inserts an element into the end of a queue.
289 1.18 ragge * Returns -1 if interlock failed, 1 if inserted OK and 0 if first in queue.
290 1.18 ragge */
291 1.18 ragge static __inline__ int
292 1.18 ragge insqti(void *entry, void *header) {
293 1.18 ragge register int ret;
294 1.18 ragge
295 1.18 ragge __asm__ __volatile("
296 1.18 ragge mnegl $1,%0;
297 1.18 ragge insqti (%1),(%2);
298 1.18 ragge bcs 1f; # failed insert
299 1.18 ragge beql 2f; # jump if first entry
300 1.18 ragge movl $1,%0;
301 1.18 ragge brb 1f;
302 1.18 ragge 2: clrl %0;
303 1.18 ragge 1:;"
304 1.18 ragge : "&=g"(ret)
305 1.18 ragge : "r"(entry), "r"(header)
306 1.18 ragge : "memory");
307 1.18 ragge
308 1.18 ragge return ret;
309 1.18 ragge }
310 1.18 ragge
311 1.18 ragge /*
312 1.18 ragge * Remqhi() removes an element from the head of the queue.
313 1.18 ragge * Returns -1 if interlock failed, 0 if queue empty, address of the
314 1.18 ragge * removed element otherwise.
315 1.18 ragge */
316 1.18 ragge static __inline__ void *
317 1.18 ragge remqhi(void *header) {
318 1.18 ragge register void *ret;
319 1.18 ragge
320 1.18 ragge __asm__ __volatile("
321 1.18 ragge remqhi (%1),%0;
322 1.18 ragge bcs 1f; # failed interlock
323 1.18 ragge bvs 2f; # nothing was removed
324 1.18 ragge brb 3f;
325 1.18 ragge 1: mnegl $1,%0;
326 1.18 ragge brb 3f;
327 1.18 ragge 2: clrl %0;
328 1.18 ragge 3:;"
329 1.18 ragge : "&=g"(ret)
330 1.18 ragge : "r"(header)
331 1.18 ragge : "memory");
332 1.18 ragge
333 1.18 ragge return ret;
334 1.18 ragge }
335 1.18 ragge #define ILCK_FAILED -1 /* Interlock failed */
336 1.18 ragge #define Q_EMPTY 0 /* Queue is/was empty */
337 1.18 ragge #define Q_OK 1 /* Inserted OK */
338 1.18 ragge
339 1.3 ragge #endif /* _VAX_MACROS_H_ */
340