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 ;\ 164name: ;\ 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 ;\ 179name: ;\ 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 ;\ 189name: 190 191/* 192 * NESTED -- declare procedure that invokes other procedures 193 */ 194#define NESTED(name, localvarsize) \ 195 .globl name ;\ 196 ALIGN ;\ 197name: ;\ 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 ;\ 212name: ;\ 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 ;\ 251name: 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 ; \ 2731: ; \ 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 ; \ 283L ## 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 ; \ 3101: ; \ 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