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 /* 29 * @OSF_COPYRIGHT@ 30 */ 31 /* 32 * Mach Operating System 33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56 57 #ifndef _I386_ASM_H_ 58 #define _I386_ASM_H_ 59 60 #ifdef _KERNEL 61 #include <gprof.h> 62 #endif /* _KERNEL */ 63 64 #ifdef MACH_KERNEL 65 #include <mach_kdb.h> 66 #else /* !MACH_KERNEL */ 67 #define MACH_KDB 0 68 #endif /* !MACH_KERNEL */ 69 70 71 #if defined(MACH_KERNEL) || defined(_KERNEL) 72 #include <gprof.h> 73 #endif /* MACH_KERNEL || _KERNEL */ 74 75 #if defined(__i386__) 76 77 #define S_PC (%esp) 78 #define S_ARG0 4(%esp) 79 #define S_ARG1 8(%esp) 80 #define S_ARG2 12(%esp) 81 #define S_ARG3 16(%esp) 82 #define S_ARG4 20(%esp) 83 84 #define FRAME pushl %ebp; movl %esp, %ebp 85 #define EMARF leave 86 87 #define B_LINK (%ebp) 88 #define B_PC 4(%ebp) 89 #define B_ARG0 8(%ebp) 90 #define B_ARG1 12(%ebp) 91 #define B_ARG2 16(%ebp) 92 #define B_ARG3 20(%ebp) 93 94 #elif defined(__x86_64__) 95 96 #define S_PC (%rsp) 97 98 #define FRAME pushq %rbp; movq %rsp, %rbp 99 #define EMARF leave 100 101 #define B_LINK (%rbp) 102 #define B_PC 8(%rbp) 103 104 #else 105 #error unsupported architecture 106 #endif 107 108 /* There is another definition of ALIGN for .c sources */ 109 #ifdef ASSEMBLER 110 #define ALIGN 4,0x90 111 #endif /* ASSEMBLER */ 112 113 #ifndef FALIGN 114 #define FALIGN ALIGN 115 #endif 116 117 #define LB(x,n) n 118 #if __STDC__ 119 #ifndef __NO_UNDERSCORES__ 120 #define LCL(x) L ## x 121 #define EXT(x) _ ## x 122 #define LEXT(x) _ ## x ## : 123 #else 124 #define LCL(x) .L ## x 125 #define EXT(x) x 126 #define LEXT(x) x ## : 127 #endif 128 #define LBc(x,n) n ## : 129 #define LBb(x,n) n ## b 130 #define LBf(x,n) n ## f 131 #else /* __STDC__ */ 132 #ifndef __NO_UNDERSCORES__ 133 #define LCL(x) L/**/x 134 #define EXT(x) _/**/x 135 #define LEXT(x) _/**/x/**/: 136 #else /* __NO_UNDERSCORES__ */ 137 #define LCL(x) .L/**/x 138 #define EXT(x) x 139 #define LEXT(x) x/**/: 140 #endif /* __NO_UNDERSCORES__ */ 141 #define LBc(x,n) n/**/: 142 #define LBb(x,n) n/**/b 143 #define LBf(x,n) n/**/f 144 #endif /* __STDC__ */ 145 146 #define SVC .byte 0x9a; .long 0; .word 0x7 147 148 #define RPC_SVC .byte 0x9a; .long 0; .word 0xf 149 150 #define String .asciz 151 #define Value .word 152 #define Times(a,b) (a*b) 153 #define Divide(a,b) (a/b) 154 155 #define INB inb %dx, %al 156 #define OUTB outb %al, %dx 157 #define INL inl %dx, %eax 158 #define OUTL outl %eax, %dx 159 160 #define data16 .byte 0x66 161 #define addr16 .byte 0x67 162 163 #if !GPROF 164 #define MCOUNT 165 166 #elif defined(__SHARED__) 167 #define MCOUNT ; .data;\ 168 .align ALIGN;\ 169 LBc(x, 8) .long 0;\ 170 .text;\ 171 Gpush;\ 172 Gload;\ 173 leal Gotoff(LBb(x,8)),%edx;\ 174 Egaddr(%eax,_mcount_ptr);\ 175 Gpop;\ 176 call *(%eax); 177 178 #else /* !GPROF, !__SHARED__ */ 179 #define MCOUNT ; call mcount; 180 #endif /* GPROF */ 181 182 #ifdef __ELF__ 183 #define ELF_FUNC(x) .type x,@function 184 #define ELF_DATA(x) .type x,@object 185 #define ELF_SIZE(x,s) .size x,s 186 #else 187 #define ELF_FUNC(x) 188 #define ELF_DATA(x) 189 #define ELF_SIZE(x,s) 190 #endif 191 192 #define Entry(x) .globl EXT(x); ELF_FUNC(EXT(x)); .align FALIGN; LEXT(x) 193 #define ENTRY(x) Entry(x) MCOUNT 194 #define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ 195 ELF_FUNC(EXT(x)); ELF_FUNC(EXT(y)); \ 196 .align FALIGN; LEXT(x); LEXT(y) \ 197 MCOUNT 198 #if __STDC__ 199 #define ASENTRY(x) .globl x; .align FALIGN; x ## : ELF_FUNC(x) MCOUNT 200 #else 201 #define ASENTRY(x) .globl x; .align FALIGN; x: ELF_FUNC(x) MCOUNT 202 #endif /* __STDC__ */ 203 204 #define DATA(x) .globl EXT(x); ELF_DATA(EXT(x)); .align ALIGN; LEXT(x) 205 206 #define End(x) ELF_SIZE(x,.-x) 207 #define END(x) End(EXT(x)) 208 #define ENDDATA(x) END(x) 209 #define Enddata(x) End(x) 210 211 /* 212 * ELF shared library accessor macros. 213 * Gpush saves the %ebx register used for the GOT address 214 * Gpop pops %ebx if we need a GOT 215 * Gload loads %ebx with the GOT address if shared libraries are used 216 * Gcall calls an external function. 217 * Gotoff allows you to reference local labels. 218 * Gotoff2 allows you to reference local labels with an index reg. 219 * Gotoff3 allows you to reference local labels with an index reg & size. 220 * Gaddr loads up a register with an address of an external item. 221 * Gstack is the number of bytes that Gpush pushes on the stack. 222 * 223 * Varients of the above with E or L prefixes do EXT(name) or LCL(name) 224 * respectively. 225 */ 226 227 #ifndef __SHARED__ 228 #define Gpush 229 #define Gpop 230 #define Gload 231 #define Gcall(func) call func 232 #define Gotoff(lab) lab 233 #define Gotoff2(l,r) l(r) 234 #define Gotoff3(l,r,s) l(,r,s) 235 #define Gaddr(to,lab) movl $lab,to 236 #define Gcmp(lab,reg) cmpl $lab,reg 237 #define Gmemload(lab,reg) movl lab,reg 238 #define Gmemstore(reg,lab,tmp) movl reg,lab 239 #define Gstack 0 240 241 #else 242 #ifdef __ELF__ /* ELF shared libraries */ 243 #define Gpush pushl %ebx 244 #define Gpop popl %ebx 245 #define Gload call 9f; 9: popl %ebx; addl $_GLOBAL_OFFSET_TABLE_+[.-9b],%ebx 246 #define Gcall(func) call EXT(func)@PLT 247 #define Gotoff(lab) lab@GOTOFF(%ebx) 248 #define Gotoff2(l,r) l@GOTOFF(%ebx,r) 249 #define Gotoff3(l,r,s) l@GOTOFF(%ebx,r,s) 250 #define Gaddr(to,lab) movl lab@GOT(%ebx),to 251 #define Gcmp(lab,reg) cmpl reg,lab@GOT(%ebx) 252 #define Gmemload(lab,reg) movl lab@GOT(%ebx),reg; movl (reg),reg 253 #define Gmemstore(reg,lab,tmp) movl lab@GOT(%ebx),tmp; movl reg,(tmp) 254 #define Gstack 4 255 256 #else /* ROSE shared libraries */ 257 #define Gpush 258 #define Gpop 259 #define Gload 260 #define Gcall(func) call *9f; .data; .align ALIGN; 9: .long func; .text 261 #define Gotoff(lab) lab 262 #define Gotoff2(l,r) l(r) 263 #define Gotoff3(l,r,s) l(,r,s) 264 #define Gaddr(to,lab) movl 9f,to; .data; .align ALIGN; 9: .long lab; .text 265 #define Gcmp(lab,reg) cmpl reg,9f; .data; .align ALIGN; 9: .long lab; .text 266 #define Gmemload(lab,reg) movl 9f,reg; movl (reg),reg; .data; .align ALIGN; 9: .long lab; .text 267 #define Gmemstore(reg,lab,tmp) movl 9f,tmp; movl reg,(tmp); .data; .align ALIGN; 9: .long lab; .text 268 #define Gstack 0 269 #endif /* __ELF__ */ 270 #endif /* __SHARED__ */ 271 272 /* Egotoff is not provided, since external symbols should not use @GOTOFF 273 relocations. */ 274 #define Egcall(func) Gcall(EXT(func)) 275 #define Egaddr(to,lab) Gaddr(to,EXT(lab)) 276 #define Egcmp(lab,reg) Gcmp(EXT(lab),reg) 277 #define Egmemload(lab,reg) Gmemload(EXT(lab),reg) 278 #define Egmemstore(reg,lab,tmp) Gmemstore(reg,EXT(lab),tmp) 279 280 #define Lgotoff(lab) Gotoff(LCL(lab)) 281 #define Lgotoff2(l,r) Gotoff2(LCL(l),r) 282 #define Lgotoff3(l,r,s) Gotoff3(LCL(l),r,s) 283 #define Lgcmp(lab,reg) Gcmp(LCL(lab),reg) 284 #define Lgmemload(lab,reg) movl Lgotoff(lab),reg 285 #define Lgmemstore(reg,lab,tmp) movl reg,Lgotoff(lab) 286 287 #ifdef ASSEMBLER 288 #if MACH_KDB 289 #include <ddb/stab.h> 290 /* 291 * This pseudo-assembler line is added so that there will be at least 292 * one N_SO entry in the symbol stable to define the current file name. 293 */ 294 #endif /* MACH_KDB */ 295 296 #else /* NOT ASSEMBLER */ 297 298 /* These defines are here for .c files that wish to reference global symbols 299 * within __asm__ statements. 300 */ 301 #ifndef __NO_UNDERSCORES__ 302 #define CC_SYM_PREFIX "_" 303 #else 304 #define CC_SYM_PREFIX "" 305 #endif /* __NO_UNDERSCORES__ */ 306 #endif /* ASSEMBLER */ 307 308 /* 309 * The following macros make calls into C code. 310 * They dynamically align the stack to 16 bytes. 311 */ 312 #if defined(__i386__) 313 /* 314 * Arguments are moved (not pushed) onto the correctly aligned stack. 315 * NOTE: ESI is destroyed in the process, and hence cannot 316 * be directly used as a parameter. Users of this macro must 317 * independently preserve ESI (a non-volatile) if the routine is 318 * intended to be called from C, for instance. 319 */ 320 321 #define CCALL(fn) \ 322 movl %esp, %esi ;\ 323 andl $0xFFFFFFF0, %esp ;\ 324 call EXT(fn) ;\ 325 movl %esi, %esp 326 327 #define CCALL1(fn, arg1) \ 328 movl %esp, %esi ;\ 329 subl $4, %esp ;\ 330 andl $0xFFFFFFF0, %esp ;\ 331 movl arg1, (%esp) ;\ 332 call EXT(fn) ;\ 333 movl %esi, %esp 334 335 #define CCALL2(fn, arg1, arg2) \ 336 movl %esp, %esi ;\ 337 subl $8, %esp ;\ 338 andl $0xFFFFFFF0, %esp ;\ 339 movl arg2, 4(%esp) ;\ 340 movl arg1, (%esp) ;\ 341 call EXT(fn) ;\ 342 movl %esi, %esp 343 344 /* This variant exists to permit adjustment of the stack by "dtrace" */ 345 #define CCALL1WITHSP(fn, arg1) \ 346 movl %esp, %esi ;\ 347 subl $12, %esp ;\ 348 andl $0xFFFFFFF0, %esp ;\ 349 movl %esi, 8(%esp) ;\ 350 leal 8(%esp), %esi ;\ 351 movl %esi, 4(%esp) ;\ 352 movl arg1, (%esp) ;\ 353 call EXT(fn) ;\ 354 movl 8(%esp), %esp 355 356 /* 357 * CCALL5 is used for callee functions with 3 arguments but 358 * where arg2 (a3:a2) and arg3 (a5:a4) are 64-bit values. 359 */ 360 #define CCALL5(fn, a1, a2, a3, a4, a5) \ 361 movl %esp, %esi ;\ 362 subl $20, %esp ;\ 363 andl $0xFFFFFFF0, %esp ;\ 364 movl a5, 16(%esp) ;\ 365 movl a4, 12(%esp) ;\ 366 movl a3, 8(%esp) ;\ 367 movl a2, 4(%esp) ;\ 368 movl a1, (%esp) ;\ 369 call EXT(fn) ;\ 370 movl %esi, %esp 371 372 #elif defined(__x86_64__) 373 374 /* This variant exists to permit adjustment of the stack by "dtrace" */ 375 #define CCALLWITHSP(fn) \ 376 mov %rsp, %r12 ;\ 377 sub $8, %rsp ;\ 378 and $0xFFFFFFFFFFFFFFF0, %rsp ;\ 379 mov %r12, (%rsp) ;\ 380 leaq (%rsp), %rsi ;\ 381 call EXT(fn) ;\ 382 mov (%rsp), %rsp 383 384 #define CCALL(fn) \ 385 mov %rsp, %r12 ;\ 386 and $0xFFFFFFFFFFFFFFF0, %rsp ;\ 387 call EXT(fn) ;\ 388 mov %r12, %rsp 389 390 #define CCALL1(fn, arg1) \ 391 mov arg1, %rdi ;\ 392 CCALL(fn) 393 394 #define CCALL2(fn, arg1, arg2) \ 395 mov arg1, %rdi ;\ 396 CCALL(fn) 397 398 #define CCALL3(fn, arg1, arg2, arg3) \ 399 mov arg1, %rdi ;\ 400 mov arg2, %rsi ;\ 401 mov arg3, %rdx ;\ 402 CCALL(fn) 403 404 #else 405 #error unsupported architecture 406 #endif 407 408 #endif /* _I386_ASM_H_ */ 409