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