Initial Linux ZFS GIT Repo
[zfs.git] / zfs / lib / libsolcompat / include / ia32 / sys / asm_linkage.h
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26
27 #ifndef _IA32_SYS_ASM_LINKAGE_H
28 #define _IA32_SYS_ASM_LINKAGE_H
29
30
31
32 #include <sys/stack.h>
33 #include <sys/trap.h>
34
35 #ifdef  __cplusplus
36 extern "C" {
37 #endif
38
39 #ifdef _ASM     /* The remainder of this file is only for assembly files */
40
41 /*
42  * make annoying differences in assembler syntax go away
43  */
44
45 /*
46  * D16 and A16 are used to insert instructions prefixes; the
47  * macros help the assembler code be slightly more portable.
48  */
49 #if !defined(__GNUC_AS__)
50 /*
51  * /usr/ccs/bin/as prefixes are parsed as separate instructions
52  */
53 #define D16     data16;
54 #define A16     addr16;
55
56 /*
57  * (There are some weird constructs in constant expressions)
58  */
59 #define _CONST(const)           [const]
60 #define _BITNOT(const)          -1!_CONST(const)
61 #define _MUL(a, b)              _CONST(a \* b)
62
63 #else
64 /*
65  * Why not use the 'data16' and 'addr16' prefixes .. well, the
66  * assembler doesn't quite believe in real mode, and thus argues with
67  * us about what we're trying to do.
68  */
69 #define D16     .byte   0x66;
70 #define A16     .byte   0x67;
71
72 #define _CONST(const)           (const)
73 #define _BITNOT(const)          ~_CONST(const)
74 #define _MUL(a, b)              _CONST(a * b)
75
76 #endif
77
78 /*
79  * C pointers are different sizes between i386 and amd64.
80  * These constants can be used to compute offsets into pointer arrays.
81  */
82 #if defined(__amd64)
83 #define CLONGSHIFT      3
84 #define CLONGSIZE       8
85 #define CLONGMASK       7
86 #elif defined(__i386)
87 #define CLONGSHIFT      2
88 #define CLONGSIZE       4
89 #define CLONGMASK       3
90 #endif
91
92 /*
93  * Since we know we're either ILP32 or LP64 ..
94  */
95 #define CPTRSHIFT       CLONGSHIFT
96 #define CPTRSIZE        CLONGSIZE
97 #define CPTRMASK        CLONGMASK
98
99 #if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT)
100 #error  "inconsistent shift constants"
101 #endif
102
103 #if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1)
104 #error  "inconsistent mask constants"
105 #endif
106
107 #define ASM_ENTRY_ALIGN 16
108
109 /*
110  * SSE register alignment and save areas
111  */
112
113 #define XMM_SIZE        16
114 #define XMM_ALIGN       16
115
116 #if defined(__amd64)
117
118 #define SAVE_XMM_PROLOG(sreg, nreg)                             \
119         subq    $_CONST(_MUL(XMM_SIZE, nreg)), %rsp;            \
120         movq    %rsp, sreg
121
122 #define RSTOR_XMM_EPILOG(sreg, nreg)                            \
123         addq    $_CONST(_MUL(XMM_SIZE, nreg)), %rsp
124
125 #elif defined(__i386)
126
127 #define SAVE_XMM_PROLOG(sreg, nreg)                             \
128         subl    $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; \
129         movl    %esp, sreg;                                     \
130         addl    $XMM_ALIGN, sreg;                               \
131         andl    $_BITNOT(XMM_ALIGN-1), sreg
132
133 #define RSTOR_XMM_EPILOG(sreg, nreg)                            \
134         addl    $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp;
135
136 #endif  /* __i386 */
137
138 /*
139  * profiling causes definitions of the MCOUNT and RTMCOUNT
140  * particular to the type
141  */
142 #ifdef GPROF
143
144 #define MCOUNT(x) \
145         pushl   %ebp; \
146         movl    %esp, %ebp; \
147         call    _mcount; \
148         popl    %ebp
149
150 #endif /* GPROF */
151
152 #ifdef PROF
153
154 #define MCOUNT(x) \
155 /* CSTYLED */ \
156         .lcomm .L_/**/x/**/1, 4, 4; \
157         pushl   %ebp; \
158         movl    %esp, %ebp; \
159 /* CSTYLED */ \
160         movl    $.L_/**/x/**/1, %edx; \
161         call    _mcount; \
162         popl    %ebp
163
164 #endif /* PROF */
165
166 /*
167  * if we are not profiling, MCOUNT should be defined to nothing
168  */
169 #if !defined(PROF) && !defined(GPROF)
170 #define MCOUNT(x)
171 #endif /* !defined(PROF) && !defined(GPROF) */
172
173 #define RTMCOUNT(x)     MCOUNT(x)
174
175 /*
176  * Macro to define weak symbol aliases. These are similar to the ANSI-C
177  *      #pragma weak name = _name
178  * except a compiler can determine type. The assembler must be told. Hence,
179  * the second parameter must be the type of the symbol (i.e.: function,...)
180  */
181 #define ANSI_PRAGMA_WEAK(sym, stype)    \
182         .weak   sym; \
183         .type sym, @stype; \
184 /* CSTYLED */ \
185 sym     = _/**/sym
186
187 /*
188  * Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in:
189  *      #pragma weak sym1 = sym2
190  */
191 #define ANSI_PRAGMA_WEAK2(sym1, sym2, stype)    \
192         .weak   sym1; \
193         .type sym1, @stype; \
194 sym1    = sym2
195
196 /*
197  * ENTRY provides the standard procedure entry code and an easy way to
198  * insert the calls to mcount for profiling. ENTRY_NP is identical, but
199  * never calls mcount.
200  */
201 #define ENTRY(x) \
202         .text; \
203         .align  ASM_ENTRY_ALIGN; \
204         .globl  x; \
205         .type   x, @function; \
206 x:      MCOUNT(x)
207
208 #define ENTRY_NP(x) \
209         .text; \
210         .align  ASM_ENTRY_ALIGN; \
211         .globl  x; \
212         .type   x, @function; \
213 x:
214
215 #define RTENTRY(x) \
216         .text; \
217         .align  ASM_ENTRY_ALIGN; \
218         .globl  x; \
219         .type   x, @function; \
220 x:      RTMCOUNT(x)
221
222 /*
223  * ENTRY2 is identical to ENTRY but provides two labels for the entry point.
224  */
225 #define ENTRY2(x, y) \
226         .text; \
227         .align  ASM_ENTRY_ALIGN; \
228         .globl  x, y; \
229         .type   x, @function; \
230         .type   y, @function; \
231 /* CSTYLED */ \
232 x:      ; \
233 y:      MCOUNT(x)
234
235 #define ENTRY_NP2(x, y) \
236         .text; \
237         .align  ASM_ENTRY_ALIGN; \
238         .globl  x, y; \
239         .type   x, @function; \
240         .type   y, @function; \
241 /* CSTYLED */ \
242 x:      ; \
243 y:
244
245
246 /*
247  * ALTENTRY provides for additional entry points.
248  */
249 #define ALTENTRY(x) \
250         .globl x; \
251         .type   x, @function; \
252 x:
253
254 /*
255  * DGDEF and DGDEF2 provide global data declarations.
256  *
257  * DGDEF provides a word aligned word of storage.
258  *
259  * DGDEF2 allocates "sz" bytes of storage with **NO** alignment.  This
260  * implies this macro is best used for byte arrays.
261  *
262  * DGDEF3 allocates "sz" bytes of storage with "algn" alignment.
263  */
264 #define DGDEF2(name, sz) \
265         .data; \
266         .globl  name; \
267         .type   name, @object; \
268         .size   name, sz; \
269 name:
270
271 #define DGDEF3(name, sz, algn) \
272         .data; \
273         .align  algn; \
274         .globl  name; \
275         .type   name, @object; \
276         .size   name, sz; \
277 name:
278
279 #define DGDEF(name)     DGDEF3(name, 4, 4)
280
281 /*
282  * SET_SIZE trails a function and set the size for the ELF symbol table.
283  */
284 #define SET_SIZE(x) \
285         .size   x, [.-x]
286
287 /*
288  * NWORD provides native word value.
289  */
290 #if defined(__amd64)
291
292 /*CSTYLED*/
293 #define NWORD   quad
294
295 #elif defined(__i386)
296
297 #define NWORD   long
298
299 #endif  /* __i386 */
300
301 #endif /* _ASM */
302
303 #ifdef  __cplusplus
304 }
305 #endif
306
307 #endif  /* _IA32_SYS_ASM_LINKAGE_H */