Home | History | Annotate | Download | only in sys
      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 (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     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 /* CSTYLED */ \
    183 	.weak	_/**/sym; \
    184 /* CSTYLED */ \
    185 	.type	_/**/sym, @stype; \
    186 /* CSTYLED */ \
    187 _/**/sym = sym
    188 
    189 /*
    190  * Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in:
    191  *	#pragma weak sym1 = sym2
    192  */
    193 #define	ANSI_PRAGMA_WEAK2(sym1, sym2, stype)	\
    194 	.weak	sym1; \
    195 	.type sym1, @stype; \
    196 sym1	= sym2
    197 
    198 /*
    199  * ENTRY provides the standard procedure entry code and an easy way to
    200  * insert the calls to mcount for profiling. ENTRY_NP is identical, but
    201  * never calls mcount.
    202  */
    203 #define	ENTRY(x) \
    204 	.text; \
    205 	.align	ASM_ENTRY_ALIGN; \
    206 	.globl	x; \
    207 	.type	x, @function; \
    208 x:	MCOUNT(x)
    209 
    210 #define	ENTRY_NP(x) \
    211 	.text; \
    212 	.align	ASM_ENTRY_ALIGN; \
    213 	.globl	x; \
    214 	.type	x, @function; \
    215 x:
    216 
    217 #define	RTENTRY(x) \
    218 	.text; \
    219 	.align	ASM_ENTRY_ALIGN; \
    220 	.globl	x; \
    221 	.type	x, @function; \
    222 x:	RTMCOUNT(x)
    223 
    224 /*
    225  * ENTRY2 is identical to ENTRY but provides two labels for the entry point.
    226  */
    227 #define	ENTRY2(x, y) \
    228 	.text; \
    229 	.align	ASM_ENTRY_ALIGN; \
    230 	.globl	x, y; \
    231 	.type	x, @function; \
    232 	.type	y, @function; \
    233 /* CSTYLED */ \
    234 x:	; \
    235 y:	MCOUNT(x)
    236 
    237 #define	ENTRY_NP2(x, y) \
    238 	.text; \
    239 	.align	ASM_ENTRY_ALIGN; \
    240 	.globl	x, y; \
    241 	.type	x, @function; \
    242 	.type	y, @function; \
    243 /* CSTYLED */ \
    244 x:	; \
    245 y:
    246 
    247 
    248 /*
    249  * ALTENTRY provides for additional entry points.
    250  */
    251 #define	ALTENTRY(x) \
    252 	.globl x; \
    253 	.type	x, @function; \
    254 x:
    255 
    256 /*
    257  * DGDEF and DGDEF2 provide global data declarations.
    258  *
    259  * DGDEF provides a word aligned word of storage.
    260  *
    261  * DGDEF2 allocates "sz" bytes of storage with **NO** alignment.  This
    262  * implies this macro is best used for byte arrays.
    263  *
    264  * DGDEF3 allocates "sz" bytes of storage with "algn" alignment.
    265  */
    266 #define	DGDEF2(name, sz) \
    267 	.data; \
    268 	.globl	name; \
    269 	.type	name, @object; \
    270 	.size	name, sz; \
    271 name:
    272 
    273 #define	DGDEF3(name, sz, algn) \
    274 	.data; \
    275 	.align	algn; \
    276 	.globl	name; \
    277 	.type	name, @object; \
    278 	.size	name, sz; \
    279 name:
    280 
    281 #define	DGDEF(name)	DGDEF3(name, 4, 4)
    282 
    283 /*
    284  * SET_SIZE trails a function and set the size for the ELF symbol table.
    285  */
    286 #define	SET_SIZE(x) \
    287 	.size	x, [.-x]
    288 
    289 /*
    290  * NWORD provides native word value.
    291  */
    292 #if defined(__amd64)
    293 
    294 /*CSTYLED*/
    295 #define	NWORD	quad
    296 
    297 #elif defined(__i386)
    298 
    299 #define	NWORD	long
    300 
    301 #endif  /* __i386 */
    302 
    303 #endif /* _ASM */
    304 
    305 #ifdef	__cplusplus
    306 }
    307 #endif
    308 
    309 #endif	/* _IA32_SYS_ASM_LINKAGE_H */
    310