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