1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vpx_ports/x86_abi_support.asm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,395 @@ 1.4 +; 1.5 +; Copyright (c) 2010 The WebM project authors. All Rights Reserved. 1.6 +; 1.7 +; Use of this source code is governed by a BSD-style license 1.8 +; that can be found in the LICENSE file in the root of the source 1.9 +; tree. An additional intellectual property rights grant can be found 1.10 +; in the file PATENTS. All contributing project authors may 1.11 +; be found in the AUTHORS file in the root of the source tree. 1.12 +; 1.13 + 1.14 + 1.15 +%include "vpx_config.asm" 1.16 + 1.17 +; 32/64 bit compatibility macros 1.18 +; 1.19 +; In general, we make the source use 64 bit syntax, then twiddle with it using 1.20 +; the preprocessor to get the 32 bit syntax on 32 bit platforms. 1.21 +; 1.22 +%ifidn __OUTPUT_FORMAT__,elf32 1.23 +%define ABI_IS_32BIT 1 1.24 +%elifidn __OUTPUT_FORMAT__,macho32 1.25 +%define ABI_IS_32BIT 1 1.26 +%elifidn __OUTPUT_FORMAT__,win32 1.27 +%define ABI_IS_32BIT 1 1.28 +%elifidn __OUTPUT_FORMAT__,aout 1.29 +%define ABI_IS_32BIT 1 1.30 +%else 1.31 +%define ABI_IS_32BIT 0 1.32 +%endif 1.33 + 1.34 +%if ABI_IS_32BIT 1.35 +%define rax eax 1.36 +%define rbx ebx 1.37 +%define rcx ecx 1.38 +%define rdx edx 1.39 +%define rsi esi 1.40 +%define rdi edi 1.41 +%define rsp esp 1.42 +%define rbp ebp 1.43 +%define movsxd mov 1.44 +%macro movq 2 1.45 + %ifidn %1,eax 1.46 + movd %1,%2 1.47 + %elifidn %2,eax 1.48 + movd %1,%2 1.49 + %elifidn %1,ebx 1.50 + movd %1,%2 1.51 + %elifidn %2,ebx 1.52 + movd %1,%2 1.53 + %elifidn %1,ecx 1.54 + movd %1,%2 1.55 + %elifidn %2,ecx 1.56 + movd %1,%2 1.57 + %elifidn %1,edx 1.58 + movd %1,%2 1.59 + %elifidn %2,edx 1.60 + movd %1,%2 1.61 + %elifidn %1,esi 1.62 + movd %1,%2 1.63 + %elifidn %2,esi 1.64 + movd %1,%2 1.65 + %elifidn %1,edi 1.66 + movd %1,%2 1.67 + %elifidn %2,edi 1.68 + movd %1,%2 1.69 + %elifidn %1,esp 1.70 + movd %1,%2 1.71 + %elifidn %2,esp 1.72 + movd %1,%2 1.73 + %elifidn %1,ebp 1.74 + movd %1,%2 1.75 + %elifidn %2,ebp 1.76 + movd %1,%2 1.77 + %else 1.78 + movq %1,%2 1.79 + %endif 1.80 +%endmacro 1.81 +%endif 1.82 + 1.83 + 1.84 +; LIBVPX_YASM_WIN64 1.85 +; Set LIBVPX_YASM_WIN64 if output is Windows 64bit so the code will work if x64 1.86 +; or win64 is defined on the Yasm command line. 1.87 +%ifidn __OUTPUT_FORMAT__,win64 1.88 +%define LIBVPX_YASM_WIN64 1 1.89 +%elifidn __OUTPUT_FORMAT__,x64 1.90 +%define LIBVPX_YASM_WIN64 1 1.91 +%else 1.92 +%define LIBVPX_YASM_WIN64 0 1.93 +%endif 1.94 + 1.95 +; sym() 1.96 +; Return the proper symbol name for the target ABI. 1.97 +; 1.98 +; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols 1.99 +; with C linkage be prefixed with an underscore. 1.100 +; 1.101 +%ifidn __OUTPUT_FORMAT__,elf32 1.102 +%define sym(x) x 1.103 +%elifidn __OUTPUT_FORMAT__,elf64 1.104 +%define sym(x) x 1.105 +%elifidn __OUTPUT_FORMAT__,elfx32 1.106 +%define sym(x) x 1.107 +%elif LIBVPX_YASM_WIN64 1.108 +%define sym(x) x 1.109 +%else 1.110 +%define sym(x) _ %+ x 1.111 +%endif 1.112 + 1.113 +; PRIVATE 1.114 +; Macro for the attribute to hide a global symbol for the target ABI. 1.115 +; This is only active if CHROMIUM is defined. 1.116 +; 1.117 +; Chromium doesn't like exported global symbols due to symbol clashing with 1.118 +; plugins among other things. 1.119 +; 1.120 +; Requires Chromium's patched copy of yasm: 1.121 +; http://src.chromium.org/viewvc/chrome?view=rev&revision=73761 1.122 +; http://www.tortall.net/projects/yasm/ticket/236 1.123 +; 1.124 +%ifdef CHROMIUM 1.125 + %ifidn __OUTPUT_FORMAT__,elf32 1.126 + %define PRIVATE :hidden 1.127 + %elifidn __OUTPUT_FORMAT__,elf64 1.128 + %define PRIVATE :hidden 1.129 + %elifidn __OUTPUT_FORMAT__,elfx32 1.130 + %define PRIVATE :hidden 1.131 + %elif LIBVPX_YASM_WIN64 1.132 + %define PRIVATE 1.133 + %else 1.134 + %define PRIVATE :private_extern 1.135 + %endif 1.136 +%else 1.137 + %define PRIVATE 1.138 +%endif 1.139 + 1.140 +; arg() 1.141 +; Return the address specification of the given argument 1.142 +; 1.143 +%if ABI_IS_32BIT 1.144 + %define arg(x) [ebp+8+4*x] 1.145 +%else 1.146 + ; 64 bit ABI passes arguments in registers. This is a workaround to get up 1.147 + ; and running quickly. Relies on SHADOW_ARGS_TO_STACK 1.148 + %if LIBVPX_YASM_WIN64 1.149 + %define arg(x) [rbp+16+8*x] 1.150 + %else 1.151 + %define arg(x) [rbp-8-8*x] 1.152 + %endif 1.153 +%endif 1.154 + 1.155 +; REG_SZ_BYTES, REG_SZ_BITS 1.156 +; Size of a register 1.157 +%if ABI_IS_32BIT 1.158 +%define REG_SZ_BYTES 4 1.159 +%define REG_SZ_BITS 32 1.160 +%else 1.161 +%define REG_SZ_BYTES 8 1.162 +%define REG_SZ_BITS 64 1.163 +%endif 1.164 + 1.165 + 1.166 +; ALIGN_STACK <alignment> <register> 1.167 +; This macro aligns the stack to the given alignment (in bytes). The stack 1.168 +; is left such that the previous value of the stack pointer is the first 1.169 +; argument on the stack (ie, the inverse of this macro is 'pop rsp.') 1.170 +; This macro uses one temporary register, which is not preserved, and thus 1.171 +; must be specified as an argument. 1.172 +%macro ALIGN_STACK 2 1.173 + mov %2, rsp 1.174 + and rsp, -%1 1.175 + lea rsp, [rsp - (%1 - REG_SZ_BYTES)] 1.176 + push %2 1.177 +%endmacro 1.178 + 1.179 + 1.180 +; 1.181 +; The Microsoft assembler tries to impose a certain amount of type safety in 1.182 +; its register usage. YASM doesn't recognize these directives, so we just 1.183 +; %define them away to maintain as much compatibility as possible with the 1.184 +; original inline assembler we're porting from. 1.185 +; 1.186 +%idefine PTR 1.187 +%idefine XMMWORD 1.188 +%idefine MMWORD 1.189 + 1.190 +; PIC macros 1.191 +; 1.192 +%if ABI_IS_32BIT 1.193 + %if CONFIG_PIC=1 1.194 + %ifidn __OUTPUT_FORMAT__,elf32 1.195 + %define GET_GOT_SAVE_ARG 1 1.196 + %define WRT_PLT wrt ..plt 1.197 + %macro GET_GOT 1 1.198 + extern _GLOBAL_OFFSET_TABLE_ 1.199 + push %1 1.200 + call %%get_got 1.201 + %%sub_offset: 1.202 + jmp %%exitGG 1.203 + %%get_got: 1.204 + mov %1, [esp] 1.205 + add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc 1.206 + ret 1.207 + %%exitGG: 1.208 + %undef GLOBAL 1.209 + %define GLOBAL(x) x + %1 wrt ..gotoff 1.210 + %undef RESTORE_GOT 1.211 + %define RESTORE_GOT pop %1 1.212 + %endmacro 1.213 + %elifidn __OUTPUT_FORMAT__,macho32 1.214 + %define GET_GOT_SAVE_ARG 1 1.215 + %macro GET_GOT 1 1.216 + push %1 1.217 + call %%get_got 1.218 + %%get_got: 1.219 + pop %1 1.220 + %undef GLOBAL 1.221 + %define GLOBAL(x) x + %1 - %%get_got 1.222 + %undef RESTORE_GOT 1.223 + %define RESTORE_GOT pop %1 1.224 + %endmacro 1.225 + %endif 1.226 + %endif 1.227 + 1.228 + %ifdef CHROMIUM 1.229 + %ifidn __OUTPUT_FORMAT__,macho32 1.230 + %define HIDDEN_DATA(x) x:private_extern 1.231 + %else 1.232 + %define HIDDEN_DATA(x) x 1.233 + %endif 1.234 + %else 1.235 + %define HIDDEN_DATA(x) x 1.236 + %endif 1.237 +%else 1.238 + %macro GET_GOT 1 1.239 + %endmacro 1.240 + %define GLOBAL(x) rel x 1.241 + %ifidn __OUTPUT_FORMAT__,elf64 1.242 + %define WRT_PLT wrt ..plt 1.243 + %define HIDDEN_DATA(x) x:data hidden 1.244 + %elifidn __OUTPUT_FORMAT__,elfx32 1.245 + %define WRT_PLT wrt ..plt 1.246 + %define HIDDEN_DATA(x) x:data hidden 1.247 + %elifidn __OUTPUT_FORMAT__,macho64 1.248 + %ifdef CHROMIUM 1.249 + %define HIDDEN_DATA(x) x:private_extern 1.250 + %else 1.251 + %define HIDDEN_DATA(x) x 1.252 + %endif 1.253 + %else 1.254 + %define HIDDEN_DATA(x) x 1.255 + %endif 1.256 +%endif 1.257 +%ifnmacro GET_GOT 1.258 + %macro GET_GOT 1 1.259 + %endmacro 1.260 + %define GLOBAL(x) x 1.261 +%endif 1.262 +%ifndef RESTORE_GOT 1.263 +%define RESTORE_GOT 1.264 +%endif 1.265 +%ifndef WRT_PLT 1.266 +%define WRT_PLT 1.267 +%endif 1.268 + 1.269 +%if ABI_IS_32BIT 1.270 + %macro SHADOW_ARGS_TO_STACK 1 1.271 + %endm 1.272 + %define UNSHADOW_ARGS 1.273 +%else 1.274 +%if LIBVPX_YASM_WIN64 1.275 + %macro SHADOW_ARGS_TO_STACK 1 ; argc 1.276 + %if %1 > 0 1.277 + mov arg(0),rcx 1.278 + %endif 1.279 + %if %1 > 1 1.280 + mov arg(1),rdx 1.281 + %endif 1.282 + %if %1 > 2 1.283 + mov arg(2),r8 1.284 + %endif 1.285 + %if %1 > 3 1.286 + mov arg(3),r9 1.287 + %endif 1.288 + %endm 1.289 +%else 1.290 + %macro SHADOW_ARGS_TO_STACK 1 ; argc 1.291 + %if %1 > 0 1.292 + push rdi 1.293 + %endif 1.294 + %if %1 > 1 1.295 + push rsi 1.296 + %endif 1.297 + %if %1 > 2 1.298 + push rdx 1.299 + %endif 1.300 + %if %1 > 3 1.301 + push rcx 1.302 + %endif 1.303 + %if %1 > 4 1.304 + push r8 1.305 + %endif 1.306 + %if %1 > 5 1.307 + push r9 1.308 + %endif 1.309 + %if %1 > 6 1.310 + %assign i %1-6 1.311 + %assign off 16 1.312 + %rep i 1.313 + mov rax,[rbp+off] 1.314 + push rax 1.315 + %assign off off+8 1.316 + %endrep 1.317 + %endif 1.318 + %endm 1.319 +%endif 1.320 + %define UNSHADOW_ARGS mov rsp, rbp 1.321 +%endif 1.322 + 1.323 +; Win64 ABI requires that XMM6:XMM15 are callee saved 1.324 +; SAVE_XMM n, [u] 1.325 +; store registers 6-n on the stack 1.326 +; if u is specified, use unaligned movs. 1.327 +; Win64 ABI requires 16 byte stack alignment, but then pushes an 8 byte return 1.328 +; value. Typically we follow this up with 'push rbp' - re-aligning the stack - 1.329 +; but in some cases this is not done and unaligned movs must be used. 1.330 +%if LIBVPX_YASM_WIN64 1.331 +%macro SAVE_XMM 1-2 a 1.332 + %if %1 < 6 1.333 + %error Only xmm registers 6-15 must be preserved 1.334 + %else 1.335 + %assign last_xmm %1 1.336 + %define movxmm movdq %+ %2 1.337 + %assign xmm_stack_space ((last_xmm - 5) * 16) 1.338 + sub rsp, xmm_stack_space 1.339 + %assign i 6 1.340 + %rep (last_xmm - 5) 1.341 + movxmm [rsp + ((i - 6) * 16)], xmm %+ i 1.342 + %assign i i+1 1.343 + %endrep 1.344 + %endif 1.345 +%endmacro 1.346 +%macro RESTORE_XMM 0 1.347 + %ifndef last_xmm 1.348 + %error RESTORE_XMM must be paired with SAVE_XMM n 1.349 + %else 1.350 + %assign i last_xmm 1.351 + %rep (last_xmm - 5) 1.352 + movxmm xmm %+ i, [rsp +((i - 6) * 16)] 1.353 + %assign i i-1 1.354 + %endrep 1.355 + add rsp, xmm_stack_space 1.356 + ; there are a couple functions which return from multiple places. 1.357 + ; otherwise, we could uncomment these: 1.358 + ; %undef last_xmm 1.359 + ; %undef xmm_stack_space 1.360 + ; %undef movxmm 1.361 + %endif 1.362 +%endmacro 1.363 +%else 1.364 +%macro SAVE_XMM 1-2 1.365 +%endmacro 1.366 +%macro RESTORE_XMM 0 1.367 +%endmacro 1.368 +%endif 1.369 + 1.370 +; Name of the rodata section 1.371 +; 1.372 +; .rodata seems to be an elf-ism, as it doesn't work on OSX. 1.373 +; 1.374 +%ifidn __OUTPUT_FORMAT__,macho64 1.375 +%define SECTION_RODATA section .text 1.376 +%elifidn __OUTPUT_FORMAT__,macho32 1.377 +%macro SECTION_RODATA 0 1.378 +section .text 1.379 +%endmacro 1.380 +%elifidn __OUTPUT_FORMAT__,aout 1.381 +%define SECTION_RODATA section .data 1.382 +%else 1.383 +%define SECTION_RODATA section .rodata 1.384 +%endif 1.385 + 1.386 + 1.387 +; Tell GNU ld that we don't require an executable stack. 1.388 +%ifidn __OUTPUT_FORMAT__,elf32 1.389 +section .note.GNU-stack noalloc noexec nowrite progbits 1.390 +section .text 1.391 +%elifidn __OUTPUT_FORMAT__,elf64 1.392 +section .note.GNU-stack noalloc noexec nowrite progbits 1.393 +section .text 1.394 +%elifidn __OUTPUT_FORMAT__,elfx32 1.395 +section .note.GNU-stack noalloc noexec nowrite progbits 1.396 +section .text 1.397 +%endif 1.398 +