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#define ROUND_TO_STACK(len) \ 56 (((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR) 57 58#ifdef notdef 59#define CALL_MCOUNT \ 60 pushl %ebp ;\ 61 movl %esp, %ebp ;\ 62 .data ;\ 63 1: .long 0 ;\ 64 .text ;\ 65 lea 9b,%edx ;\ 66 call mcount ;\ 67 popl %ebp ; 68#else 69#define CALL_MCOUNT 70#endif 71 72/* 73 * Prologue for functions that may call other functions. Saves 74 * registers and sets up a C frame. 75 */ 76#define NESTED_FUNCTION_PROLOGUE(localvarsize) \ 77 .set __framesize,ROUND_TO_STACK(localvarsize) ;\ 78 .set __nested_function, 1 ;\ 79 CALL_MCOUNT \ 80 .if __framesize ;\ 81 pushl %ebp ;\ 82 movl %esp, %ebp ;\ 83 subl $__framesize, %esp ;\ 84 .endif ;\ 85 pushl %edi ;\ 86 pushl %esi ;\ 87 pushl %ebx 88 89/* 90 * Prologue for functions that do not call other functions. Does not 91 * save registers (this is the functions responsibility). Does set 92 * up a C frame. 93 */ 94#define LEAF_FUNCTION_PROLOGUE(localvarsize) \ 95 .set __framesize,ROUND_TO_STACK(localvarsize) ;\ 96 .set __nested_function, 0 ;\ 97 CALL_MCOUNT \ 98 .if __framesize ;\ 99 pushl %ebp ;\ 100 movl %esp, %ebp ;\ 101 subl $__framesize, %esp ;\ 102 .endif 103 104/* 105 * Prologue for any function. 106 * 107 * We assume that all Leaf functions will be responsible for saving any 108 * local registers they clobber. 109 */ 110#define FUNCTION_EPILOGUE \ 111 .if __nested_function ;\ 112 popl %ebx ;\ 113 popl %esi ;\ 114 popl %edi ;\ 115 .endif ;\ 116 .if __framesize ;\ 117 movl %ebp, %esp ;\ 118 popl %ebp ;\ 119 .endif ;\ 120 ret 121 122 123/* 124 * Macros for declaring procedures 125 * 126 * Use of these macros allows ctags to have a predictable way 127 * to find various types of declarations. They also simplify 128 * inserting appropriate symbol table information. 129 * 130 * NOTE: these simple stubs will be replaced with more 131 * complicated versions once we know what the linker and gdb 132 * will require as far as register use masks and frame declarations. 133 * These macros may also be ifdef'ed in the future to contain profiling 134 * code. 135 * 136 */ 137 138/* 139 * TEXT -- declare start of text segment 140 */ 141#define TEXT \ 142 .text 143 144/* 145 * DATA -- declare start of data segment 146 */ 147#define DATA \ 148 .data 149 150/* 151 * LEAF -- declare global leaf procedure 152 * NOTE: Control SHOULD NOT FLOW into a LEAF! A LEAF should only 153 * be jumped to. (A leaf may do an align.) Use a LABEL() if you 154 * need control to flow into the label. 155 */ 156#define LEAF(name, localvarsize) \ 157 .globl name ;\ 158 ALIGN ;\ 159name: ;\ 160 LEAF_FUNCTION_PROLOGUE(localvarsize) 161 162/* 163 * X_LEAF -- declare alternate global label for leaf 164 */ 165#define X_LEAF(name, value) \ 166 .globl name ;\ 167 .set name,value 168 169/* 170 * P_LEAF -- declare private leaf procedure 171 */ 172#define P_LEAF(name, localvarsize) \ 173 ALIGN ;\ 174name: ;\ 175 LEAF_FUNCTION_PROLOGUE(localvarsize) 176 177/* 178 * LABEL -- declare a global code label 179 * MUST be used (rather than LEAF, NESTED, etc) if control 180 * "flows into" the label. 181 */ 182#define LABEL(name) \ 183 .globl name ;\ 184name: 185 186/* 187 * NESTED -- declare procedure that invokes other procedures 188 */ 189#define NESTED(name, localvarsize) \ 190 .globl name ;\ 191 ALIGN ;\ 192name: ;\ 193 NESTED_FUNCTION_PROLOGUE(localvarsize) 194 195/* 196 * X_NESTED -- declare alternate global label for nested proc 197 */ 198#define X_NESTED(name, value) \ 199 .globl name ;\ 200 .set name,value 201 202/* 203 * P_NESTED -- declare private nested procedure 204 */ 205#define P_NESTED(name, localvarsize) \ 206 ALIGN ;\ 207name: ;\ 208 NESTED_FUNCTION_PROLOGUE(localvarsize) 209 210/* 211 * END -- mark end of procedure 212 */ 213#define END(name) \ 214 FUNCTION_EPILOGUE 215 216 217/* 218 * Storage definition macros 219 * The main purpose of these is to allow an easy handle for ctags 220 */ 221 222/* 223 * IMPORT -- import symbol 224 */ 225#define IMPORT(name) \ 226 .reference name 227 228/* 229 * ABS -- declare global absolute symbol 230 */ 231#define ABS(name, value) \ 232 .globl name ;\ 233 .set name,value 234 235/* 236 * P_ABS -- declare private absolute symbol 237 */ 238#define P_ABS(name, value) \ 239 .set name,value 240 241/* 242 * EXPORT -- declare global label for data 243 */ 244#define EXPORT(name) \ 245 .globl name ;\ 246name: 247 248/* 249 * BSS -- declare global zero'ed storage 250 */ 251#define BSS(name,size) \ 252 .comm name,size 253 254 255/* 256 * P_BSS -- declare private zero'ed storage 257 */ 258#define P_BSS(name,size) \ 259 .lcomm name,size 260 261/* 262 * dynamic/PIC macros for routines which reference external symbols 263 */ 264 265#if defined(__DYNAMIC__) 266#define PICIFY(var) \ 267 call 1f ; \ 2681: ; \ 269 popl %edx ; \ 270 movl L ## var ## $non_lazy_ptr-1b(%edx),%edx 271 272#define CALL_EXTERN_AGAIN(func) \ 273 PICIFY(func) ; \ 274 call %edx 275 276#define NON_LAZY_STUB(var) \ 277.non_lazy_symbol_pointer ; \ 278L ## var ## $non_lazy_ptr: ; \ 279.indirect_symbol var ; \ 280.long 0 ; \ 281.text 282 283#define CALL_EXTERN(func) \ 284 CALL_EXTERN_AGAIN(func) ; \ 285 NON_LAZY_STUB(func) 286 287#define BRANCH_EXTERN(func) \ 288 PICIFY(func) ; \ 289 jmp %edx ; \ 290 NON_LAZY_STUB(func) 291 292#define PUSH_EXTERN(var) \ 293 PICIFY(var) ; \ 294 movl (%edx),%edx ; \ 295 pushl %edx ; \ 296 NON_LAZY_STUB(var) 297 298#define REG_TO_EXTERN(reg, var) \ 299 PICIFY(var) ; \ 300 movl reg, (%edx) ; \ 301 NON_LAZY_STUB(var) 302 303#define EXTERN_TO_REG(var, reg) \ 304 call 1f ; \ 3051: ; \ 306 popl %edx ; \ 307 movl L ## var ##$non_lazy_ptr-1b(%edx),reg ; \ 308 NON_LAZY_STUB(var) 309 310 311#else 312#define BRANCH_EXTERN(func) jmp func 313#define PUSH_EXTERN(var) pushl var 314#define CALL_EXTERN(func) call func 315#define CALL_EXTERN_AGAIN(func) call func 316#define REG_TO_EXTERN(reg, var) movl reg, var 317#define EXTERN_TO_REG(var, reg) movl $ ## var, reg 318#endif 319 320#endif /* __ASSEMBLER__ */ 321 322#endif /* _ARCH_I386_ASM_HELP_H_ */ 323