x86_abi_support.asm 9.13 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
;
2
;  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
;
4
;  Use of this source code is governed by a BSD-style license
5 6
;  that can be found in the LICENSE file in the root of the source
;  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.
John Koleszar's avatar
John Koleszar committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
;


%include "vpx_config.asm"

; 32/64 bit compatibility macros
;
; In general, we make the source use 64 bit syntax, then twiddle with it using
; the preprocessor to get the 32 bit syntax on 32 bit platforms.
;
%ifidn __OUTPUT_FORMAT__,elf32
%define ABI_IS_32BIT 1
%elifidn __OUTPUT_FORMAT__,macho32
%define ABI_IS_32BIT 1
%elifidn __OUTPUT_FORMAT__,win32
%define ABI_IS_32BIT 1
KO Myung-Hun's avatar
KO Myung-Hun committed
25 26
%elifidn __OUTPUT_FORMAT__,aout
%define ABI_IS_32BIT 1
John Koleszar's avatar
John Koleszar committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40
%else
%define ABI_IS_32BIT 0
%endif

%if ABI_IS_32BIT
%define rax eax
%define rbx ebx
%define rcx ecx
%define rdx edx
%define rsi esi
%define rdi edi
%define rsp esp
%define rbp ebp
%define movsxd mov
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
%macro movq 2
  %ifidn %1,eax
    movd %1,%2
  %elifidn %2,eax
    movd %1,%2
  %elifidn %1,ebx
    movd %1,%2
  %elifidn %2,ebx
    movd %1,%2
  %elifidn %1,ecx
    movd %1,%2
  %elifidn %2,ecx
    movd %1,%2
  %elifidn %1,edx
    movd %1,%2
  %elifidn %2,edx
    movd %1,%2
  %elifidn %1,esi
    movd %1,%2
  %elifidn %2,esi
    movd %1,%2
  %elifidn %1,edi
    movd %1,%2
  %elifidn %2,edi
    movd %1,%2
  %elifidn %1,esp
    movd %1,%2
  %elifidn %2,esp
    movd %1,%2
  %elifidn %1,ebp
    movd %1,%2
  %elifidn %2,ebp
    movd %1,%2
  %else
    movq %1,%2
  %endif
%endmacro
John Koleszar's avatar
John Koleszar committed
78 79 80
%endif


81 82 83 84 85 86 87 88 89 90 91
; LIBVPX_YASM_WIN64
; Set LIBVPX_YASM_WIN64 if output is Windows 64bit so the code will work if x64
; or win64 is defined on the Yasm command line.
%ifidn __OUTPUT_FORMAT__,win64
%define LIBVPX_YASM_WIN64 1
%elifidn __OUTPUT_FORMAT__,x64
%define LIBVPX_YASM_WIN64 1
%else
%define LIBVPX_YASM_WIN64 0
%endif

John Koleszar's avatar
John Koleszar committed
92 93 94 95 96 97 98 99 100 101
; sym()
; Return the proper symbol name for the target ABI.
;
; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols
; with C linkage be prefixed with an underscore.
;
%ifidn   __OUTPUT_FORMAT__,elf32
%define sym(x) x
%elifidn __OUTPUT_FORMAT__,elf64
%define sym(x) x
Mike Frysinger's avatar
Mike Frysinger committed
102 103
%elifidn __OUTPUT_FORMAT__,elfx32
%define sym(x) x
104
%elif LIBVPX_YASM_WIN64
John Koleszar's avatar
John Koleszar committed
105 106 107 108 109
%define sym(x) x
%else
%define sym(x) _ %+ x
%endif

110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
;  PRIVATE
;  Macro for the attribute to hide a global symbol for the target ABI.
;  This is only active if CHROMIUM is defined.
;
;  Chromium doesn't like exported global symbols due to symbol clashing with
;  plugins among other things.
;
;  Requires Chromium's patched copy of yasm:
;    http://src.chromium.org/viewvc/chrome?view=rev&revision=73761
;    http://www.tortall.net/projects/yasm/ticket/236
;
%ifdef CHROMIUM
  %ifidn   __OUTPUT_FORMAT__,elf32
    %define PRIVATE :hidden
  %elifidn __OUTPUT_FORMAT__,elf64
    %define PRIVATE :hidden
Mike Frysinger's avatar
Mike Frysinger committed
126 127
  %elifidn __OUTPUT_FORMAT__,elfx32
    %define PRIVATE :hidden
128
  %elif LIBVPX_YASM_WIN64
129 130 131 132 133 134 135 136
    %define PRIVATE
  %else
    %define PRIVATE :private_extern
  %endif
%else
  %define PRIVATE
%endif

John Koleszar's avatar
John Koleszar committed
137 138 139 140 141 142 143 144
; arg()
; Return the address specification of the given argument
;
%if ABI_IS_32BIT
  %define arg(x) [ebp+8+4*x]
