1*6a602769Sragge /* $NetBSD: macros.h,v 1.46 2017/05/22 17:12:11 ragge Exp $ */
2d62187c0Scgd
38026fb53Sragge /*
49b917327Sragge * Copyright (c) 1994, 1998, 2000 Ludd, University of Lule}, Sweden.
58026fb53Sragge * All rights reserved.
68026fb53Sragge *
78026fb53Sragge * Redistribution and use in source and binary forms, with or without
88026fb53Sragge * modification, are permitted provided that the following conditions
98026fb53Sragge * are met:
108026fb53Sragge * 1. Redistributions of source code must retain the above copyright
118026fb53Sragge * notice, this list of conditions and the following disclaimer.
128026fb53Sragge * 2. Redistributions in binary form must reproduce the above copyright
138026fb53Sragge * notice, this list of conditions and the following disclaimer in the
148026fb53Sragge * documentation and/or other materials provided with the distribution.
158026fb53Sragge *
168026fb53Sragge * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
178026fb53Sragge * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
188026fb53Sragge * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
198026fb53Sragge * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
208026fb53Sragge * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
218026fb53Sragge * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
228026fb53Sragge * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
238026fb53Sragge * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
248026fb53Sragge * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
258026fb53Sragge * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
268026fb53Sragge */
278026fb53Sragge
288026fb53Sragge /* All bugs are subject to removal without further notice */
298026fb53Sragge
30d93fc4c1Skleink #if !defined(_VAX_MACROS_H_) && !defined(__lint__)
314fb1817eSragge #define _VAX_MACROS_H_
328026fb53Sragge
3392310636Sragge void __blkset(void *, int, size_t);
3492310636Sragge void __blkcpy(const void *, void *, size_t);
3592310636Sragge
36cf078da5Smatt #if !__GNUC_PREREQ__(4, 1)
378026fb53Sragge /* Here general macros are supposed to be stored */
388026fb53Sragge
39fbae48b9Sperry static __inline int __attribute__((__unused__))
vax_ffs(int reg)4008f6d014Smatt vax_ffs(int reg)
418fdb1c8eSragge {
424fb1817eSragge register int val;
438026fb53Sragge
4450a256a3Sperry __asm volatile ("ffs $0,$32,%1,%0;"
4528b1aa2bSmatt "bneq 1f;"
4628b1aa2bSmatt "mnegl $1,%0;"
4728b1aa2bSmatt "1:;"
4828b1aa2bSmatt "incl %0"
49c9e87920Smatt : "=&r" (val)
504fb1817eSragge : "r" (reg) );
514fb1817eSragge return val;
524fb1817eSragge }
5308f6d014Smatt #define ffs vax_ffs
54cf078da5Smatt #endif
558026fb53Sragge
56fbae48b9Sperry static __inline void __attribute__((__unused__))
vax_remque(void * p)5708f6d014Smatt vax_remque(void *p)
588fdb1c8eSragge {
5950a256a3Sperry __asm volatile ("remque (%0),%0;clrl 4(%0)"
604fb1817eSragge :
614fb1817eSragge : "r" (p)
624fb1817eSragge : "memory" );
634fb1817eSragge }
644fb1817eSragge
65fbae48b9Sperry static __inline void __attribute__((__unused__))
vax_insque(void * p,void * q)6608f6d014Smatt vax_insque(void *p, void *q)
678fdb1c8eSragge {
6850a256a3Sperry __asm volatile ("insque (%0),(%1)"
694fb1817eSragge :
704fb1817eSragge : "r" (p),"r" (q)
714fb1817eSragge : "memory" );
724fb1817eSragge }
734fb1817eSragge
7408f6d014Smatt #if 0
75fbae48b9Sperry static __inline void *__attribute__((__unused__))
7608f6d014Smatt vax_memcpy(void *to, const void *from, size_t len)
778fdb1c8eSragge {
7892310636Sragge if (len > 65535) {
7992310636Sragge __blkcpy(from, to, len);
8092310636Sragge } else {
8108f6d014Smatt __asm volatile ("movc3 %1,(%2),%0"
8208f6d014Smatt : "=m" (*(char *)to)
8308f6d014Smatt : "g" (len), "r" (*(const char *)from)
848fdb1c8eSragge :"r0","r1","r2","r3","r4","r5","memory","cc");
8592310636Sragge }
864622cfafSmatt return to;
878fdb1c8eSragge }
8808f6d014Smatt #define memcpy vax_memcpy
8908f6d014Smatt
90fbae48b9Sperry static __inline void *__attribute__((__unused__))
9108f6d014Smatt vax_memmove(void *to, const void *from, size_t len)
928fdb1c8eSragge {
9392310636Sragge if (len > 65535) {
9492310636Sragge __blkcpy(from, to, len);
9592310636Sragge } else {
96ea4611dbSmatt __asm __volatile ("movc3 %1,%2,%0"
9708f6d014Smatt : "=m" (*(char *)to)
9808f6d014Smatt : "g" (len), "mo" (*(const char *)from)
998fdb1c8eSragge :"r0","r1","r2","r3","r4","r5","memory","cc");
10092310636Sragge }
1014622cfafSmatt return to;
1028fdb1c8eSragge }
10308f6d014Smatt #define memmove vax_memmove
1048e2874bfSragge
105fbae48b9Sperry static __inline void *__attribute__((__unused__))
10608f6d014Smatt vax_memset(void *block, int c, size_t len)
1078fdb1c8eSragge {
10892310636Sragge if (len > 65535) {
10930bdf5c1Sthorpej __blkset(block, c, len);
11092310636Sragge } else {
111ea4611dbSmatt __asm __volatile ("movc5 $0,(%%sp),%2,%1,%0"
11208f6d014Smatt : "=m" (*(char *)block)
11308f6d014Smatt : "g" (len), "g" (c)
1148fdb1c8eSragge :"r0","r1","r2","r3","r4","r5","memory","cc");
1158fdb1c8eSragge }
1168fdb1c8eSragge return block;
1178fdb1c8eSragge }
11808f6d014Smatt #define memset vax_memset
119e873fd06Schs #endif
1204fb1817eSragge
12192310636Sragge #ifdef notdef
1228fdb1c8eSragge /* XXX - the return syntax of memcmp is wrong */
123fbae48b9Sperry static __inline int __attribute__((__unused__))
memcmp(const void * b1,const void * b2,size_t len)1248fdb1c8eSragge memcmp(const void *b1, const void *b2, size_t len)
1258fdb1c8eSragge {
126b6158fa5Sragge register int ret;
1274fb1817eSragge
12850a256a3Sperry __asm volatile("cmpc3 %3,(%1),(%2);"
12928b1aa2bSmatt "movl %%r0,%0"
1304fb1817eSragge : "=r" (ret)
1314fb1817eSragge : "r" (b1), "r" (b2), "r" (len)
1324fb1817eSragge : "r0","r1","r2","r3" );
1334fb1817eSragge return ret;
1344fb1817eSragge }
1354fb1817eSragge
136fbae48b9Sperry static __inline int __attribute__((__unused__))
bcmp(const void * b1,const void * b2,size_t len)1378fdb1c8eSragge bcmp(const void *b1, const void *b2, size_t len)
1388fdb1c8eSragge {
139b6158fa5Sragge register int ret;
1408fdb1c8eSragge
14150a256a3Sperry __asm volatile("cmpc3 %3,(%1),(%2);"
14228b1aa2bSmatt "movl %%r0,%0"
1438fdb1c8eSragge : "=r" (ret)
1448fdb1c8eSragge : "r" (b1), "r" (b2), "r" (len)
1458fdb1c8eSragge : "r0","r1","r2","r3" );
1468fdb1c8eSragge return ret;
1478fdb1c8eSragge }
1488fdb1c8eSragge
1498fdb1c8eSragge /* Begin nya */
150fbae48b9Sperry static __inline size_t __attribute__((__unused__))
strlen(const char * cp)1518fdb1c8eSragge strlen(const char *cp)
1528fdb1c8eSragge {
153b6158fa5Sragge register size_t ret;
1548fdb1c8eSragge
15550a256a3Sperry __asm volatile("locc $0,$65535,(%1);"
15628b1aa2bSmatt "subl3 %%r0,$65535,%0"
1578fdb1c8eSragge : "=r" (ret)
1588fdb1c8eSragge : "r" (cp)
1598fdb1c8eSragge : "r0","r1","cc" );
1608fdb1c8eSragge return ret;
1618fdb1c8eSragge }
1628fdb1c8eSragge
163fbae48b9Sperry static __inline char * __attribute__((__unused__))
strcat(char * cp,const char * c2)1648fdb1c8eSragge strcat(char *cp, const char *c2)
1658fdb1c8eSragge {
16650a256a3Sperry __asm volatile("locc $0,$65535,(%1);"
16728b1aa2bSmatt "subl3 %%r0,$65535,%%r2;"
16828b1aa2bSmatt "incl %%r2;"
16928b1aa2bSmatt "locc $0,$65535,(%0);"
17028b1aa2bSmatt "movc3 %%r2,(%1),(%%r1)"
1718fdb1c8eSragge :
1728fdb1c8eSragge : "r" (cp), "r" (c2)
1738fdb1c8eSragge : "r0","r1","r2","r3","r4","r5","memory","cc");
1748fdb1c8eSragge return cp;
1758fdb1c8eSragge }
1768fdb1c8eSragge
177fbae48b9Sperry static __inline char * __attribute__((__unused__))
strncat(char * cp,const char * c2,size_t count)1788fdb1c8eSragge strncat(char *cp, const char *c2, size_t count)
1798fdb1c8eSragge {
18050a256a3Sperry __asm volatile("locc $0,%2,(%1);"
181d2275d51Sthorpej "subl3 %%r0,%2,%%r2;"
18228b1aa2bSmatt "locc $0,$65535,(%0);"
18328b1aa2bSmatt "movc3 %%r2,(%1),(%%r1);"
18428b1aa2bSmatt "movb $0,(%%r3)"
1858fdb1c8eSragge :
1868fdb1c8eSragge : "r" (cp), "r" (c2), "g"(count)
1878fdb1c8eSragge : "r0","r1","r2","r3","r4","r5","memory","cc");
1888fdb1c8eSragge return cp;
1898fdb1c8eSragge }
1908fdb1c8eSragge
191fbae48b9Sperry static __inline char * __attribute__((__unused__))
strcpy(char * cp,const char * c2)1928fdb1c8eSragge strcpy(char *cp, const char *c2)
1938fdb1c8eSragge {
19450a256a3Sperry __asm volatile("locc $0,$65535,(%1);"
19528b1aa2bSmatt "subl3 %%r0,$65535,%%r2;"
19628b1aa2bSmatt "movc3 %%r2,(%1),(%0);"
19728b1aa2bSmatt "movb $0,(%%r3)"
1988fdb1c8eSragge :
1998fdb1c8eSragge : "r" (cp), "r" (c2)
2008fdb1c8eSragge : "r0","r1","r2","r3","r4","r5","memory","cc");
2018fdb1c8eSragge return cp;
2028fdb1c8eSragge }
2038fdb1c8eSragge
204fbae48b9Sperry static __inline char * __attribute__((__unused__))
strncpy(char * cp,const char * c2,size_t len)2058fdb1c8eSragge strncpy(char *cp, const char *c2, size_t len)
2068fdb1c8eSragge {
20750a256a3Sperry __asm volatile("movl %2,%%r2;"
20828b1aa2bSmatt "locc $0,%%r2,(%1);"
20928b1aa2bSmatt "beql 1f;"
21028b1aa2bSmatt "subl3 %%r0,%2,%%r2;"
21128b1aa2bSmatt "clrb (%0)[%%r2];"
21228b1aa2bSmatt "1:;"
21328b1aa2bSmatt "movc3 %%r2,(%1),(%0)"
2148fdb1c8eSragge :
2158fdb1c8eSragge : "r" (cp), "r" (c2), "g"(len)
2168fdb1c8eSragge : "r0","r1","r2","r3","r4","r5","memory","cc");
2178fdb1c8eSragge return cp;
2188fdb1c8eSragge }
2198fdb1c8eSragge
220fbae48b9Sperry static __inline void *__attribute__((__unused__))
memchr(const void * cp,int c,size_t len)2218fdb1c8eSragge memchr(const void *cp, int c, size_t len)
2228fdb1c8eSragge {
2238fdb1c8eSragge void *ret;
22450a256a3Sperry __asm volatile("locc %2,%3,(%1);"
22528b1aa2bSmatt "bneq 1f;"
22628b1aa2bSmatt "clrl %%r1;"
22728b1aa2bSmatt "1:;"
22828b1aa2bSmatt "movl %%r1,%0"
2298fdb1c8eSragge : "=g"(ret)
2308fdb1c8eSragge : "r" (cp), "r" (c), "g"(len)
2318fdb1c8eSragge : "r0","r1","cc");
2328fdb1c8eSragge return ret;
2338fdb1c8eSragge }
2348fdb1c8eSragge
235fbae48b9Sperry static __inline int __attribute__((__unused__))
strcmp(const char * cp,const char * c2)2368fdb1c8eSragge strcmp(const char *cp, const char *c2)
2378fdb1c8eSragge {
238b6158fa5Sragge register int ret;
23950a256a3Sperry __asm volatile("locc $0,$65535,(%1);"
24028b1aa2bSmatt "subl3 %%r0,$65535,%%r0;"
24128b1aa2bSmatt "incl %%r0;"
24228b1aa2bSmatt "cmpc3 %%r0,(%1),(%2);"
24328b1aa2bSmatt "beql 1f;"
24428b1aa2bSmatt "movl $1,%%r2;"
24528b1aa2bSmatt "cmpb (%%r1),(%%r3);"
24628b1aa2bSmatt "bcc 1f;"
24728b1aa2bSmatt "mnegl $1,%%r2;"
24828b1aa2bSmatt "1:;"
24928b1aa2bSmatt "movl %%r2,%0"
2508fdb1c8eSragge : "=g"(ret)
2518fdb1c8eSragge : "r" (cp), "r" (c2)
2528fdb1c8eSragge : "r0","r1","r2","r3","cc");
2538fdb1c8eSragge return ret;
2548fdb1c8eSragge }
25592310636Sragge #endif
2568fdb1c8eSragge
257352d972cScgd #if 0 /* unused, but no point in deleting it since it _is_ an instruction */
258fbae48b9Sperry static __inline int __attribute__((__unused__))
25930bdf5c1Sthorpej locc(int mask, char *cp, size_t size){
2604fb1817eSragge register ret;
2614fb1817eSragge
26250a256a3Sperry __asm volatile("locc %1,%2,(%3);"
26328b1aa2bSmatt "movl %%r0,%0"
2644fb1817eSragge : "=r" (ret)
2654fb1817eSragge : "r" (mask),"r"(size),"r"(cp)
2664fb1817eSragge : "r0","r1" );
2674fb1817eSragge return ret;
2684fb1817eSragge }
269352d972cScgd #endif
2704fb1817eSragge
271fbae48b9Sperry static __inline int __attribute__((__unused__))
vax_scanc(u_int size,const u_char * cp,const u_char * table,int mask)27208f6d014Smatt vax_scanc(u_int size, const u_char *cp, const u_char *table, int mask)
2738fdb1c8eSragge {
274b6158fa5Sragge register int ret;
2754fb1817eSragge
27650a256a3Sperry __asm volatile("scanc %1,(%2),(%3),%4;"
27728b1aa2bSmatt "movl %%r0,%0"
2784fb1817eSragge : "=g"(ret)
2794fb1817eSragge : "r"(size),"r"(cp),"r"(table),"r"(mask)
2804fb1817eSragge : "r0","r1","r2","r3" );
2814fb1817eSragge return ret;
2824fb1817eSragge }
28308f6d014Smatt #define scanc vax_scanc
2844fb1817eSragge
285fbae48b9Sperry static __inline int __attribute__((__unused__))
vax_skpc(int mask,size_t size,u_char * cp)28608f6d014Smatt vax_skpc(int mask, size_t size, u_char *cp)
2878fdb1c8eSragge {
288b6158fa5Sragge register int ret;
2894fb1817eSragge
29050a256a3Sperry __asm volatile("skpc %1,%2,(%3);"
29128b1aa2bSmatt "movl %%r0,%0"
2924fb1817eSragge : "=g"(ret)
2934fb1817eSragge : "r"(mask),"r"(size),"r"(cp)
2944fb1817eSragge : "r0","r1" );
2954fb1817eSragge return ret;
2964fb1817eSragge }
29708f6d014Smatt #define skpc vax_skpc
2984fb1817eSragge
2996e219aa5Sragge /*
3006e219aa5Sragge * Set/clear a bit at a memory position; interlocked.
3016e219aa5Sragge * Return 0 if already set, 1 otherwise.
3026e219aa5Sragge */
303fbae48b9Sperry static __inline int __attribute__((__unused__))
bbssi(int bitnr,long * addr)3046e219aa5Sragge bbssi(int bitnr, long *addr)
3056e219aa5Sragge {
3066e219aa5Sragge register int ret;
3076e219aa5Sragge
30850a256a3Sperry __asm volatile("clrl %%r0;"
30928b1aa2bSmatt "bbssi %1,%2,1f;"
31028b1aa2bSmatt "incl %%r0;"
31128b1aa2bSmatt "1:;"
31228b1aa2bSmatt "movl %%r0,%0"
3136e219aa5Sragge : "=&r"(ret)
3146e219aa5Sragge : "g"(bitnr),"m"(*addr)
3156e219aa5Sragge : "r0","cc","memory");
3166e219aa5Sragge return ret;
3176e219aa5Sragge }
3186e219aa5Sragge
319fbae48b9Sperry static __inline int __attribute__((__unused__))
bbcci(int bitnr,long * addr)3206e219aa5Sragge bbcci(int bitnr, long *addr)
3216e219aa5Sragge {
3226e219aa5Sragge register int ret;
3236e219aa5Sragge
32450a256a3Sperry __asm volatile("clrl %%r0;"
32528b1aa2bSmatt "bbcci %1,%2,1f;"
32628b1aa2bSmatt "incl %%r0;"
32728b1aa2bSmatt "1:;"
32828b1aa2bSmatt "movl %%r0,%0"
3296e219aa5Sragge : "=&r"(ret)
3306e219aa5Sragge : "g"(bitnr),"m"(*addr)
3316e219aa5Sragge : "r0","cc","memory");
3326e219aa5Sragge return ret;
3336e219aa5Sragge }
3346e219aa5Sragge
335f0301095Syamt static inline struct lwp *
cpu_switchto(struct lwp * oldlwp,struct lwp * newlwp,bool returning)336c64de7a6Syamt cpu_switchto(struct lwp *oldlwp, struct lwp *newlwp, bool returning)
337f0301095Syamt {
338f0301095Syamt struct lwp *prevlwp;
339f0301095Syamt __asm volatile(
340f0301095Syamt "movl %1,%%r0;"
341f0301095Syamt "movl %2,%%r1;"
342f0301095Syamt "movpsl -(%%sp);"
343f0301095Syamt "jsb Swtchto;"
344f0301095Syamt "movl %%r0,%0"
345f0301095Syamt : "=g"(prevlwp)
346f0301095Syamt : "g" (oldlwp), "g" (newlwp)
347f0301095Syamt : "r0", "r1");
348f0301095Syamt return prevlwp;
349f0301095Syamt }
3509b917327Sragge
3519b917327Sragge /*
3529b917327Sragge * Interlock instructions. Used both in multiprocessor environments to
3539b917327Sragge * lock between CPUs and in uniprocessor systems when locking is required
3549b917327Sragge * between I/O devices and the master CPU.
3559b917327Sragge */
3569b917327Sragge /*
3579b917327Sragge * Insqti() locks and inserts an element into the end of a queue.
3589b917327Sragge * Returns -1 if interlock failed, 1 if inserted OK and 0 if first in queue.
3599b917327Sragge */
360fbae48b9Sperry static __inline int __attribute__((__unused__))
insqti(void * entry,void * header)3619b917327Sragge insqti(void *entry, void *header) {
3629b917327Sragge register int ret;
3639b917327Sragge
36450a256a3Sperry __asm volatile(
3654cfae24fSmatt " mnegl $1,%0;"
3664cfae24fSmatt " insqti (%1),(%2);"
3674cfae24fSmatt " bcs 1f;" /* failed insert */
3684cfae24fSmatt " beql 2f;" /* jump if first entry */
3694cfae24fSmatt " movl $1,%0;"
3704cfae24fSmatt " brb 1f;"
3714cfae24fSmatt "2: clrl %0;"
3724cfae24fSmatt " 1:;"
373c9e87920Smatt : "=&g"(ret)
3749b917327Sragge : "r"(entry), "r"(header)
3759b917327Sragge : "memory");
3769b917327Sragge
3779b917327Sragge return ret;
3789b917327Sragge }
3799b917327Sragge
3809b917327Sragge /*
3819b917327Sragge * Remqhi() removes an element from the head of the queue.
3829b917327Sragge * Returns -1 if interlock failed, 0 if queue empty, address of the
3839b917327Sragge * removed element otherwise.
3849b917327Sragge */
385fbae48b9Sperry static __inline void *__attribute__((__unused__))
remqhi(void * header)3869b917327Sragge remqhi(void *header) {
3879b917327Sragge register void *ret;
3889b917327Sragge
38950a256a3Sperry __asm volatile(
3904cfae24fSmatt " remqhi (%1),%0;"
3914cfae24fSmatt " bcs 1f;" /* failed interlock */
3924cfae24fSmatt " bvs 2f;" /* nothing was removed */
3934cfae24fSmatt " brb 3f;"
3944cfae24fSmatt "1: mnegl $1,%0;"
3954cfae24fSmatt " brb 3f;"
3964cfae24fSmatt "2: clrl %0;"
3974cfae24fSmatt " 3:;"
398c9e87920Smatt : "=&g"(ret)
3999b917327Sragge : "r"(header)
4009b917327Sragge : "memory");
4019b917327Sragge
4029b917327Sragge return ret;
4039b917327Sragge }
4049b917327Sragge #define ILCK_FAILED -1 /* Interlock failed */
4059b917327Sragge #define Q_EMPTY 0 /* Queue is/was empty */
4069b917327Sragge #define Q_OK 1 /* Inserted OK */
4079b917327Sragge
408d93fc4c1Skleink #endif /* !_VAX_MACROS_H_ && !__lint__ */
409