1 /*
2  * Copyright (c) 1996-2007 MIPS Technologies, Inc.
3  * Copyright (C) 2009 CodeSourcery, LLC.
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  *      * Redistributions of source code must retain the above copyright
12  *        notice, this list of conditions and the following disclaimer.
13  *      * Redistributions in binary form must reproduce the above
14  *      copyright
15  *        notice, this list of conditions and the following disclaimer
16  *        in the documentation and/or other materials provided with
17  *        the distribution.
18  *      * Neither the name of MIPS Technologies Inc. nor the names of its
19  *        contributors may be used to endorse or promote products derived
20  *        from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /*
36  * asm.h: various macros to help assembly language writers
37  */
38 
39 #ifndef _MIPS_ASM_H_
40 #define _MIPS_ASM_H_
41 
42 /* ABI specific stack frame layout and manipulation. */
43 #if _MIPS_SIM==_ABIO32 && ! __mips64
44 /* Standard O32 */
45 #define SZREG		4	/* saved register size */
46 #define	REG_S		sw	/* store saved register */
47 #define	REG_L		lw	/* load saved register */
48 #define SZARG		4	/* argument register size */
49 #define	NARGSAVE	4	/* arg register space on caller stack */
50 #define ALSZ		7	/* stack alignment - 1 */
51 #define ALMASK		(~7)	/* stack alignment mask */
52 #define LOG2_STACK_ALGN	3	/* log2(8) */
53 #define SZPTR		4	/* pointer size */
54 #define LOG2_SZPTR	2	/* log2(4) */
55 #define PTR_S		sw	/* store pointer */
56 #define PTR_L		lw	/* load pointer */
57 #define PTR_SUBU	subu	/* decrement pointer */
58 #define PTR_ADDU	addu	/* increment pointer */
59 #define PTR		.word	/* pointer type pseudo */
60 #elif _MIPS_SIM==_ABIO32 && __mips64
61 /* Algorithmics O32+64-bit */
62 #define SZREG		8	/* saved register size */
63 #define	REG_S		sd	/* store saved register */
64 #define	REG_L		ld	/* load saved register */
65 #define SZARG		4	/* argument register size */
66 #define	NARGSAVE	4	/* arg register space on caller stack */
67 #define ALSZ		7	/* stack alignment - 1 */
68 #define ALMASK		(~7)	/* stack alignment mask */
69 #define LOG2_STACK_ALGN	3	/* log2(8) */
70 #define SZPTR		4	/* pointer size */
71 #define LOG2_SZPTR	2	/* log2(4) */
72 #define PTR_S		sw	/* store pointer */
73 #define PTR_L		lw	/* load pointer */
74 #define PTR_SUBU	subu	/* decrement pointer */
75 #define PTR_ADDU	addu	/* increment pointer */
76 #define PTR		.word	/* pointer type pseudo */
77 #elif _MIPS_SIM==_ABIO64
78 /* Cygnus O64 */
79 #define SZREG		8	/* saved register size */
80 #define	REG_S		sd	/* store saved register */
81 #define	REG_L		ld	/* load saved register */
82 #define SZARG		8	/* argument register size */
83 #define	NARGSAVE	4	/* arg register space on caller stack */
84 #define ALSZ		7	/* stack alignment - 1 */
85 #define ALMASK		(~7)	/* stack alignment mask */
86 #define LOG2_STACK_ALGN	3	/* log2(8) */
87 #define SZPTR		4	/* pointer size */
88 #define LOG2_SZPTR	2	/* log2(4) */
89 #define PTR_S		sw	/* store pointer */
90 #define PTR_L		lw	/* load pointer */
91 #define PTR_SUBU	subu	/* decrement pointer */
92 #define PTR_ADDU	addu	/* increment pointer */
93 #define PTR		.word	/* pointer type pseudo */
94 #elif _MIPS_SIM==_ABIN32
95 /* Standard N32 */
96 #define SZREG		8	/* saved register size */
97 #define	REG_S		sd	/* store saved register */
98 #define	REG_L		ld	/* load saved register */
99 #define SZARG		8	/* argument register size */
100 #define	NARGSAVE	0	/* arg register space on caller stack */
101 #define ALSZ		15	/* stack alignment - 1 */
102 #define ALMASK		(~15)	/* stack alignment mask */
103 #define LOG2_STACK_ALGN	4	/* log2(16) */
104 #define SZPTR		4	/* pointer size */
105 #define LOG2_SZPTR	2	/* log2(4) */
106 #define PTR_S		sw	/* store pointer */
107 #define PTR_L		lw	/* load pointer */
108 #define PTR_SUBU	subu	/* decrement pointer (SGI uses sub) */
109 #define PTR_ADDU	addu	/* increment pointer (SGI uses add) */
110 #define PTR		.word	/* pointer type pseudo */
111 #elif _MIPS_SIM==_ABI64
112 /* Standard N64 */
113 #define SZREG		8	/* saved register size */
114 #define	REG_S		sd	/* store saved register */
115 #define	REG_L		ld	/* load saved register */
116 #define SZARG		8	/* argument register size */
117 #define	NARGSAVE	0	/* arg register space on caller stack */
118 #define ALSZ		15	/* stack alignment - 1 */
119 #define ALMASK		(~15)	/* stack alignment mask */
120 #define LOG2_STACK_ALGN	4	/* log2(16) */
121 #define SZPTR		8	/* pointer size */
122 #define LOG2_SZPTR	3	/* log2(8) */
123 #define PTR_S		sd	/* store pointer */
124 #define PTR_L		ld	/* load pointer */
125 #define PTR_SUBU	dsubu	/* decrement pointer */
126 #define PTR_ADDU	daddu	/* increment pointer */
127 #define PTR		.dword	/* pointer type pseudo */
128 #else
129 #error Unknown ABI
130 #endif
131 
132 /* Concatenate two names. */
133 #ifdef __STDC__
134 # define _ASMCONCAT(A, B) A ## B
135 #else
136 # define _ASMCONCAT(A, B) A/**/B
137 #endif
138 
139 /* Name of reset code section. */
140 #ifndef _RESET_SECTION
141 # define _RESET_SECTION .section .reset, "ax", @progbits
142 #endif
143 
144 #ifndef _RESET_SECTION_NAMED
145 /* No function section support for now, since binutils fails to cope with
146    external branches. */
147 # define _RESET_SECTION_NAMED(name) .pushsection .reset, "ax", @progbits
148 #endif
149 
150 /* Name of boot code section. */
151 #ifndef _BOOT_SECTION
152 # define _BOOT_SECTION .section .boot, "ax", @progbits
153 #endif
154 
155 #ifndef _BOOT_SECTION_NAMED
156 /* No function section support for now, since binutils fails to cope with
157    external branches. */
158 # define _BOOT_SECTION_NAMED(name) .pushsection .boot, "ax", @progbits
159 #endif
160 
161 /* Name of standard code section. */
162 #ifndef _NORMAL_SECTION_UNNAMED
163 # define _NORMAL_SECTION_UNNAMED .section .text, "ax", @progbits
164 #endif
165 
166 #ifndef _NORMAL_SECTION_NAMED
167 # ifdef _FUNCTION_SECTIONS_
168 #  define _NORMAL_SECTION_NAMED(name) .pushsection .text ##.name, "ax", @progbits
169 # else
170 #  define _NORMAL_SECTION_NAMED(name) .pushsection .text, "ax", @progbits
171 # endif
172 #endif
173 
174 /* Default code section. */
175 #ifndef _TEXT_SECTION_NAMED
176 # if defined(_RESETCODE)
177 #  define _TEXT_SECTION_NAMED _RESET_SECTION_NAMED
178 # elif defined(_BOOTCODE)
179 #  define _TEXT_SECTION_NAMED _BOOT_SECTION_NAMED
180 # else
181 #  define _TEXT_SECTION_NAMED _NORMAL_SECTION_NAMED
182 # endif
183 #endif
184 
185 #ifndef _TEXT_SECTION
186 # if defined(_RESETCODE)
187 #  define _TEXT_SECTION _RESET_SECTION
188 # elif defined(_BOOTCODE)
189 #  define _TEXT_SECTION _BOOT_SECTION
190 # else
191 #  define _TEXT_SECTION _NORMAL_SECTION_UNNAMED
192 # endif
193 	_TEXT_SECTION
194 #endif
195 
196 /*
197  * Leaf functions declarations.
198  */
199 
200 /* Global leaf function. */
201 #define LEAF(name) 			\
202   	_TEXT_SECTION_NAMED(name);	\
203   	.globl	name; 			\
204 	.balign	4;			\
205   	.ent	name; 			\
206 name:
207 
208 /* Static/Local leaf function. */
209 #define SLEAF(name) 			\
210   	_TEXT_SECTION_NAMED(name);	\
211 	.balign	4;			\
212   	.ent	name; 			\
213 name:
214 
215 /* Weak leaf function. */
216 #define WLEAF(name) 			\
217   	_TEXT_SECTION_NAMED(name);	\
218   	.weakext name; 			\
219 	.balign	4;			\
220   	.ent	name; 			\
221 name:
222 
223 /* Weak alias leaf function. */
224 #define ALEAF(name,alias) 		\
225   	_TEXT_SECTION_NAMED(name);	\
226   	.weakext alias,name; 		\
227 	.balign	4;			\
228   	.ent	name; 			\
229 name:
230 
231 /*
232  * Alternative function entrypoints.
233  */
234 
235 /* Global alternative entrypoint. */
236 #define AENT(name) 			\
237   	.globl	name; 			\
238 	.balign	4;			\
239   	.aent	name; 			\
240 name:
241 #define XLEAF(name)	AENT(name)
242 
243 /* Local/static alternative entrypoint. */
244 #define SAENT(name) 			\
245 	.balign	4;			\
246   	.aent	name; 			\
247 name:
248 #define SXLEAF(name)	SAENT(name)
249 
250 
251 /*
252  * Leaf functions declarations.
253  */
254 
255 /* Global nested function. */
256 #define NESTED(name, framesz, rareg)	\
257   	_TEXT_SECTION_NAMED(name);	\
258   	.globl	name; 			\
259 	.balign	4;			\
260   	.ent	name; 			\
261 	.frame	sp, framesz, rareg;	\
262 name:
263 
264 /* Static/Local nested function. */
265 #define SNESTED(name, framesz, rareg)	\
266   	_TEXT_SECTION_NAMED(name);	\
267 	.balign	4;			\
268   	.ent	name; 			\
269 	.frame	sp, framesz, rareg;	\
270 name:
271 
272 /* Weak nested function. */
273 #define WNESTED(name, framesz, rareg)	\
274   	_TEXT_SECTION_NAMED(name);	\
275   	.weakext name; 			\
276 	.balign	4;			\
277   	.ent	name; 			\
278 	.frame	sp, framesz, rareg;	\
279 name:
280 
281 /* Weak alias nested function. */
282 #define ANESTED(name, alias, framesz, rareg) \
283   	_TEXT_SECTION_NAMED(name);	\
284     	.weakext alias, name;		\
285 	.balign	4;			\
286   	.ent	name; 			\
287 	.frame	sp, framesz, rareg;	\
288 name:
289 
290 /*
291  * Function termination
292  */
293 #define END(name) 			\
294   	.size name,.-name; 		\
295   	.end	name;			\
296 	.popsection
297 
298 #define SEND(name)	END(name)
299 #define WEND(name)	END(name)
300 #define AEND(name,alias) END(name)
301 
302 /*
303  * Global data declaration.
304  */
305 #define EXPORT(name) \
306   	.globl name; \
307   	.type name,@object; \
308 name:
309 
310 /*
311  * Global data declaration with size.
312  */
313 #define EXPORTS(name,sz) 		\
314   	.globl name; 			\
315   	.type name,@object; 		\
316   	.size name,sz; 			\
317 name:
318 
319 /*
320  * Weak data declaration with size.
321  */
322 #define WEXPORT(name,sz) 		\
323   	.weakext name; 			\
324   	.type name,@object; 		\
325   	.size name,sz; 			\
326 name:
327 
328 /*
329  * Global data reference with size.
330  */
331 #define	IMPORT(name, size) 		\
332 	.extern	name,size
333 
334 /*
335  * Global zeroed data.
336  */
337 #define BSS(name,size) 			\
338   	.type name,@object; 		\
339 	.comm	name,size
340 
341 /*
342  * Local zeroed data.
343  */
344 #define LBSS(name,size) 		\
345   	.lcomm	name,size
346 
347 /*
348  * Insert call to _mcount if profiling.
349  */
350 #ifdef __PROFILING__
351 #define _MCOUNT 			\
352 	.set push; 			\
353 	.set noat; 			\
354 	move	$1,$31; 		\
355 	jal	_mcount; 		\
356   	.set pop
357 #else
358 #define _MCOUNT
359 #endif
360 
361 #endif
362