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