2010-06-08 16:31:28 -07:00
|
|
|
;
|
2010-11-07 23:47:17 -08:00
|
|
|
; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
2010-06-08 16:31:28 -07:00
|
|
|
;
|
2010-09-09 05:06:21 -07:00
|
|
|
; Use of this source code is governed by a BSD-style license
|
2010-06-08 16:31:28 -07:00
|
|
|
; that can be found in the LICENSE file in the root of the source
|
|
|
|
; tree. An additional intellectual property rights grant can be found
|
2010-09-09 05:06:21 -07:00
|
|
|
; in the file PATENTS. All contributing project authors may
|
2010-06-08 16:31:28 -07:00
|
|
|
; be found in the AUTHORS file in the root of the source tree.
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
%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
|
|
|
|
%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
|
2010-11-07 23:47:17 -08:00
|
|
|
%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
|
2010-06-08 16:31:28 -07:00
|
|
|
%endif
|
|
|
|
|
|
|
|
|
|
|
|
; 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
|
|
|
|
%elifidn __OUTPUT_FORMAT__,x64
|
|
|
|
%define sym(x) x
|
|
|
|
%else
|
|
|
|
%define sym(x) _ %+ x
|
|
|
|
%endif
|
|
|
|
|
|
|
|
; 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
|
|
|
|
%ifidn __OUTPUT_FORMAT__,x64
|
|
|
|
%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
|
2010-11-07 23:47:17 -08:00
|
|
|
lea rsp, [rsp - (%1 - REG_SZ_BYTES)]
|
2010-06-08 16:31:28 -07:00
|
|
|
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
|
2010-11-07 23:47:17 -08:00
|
|
|
%%sub_offset:
|
|
|
|
jmp %%exitGG
|
2010-06-08 16:31:28 -07:00
|
|
|
%%get_got:
|
2010-11-07 23:47:17 -08:00
|
|
|
mov %1, [esp]
|
|
|
|
add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc
|
|
|
|
ret
|
|
|
|
%%exitGG:
|
2010-06-08 16:31:28 -07:00
|
|
|
%undef GLOBAL
|
2010-11-07 23:47:17 -08:00
|
|
|
%define GLOBAL(x) x + %1 wrt ..gotoff
|
2010-06-08 16:31:28 -07:00
|
|
|
%undef RESTORE_GOT
|
|
|
|
%define RESTORE_GOT pop %1
|
|
|
|
%endmacro
|
|
|
|
%elifidn __OUTPUT_FORMAT__,macho32
|
|
|
|
%macro GET_GOT 1
|
|
|
|
push %1
|
|
|
|
call %%get_got
|
2010-11-07 23:47:17 -08:00
|
|
|
%%sub_offset:
|
|
|
|
jmp %%exitGG
|
2010-06-08 16:31:28 -07:00
|
|
|
%%get_got:
|
2010-11-07 23:47:17 -08:00
|
|
|
mov %1, [esp]
|
|
|
|
add %1, fake_got - %%sub_offset
|
|
|
|
ret
|
|
|
|
%%exitGG:
|
2010-06-08 16:31:28 -07:00
|
|
|
%undef GLOBAL
|
2010-11-07 23:47:17 -08:00
|
|
|
%define GLOBAL(x) x + %1 - fake_got
|
2010-06-08 16:31:28 -07:00
|
|
|
%undef RESTORE_GOT
|
|
|
|
%define RESTORE_GOT pop %1
|
|
|
|
%endmacro
|
|
|
|
%endif
|
|
|
|
%endif
|
2010-09-09 05:06:21 -07:00
|
|
|
%define HIDDEN_DATA(x) x
|
2010-06-08 16:31:28 -07:00
|
|
|
%else
|
|
|
|
%macro GET_GOT 1
|
|
|
|
%endmacro
|
2010-11-07 23:47:17 -08:00
|
|
|
%define GLOBAL(x) rel x
|
2010-06-08 16:31:28 -07:00
|
|
|
%ifidn __OUTPUT_FORMAT__,elf64
|
|
|
|
%define WRT_PLT wrt ..plt
|
2010-09-09 05:06:21 -07:00
|
|
|
%define HIDDEN_DATA(x) x:data hidden
|
2010-06-21 17:01:48 -07:00
|
|
|
%else
|
2010-09-09 05:06:21 -07:00
|
|
|
%define HIDDEN_DATA(x) x
|
2010-06-08 16:31:28 -07:00
|
|
|
%endif
|
|
|
|
%endif
|
|
|
|
%ifnmacro GET_GOT
|
|
|
|
%macro GET_GOT 1
|
|
|
|
%endmacro
|
2010-11-07 23:47:17 -08:00
|
|
|
%define GLOBAL(x) x
|
2010-06-08 16:31:28 -07:00
|
|
|
%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
|
|
|
|
%ifidn __OUTPUT_FORMAT__,x64
|
|
|
|
%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
|
2010-09-09 05:06:21 -07:00
|
|
|
%assign i %1-6
|
|
|
|
%assign off 16
|
|
|
|
%rep i
|
|
|
|
mov rax,[rbp+off]
|
2010-06-08 16:31:28 -07:00
|
|
|
push rax
|
2010-09-09 05:06:21 -07:00
|
|
|
%assign off off+8
|
|
|
|
%endrep
|
2010-06-08 16:31:28 -07:00
|
|
|
%endif
|
|
|
|
%endm
|
|
|
|
%endif
|
|
|
|
%define UNSHADOW_ARGS mov rsp, rbp
|
|
|
|
%endif
|
|
|
|
|
2010-09-09 05:06:21 -07:00
|
|
|
; must keep XMM6:XMM15 (libvpx uses XMM6 and XMM7) on Win64 ABI
|
|
|
|
; rsp register has to be aligned
|
|
|
|
%ifidn __OUTPUT_FORMAT__,x64
|
|
|
|
%macro SAVE_XMM 0
|
|
|
|
sub rsp, 32
|
|
|
|
movdqa XMMWORD PTR [rsp], xmm6
|
|
|
|
movdqa XMMWORD PTR [rsp+16], xmm7
|
|
|
|
%endmacro
|
|
|
|
%macro RESTORE_XMM 0
|
|
|
|
movdqa xmm6, XMMWORD PTR [rsp]
|
|
|
|
movdqa xmm7, XMMWORD PTR [rsp+16]
|
|
|
|
add rsp, 32
|
|
|
|
%endmacro
|
|
|
|
%else
|
|
|
|
%macro SAVE_XMM 0
|
|
|
|
%endmacro
|
|
|
|
%macro RESTORE_XMM 0
|
|
|
|
%endmacro
|
|
|
|
%endif
|
2010-06-08 16:31:28 -07:00
|
|
|
|
|
|
|
; 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
|
|
|
|
fake_got:
|
|
|
|
%endmacro
|
|
|
|
%else
|
|
|
|
%define SECTION_RODATA section .rodata
|
|
|
|
%endif
|
|
|
|
|
|
|
|
|
|
|
|
; 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
|
|
|
|
%endif
|
|
|
|
|