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 _SYS_ASM_LINKAGE_H
28#define	_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
36extern "C" {
37#endif
38
39#ifdef _ASM	/* The remainder of this file is only for assembly files */
40
41/*
42 * C pointers are different sizes between V8 and V9.
43 * These constants can be used to compute offsets into pointer arrays.
44 */
45#ifdef __sparcv9
46#define	CPTRSHIFT	3
47#define	CLONGSHIFT	3
48#else
49#define	CPTRSHIFT	2
50#define	CLONGSHIFT	2
51#endif
52#define	CPTRSIZE	(1<<CPTRSHIFT)
53#define	CLONGSIZE	(1<<CLONGSHIFT)
54#define	CPTRMASK	(CPTRSIZE - 1)
55#define	CLONGMASK	(CLONGSIZE - 1)
56
57/*
58 * Symbolic section definitions.
59 */
60#define	RODATA	".rodata"
61
62/*
63 * profiling causes defintions of the MCOUNT and RTMCOUNT
64 * particular to the type
65 */
66#ifdef GPROF
67
68#define	MCOUNT_SIZE	(4*4)	/* 4 instructions */
69#define	MCOUNT(x) \
70	save	%sp, -SA(MINFRAME), %sp; \
71	call	_mcount; \
72	nop; \
73	restore;
74
75#endif /* GPROF */
76
77#ifdef PROF
78
79#if defined(__sparcv9)
80
81#define	MCOUNT_SIZE	(9*4)	/* 9 instructions */
82#define	MCOUNT(x) \
83	save	%sp, -SA(MINFRAME), %sp; \
84/* CSTYLED */ \
85	sethi	%hh(.L_/**/x/**/1), %o0; \
86/* CSTYLED */ \
87	sethi	%lm(.L_/**/x/**/1), %o1; \
88/* CSTYLED */ \
89	or	%o0, %hm(.L_/**/x/**/1), %o0; \
90/* CSTYLED */ \
91	or	%o1, %lo(.L_/**/x/**/1), %o1; \
92	sllx	%o0, 32, %o0; \
93	call	_mcount; \
94	or	%o0, %o1, %o0; \
95	restore; \
96/* CSTYLED */ \
97	.common .L_/**/x/**/1, 8, 8
98
99#else	/* __sparcv9 */
100
101#define	MCOUNT_SIZE	(5*4)	/* 5 instructions */
102#define	MCOUNT(x) \
103	save	%sp, -SA(MINFRAME), %sp; \
104/* CSTYLED */ \
105	sethi	%hi(.L_/**/x/**/1), %o0; \
106	call	_mcount; \
107/* CSTYLED */ \
108	or	%o0, %lo(.L_/**/x/**/1), %o0; \
109	restore; \
110/* CSTYLED */ \
111	.common .L_/**/x/**/1, 4, 4
112
113#endif	/* __sparcv9 */
114
115#endif /* PROF */
116
117/*
118 * if we are not profiling, MCOUNT should be defined to nothing
119 */
120#if !defined(PROF) && !defined(GPROF)
121#define	MCOUNT_SIZE	0	/* no instructions inserted */
122#define	MCOUNT(x)
123#endif /* !defined(PROF) && !defined(GPROF) */
124
125#define	RTMCOUNT(x)	MCOUNT(x)
126
127/*
128 * Macro to define weak symbol aliases. These are similar to the ANSI-C
129 *	#pragma weak _name = name
130 * except a compiler can determine type. The assembler must be told. Hence,
131 * the second parameter must be the type of the symbol (i.e.: function,...)
132 */
133#define	ANSI_PRAGMA_WEAK(sym, stype)	\
134/* CSTYLED */ \
135	.weak	_/**/sym; \
136/* CSTYLED */ \
137	.type	_/**/sym, #stype; \
138/* CSTYLED */ \
139_/**/sym = sym
140
141/*
142 * Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in:
143 *	#pragma weak sym1 = sym2
144 */
145#define	ANSI_PRAGMA_WEAK2(sym1, sym2, stype)	\
146	.weak	sym1; \
147	.type sym1, #stype; \
148sym1	= sym2
149
150/*
151 * ENTRY provides the standard procedure entry code and an easy way to
152 * insert the calls to mcount for profiling. ENTRY_NP is identical, but
153 * never calls mcount.
154 */
155#define	ENTRY(x) \
156	.section	".text"; \
157	.align	4; \
158	.global	x; \
159	.type	x, #function; \
160x:	MCOUNT(x)
161
162#define	ENTRY_SIZE	MCOUNT_SIZE
163
164#define	ENTRY_NP(x) \
165	.section	".text"; \
166	.align	4; \
167	.global	x; \
168	.type	x, #function; \
169x:
170
171#define	RTENTRY(x) \
172	.section	".text"; \
173	.align	4; \
174	.global	x; \
175	.type	x, #function; \
176x:	RTMCOUNT(x)
177
178/*
179 * ENTRY2 is identical to ENTRY but provides two labels for the entry point.
180 */
181#define	ENTRY2(x, y) \
182	.section	".text"; \
183	.align	4; \
184	.global	x, y; \
185	.type	x, #function; \
186	.type	y, #function; \
187/* CSTYLED */ \
188x:	; \
189y:	MCOUNT(x)
190
191#define	ENTRY_NP2(x, y) \
192	.section	".text"; \
193	.align	4; \
194	.global	x, y; \
195	.type	x, #function; \
196	.type	y, #function; \
197/* CSTYLED */ \
198x:	; \
199y:
200
201
202/*
203 * ALTENTRY provides for additional entry points.
204 */
205#define	ALTENTRY(x) \
206	.global x; \
207	.type	x, #function; \
208x:
209
210/*
211 * DGDEF and DGDEF2 provide global data declarations.
212 *
213 * DGDEF provides a word aligned word of storage.
214 *
215 * DGDEF2 allocates "sz" bytes of storage with **NO** alignment.  This
216 * implies this macro is best used for byte arrays.
217 *
218 * DGDEF3 allocates "sz" bytes of storage with "algn" alignment.
219 */
220#define	DGDEF2(name, sz) \
221	.section	".data"; \
222	.global name; \
223	.type	name, #object; \
224	.size	name, sz; \
225name:
226
227#define	DGDEF3(name, sz, algn) \
228	.section	".data"; \
229	.align	algn; \
230	.global name; \
231	.type	name, #object; \
232	.size	name, sz; \
233name:
234
235#define	DGDEF(name)	DGDEF3(name, 4, 4)
236
237/*
238 * SET_SIZE trails a function and set the size for the ELF symbol table.
239 */
240#define	SET_SIZE(x) \
241	.size	x, (.-x)
242
243#endif /* _ASM */
244
245#ifdef	__cplusplus
246}
247#endif
248
249#endif	/* _SYS_ASM_LINKAGE_H */
250