| 1 | /* |
| 2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. |
| 3 | * |
| 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
| 5 | * |
| 6 | * This file contains Original Code and/or Modifications of Original Code |
| 7 | * as defined in and that are subject to the Apple Public Source License |
| 8 | * Version 2.0 (the 'License'). You may not use this file except in |
| 9 | * compliance with the License. The rights granted to you under the License |
| 10 | * may not be used to create, or enable the creation or redistribution of, |
| 11 | * unlawful or unlicensed copies of an Apple operating system, or to |
| 12 | * circumvent, violate, or enable the circumvention or violation of, any |
| 13 | * terms of an Apple operating system software license agreement. |
| 14 | * |
| 15 | * Please obtain a copy of the License at |
| 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
| 17 | * |
| 18 | * The Original Code and all software distributed under the License are |
| 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
| 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
| 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
| 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
| 23 | * Please see the License for the specific language governing rights and |
| 24 | * limitations under the License. |
| 25 | * |
| 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
| 27 | */ |
| 28 | /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved. |
| 29 | * |
| 30 | * File: architecture/i386/asm_help.h |
| 31 | * Author: Mike DeMoney, NeXT Computer, Inc. |
| 32 | * Modified for i386 by: Bruce Martin, NeXT Computer, Inc. |
| 33 | * |
| 34 | * This header file defines macros useful when writing assembly code |
| 35 | * for the Intel i386 family processors. |
| 36 | * |
| 37 | * HISTORY |
| 38 | * 10-Mar-92 Bruce Martin (bmartin@next.com) |
| 39 | * Adapted to i386 |
| 40 | * 23-Jan-91 Mike DeMoney (mike@next.com) |
| 41 | * Created. |
| 42 | */ |
| 43 | |
| 44 | #ifndef _ARCH_I386_ASM_HELP_H_ |
| 45 | #define _ARCH_I386_ASM_HELP_H_ |
| 46 | |
| 47 | #include <architecture/i386/reg_help.h> |
| 48 | |
| 49 | |
| 50 | #ifdef __ASSEMBLER__ |
| 51 | |
| 52 | #define ALIGN \ |
| 53 | .align 2, 0x90 |
| 54 | |
| 55 | /* Note that ROUND_TO_STACK rounds to Intel's stack alignment requirement, |
| 56 | * but it is not sufficient for the Apple ABI which requires a 16-byte |
| 57 | * aligned stack. Various parts of the OS depend on this requirement, |
| 58 | * including dyld. |
| 59 | */ |
| 60 | #define ROUND_TO_STACK(len) \ |
| 61 | (((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR) |
| 62 | |
| 63 | #ifdef notdef |
| 64 | #define CALL_MCOUNT \ |
| 65 | pushl %ebp ;\ |
| 66 | movl %esp, %ebp ;\ |
| 67 | .data ;\ |
| 68 | 1: .long 0 ;\ |
| 69 | .text ;\ |
| 70 | lea 9b,%edx ;\ |
| 71 | call mcount ;\ |
| 72 | popl %ebp ; |
| 73 | #else |
| 74 | #define CALL_MCOUNT |
| 75 | #endif |
| 76 | |
| 77 | /* |
| 78 | * Prologue for functions that may call other functions. Saves |
| 79 | * registers and sets up a C frame. |
| 80 | */ |
| 81 | #define NESTED_FUNCTION_PROLOGUE(localvarsize) \ |
| 82 | .set __framesize,ROUND_TO_STACK(localvarsize) ;\ |
| 83 | .set __nested_function, 1 ;\ |
| 84 | CALL_MCOUNT \ |
| 85 | .if __framesize ;\ |
| 86 | pushl %ebp ;\ |
| 87 | movl %esp, %ebp ;\ |
| 88 | subl $__framesize, %esp ;\ |
| 89 | .endif ;\ |
| 90 | pushl %edi ;\ |
| 91 | pushl %esi ;\ |
| 92 | pushl %ebx |
| 93 | |
| 94 | /* |
| 95 | * Prologue for functions that do not call other functions. Does not |
| 96 | * save registers (this is the functions responsibility). Does set |
| 97 | * up a C frame. |
| 98 | */ |
| 99 | #define LEAF_FUNCTION_PROLOGUE(localvarsize) \ |
| 100 | .set __framesize,ROUND_TO_STACK(localvarsize) ;\ |
| 101 | .set __nested_function, 0 ;\ |
| 102 | CALL_MCOUNT \ |
| 103 | .if __framesize ;\ |
| 104 | pushl %ebp ;\ |
| 105 | movl %esp, %ebp ;\ |
| 106 | subl $__framesize, %esp ;\ |
| 107 | .endif |
| 108 | |
| 109 | /* |
| 110 | * Prologue for any function. |
| 111 | * |
| 112 | * We assume that all Leaf functions will be responsible for saving any |
| 113 | * local registers they clobber. |
| 114 | */ |
| 115 | #define FUNCTION_EPILOGUE \ |
| 116 | .if __nested_function ;\ |
| 117 | popl %ebx ;\ |
| 118 | popl %esi ;\ |
| 119 | popl %edi ;\ |
| 120 | .endif ;\ |
| 121 | .if __framesize ;\ |
| 122 | movl %ebp, %esp ;\ |
| 123 | popl %ebp ;\ |
| 124 | .endif ;\ |
| 125 | ret |
| 126 | |
| 127 | |
| 128 | /* |
| 129 | * Macros for declaring procedures |
| 130 | * |
| 131 | * Use of these macros allows ctags to have a predictable way |
| 132 | * to find various types of declarations. They also simplify |
| 133 | * inserting appropriate symbol table information. |
| 134 | * |
| 135 | * NOTE: these simple stubs will be replaced with more |
| 136 | * complicated versions once we know what the linker and gdb |
| 137 | * will require as far as register use masks and frame declarations. |
| 138 | * These macros may also be ifdef'ed in the future to contain profiling |
| 139 | * code. |
| 140 | * |
| 141 | */ |
| 142 | |
| 143 | /* |
| 144 | * TEXT -- declare start of text segment |
| 145 | */ |
| 146 | #define TEXT \ |
| 147 | .text |
| 148 | |
| 149 | /* |
| 150 | * DATA -- declare start of data segment |
| 151 | */ |
| 152 | #define DATA \ |
| 153 | .data |
| 154 | |
| 155 | /* |
| 156 | * LEAF -- declare global leaf procedure |
| 157 | * NOTE: Control SHOULD NOT FLOW into a LEAF! A LEAF should only |
| 158 | * be jumped to. (A leaf may do an align.) Use a LABEL() if you |
| 159 | * need control to flow into the label. |
| 160 | */ |
| 161 | #define LEAF(name, localvarsize) \ |
| 162 | .globl name ;\ |
| 163 | ALIGN ;\ |
| 164 | name: ;\ |
| 165 | LEAF_FUNCTION_PROLOGUE(localvarsize) |
| 166 | |
| 167 | /* |
| 168 | * X_LEAF -- declare alternate global label for leaf |
| 169 | */ |
| 170 | #define X_LEAF(name, value) \ |
| 171 | .globl name ;\ |
| 172 | .set name,value |
| 173 | |
| 174 | /* |
| 175 | * P_LEAF -- declare private leaf procedure |
| 176 | */ |
| 177 | #define P_LEAF(name, localvarsize) \ |
| 178 | ALIGN ;\ |
| 179 | name: ;\ |
| 180 | LEAF_FUNCTION_PROLOGUE(localvarsize) |
| 181 | |
| 182 | /* |
| 183 | * LABEL -- declare a global code label |
| 184 | * MUST be used (rather than LEAF, NESTED, etc) if control |
| 185 | * "flows into" the label. |
| 186 | */ |
| 187 | #define LABEL(name) \ |
| 188 | .globl name ;\ |
| 189 | name: |
| 190 | |
| 191 | /* |
| 192 | * NESTED -- declare procedure that invokes other procedures |
| 193 | */ |
| 194 | #define NESTED(name, localvarsize) \ |
| 195 | .globl name ;\ |
| 196 | ALIGN ;\ |
| 197 | name: ;\ |
| 198 | NESTED_FUNCTION_PROLOGUE(localvarsize) |
| 199 | |
| 200 | /* |
| 201 | * X_NESTED -- declare alternate global label for nested proc |
| 202 | */ |
| 203 | #define X_NESTED(name, value) \ |
| 204 | .globl name ;\ |
| 205 | .set name,value |
| 206 | |
| 207 | /* |
| 208 | * P_NESTED -- declare private nested procedure |
| 209 | */ |
| 210 | #define P_NESTED(name, localvarsize) \ |
| 211 | ALIGN ;\ |
| 212 | name: ;\ |
| 213 | NESTED_FUNCTION_PROLOGUE(localvarsize) |
| 214 | |
| 215 | /* |
| 216 | * END -- mark end of procedure |
| 217 | */ |
| 218 | #define END(name) \ |
| 219 | FUNCTION_EPILOGUE |
| 220 | |
| 221 | |
| 222 | /* |
| 223 | * Storage definition macros |
| 224 | * The main purpose of these is to allow an easy handle for ctags |
| 225 | */ |
| 226 | |
| 227 | /* |
| 228 | * IMPORT -- import symbol |
| 229 | */ |
| 230 | #define IMPORT(name) \ |
| 231 | .reference name |
| 232 | |
| 233 | /* |
| 234 | * ABS -- declare global absolute symbol |
| 235 | */ |
| 236 | #define ABS(name, value) \ |
| 237 | .globl name ;\ |
| 238 | .set name,value |
| 239 | |
| 240 | /* |
| 241 | * P_ABS -- declare private absolute symbol |
| 242 | */ |
| 243 | #define P_ABS(name, value) \ |
| 244 | .set name,value |
| 245 | |
| 246 | /* |
| 247 | * EXPORT -- declare global label for data |
| 248 | */ |
| 249 | #define EXPORT(name) \ |
| 250 | .globl name ;\ |
| 251 | name: |
| 252 | |
| 253 | /* |
| 254 | * BSS -- declare global zero'ed storage |
| 255 | */ |
| 256 | #define BSS(name,size) \ |
| 257 | .comm name,size |
| 258 | |
| 259 | |
| 260 | /* |
| 261 | * P_BSS -- declare private zero'ed storage |
| 262 | */ |
| 263 | #define P_BSS(name,size) \ |
| 264 | .lcomm name,size |
| 265 | |
| 266 | /* |
| 267 | * dynamic/PIC macros for routines which reference external symbols |
| 268 | */ |
| 269 | |
| 270 | #if defined(__DYNAMIC__) |
| 271 | #define PICIFY(var) \ |
| 272 | call 1f ; \ |
| 273 | 1: ; \ |
| 274 | popl %edx ; \ |
| 275 | movl L ## var ## $non_lazy_ptr-1b(%edx),%edx |
| 276 | |
| 277 | #define CALL_EXTERN_AGAIN(func) \ |
| 278 | PICIFY(func) ; \ |
| 279 | call %edx |
| 280 | |
| 281 | #define NON_LAZY_STUB(var) \ |
| 282 | .non_lazy_symbol_pointer ; \ |
| 283 | L ## var ## $non_lazy_ptr: ; \ |
| 284 | .indirect_symbol var ; \ |
| 285 | .long 0 ; \ |
| 286 | .text |
| 287 | |
| 288 | #define CALL_EXTERN(func) \ |
| 289 | CALL_EXTERN_AGAIN(func) ; \ |
| 290 | NON_LAZY_STUB(func) |
| 291 | |
| 292 | #define BRANCH_EXTERN(func) \ |
| 293 | PICIFY(func) ; \ |
| 294 | jmp %edx ; \ |
| 295 | NON_LAZY_STUB(func) |
| 296 | |
| 297 | #define PUSH_EXTERN(var) \ |
| 298 | PICIFY(var) ; \ |
| 299 | movl (%edx),%edx ; \ |
| 300 | pushl %edx ; \ |
| 301 | NON_LAZY_STUB(var) |
| 302 | |
| 303 | #define REG_TO_EXTERN(reg, var) \ |
| 304 | PICIFY(var) ; \ |
| 305 | movl reg, (%edx) ; \ |
| 306 | NON_LAZY_STUB(var) |
| 307 | |
| 308 | #define EXTERN_TO_REG(var, reg) \ |
| 309 | call 1f ; \ |
| 310 | 1: ; \ |
| 311 | popl %edx ; \ |
| 312 | movl L ## var ##$non_lazy_ptr-1b(%edx),reg ; \ |
| 313 | NON_LAZY_STUB(var) |
| 314 | |
| 315 | |
| 316 | #else |
| 317 | #define BRANCH_EXTERN(func) jmp func |
| 318 | #define PUSH_EXTERN(var) pushl var |
| 319 | #define CALL_EXTERN(func) call func |
| 320 | #define CALL_EXTERN_AGAIN(func) call func |
| 321 | #define REG_TO_EXTERN(reg, var) movl reg, var |
| 322 | #define EXTERN_TO_REG(var, reg) movl $ ## var, reg |
| 323 | #endif |
| 324 | |
| 325 | #endif /* __ASSEMBLER__ */ |
| 326 | |
| 327 | #endif /* _ARCH_I386_ASM_HELP_H_ */ |
| 328 | |