xref: /titanic_52/usr/src/lib/libbc/sparc/inc/sparc/asm_linkage.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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 (c) 1987 by Sun Microsystems, Inc.
24  */
25 
26 #ifndef _SYS_ASM_LINKAGE_H
27 #define _SYS_ASM_LINKAGE_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 		/* from SunOS 4.0 1.4 */
31 
32 /* allow word aligned user stacks */
33 #define PARTIAL_ALIGN
34 
35 /*
36  * A stack frame looks like:
37  *
38  * %fp->|				|
39  *	|-------------------------------|
40  *	|  Locals, temps, saved floats	|
41  *	|-------------------------------|
42  *	|  outgoing parameters past 6	|
43  *	|-------------------------------|-\
44  *	|  6 words for callee to dump	| |
45  *	|  register arguments		| |
46  *	|-------------------------------|  > minimum stack frame
47  *	|  One word struct-ret address	| |
48  *	|-------------------------------| |
49  *	|  16 words to save IN and	| |
50  * %sp->|  LOCAL register on overflow	| |
51  *	|-------------------------------|-/
52  */
53 
54 /*
55  * Constants defining a stack frame.
56  */
57 #define WINDOWSIZE	(16*4)		/* size of window save area */
58 #define ARGPUSHSIZE	(6*4)		/* size of arg dump area */
59 #define ARGPUSH		(WINDOWSIZE+4)	/* arg dump area offset */
60 #define MINFRAME	(WINDOWSIZE+ARGPUSHSIZE+4) /* min frame */
61 
62 /*
63  * Stack alignment macros.
64  */
65 #define STACK_ALIGN	8
66 #define SA(X)	(((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
67 
68 #ifdef _ASM	/* The remainder of this file is only for assembly files */
69 
70 /*
71  * Symbolic section definitions.
72  */
73 #define	RODATA	".rodata"
74 
75 /*
76  * profiling causes defintions of the MCOUNT and RTMCOUNT
77  * particular to the type
78  */
79 #ifdef GPROF
80 
81 #define MCOUNT(x) \
82 	save	%sp, -SA(MINFRAME), %sp; \
83 	call	mcount; \
84 	nop ; \
85 	restore	;
86 
87 #endif /* GPROF */
88 
89 #ifdef PROF
90 
91 #define MCOUNT(x) \
92 	save	%sp, -SA(MINFRAME), %sp; \
93 	sethi	%hi(.L_/**/x/**/1), %o0; \
94 	call	mcount; \
95         or      %o0, %lo(.L_/**/x/**/1), %o0; \
96         restore; \
97 	.common .L_/**/x/**/1, 4, ".bss";
98 
99 #endif /* PROF */
100 
101 /*
102  * if we are not profiling, MCOUNT should be defined to nothing
103  */
104 #if !defined(PROF) && !defined(GPROF)
105 #define MCOUNT(x)
106 #endif /* !defined(PROF) && !defined(GPROF) */
107 
108 #define RTMCOUNT(x)	MCOUNT(x)
109 
110 /*
111  * Pre-ansi compiler versions prepended an underscore to function names.
112  * This macro provides this function.
113  */
114 #ifndef	__STDC__
115 #define NAME(x) _/**/x
116 #endif	/* __STDC__ */
117 
118 /*
119  * Macro to define weak symbol aliases. These are similar to the ANSI-C
120  *	#pragma weak name = _name
121  * except a compiler can determine type. The assembler must be told. Hence,
122  * the second parameter must be the type of the symbol (i.e.: function,...)
123  */
124 #ifdef	__STDC__
125 #define ANSI_PRAGMA_WEAK(sym,stype)	\
126 	.weak	sym; \
127 	.type sym,#stype; \
128 sym	= _/**/sym
129 #endif	/* __STDC__ */
130 
131 /*
132  * ENTRY provides a way to insert the calls to mcount for profiling.
133  */
134 #ifdef	__STDC__
135 
136 #define ENTRY(x) \
137 	.section	".text"; \
138 	.align	4; \
139 	.global	x; \
140 	.type	x,#function; \
141 x:	MCOUNT(x)
142 
143 #define RTENTRY(x) \
144 	.global x; x: RTMCOUNT(x)
145 
146 #else	/* __STDC__ */
147 
148 #define ENTRY(x) \
149 	.global NAME(x); \
150 	NAME(x): MCOUNT(x)
151 
152 #define RTENTRY(x) \
153 	.global x; x: RTMCOUNT(x)
154 
155 #endif	/* __STDC__ */
156 
157 /*
158  * ENTRY2 is identical to ENTRY but provides two labels for the entry point.
159  */
160 #ifdef	__STDC__
161 
162 #define ENTRY2(x,y) \
163 	.section	".text"; \
164 	.align	4; \
165 	.global	x, y; \
166 	.type	x,#function; \
167 	.type	y,#function; \
168 x:	; \
169 y:	MCOUNT(x)
170 
171 #else	/* __STDC__ */
172 
173 #define ENTRY2(x,y) \
174 	.global NAME(x), NAME(y); \
175 	NAME(x): ; \
176 	NAME(y): MCOUNT(x)
177 
178 #endif	/* __STDC__ */
179 
180 /*
181  * ALTENTRY provides for additional entry points.
182  */
183 #ifdef	__STDC__
184 
185 #define ALTENTRY(x) \
186 	.global x; \
187 	.type	x,#function; \
188 x:
189 
190 #else	/* __STDC__ */
191 
192 #define ALTENTRY(x) \
193 	.global NAME(x); \
194 	NAME(x):
195 
196 #endif	/* __STDC__ */
197 
198 /*
199  * DGDEF and DGDEF2 provide global data declarations.
200  */
201 #ifdef	__STDC__
202 
203 #define DGDEF2(name,sz) \
204 	.section	".data"; \
205 	.global name; \
206 	.type	name,#object; \
207 	.size	name,sz; \
208 name:
209 
210 #else	/* __STDC__ */
211 
212 #define DGDEF2(name,sz) \
213 	.section	".data"; \
214 	.global name; \
215 name:
216 
217 #endif	/* __STDC__ */
218 
219 #define DGDEF(name)	DGDEF2(name,4)
220 
221 /*
222  * SET_SIZE trails a function and set the size for the ELF symbol table.
223  */
224 #ifdef	__STDC__
225 
226 #define SET_SIZE(x) \
227 	.size	x,(.-x)
228 
229 #else	/* __STDC__ */
230 
231 #define SET_SIZE(x)
232 
233 #endif	/* __STDC__ */
234 
235 #ifdef _KERNEL
236 /*
237  * Macros for saving/restoring registers.
238  */
239 
240 #define SAVE_GLOBALS(RP) \
241 	st	%g1, [RP + G1*4]; \
242 	std	%g2, [RP + G2*4]; \
243 	std	%g4, [RP + G4*4]; \
244 	std	%g6, [RP + G6*4]; \
245 	mov	%y, %g1; \
246 	st	%g1, [RP + Y*4]
247 
248 #define RESTORE_GLOBALS(RP) \
249 	ld	[RP + Y*4], %g1; \
250 	mov	%g1, %y; \
251 	ld	[RP + G1*4], %g1; \
252 	ldd	[RP + G2*4], %g2; \
253 	ldd	[RP + G4*4], %g4; \
254 	ldd	[RP + G6*4], %g6;
255 
256 #define SAVE_OUTS(RP) \
257 	std	%i0, [RP + O0*4]; \
258 	std	%i2, [RP + O2*4]; \
259 	std	%i4, [RP + O4*4]; \
260 	std	%i6, [RP + O6*4];
261 
262 #define RESTORE_OUTS(RP) \
263 	ldd	[RP + O0*4], %i0; \
264 	ldd	[RP + O2*4], %i2; \
265 	ldd	[RP + O4*4], %i4; \
266 	ldd	[RP + O6*4], %i6;
267 
268 #define SAVE_WINDOW(SBP) \
269 	std	%l0, [SBP + (0*4)]; \
270 	std	%l2, [SBP + (2*4)]; \
271 	std	%l4, [SBP + (4*4)]; \
272 	std	%l6, [SBP + (6*4)]; \
273 	std	%i0, [SBP + (8*4)]; \
274 	std	%i2, [SBP + (10*4)]; \
275 	std	%i4, [SBP + (12*4)]; \
276 	std	%i6, [SBP + (14*4)];
277 
278 #define RESTORE_WINDOW(SBP) \
279 	ldd	[SBP + (0*4)], %l0; \
280 	ldd	[SBP + (2*4)], %l2; \
281 	ldd	[SBP + (4*4)], %l4; \
282 	ldd	[SBP + (6*4)], %l6; \
283 	ldd	[SBP + (8*4)], %i0; \
284 	ldd	[SBP + (10*4)], %i2; \
285 	ldd	[SBP + (12*4)], %i4; \
286 	ldd	[SBP + (14*4)], %i6;
287 
288 #ifdef PARTIAL_ALIGN
289 
290 #define SAVE_WINDOW_S(SBP) \
291 	st	%l0, [SBP + (0*4)]; \
292 	st	%l1, [SBP + (1*4)]; \
293 	st	%l2, [SBP + (2*4)]; \
294 	st	%l3, [SBP + (3*4)]; \
295 	st	%l4, [SBP + (4*4)]; \
296 	st	%l5, [SBP + (5*4)]; \
297 	st	%l6, [SBP + (6*4)]; \
298 	st	%l7, [SBP + (7*4)]; \
299 	st	%i0, [SBP + (8*4)]; \
300 	st	%i1, [SBP + (9*4)]; \
301 	st	%i2, [SBP + (10*4)]; \
302 	st	%i3, [SBP + (11*4)]; \
303 	st	%i4, [SBP + (12*4)]; \
304 	st	%i5, [SBP + (13*4)]; \
305 	st	%i6, [SBP + (14*4)]; \
306 	st	%i7, [SBP + (15*4)]
307 
308 #define RESTORE_WINDOW_S(SBP) \
309 	ld	[SBP + (0*4)], %l0; \
310 	ld	[SBP + (1*4)], %l1; \
311 	ld	[SBP + (2*4)], %l2; \
312 	ld	[SBP + (3*4)], %l3; \
313 	ld	[SBP + (4*4)], %l4; \
314 	ld	[SBP + (5*4)], %l5; \
315 	ld	[SBP + (6*4)], %l6; \
316 	ld	[SBP + (7*4)], %l7; \
317 	ld	[SBP + (8*4)], %i0; \
318 	ld	[SBP + (9*4)], %i1; \
319 	ld	[SBP + (10*4)], %i2; \
320 	ld	[SBP + (11*4)], %i3; \
321 	ld	[SBP + (12*4)], %i4; \
322 	ld	[SBP + (13*4)], %i5; \
323 	ld	[SBP + (14*4)], %i6; \
324 	ld	[SBP + (15*4)], %i7
325 
326 #endif /* PARTIAL_ALIGN */
327 
328 #endif /* _KERNEL */
329 
330 #endif /* _ASM */
331 
332 #endif /* _SYS_ASM_LINKAGE_H */
333