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