%else
  ; 64 bit ABI passes arguments in registers. This is a workaround to get up
  ; and running quickly. Relies on SHADOW_ARGS_TO_STACK
145
  %if LIBVPX_YASM_WIN64
John Koleszar's avatar
John Koleszar committed
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
    %define arg(x) [rbp+16+8*x]
  %else
    %define arg(x) [rbp-8-8*x]
  %endif
%endif

; REG_SZ_BYTES, REG_SZ_BITS
; Size of a register
%if ABI_IS_32BIT
%define REG_SZ_BYTES 4
%define REG_SZ_BITS  32
%else
%define REG_SZ_BYTES 8
%define REG_SZ_BITS  64
%endif


; ALIGN_STACK <alignment> <register>
; This macro aligns the stack to the given alignment (in bytes). The stack
; is left such that the previous value of the stack pointer is the first
; argument on the stack (ie, the inverse of this macro is 'pop rsp.')
; This macro uses one temporary register, which is not preserved, and thus
; must be specified as an argument.
%macro ALIGN_STACK 2
    mov         %2, rsp
    and         rsp, -%1
172
    lea         rsp, [rsp - (%1 - REG_SZ_BYTES)]
John Koleszar's avatar
John Koleszar committed
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
    push        %2
%endmacro


;
; The Microsoft assembler tries to impose a certain amount of type safety in
; its register usage. YASM doesn't recognize these directives, so we just
; %define them away to maintain as much compatibility as possible with the
; original inline assembler we're porting from.
;
%idefine PTR
%idefine XMMWORD
%idefine MMWORD

; PIC macros
;
%if ABI_IS_32BIT
  %if CONFIG_PIC=1
  %ifidn __OUTPUT_FORMAT__,elf32
    %define WRT_PLT wrt ..plt
    %macro GET_GOT 1
      extern _GLOBAL_OFFSET_TABLE_
      push %1
      call %%get_got
197 198
      %%sub_offset:
      jmp %%exitGG
John Koleszar's avatar
John Koleszar committed
199
      %%get_got:
200 201 202 203
      mov %1, [esp]
      add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc
      ret
      %%exitGG:
John Koleszar's avatar
John Koleszar committed
204
      %undef GLOBAL
205
      %define GLOBAL(x) x + %1 wrt ..gotoff
John Koleszar's avatar
John Koleszar committed
206 207 208 209 210 211 212 213
      %undef RESTORE_GOT
      %define RESTORE_GOT pop %1
    %endmacro
  %elifidn __OUTPUT_FORMAT__,macho32
    %macro GET_GOT 1
      push %1
      call %%get_got
      %%get_got:
214
      pop  %1
John Koleszar's avatar
John Koleszar committed
215
      %undef GLOBAL
216
      %define GLOBAL(x) x + %1 - %%get_got
John Koleszar's avatar
John Koleszar committed
217 218 219 220 221
      %undef RESTORE_GOT
      %define RESTORE_GOT pop %1
    %endmacro
  %endif
  %endif
222 223 224 225 226 227 228 229 230 231

  %ifdef CHROMIUM
    %ifidn __OUTPUT_FORMAT__,macho32
      %define HIDDEN_DATA(x) x:private_extern
    %else
      %define HIDDEN_DATA(x) x
    %endif
  %else
    %define HIDDEN_DATA(x) x
  %endif
John Koleszar's avatar
John Koleszar committed
232 233 234
%else
  %macro GET_GOT 1
  %endmacro
235
  %define GLOBAL(x) rel x
John Koleszar's avatar
John Koleszar committed
236 237
  %ifidn __OUTPUT_FORMAT__,elf64
    %define WRT_PLT wrt ..plt
238
    %define HIDDEN_DATA(x) x:data hidden
Mike Frysinger's avatar
Mike Frysinger committed
239 240 241
  %elifidn __OUTPUT_FORMAT__,elfx32
    %define WRT_PLT wrt ..plt
    %define HIDDEN_DATA(x) x:data hidden
242 243 244 245 246 247
  %elifidn __OUTPUT_FORMAT__,macho64
    %ifdef CHROMIUM
      %define HIDDEN_DATA(x) x:private_extern
    %else
      %define HIDDEN_DATA(x) x
    %endif
248
  %else
249
    %define HIDDEN_DATA(x) x
John Koleszar's avatar
John Koleszar committed
250 251 252 253 254
  %endif
%endif
%ifnmacro GET_GOT
    %macro GET_GOT 1
    %endmacro
255
    %define GLOBAL(x) x
John Koleszar's avatar
John Koleszar committed
256 257 258 259 260 261 262 263 264 265 266 267 268
%endif
%ifndef RESTORE_GOT
%define RESTORE_GOT
%endif
%ifndef WRT_PLT
%define WRT_PLT
%endif

%if ABI_IS_32BIT
  %macro SHADOW_ARGS_TO_STACK 1
  %endm
  %define UNSHADOW_ARGS
