Ports -> pkgsrc
[dragonfly.git] / sys / emulation / ndis / regcall.h
1 /*
2  * 
3  * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
4  * 
5  * This code is derived from software contributed to The DragonFly Project
6  * by Matthew Dillon <dillon@backplane.com>
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  * 3. Neither the name of The DragonFly Project nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific, prior written permission.
21  * 
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
26  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  * 
35  * Copyright (c) 2003
36  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  * 3. All advertising materials mentioning features or use of this software
47  *    must display the following acknowledgement:
48  *      This product includes software developed by Bill Paul.
49  * 4. Neither the name of the author nor the names of any co-contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
57  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
58  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
59  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
61  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
63  * THE POSSIBILITY OF SUCH DAMAGE.
64  *
65  * $FreeBSD: src/sys/compat/ndis/pe_var.h,v 1.7 2004/04/14 07:48:02 wpaul Exp $
66  * $DragonFly: src/sys/emulation/ndis/regcall.h,v 1.1 2004/07/29 20:51:34 dillon Exp $
67  */
68
69 #ifndef _REGCALL_H_
70 #define _REGCALL_H_
71
72 /*
73  * Note: Windows uses the _stdcall calling convention. This means
74  * that the callback functions provided in the function table must
75  * be declared using __attribute__((__stdcall__)), otherwise the
76  * Windows code will likely screw up the %esp register and cause
77  * us to jump to an invalid address when it returns.   With the
78  * stdcall calling convention the target procedure is responsible for
79  * popping the call arguments.
80  *
81  * Note: Windows often passes arguments in registers.  In windows
82  * the order is: %ecx, %edx.  The regparm(3) attribute in GNU C will
83  * pass arguments in the order: %eax, %edx, %ecx, with any remaining
84  * arguments passed on the stack.
85  */
86
87 #ifdef __amd64__
88 #define __stdcall
89 #define __regcall
90 #define REGARGS1(decl1)         decl1
91 #define REGARGS2(decl1, decl2)  decl1, decl2
92 #define REGCALL1(arg1)          arg1
93 #define REGCALL2(arg1, arg2)    arg1, arg2
94 #else
95 #define __stdcall __attribute__((__stdcall__))
96 #define __regcall __attribute__((__regparm__(3)))
97 #define REGARGS1(decl1)         int dummy1, int dummy2, decl1
98 #define REGARGS2(decl1, decl2)  int dummy1, decl2, decl1
99 #define REGCALL1(arg1)          0, 0, arg1
100 #define REGCALL2(arg1, arg2)    0, arg2, arg1
101 #endif
102
103
104 /*
105  * This mess allows us to call a _fastcall style routine with our
106  * version of gcc, which lacks __attribute__((__fastcall__)). Only
107  * has meaning on x86; everywhere else, it's a no-op.
108  */
109
110 #ifdef __i386__
111 typedef __stdcall __regcall int (*fcall1)(REGARGS1(uint32_t));
112 typedef __stdcall __regcall int (*fcall2)(REGARGS2(uint32_t, uint32_t));
113 typedef __stdcall __regcall int (*fcall3)(REGARGS2(uint32_t, uint32_t), uint32_t);
114 static __inline uint32_t 
115 fastcall1(fcall1 f, uint32_t a)
116 {
117         return(f(REGCALL1(a)));
118 }
119
120 static __inline uint32_t 
121 fastcall2(fcall2 f, uint32_t a, uint32_t b)
122 {
123         return(f(REGCALL2(a, b)));
124 }
125
126 static __inline uint32_t 
127 fastcall3(fcall3 f, uint32_t a, uint32_t b, uint32_t c)
128 {
129         return(f(REGCALL2(a, b), c));
130 }
131
132 #define FASTCALL1(f, a)         \
133         fastcall1((fcall1)(f), (uint32_t)(a))
134 #define FASTCALL2(f, a, b)      \
135         fastcall2((fcall2)(f), (uint32_t)(a), (uint32_t)(b))
136 #define FASTCALL3(f, a, b, c)   \
137         fastcall3((fcall3)(f), (uint32_t)(a), (uint32_t)(b), (uint32_t)(c))
138 #else
139 #define FASTCALL1(f, a) (f)((a))
140 #define FASTCALL2(f, a, b) (f)((a), (b))
141 #define FASTCALL3(f, a, b, c) (f)((a), (b), (c))
142 #endif /* __i386__ */
143
144 #endif