osx_asm.h 11 KB

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