%else
269
%if LIBVPX_YASM_WIN64
John Koleszar's avatar
John Koleszar committed
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
  %macro SHADOW_ARGS_TO_STACK 1 ; argc
    %if %1 > 0
        mov arg(0),rcx
    %endif
    %if %1 > 1
        mov arg(1),rdx
    %endif
    %if %1 > 2
        mov arg(2),r8
    %endif
    %if %1 > 3
        mov arg(3),r9
    %endif
  %endm
%else
  %macro SHADOW_ARGS_TO_STACK 1 ; argc
    %if %1 > 0
        push rdi
    %endif
    %if %1 > 1
        push rsi
    %endif
    %if %1 > 2
        push rdx
    %endif
    %if %1 > 3
        push rcx
    %endif
    %if %1 > 4
        push r8
    %endif
    %if %1 > 5
        push r9
    %endif
    %if %1 > 6
305 306 307 308
      %assign i %1-6
      %assign off 16
      %rep i
        mov rax,[rbp+off]
John Koleszar's avatar
John Koleszar committed
309
        push rax
310 311
        %assign off off+8
      %endrep
John Koleszar's avatar
John Koleszar committed
312 313 314 315 316 317
    %endif
  %endm
%endif
  %define UNSHADOW_ARGS mov rsp, rbp
%endif

318 319 320 321 322 323 324
; Win64 ABI requires that XMM6:XMM15 are callee saved
; SAVE_XMM n, [u]
; store registers 6-n on the stack
; if u is specified, use unaligned movs.
; Win64 ABI requires 16 byte stack alignment, but then pushes an 8 byte return
; value. Typically we follow this up with 'push rbp' - re-aligning the stack -
; but in some cases this is not done and unaligned movs must be used.
325
%if LIBVPX_YASM_WIN64
326 327 328 329 330 331 332 333 334 335 336 337 338 339
%macro SAVE_XMM 1-2 a
  %if %1 < 6
    %error Only xmm registers 6-15 must be preserved
  %else
    %assign last_xmm %1
    %define movxmm movdq %+ %2
    %assign xmm_stack_space ((last_xmm - 5) * 16)
    sub rsp, xmm_stack_space
    %assign i 6
    %rep (last_xmm - 5)
      movxmm [rsp + ((i - 6) * 16)], xmm %+ i
      %assign i i+1
    %endrep
  %endif
340 341
%endmacro
%macro RESTORE_XMM 0
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
  %ifndef last_xmm
    %error RESTORE_XMM must be paired with SAVE_XMM n
  %else
    %assign i last_xmm
    %rep (last_xmm - 5)
      movxmm xmm %+ i, [rsp +((i - 6) * 16)]
      %assign i i-1
    %endrep
    add rsp, xmm_stack_space
    ; there are a couple functions which return from multiple places.
    ; otherwise, we could uncomment these:
    ; %undef last_xmm
    ; %undef xmm_stack_space
    ; %undef movxmm
  %endif
357 358
%endmacro
%else
359
%macro SAVE_XMM 1-2
360 361 362 363
%endmacro
%macro RESTORE_XMM 0
%endmacro
%endif
John Koleszar's avatar
John Koleszar committed
364 365 366 367 368 369 370 371 372 373 374

; Name of the rodata section
;
; .rodata seems to be an elf-ism, as it doesn't work on OSX.
;
%ifidn __OUTPUT_FORMAT__,macho64
%define SECTION_RODATA section .text
%elifidn __OUTPUT_FORMAT__,macho32
%macro SECTION_RODATA 0
section .text
%endmacro
KO Myung-Hun's avatar
KO Myung-Hun committed
375 376
%elifidn __OUTPUT_FORMAT__,aout
%define SECTION_RODATA section .data
John Koleszar's avatar
John Koleszar committed
377 378 379
%else
%define SECTION_RODATA section .rodata
%endif
380 381 382 383 384 385 386 387 388


; Tell GNU ld that we don't require an executable stack.
%ifidn __OUTPUT_FORMAT__,elf32
section .note.GNU-stack noalloc noexec nowrite progbits
section .text
%elifidn __OUTPUT_FORMAT__,elf64
section .note.GNU-stack noalloc noexec nowrite progbits
section .text
Mike Frysinger's avatar
Mike Frysinger committed
389 390 391
%elifidn __OUTPUT_FORMAT__,elfx32
section .note.GNU-stack noalloc noexec nowrite progbits
section .text
392 393
%endif

Johann's avatar
Johann committed
394 395
; On Android platforms use lrand48 when building postproc routines. Prior to L
; rand() was not available.
396
%if CONFIG_POSTPROC=1 || CONFIG_VP9_POSTPROC=1
Johann's avatar
Johann committed
397 398 399 400 401 402 403
%ifdef __ANDROID__
extern sym(lrand48)
%define LIBVPX_RAND lrand48
%else
extern sym(rand)
%define LIBVPX_RAND rand
%endif
404
%endif ; CONFIG_POSTPROC || CONFIG_VP9_POSTPROC