diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2012-07-26 20:26:17 -0700 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2012-07-28 08:29:44 -0700 |
commit | 96c9cc10947a374b99f56970959cdedbbb1e4331 (patch) | |
tree | fcab00168226cb2592d8d91ea83b67d588f71cd7 | |
parent | b3c5ae5607275f691289df737edaf47c72e6028c (diff) | |
download | ffmpeg-96c9cc10947a374b99f56970959cdedbbb1e4331.tar.gz |
x86inc: sync to latest version from x264.
-rw-r--r-- | libavutil/x86/x86inc.asm | 216 |
1 files changed, 124 insertions, 92 deletions
diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm index 4b4a19b208..1030f10a32 100644 --- a/libavutil/x86/x86inc.asm +++ b/libavutil/x86/x86inc.asm @@ -36,8 +36,8 @@ %define program_name ff -%define UNIX64 0 %define WIN64 0 +%define UNIX64 0 %if ARCH_X86_64 %ifidn __OUTPUT_FORMAT__,win32 %define WIN64 1 @@ -54,11 +54,6 @@ %define mangle(x) x %endif -; FIXME: All of the 64bit asm functions that take a stride as an argument -; via register, assume that the high dword of that register is filled with 0. -; This is true in practice (since we never do any 64bit arithmetic on strides, -; and x264's strides are all positive), but is not guaranteed by the ABI. - ; Name of the .rodata section. ; Kludge: Something on OS X fails to align .rodata even given an align attribute, ; so use a different read-only section. @@ -129,34 +124,38 @@ CPU amdnop ; registers: ; rN and rNq are the native-size register holding function argument N ; rNd, rNw, rNb are dword, word, and byte size +; rNh is the high 8 bits of the word size ; rNm is the original location of arg N (a register or on the stack), dword ; rNmp is native size -%macro DECLARE_REG 5-6 +%macro DECLARE_REG 2-3 %define r%1q %2 - %define r%1d %3 - %define r%1w %4 - %define r%1b %5 - %if %0 == 5 - %define r%1m %3 + %define r%1d %2d + %define r%1w %2w + %define r%1b %2b + %define r%1h %2h + %if %0 == 2 + %define r%1m %2d %define r%1mp %2 %elif ARCH_X86_64 ; memory - %define r%1m [rsp + stack_offset + %6] + %define r%1m [rsp + stack_offset + %3] %define r%1mp qword r %+ %1m %else - %define r%1m [esp + stack_offset + %6] + %define r%1m [esp + stack_offset + %3] %define r%1mp dword r %+ %1m %endif %define r%1 %2 %endmacro -%macro DECLARE_REG_SIZE 2 +%macro DECLARE_REG_SIZE 3 %define r%1q r%1 %define e%1q r%1 %define r%1d e%1 %define e%1d e%1 %define r%1w %1 %define e%1w %1 + %define r%1h %3 + %define e%1h %3 %define r%1b %2 %define e%1b %2 %if ARCH_X86_64 == 0 @@ -164,13 +163,13 @@ CPU amdnop %endif %endmacro -DECLARE_REG_SIZE ax, al -DECLARE_REG_SIZE bx, bl -DECLARE_REG_SIZE cx, cl -DECLARE_REG_SIZE dx, dl -DECLARE_REG_SIZE si, sil -DECLARE_REG_SIZE di, dil -DECLARE_REG_SIZE bp, bpl +DECLARE_REG_SIZE ax, al, ah +DECLARE_REG_SIZE bx, bl, bh +DECLARE_REG_SIZE cx, cl, ch +DECLARE_REG_SIZE dx, dl, dh +DECLARE_REG_SIZE si, sil, null +DECLARE_REG_SIZE di, dil, null +DECLARE_REG_SIZE bp, bpl, null ; t# defines for when per-arch register allocation is more complex than just function arguments @@ -188,6 +187,7 @@ DECLARE_REG_SIZE bp, bpl %define t%1q t%1 %+ q %define t%1d t%1 %+ d %define t%1w t%1 %+ w + %define t%1h t%1 %+ h %define t%1b t%1 %+ b %rotate 1 %endrep @@ -277,6 +277,7 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 CAT_UNDEF arg_name %+ %%i, q CAT_UNDEF arg_name %+ %%i, d CAT_UNDEF arg_name %+ %%i, w + CAT_UNDEF arg_name %+ %%i, h CAT_UNDEF arg_name %+ %%i, b CAT_UNDEF arg_name %+ %%i, m CAT_UNDEF arg_name %+ %%i, mp @@ -292,6 +293,7 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %xdefine %1q r %+ %%i %+ q %xdefine %1d r %+ %%i %+ d %xdefine %1w r %+ %%i %+ w + %xdefine %1h r %+ %%i %+ h %xdefine %1b r %+ %%i %+ b %xdefine %1m r %+ %%i %+ m %xdefine %1mp r %+ %%i %+ mp @@ -305,21 +307,21 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 %if WIN64 ; Windows x64 ;================================================= -DECLARE_REG 0, rcx, ecx, cx, cl -DECLARE_REG 1, rdx, edx, dx, dl -DECLARE_REG 2, R8, R8D, R8W, R8B -DECLARE_REG 3, R9, R9D, R9W, R9B -DECLARE_REG 4, R10, R10D, R10W, R10B, 40 -DECLARE_REG 5, R11, R11D, R11W, R11B, 48 -DECLARE_REG 6, rax, eax, ax, al, 56 -DECLARE_REG 7, rdi, edi, di, dil, 64 -DECLARE_REG 8, rsi, esi, si, sil, 72 -DECLARE_REG 9, rbx, ebx, bx, bl, 80 -DECLARE_REG 10, rbp, ebp, bp, bpl, 88 -DECLARE_REG 11, R12, R12D, R12W, R12B, 96 -DECLARE_REG 12, R13, R13D, R13W, R13B, 104 -DECLARE_REG 13, R14, R14D, R14W, R14B, 112 -DECLARE_REG 14, R15, R15D, R15W, R15B, 120 +DECLARE_REG 0, rcx +DECLARE_REG 1, rdx +DECLARE_REG 2, R8 +DECLARE_REG 3, R9 +DECLARE_REG 4, R10, 40 +DECLARE_REG 5, R11, 48 +DECLARE_REG 6, rax, 56 +DECLARE_REG 7, rdi, 64 +DECLARE_REG 8, rsi, 72 +DECLARE_REG 9, rbx, 80 +DECLARE_REG 10, rbp, 88 +DECLARE_REG 11, R12, 96 +DECLARE_REG 12, R13, 104 +DECLARE_REG 13, R14, 112 +DECLARE_REG 14, R15, 120 %macro PROLOGUE 2-4+ 0 ; #args, #regs, #xmm_regs, arg_names... %assign num_args %1 @@ -366,6 +368,8 @@ DECLARE_REG 14, R15, R15D, R15W, R15B, 120 %assign xmm_regs_used 0 %endmacro +%define has_epilogue regs_used > 7 || xmm_regs_used > 6 || mmsize == 32 + %macro RET 0 WIN64_RESTORE_XMM_INTERNAL rsp POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7 @@ -375,31 +379,23 @@ DECLARE_REG 14, R15, R15D, R15W, R15B, 120 ret %endmacro -%macro REP_RET 0 - %if regs_used > 7 || xmm_regs_used > 6 || mmsize == 32 - RET - %else - rep ret - %endif -%endmacro - %elif ARCH_X86_64 ; *nix x64 ;============================================= -DECLARE_REG 0, rdi, edi, di, dil -DECLARE_REG 1, rsi, esi, si, sil -DECLARE_REG 2, rdx, edx, dx, dl -DECLARE_REG 3, rcx, ecx, cx, cl -DECLARE_REG 4, R8, R8D, R8W, R8B -DECLARE_REG 5, R9, R9D, R9W, R9B -DECLARE_REG 6, rax, eax, ax, al, 8 -DECLARE_REG 7, R10, R10D, R10W, R10B, 16 -DECLARE_REG 8, R11, R11D, R11W, R11B, 24 -DECLARE_REG 9, rbx, ebx, bx, bl, 32 -DECLARE_REG 10, rbp, ebp, bp, bpl, 40 -DECLARE_REG 11, R12, R12D, R12W, R12B, 48 -DECLARE_REG 12, R13, R13D, R13W, R13B, 56 -DECLARE_REG 13, R14, R14D, R14W, R14B, 64 -DECLARE_REG 14, R15, R15D, R15W, R15B, 72 +DECLARE_REG 0, rdi +DECLARE_REG 1, rsi +DECLARE_REG 2, rdx +DECLARE_REG 3, rcx +DECLARE_REG 4, R8 +DECLARE_REG 5, R9 +DECLARE_REG 6, rax, 8 +DECLARE_REG 7, R10, 16 +DECLARE_REG 8, R11, 24 +DECLARE_REG 9, rbx, 32 +DECLARE_REG 10, rbp, 40 +DECLARE_REG 11, R12, 48 +DECLARE_REG 12, R13, 56 +DECLARE_REG 13, R14, 64 +DECLARE_REG 14, R15, 72 %macro PROLOGUE 2-4+ ; #args, #regs, #xmm_regs, arg_names... %assign num_args %1 @@ -411,6 +407,8 @@ DECLARE_REG 14, R15, R15D, R15W, R15B, 72 DEFINE_ARGS %4 %endmacro +%define has_epilogue regs_used > 9 || mmsize == 32 + %macro RET 0 POP_IF_USED 14, 13, 12, 11, 10, 9 %if mmsize == 32 @@ -419,23 +417,15 @@ DECLARE_REG 14, R15, R15D, R15W, R15B, 72 ret %endmacro -%macro REP_RET 0 - %if regs_used > 9 || mmsize == 32 - RET - %else - rep ret - %endif -%endmacro - %else ; X86_32 ;============================================================== -DECLARE_REG 0, eax, eax, ax, al, 4 -DECLARE_REG 1, ecx, ecx, cx, cl, 8 -DECLARE_REG 2, edx, edx, dx, dl, 12 -DECLARE_REG 3, ebx, ebx, bx, bl, 16 -DECLARE_REG 4, esi, esi, si, null, 20 -DECLARE_REG 5, edi, edi, di, null, 24 -DECLARE_REG 6, ebp, ebp, bp, null, 28 +DECLARE_REG 0, eax, 4 +DECLARE_REG 1, ecx, 8 +DECLARE_REG 2, edx, 12 +DECLARE_REG 3, ebx, 16 +DECLARE_REG 4, esi, 20 +DECLARE_REG 5, edi, 24 +DECLARE_REG 6, ebp, 28 %define rsp esp %macro DECLARE_ARG 1-* @@ -460,6 +450,8 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 DEFINE_ARGS %4 %endmacro +%define has_epilogue regs_used > 3 || mmsize == 32 + %macro RET 0 POP_IF_USED 6, 5, 4, 3 %if mmsize == 32 @@ -468,14 +460,6 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 ret %endmacro -%macro REP_RET 0 - %if regs_used > 3 || mmsize == 32 - RET - %else - rep ret - %endif -%endmacro - %endif ;====================================================================== %if WIN64 == 0 @@ -485,6 +469,23 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 %endmacro %endif +%macro REP_RET 0 + %if has_epilogue + RET + %else + rep ret + %endif +%endmacro + +%macro TAIL_CALL 2 ; callee, is_nonadjacent + %if has_epilogue + call %1 + RET + %elif %2 + jmp %1 + %endif +%endmacro + ;============================================================================= ; arch-independent part ;============================================================================= @@ -564,6 +565,8 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits %assign cpuflags_avx (1<<11)| cpuflags_sse42 %assign cpuflags_xop (1<<12)| cpuflags_avx %assign cpuflags_fma4 (1<<13)| cpuflags_avx +%assign cpuflags_avx2 (1<<14)| cpuflags_avx +%assign cpuflags_fma3 (1<<15)| cpuflags_avx %assign cpuflags_cache32 (1<<16) %assign cpuflags_cache64 (1<<17) @@ -572,6 +575,9 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits %assign cpuflags_misalign (1<<20) %assign cpuflags_aligned (1<<21) ; not a cpu feature, but a function variant %assign cpuflags_atom (1<<22) +%assign cpuflags_bmi1 (1<<23) +%assign cpuflags_bmi2 (1<<24)|cpuflags_bmi1 +%assign cpuflags_tbm (1<<25)|cpuflags_bmi1 %define cpuflag(x) ((cpuflags & (cpuflags_ %+ x)) == (cpuflags_ %+ x)) %define notcpuflag(x) ((cpuflags & (cpuflags_ %+ x)) != (cpuflags_ %+ x)) @@ -833,25 +839,38 @@ INIT_XMM %endrep %undef i +%macro CHECK_AVX_INSTR_EMU 3-* + %xdefine %%opcode %1 + %xdefine %%dst %2 + %rep %0-2 + %ifidn %%dst, %3 + %error non-avx emulation of ``%%opcode'' is not supported + %endif + %rotate 1 + %endrep +%endmacro + ;%1 == instruction ;%2 == 1 if float, 0 if int ;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 2- or 3-operand (xmm, xmm, xmm) ;%4 == number of operands given ;%5+: operands %macro RUN_AVX_INSTR 6-7+ - %ifid %5 - %define %%size sizeof%5 + %ifid %6 + %define %%sizeofreg sizeof%6 + %elifid %5 + %define %%sizeofreg sizeof%5 %else - %define %%size mmsize + %define %%sizeofreg mmsize %endif - %if %%size==32 - %if %0 >= 7 + %if %%sizeofreg==32 + %if %4>=3 v%1 %5, %6, %7 %else v%1 %5, %6 %endif %else - %if %%size==8 + %if %%sizeofreg==8 %define %%regmov movq %elif %2 %define %%regmov movaps @@ -861,16 +880,17 @@ INIT_XMM %if %4>=3+%3 %ifnidn %5, %6 - %if avx_enabled && sizeof%5==16 + %if avx_enabled && %%sizeofreg==16 v%1 %5, %6, %7 %else + CHECK_AVX_INSTR_EMU {%1 %5, %6, %7}, %5, %7 %%regmov %5, %6 %1 %5, %7 %endif %else %1 %5, %7 %endif - %elif %3 + %elif %4>=3 %1 %5, %6, %7 %else %1 %5, %6 @@ -901,7 +921,7 @@ INIT_XMM ;%1 == instruction ;%2 == 1 if float, 0 if int -;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 3-operand (xmm, xmm, xmm) +;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 2- or 3-operand (xmm, xmm, xmm) ;%4 == 1 if symmetric (i.e. doesn't matter which src arg is which), 0 if not %macro AVX_INSTR 4 %macro %1 2-9 fnord, fnord, fnord, %1, %2, %3, %4 @@ -966,6 +986,9 @@ AVX_INSTR mulsd, 1, 0, 1 AVX_INSTR mulss, 1, 0, 1 AVX_INSTR orpd, 1, 0, 1 AVX_INSTR orps, 1, 0, 1 +AVX_INSTR pabsb, 0, 0, 0 +AVX_INSTR pabsw, 0, 0, 0 +AVX_INSTR pabsd, 0, 0, 0 AVX_INSTR packsswb, 0, 0, 0 AVX_INSTR packssdw, 0, 0, 0 AVX_INSTR packuswb, 0, 0, 0 @@ -1017,6 +1040,7 @@ AVX_INSTR pminsd, 0, 0, 1 AVX_INSTR pminub, 0, 0, 1 AVX_INSTR pminuw, 0, 0, 1 AVX_INSTR pminud, 0, 0, 1 +AVX_INSTR pmovmskb, 0, 0, 0 AVX_INSTR pmulhuw, 0, 0, 1 AVX_INSTR pmulhrsw, 0, 0, 1 AVX_INSTR pmulhw, 0, 0, 1 @@ -1027,6 +1051,9 @@ AVX_INSTR pmuldq, 0, 0, 1 AVX_INSTR por, 0, 0, 1 AVX_INSTR psadbw, 0, 0, 1 AVX_INSTR pshufb, 0, 0, 0 +AVX_INSTR pshufd, 0, 1, 0 +AVX_INSTR pshufhw, 0, 1, 0 +AVX_INSTR pshuflw, 0, 1, 0 AVX_INSTR psignb, 0, 0, 0 AVX_INSTR psignw, 0, 0, 0 AVX_INSTR psignd, 0, 0, 0 @@ -1048,6 +1075,7 @@ AVX_INSTR psubsb, 0, 0, 0 AVX_INSTR psubsw, 0, 0, 0 AVX_INSTR psubusb, 0, 0, 0 AVX_INSTR psubusw, 0, 0, 0 +AVX_INSTR ptest, 0, 0, 0 AVX_INSTR punpckhbw, 0, 0, 0 AVX_INSTR punpckhwd, 0, 0, 0 AVX_INSTR punpckhdq, 0, 0, 0 @@ -1112,3 +1140,7 @@ FMA_INSTR fmaddps, mulps, addps FMA_INSTR pmacsdd, pmulld, paddd FMA_INSTR pmacsww, pmullw, paddw FMA_INSTR pmadcswd, pmaddwd, paddd + +; tzcnt is equivalent to "rep bsf" and is backwards-compatible with bsf. +; This lets us use tzcnt without bumping the yasm version requirement yet. +%define tzcnt rep bsf |