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 11 12%include "vpx_config.asm" 13 14; 32/64 bit compatibility macros 15; 16; In general, we make the source use 64 bit syntax, then twiddle with it using 17; the preprocessor to get the 32 bit syntax on 32 bit platforms. 18; 19%ifidn __OUTPUT_FORMAT__,elf32 20%define ABI_IS_32BIT 1 21%elifidn __OUTPUT_FORMAT__,macho32 22%define ABI_IS_32BIT 1 23%elifidn __OUTPUT_FORMAT__,win32 24%define ABI_IS_32BIT 1 25%else 26%define ABI_IS_32BIT 0 27%endif 28 29%if ABI_IS_32BIT 30%define rax eax 31%define rbx ebx 32%define rcx ecx 33%define rdx edx 34%define rsi esi 35%define rdi edi 36%define rsp esp 37%define rbp ebp 38%define movsxd mov 39%macro movq 2 40 %ifidn %1,eax 41 movd %1,%2 42 %elifidn %2,eax 43 movd %1,%2 44 %elifidn %1,ebx 45 movd %1,%2 46 %elifidn %2,ebx 47 movd %1,%2 48 %elifidn %1,ecx 49 movd %1,%2 50 %elifidn %2,ecx 51 movd %1,%2 52 %elifidn %1,edx 53 movd %1,%2 54 %elifidn %2,edx 55 movd %1,%2 56 %elifidn %1,esi 57 movd %1,%2 58 %elifidn %2,esi 59 movd %1,%2 60 %elifidn %1,edi 61 movd %1,%2 62 %elifidn %2,edi 63 movd %1,%2 64 %elifidn %1,esp 65 movd %1,%2 66 %elifidn %2,esp 67 movd %1,%2 68 %elifidn %1,ebp 69 movd %1,%2 70 %elifidn %2,ebp 71 movd %1,%2 72 %else 73 movq %1,%2 74 %endif 75%endmacro 76%endif 77 78 79; sym() 80; Return the proper symbol name for the target ABI. 81; 82; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols 83; with C linkage be prefixed with an underscore. 84; 85%ifidn __OUTPUT_FORMAT__,elf32 86%define sym(x) x 87%elifidn __OUTPUT_FORMAT__,elf64 88%define sym(x) x 89%elifidn __OUTPUT_FORMAT__,x64 90%define sym(x) x 91%else 92%define sym(x) _ %+ x 93%endif 94 95; arg() 96; Return the address specification of the given argument 97; 98%if ABI_IS_32BIT 99 %define arg(x) [ebp+8+4*x] 100%else 101 ; 64 bit ABI passes arguments in registers. This is a workaround to get up 102 ; and running quickly. Relies on SHADOW_ARGS_TO_STACK 103 %ifidn __OUTPUT_FORMAT__,x64 104 %define arg(x) [rbp+16+8*x] 105 %else 106 %define arg(x) [rbp-8-8*x] 107 %endif 108%endif 109 110; REG_SZ_BYTES, REG_SZ_BITS 111; Size of a register 112%if ABI_IS_32BIT 113%define REG_SZ_BYTES 4 114%define REG_SZ_BITS 32 115%else 116%define REG_SZ_BYTES 8 117%define REG_SZ_BITS 64 118%endif 119 120 121; ALIGN_STACK <alignment> <register> 122; This macro aligns the stack to the given alignment (in bytes). The stack 123; is left such that the previous value of the stack pointer is the first 124; argument on the stack (ie, the inverse of this macro is 'pop rsp.') 125; This macro uses one temporary register, which is not preserved, and thus 126; must be specified as an argument. 127%macro ALIGN_STACK 2 128 mov %2, rsp 129 and rsp, -%1 130 lea rsp, [rsp - (%1 - REG_SZ_BYTES)] 131 push %2 132%endmacro 133 134 135; 136; The Microsoft assembler tries to impose a certain amount of type safety in 137; its register usage. YASM doesn't recognize these directives, so we just 138; %define them away to maintain as much compatibility as possible with the 139; original inline assembler we're porting from. 140; 141%idefine PTR 142%idefine XMMWORD 143%idefine MMWORD 144 145; PIC macros 146; 147%if ABI_IS_32BIT 148 %if CONFIG_PIC=1 149 %ifidn __OUTPUT_FORMAT__,elf32 150 %define WRT_PLT wrt ..plt 151 %macro GET_GOT 1 152 extern _GLOBAL_OFFSET_TABLE_ 153 push %1 154 call %%get_got 155 %%sub_offset: 156 jmp %%exitGG 157 %%get_got: 158 mov %1, [esp] 159 add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc 160 ret 161 %%exitGG: 162 %undef GLOBAL 163 %define GLOBAL(x) x + %1 wrt ..gotoff 164 %undef RESTORE_GOT 165 %define RESTORE_GOT pop %1 166 %endmacro 167 %elifidn __OUTPUT_FORMAT__,macho32 168 %macro GET_GOT 1 169 push %1 170 call %%get_got 171 %%get_got: 172 pop %1 173 %undef GLOBAL 174 %define GLOBAL(x) x + %1 - %%get_got 175 %undef RESTORE_GOT 176 %define RESTORE_GOT pop %1 177 %endmacro 178 %endif 179 %endif 180 %define HIDDEN_DATA(x) x 181%else 182 %macro GET_GOT 1 183 %endmacro 184 %define GLOBAL(x) rel x 185 %ifidn __OUTPUT_FORMAT__,elf64 186 %define WRT_PLT wrt ..plt 187 %define HIDDEN_DATA(x) x:data hidden 188 %else 189 %define HIDDEN_DATA(x) x 190 %endif 191%endif 192%ifnmacro GET_GOT 193 %macro GET_GOT 1 194 %endmacro 195 %define GLOBAL(x) x 196%endif 197%ifndef RESTORE_GOT 198%define RESTORE_GOT 199%endif 200%ifndef WRT_PLT 201%define WRT_PLT 202%endif 203 204%if ABI_IS_32BIT 205 %macro SHADOW_ARGS_TO_STACK 1 206 %endm 207 %define UNSHADOW_ARGS 208%else 209%ifidn __OUTPUT_FORMAT__,x64 210 %macro SHADOW_ARGS_TO_STACK 1 ; argc 211 %if %1 > 0 212 mov arg(0),rcx 213 %endif 214 %if %1 > 1 215 mov arg(1),rdx 216 %endif 217 %if %1 > 2 218 mov arg(2),r8 219 %endif 220 %if %1 > 3 221 mov arg(3),r9 222 %endif 223 %endm 224%else 225 %macro SHADOW_ARGS_TO_STACK 1 ; argc 226 %if %1 > 0 227 push rdi 228 %endif 229 %if %1 > 1 230 push rsi 231 %endif 232 %if %1 > 2 233 push rdx 234 %endif 235 %if %1 > 3 236 push rcx 237 %endif 238 %if %1 > 4 239 push r8 240 %endif 241 %if %1 > 5 242 push r9 243 %endif 244 %if %1 > 6 245 %assign i %1-6 246 %assign off 16 247 %rep i 248 mov rax,[rbp+off] 249 push rax 250 %assign off off+8 251 %endrep 252 %endif 253 %endm 254%endif 255 %define UNSHADOW_ARGS mov rsp, rbp 256%endif 257 258; must keep XMM6:XMM15 (libvpx uses XMM6 and XMM7) on Win64 ABI 259; rsp register has to be aligned 260%ifidn __OUTPUT_FORMAT__,x64 261%macro SAVE_XMM 0 262 sub rsp, 32 263 movdqa XMMWORD PTR [rsp], xmm6 264 movdqa XMMWORD PTR [rsp+16], xmm7 265%endmacro 266%macro RESTORE_XMM 0 267 movdqa xmm6, XMMWORD PTR [rsp] 268 movdqa xmm7, XMMWORD PTR [rsp+16] 269 add rsp, 32 270%endmacro 271%else 272%macro SAVE_XMM 0 273%endmacro 274%macro RESTORE_XMM 0 275%endmacro 276%endif 277 278; Name of the rodata section 279; 280; .rodata seems to be an elf-ism, as it doesn't work on OSX. 281; 282%ifidn __OUTPUT_FORMAT__,macho64 283%define SECTION_RODATA section .text 284%elifidn __OUTPUT_FORMAT__,macho32 285%macro SECTION_RODATA 0 286section .text 287%endmacro 288%else 289%define SECTION_RODATA section .rodata 290%endif 291 292 293; Tell GNU ld that we don't require an executable stack. 294%ifidn __OUTPUT_FORMAT__,elf32 295section .note.GNU-stack noalloc noexec nowrite progbits 296section .text 297%elifidn __OUTPUT_FORMAT__,elf64 298section .note.GNU-stack noalloc noexec nowrite progbits 299section .text 300%endif 301 302