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