x86_abi_support.asm 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. ;
  2. ; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
  3. ;
  4. ; Use of this source code is governed by a BSD-style license
  5. ; that can be found in the LICENSE file in the root of the source
  6. ; tree. An additional intellectual property rights grant can be found
  7. ; in the file PATENTS. All contributing project authors may
  8. ; be found in the AUTHORS file in the root of the source tree.
  9. ;
  10. %include "vpx_config.asm"
  11. ; 32/64 bit compatibility macros
  12. ;
  13. ; In general, we make the source use 64 bit syntax, then twiddle with it using
  14. ; the preprocessor to get the 32 bit syntax on 32 bit platforms.
  15. ;
  16. %ifidn __OUTPUT_FORMAT__,elf32
  17. %define ABI_IS_32BIT 1
  18. %elifidn __OUTPUT_FORMAT__,macho32
  19. %define ABI_IS_32BIT 1
  20. %elifidn __OUTPUT_FORMAT__,win32
  21. %define ABI_IS_32BIT 1
  22. %elifidn __OUTPUT_FORMAT__,aout
  23. %define ABI_IS_32BIT 1
  24. %else
  25. %define ABI_IS_32BIT 0
  26. %endif
  27. %if ABI_IS_32BIT
  28. %define rax eax
  29. %define rbx ebx
  30. %define rcx ecx
  31. %define rdx edx
  32. %define rsi esi
  33. %define rdi edi
  34. %define rsp esp
  35. %define rbp ebp
  36. %define movsxd mov
  37. %macro movq 2
  38. %ifidn %1,eax
  39. movd %1,%2
  40. %elifidn %2,eax
  41. movd %1,%2
  42. %elifidn %1,ebx
  43. movd %1,%2
  44. %elifidn %2,ebx
  45. movd %1,%2
  46. %elifidn %1,ecx
  47. movd %1,%2
  48. %elifidn %2,ecx
  49. movd %1,%2
  50. %elifidn %1,edx
  51. movd %1,%2
  52. %elifidn %2,edx
  53. movd %1,%2
  54. %elifidn %1,esi
  55. movd %1,%2
  56. %elifidn %2,esi
  57. movd %1,%2
  58. %elifidn %1,edi
  59. movd %1,%2
  60. %elifidn %2,edi
  61. movd %1,%2
  62. %elifidn %1,esp
  63. movd %1,%2
  64. %elifidn %2,esp
  65. movd %1,%2
  66. %elifidn %1,ebp
  67. movd %1,%2
  68. %elifidn %2,ebp
  69. movd %1,%2
  70. %else
  71. movq %1,%2
  72. %endif
  73. %endmacro
  74. %endif
  75. ; LIBVPX_YASM_WIN64
  76. ; Set LIBVPX_YASM_WIN64 if output is Windows 64bit so the code will work if x64
  77. ; or win64 is defined on the Yasm command line.
  78. %ifidn __OUTPUT_FORMAT__,win64
  79. %define LIBVPX_YASM_WIN64 1
  80. %elifidn __OUTPUT_FORMAT__,x64
  81. %define LIBVPX_YASM_WIN64 1
  82. %else
  83. %define LIBVPX_YASM_WIN64 0
  84. %endif
  85. ; sym()
  86. ; Return the proper symbol name for the target ABI.
  87. ;
  88. ; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols
  89. ; with C linkage be prefixed with an underscore.
  90. ;
  91. %ifidn __OUTPUT_FORMAT__,elf32
  92. %define sym(x) x
  93. %elifidn __OUTPUT_FORMAT__,elf64
  94. %define sym(x) x
  95. %elifidn __OUTPUT_FORMAT__,elfx32
  96. %define sym(x) x
  97. %elif LIBVPX_YASM_WIN64
  98. %define sym(x) x
  99. %else
  100. %define sym(x) _ %+ x
  101. %endif
  102. ; PRIVATE
  103. ; Macro for the attribute to hide a global symbol for the target ABI.
  104. ; This is only active if CHROMIUM is defined.
  105. ;
  106. ; Chromium doesn't like exported global symbols due to symbol clashing with
  107. ; plugins among other things.
  108. ;
  109. ; Requires Chromium's patched copy of yasm:
  110. ; http://src.chromium.org/viewvc/chrome?view=rev&revision=73761
  111. ; http://www.tortall.net/projects/yasm/ticket/236
  112. ;
  113. %ifdef CHROMIUM
  114. %ifidn __OUTPUT_FORMAT__,elf32
  115. %define PRIVATE :hidden
  116. %elifidn __OUTPUT_FORMAT__,elf64
  117. %define PRIVATE :hidden
  118. %elifidn __OUTPUT_FORMAT__,elfx32
  119. %define PRIVATE :hidden
  120. %elif LIBVPX_YASM_WIN64
  121. %define PRIVATE
  122. %else
  123. %define PRIVATE :private_extern
  124. %endif
  125. %else
  126. %define PRIVATE
  127. %endif
  128. ; arg()
  129. ; Return the address specification of the given argument
  130. ;
  131. %if ABI_IS_32BIT
  132. %define arg(x) [ebp+8+4*x]
  133. %else
  134. ; 64 bit ABI passes arguments in registers. This is a workaround to get up
  135. ; and running quickly. Relies on SHADOW_ARGS_TO_STACK
  136. %if LIBVPX_YASM_WIN64
  137. %define arg(x) [rbp+16+8*x]
  138. %else
  139. %define arg(x) [rbp-8-8*x]
  140. %endif
  141. %endif
  142. ; REG_SZ_BYTES, REG_SZ_BITS
  143. ; Size of a register
  144. %if ABI_IS_32BIT
  145. %define REG_SZ_BYTES 4
  146. %define REG_SZ_BITS 32
  147. %else
  148. %define REG_SZ_BYTES 8
  149. %define REG_SZ_BITS 64
  150. %endif
  151. ; ALIGN_STACK <alignment> <register>
  152. ; This macro aligns the stack to the given alignment (in bytes). The stack
  153. ; is left such that the previous value of the stack pointer is the first
  154. ; argument on the stack (ie, the inverse of this macro is 'pop rsp.')
  155. ; This macro uses one temporary register, which is not preserved, and thus
  156. ; must be specified as an argument.
  157. %macro ALIGN_STACK 2
  158. mov %2, rsp
  159. and rsp, -%1
  160. lea rsp, [rsp - (%1 - REG_SZ_BYTES)]
  161. push %2
  162. %endmacro
  163. ;
  164. ; The Microsoft assembler tries to impose a certain amount of type safety in
  165. ; its register usage. YASM doesn't recognize these directives, so we just
  166. ; %define them away to maintain as much compatibility as possible with the
  167. ; original inline assembler we're porting from.
  168. ;
  169. %idefine PTR
  170. %idefine XMMWORD
  171. %idefine MMWORD
  172. ; PIC macros
  173. ;
  174. %if ABI_IS_32BIT
  175. %if CONFIG_PIC=1
  176. %ifidn __OUTPUT_FORMAT__,elf32
  177. %define WRT_PLT wrt ..plt
  178. %macro GET_GOT 1
  179. extern _GLOBAL_OFFSET_TABLE_
  180. push %1
  181. call %%get_got
  182. %%sub_offset:
  183. jmp %%exitGG
  184. %%get_got:
  185. mov %1, [esp]
  186. add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc
  187. ret
  188. %%exitGG:
  189. %undef GLOBAL
  190. %define GLOBAL(x) x + %1 wrt ..gotoff
  191. %undef RESTORE_GOT
  192. %define RESTORE_GOT pop %1
  193. %endmacro
  194. %elifidn __OUTPUT_FORMAT__,macho32
  195. %macro GET_GOT 1
  196. push %1
  197. call %%get_got
  198. %%get_got:
  199. pop %1
  200. %undef GLOBAL
  201. %define GLOBAL(x) x + %1 - %%get_got
  202. %undef RESTORE_GOT
  203. %define RESTORE_GOT pop %1
  204. %endmacro
  205. %endif
  206. %endif
  207. %ifdef CHROMIUM
  208. %ifidn __OUTPUT_FORMAT__,macho32
  209. %define HIDDEN_DATA(x) x:private_extern
  210. %else
  211. %define HIDDEN_DATA(x) x
  212. %endif
  213. %else
  214. %define HIDDEN_DATA(x) x
  215. %endif
  216. %else
  217. %macro GET_GOT 1
  218. %endmacro
  219. %define GLOBAL(x) rel x
  220. %ifidn __OUTPUT_FORMAT__,elf64
  221. %define WRT_PLT wrt ..plt
  222. %define HIDDEN_DATA(x) x:data hidden
  223. %elifidn __OUTPUT_FORMAT__,elfx32
  224. %define WRT_PLT wrt ..plt
  225. %define HIDDEN_DATA(x) x:data hidden
  226. %elifidn __OUTPUT_FORMAT__,macho64
  227. %ifdef CHROMIUM
  228. %define HIDDEN_DATA(x) x:private_extern
  229. %else
  230. %define HIDDEN_DATA(x) x
  231. %endif
  232. %else
  233. %define HIDDEN_DATA(x) x
  234. %endif
  235. %endif
  236. %ifnmacro GET_GOT
  237. %macro GET_GOT 1
  238. %endmacro
  239. %define GLOBAL(x) x
  240. %endif
  241. %ifndef RESTORE_GOT
  242. %define RESTORE_GOT
  243. %endif
  244. %ifndef WRT_PLT
  245. %define WRT_PLT
  246. %endif
  247. %if ABI_IS_32BIT
  248. %macro SHADOW_ARGS_TO_STACK 1
  249. %endm
  250. %define UNSHADOW_ARGS
  251. %else
  252. %if LIBVPX_YASM_WIN64
  253. %macro SHADOW_ARGS_TO_STACK 1 ; argc
  254. %if %1 > 0
  255. mov arg(0),rcx
  256. %endif
  257. %if %1 > 1
  258. mov arg(1),rdx
  259. %endif
  260. %if %1 > 2
  261. mov arg(2),r8
  262. %endif
  263. %if %1 > 3
  264. mov arg(3),r9
  265. %endif
  266. %endm
  267. %else
  268. %macro SHADOW_ARGS_TO_STACK 1 ; argc
  269. %if %1 > 0
  270. push rdi
  271. %endif
  272. %if %1 > 1
  273. push rsi
  274. %endif
  275. %if %1 > 2
  276. push rdx
  277. %endif
  278. %if %1 > 3
  279. push rcx
  280. %endif
  281. %if %1 > 4
  282. push r8
  283. %endif
  284. %if %1 > 5
  285. push r9
  286. %endif
  287. %if %1 > 6
  288. %assign i %1-6
  289. %assign off 16
  290. %rep i
  291. mov rax,[rbp+off]
  292. push rax
  293. %assign off off+8
  294. %endrep
  295. %endif
  296. %endm
  297. %endif
  298. %define UNSHADOW_ARGS mov rsp, rbp
  299. %endif
  300. ; Win64 ABI requires that XMM6:XMM15 are callee saved
  301. ; SAVE_XMM n, [u]
  302. ; store registers 6-n on the stack
  303. ; if u is specified, use unaligned movs.
  304. ; Win64 ABI requires 16 byte stack alignment, but then pushes an 8 byte return
  305. ; value. Typically we follow this up with 'push rbp' - re-aligning the stack -
  306. ; but in some cases this is not done and unaligned movs must be used.
  307. %if LIBVPX_YASM_WIN64
  308. %macro SAVE_XMM 1-2 a
  309. %if %1 < 6
  310. %error Only xmm registers 6-15 must be preserved
  311. %else
  312. %assign last_xmm %1
  313. %define movxmm movdq %+ %2
  314. %assign xmm_stack_space ((last_xmm - 5) * 16)
  315. sub rsp, xmm_stack_space
  316. %assign i 6
  317. %rep (last_xmm - 5)
  318. movxmm [rsp + ((i - 6) * 16)], xmm %+ i
  319. %assign i i+1
  320. %endrep
  321. %endif
  322. %endmacro
  323. %macro RESTORE_XMM 0
  324. %ifndef last_xmm
  325. %error RESTORE_XMM must be paired with SAVE_XMM n
  326. %else
  327. %assign i last_xmm
  328. %rep (last_xmm - 5)
  329. movxmm xmm %+ i, [rsp +((i - 6) * 16)]
  330. %assign i i-1
  331. %endrep
  332. add rsp, xmm_stack_space
  333. ; there are a couple functions which return from multiple places.
  334. ; otherwise, we could uncomment these:
  335. ; %undef last_xmm
  336. ; %undef xmm_stack_space
  337. ; %undef movxmm
  338. %endif
  339. %endmacro
  340. %else
  341. %macro SAVE_XMM 1-2
  342. %endmacro
  343. %macro RESTORE_XMM 0
  344. %endmacro
  345. %endif
  346. ; Name of the rodata section
  347. ;
  348. ; .rodata seems to be an elf-ism, as it doesn't work on OSX.
  349. ;
  350. %ifidn __OUTPUT_FORMAT__,macho64
  351. %define SECTION_RODATA section .text
  352. %elifidn __OUTPUT_FORMAT__,macho32
  353. %macro SECTION_RODATA 0
  354. section .text
  355. %endmacro
  356. %elifidn __OUTPUT_FORMAT__,aout
  357. %define SECTION_RODATA section .data
  358. %else
  359. %define SECTION_RODATA section .rodata
  360. %endif
  361. ; Tell GNU ld that we don't require an executable stack.
  362. %ifidn __OUTPUT_FORMAT__,elf32
  363. section .note.GNU-stack noalloc noexec nowrite progbits
  364. section .text
  365. %elifidn __OUTPUT_FORMAT__,elf64
  366. section .note.GNU-stack noalloc noexec nowrite progbits
  367. section .text
  368. %elifidn __OUTPUT_FORMAT__,elfx32
  369. section .note.GNU-stack noalloc noexec nowrite progbits
  370. section .text
  371. %endif
  372. ; On Android platforms use lrand48 when building postproc routines. Prior to L
  373. ; rand() was not available.
  374. %if CONFIG_POSTPROC=1 || CONFIG_VP9_POSTPROC=1
  375. %ifdef __ANDROID__
  376. extern sym(lrand48)
  377. %define LIBVPX_RAND lrand48
  378. %else
  379. extern sym(rand)
  380. %define LIBVPX_RAND rand
  381. %endif
  382. %endif ; CONFIG_POSTPROC || CONFIG_VP9_POSTPROC