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