John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 1 | ; |
John Koleszar | c2140b8 | 2010-09-09 08:16:39 -0400 | [diff] [blame] | 2 | ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 3 | ; |
John Koleszar | 94c52e4 | 2010-06-18 12:39:21 -0400 | [diff] [blame] | 4 | ; Use of this source code is governed by a BSD-style license |
John Koleszar | 09202d8 | 2010-06-04 16:19:40 -0400 | [diff] [blame] | 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 |
John Koleszar | 94c52e4 | 2010-06-18 12:39:21 -0400 | [diff] [blame] | 7 | ; in the file PATENTS. All contributing project authors may |
John Koleszar | 09202d8 | 2010-06-04 16:19:40 -0400 | [diff] [blame] | 8 | ; be found in the AUTHORS file in the root of the source tree. |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 |
Jan Kratochvil | e114f69 | 2010-10-04 23:19:33 +0200 | [diff] [blame] | 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 |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 |
Fritz Koenig | 746439e | 2010-09-14 15:46:37 -0700 | [diff] [blame] | 130 | lea rsp, [rsp - (%1 - REG_SZ_BYTES)] |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 | |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 |
Fritz Koenig | 746439e | 2010-09-14 15:46:37 -0700 | [diff] [blame] | 155 | %%sub_offset: |
| 156 | jmp %%exitGG |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 157 | %%get_got: |
Fritz Koenig | 746439e | 2010-09-14 15:46:37 -0700 | [diff] [blame] | 158 | mov %1, [esp] |
| 159 | add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc |
| 160 | ret |
| 161 | %%exitGG: |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 162 | %undef GLOBAL |
Jan Kratochvil | 5cdc3a4 | 2010-10-04 23:18:58 +0200 | [diff] [blame] | 163 | %define GLOBAL(x) x + %1 wrt ..gotoff |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 |
Fritz Koenig | 746439e | 2010-09-14 15:46:37 -0700 | [diff] [blame] | 171 | %%sub_offset: |
| 172 | jmp %%exitGG |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 173 | %%get_got: |
Fritz Koenig | 746439e | 2010-09-14 15:46:37 -0700 | [diff] [blame] | 174 | mov %1, [esp] |
| 175 | add %1, fake_got - %%sub_offset |
| 176 | ret |
| 177 | %%exitGG: |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 178 | %undef GLOBAL |
Jan Kratochvil | 5cdc3a4 | 2010-10-04 23:18:58 +0200 | [diff] [blame] | 179 | %define GLOBAL(x) x + %1 - fake_got |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 180 | %undef RESTORE_GOT |
| 181 | %define RESTORE_GOT pop %1 |
| 182 | %endmacro |
| 183 | %endif |
| 184 | %endif |
Jan Kratochvil | 0e8f108 | 2010-07-31 17:12:31 +0200 | [diff] [blame] | 185 | %define HIDDEN_DATA(x) x |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 186 | %else |
| 187 | %macro GET_GOT 1 |
| 188 | %endmacro |
Jan Kratochvil | 5cdc3a4 | 2010-10-04 23:18:58 +0200 | [diff] [blame] | 189 | %define GLOBAL(x) rel x |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 190 | %ifidn __OUTPUT_FORMAT__,elf64 |
| 191 | %define WRT_PLT wrt ..plt |
Jan Kratochvil | 0e8f108 | 2010-07-31 17:12:31 +0200 | [diff] [blame] | 192 | %define HIDDEN_DATA(x) x:data hidden |
Timothy B. Terriberry | 9f81463 | 2010-06-17 19:33:52 -0700 | [diff] [blame] | 193 | %else |
Jan Kratochvil | 0e8f108 | 2010-07-31 17:12:31 +0200 | [diff] [blame] | 194 | %define HIDDEN_DATA(x) x |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 195 | %endif |
| 196 | %endif |
| 197 | %ifnmacro GET_GOT |
| 198 | %macro GET_GOT 1 |
| 199 | %endmacro |
Jan Kratochvil | 5cdc3a4 | 2010-10-04 23:18:58 +0200 | [diff] [blame] | 200 | %define GLOBAL(x) x |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 201 | %endif |
| 202 | %ifndef RESTORE_GOT |
| 203 | %define RESTORE_GOT |
| 204 | %endif |
| 205 | %ifndef WRT_PLT |
| 206 | %define WRT_PLT |
| 207 | %endif |
| 208 | |
| 209 | %if ABI_IS_32BIT |
| 210 | %macro SHADOW_ARGS_TO_STACK 1 |
| 211 | %endm |
| 212 | %define UNSHADOW_ARGS |
| 213 | %else |
| 214 | %ifidn __OUTPUT_FORMAT__,x64 |
| 215 | %macro SHADOW_ARGS_TO_STACK 1 ; argc |
| 216 | %if %1 > 0 |
| 217 | mov arg(0),rcx |
| 218 | %endif |
| 219 | %if %1 > 1 |
| 220 | mov arg(1),rdx |
| 221 | %endif |
| 222 | %if %1 > 2 |
| 223 | mov arg(2),r8 |
| 224 | %endif |
| 225 | %if %1 > 3 |
| 226 | mov arg(3),r9 |
| 227 | %endif |
| 228 | %endm |
| 229 | %else |
| 230 | %macro SHADOW_ARGS_TO_STACK 1 ; argc |
| 231 | %if %1 > 0 |
| 232 | push rdi |
| 233 | %endif |
| 234 | %if %1 > 1 |
| 235 | push rsi |
| 236 | %endif |
| 237 | %if %1 > 2 |
| 238 | push rdx |
| 239 | %endif |
| 240 | %if %1 > 3 |
| 241 | push rcx |
| 242 | %endif |
| 243 | %if %1 > 4 |
| 244 | push r8 |
| 245 | %endif |
| 246 | %if %1 > 5 |
| 247 | push r9 |
| 248 | %endif |
| 249 | %if %1 > 6 |
Scott LaVarnway | 48c84d1 | 2010-06-14 14:07:56 -0400 | [diff] [blame] | 250 | %assign i %1-6 |
| 251 | %assign off 16 |
| 252 | %rep i |
| 253 | mov rax,[rbp+off] |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 254 | push rax |
Scott LaVarnway | 48c84d1 | 2010-06-14 14:07:56 -0400 | [diff] [blame] | 255 | %assign off off+8 |
| 256 | %endrep |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 257 | %endif |
| 258 | %endm |
| 259 | %endif |
| 260 | %define UNSHADOW_ARGS mov rsp, rbp |
| 261 | %endif |
| 262 | |
Makoto Kato | 63ea870 | 2010-06-11 18:32:28 +0900 | [diff] [blame] | 263 | ; must keep XMM6:XMM15 (libvpx uses XMM6 and XMM7) on Win64 ABI |
| 264 | ; rsp register has to be aligned |
| 265 | %ifidn __OUTPUT_FORMAT__,x64 |
| 266 | %macro SAVE_XMM 0 |
| 267 | sub rsp, 32 |
| 268 | movdqa XMMWORD PTR [rsp], xmm6 |
| 269 | movdqa XMMWORD PTR [rsp+16], xmm7 |
| 270 | %endmacro |
| 271 | %macro RESTORE_XMM 0 |
| 272 | movdqa xmm6, XMMWORD PTR [rsp] |
| 273 | movdqa xmm7, XMMWORD PTR [rsp+16] |
| 274 | add rsp, 32 |
| 275 | %endmacro |
| 276 | %else |
| 277 | %macro SAVE_XMM 0 |
| 278 | %endmacro |
| 279 | %macro RESTORE_XMM 0 |
| 280 | %endmacro |
| 281 | %endif |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 282 | |
| 283 | ; Name of the rodata section |
| 284 | ; |
| 285 | ; .rodata seems to be an elf-ism, as it doesn't work on OSX. |
| 286 | ; |
| 287 | %ifidn __OUTPUT_FORMAT__,macho64 |
| 288 | %define SECTION_RODATA section .text |
| 289 | %elifidn __OUTPUT_FORMAT__,macho32 |
| 290 | %macro SECTION_RODATA 0 |
| 291 | section .text |
| 292 | fake_got: |
| 293 | %endmacro |
| 294 | %else |
| 295 | %define SECTION_RODATA section .rodata |
| 296 | %endif |
John Koleszar | c3c870e | 2010-05-27 08:56:34 -0400 | [diff] [blame] | 297 | |
| 298 | |
| 299 | ; Tell GNU ld that we don't require an executable stack. |
| 300 | %ifidn __OUTPUT_FORMAT__,elf32 |
| 301 | section .note.GNU-stack noalloc noexec nowrite progbits |
| 302 | section .text |
| 303 | %elifidn __OUTPUT_FORMAT__,elf64 |
| 304 | section .note.GNU-stack noalloc noexec nowrite progbits |
| 305 | section .text |
| 306 | %endif |
| 307 | |