PS2SDK
PS2 Homebrew Libraries
asm.h
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) AB
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