[x264-devel] [RFC] [PATCH] x86inc add extended function declaration
Matthias Räncker
theonetruecamper at gmx.de
Thu Jan 31 21:33:10 CET 2013
This is a patch to extend the existing functionality of declaring functions.
The goal is to
- provide a means to transfrom a function prototype given C into a function
declaration in asm.
- give the assembler sufficient information about arguments so as to make
superfluous explicit movsxifnidn&co
- aid debugging by checking assertions for function arguments on entry
To illustrate its use I've added test.asm to play around with this.
code for x86:
77 [cpu amdnop]
221 [section .note.GNU-stack noalloc noexec nowrite progbits]
451 [global x264_foo:function hidden]
452 [align 16]
453 x264_foo:
454 00000000 8B442404 mov eax, dword [esp + 0 + 4]
455 00000004 8B4C2408 mov ecx, dword [esp + 0 + 8]
456 00000008 8B54240C mov edx, dword [esp + 0 + 12]
458 0000000C C3 ret
478 [global x264_bar:function hidden]
479 [align 16]
480 x264_bar:
481 00000010 8B442404 mov eax, dword [esp + 0 + 4]
482 00000014 8B4C2408 mov ecx, dword [esp + 0 + 8]
483 00000018 8B54240C mov edx, dword [esp + 0 + 12]
485 0000001C C3 ret
code for x32 (note how the constraint is used to change movsxd into mov for the 2nd argument)
73 [cpu amdnop]
213 [section .note.GNU-stack noalloc noexec nowrite progbits]
443 [global x264_foo:function hidden]
444 [align 16]
445 x264_foo:
447 00000000 4863F6 movsxd rsi, esi
448 00000003 89D2 mov edx, edx
450 00000005 C3 ret
470 [global x264_bar:function hidden]
471 [align 16]
472 x264_bar:
474 00000010 89F6 mov esi, esi
475 00000012 89D2 mov edx, edx
477 00000014 C3 ret
code for x64 with DEBUG (we try to write at address zero to trigger a seg fault if the test fails)
73 [cpu amdnop]
213 [section .note.GNU-stack noalloc noexec nowrite progbits]
443 [global x264_foo:function hidden]
444 [align 16]
445 x264_foo:
447 00000000 C3 ret
467 [global x264_bar:function hidden]
468 [align 16]
469 x264_bar:
470 [section .rodata align=16]
471 .. at 3714.val_0:
472 00000000 0000000000000000 dq 0
473 [section .rodata align=16]
474 00000008 4881FF[00000000] cmp rdi, .. at 3714.val_0
475 0000000F 7509 jne .. at 3714.ok_0
476 .. at 3725.branch_instr:
477 00000011 C70425000000000000- mov dword [0], 0
479 .. at 3714.ok_0:
480 [section .rodata align=16]
481 .. at 3714.val_1:
482 0000001C 0F00000000000000 dq 15
483 [section .rodata align=16]
484 00000024 48F7C7[00000000] test rdi, .. at 3714.val_1
485 0000002B 7409 jz .. at 3714.ok_1
486 .. at 3733.branch_instr:
487 0000002D C70425000000000100- mov dword [0], 1
489 .. at 3714.ok_1:
490 [section .rodata align=16]
491 .. at 3714.val_2:
492 00000038 00000000 dd 0
493 [section .rodata align=16]
494 0000003C 81FE[00000000] cmp esi, .. at 3714.val_2
495 00000042 7D09 jge .. at 3714.ok_2
496 .. at 3740.branch_instr:
497 00000044 C70425000000000200- mov dword [0], 2
499 .. at 3714.ok_2:
500 [section .rodata align=16]
501 .. at 3714.val_3:
502 0000004F 0300000000000000 dq 3
503 [section .rodata align=16]
504 00000057 4881FA[00000000] cmp rdx, .. at 3714.val_3
505 0000005E 7709 ja .. at 3714.ok_3
506 .. at 3753.branch_instr:
507 00000060 C70425000000000300- mov dword [0], 3
509 .. at 3714.ok_3:
510 0000006B 89F6 mov esi, esi
512 0000006D C3 ret
This is a draft, the code needs to be cleaned up a bit.
Honestly though, that yasm preprocessor isn't very cooperative when it comes
to writing code neatly...
Comments/feature requests etc. welcome
Signed-off-by: Matthias Räncker <theonetruecamper at gmx.de>
---
common/x86/test.asm | 8 +
common/x86/x86inc.asm | 1002 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 993 insertions(+), 17 deletions(-)
create mode 100644 common/x86/test.asm
diff --git a/common/x86/test.asm b/common/x86/test.asm
new file mode 100644
index 0000000..4371c1c
--- /dev/null
+++ b/common/x86/test.asm
@@ -0,0 +1,8 @@
+%include "x86inc.asm"
+
+cglobalx " void foo ( void* q , intptr_t q , uintptr_t q ) ", 3
+ret
+
+cglobalx " void bar ( void * q , int q , uintptr_t q ), \
+ [0] !0 &15, [1] >=0 , [2] >3 ", 3, 0
+ret
diff --git a/common/x86/x86inc.asm b/common/x86/x86inc.asm
index f45bdb4..1711bf7 100644
--- a/common/x86/x86inc.asm
+++ b/common/x86/x86inc.asm
@@ -38,6 +38,62 @@
%define program_name x264
%endif
+; convenience single line if
+; 2 operands: cc, inst - cc ? a :
+; 3 operands: cc, a, b - cc ? a : b
+; 4 operands: cc, foo, a, b - cc ? foo a : foo b
+%macro IF 2-4
+ %if %1
+ %if %0 < 4
+ %2
+ %else
+ %2 %3
+ %endif
+ %elif %0 > 2
+ %if %0 < 4
+ %3
+ %else
+ %2 %4
+ %endif
+ %endif
+%endmacro
+
+%macro IFNIDN 3+
+ %ifnidn %1, %2
+ %3
+ %endif
+%endmacro
+
+%ifndef ARCH_X86_64
+ %ifdef ARCH_X86_64_X32
+ %assign ARCH_X86_64 1
+ %elifdef ARCH_X86_64_X64
+ %assign ARCH_X86_64 1
+ %else
+ %assign ARCH_X86_64 0
+ %endif
+%elifnnum ARCH_X86_64
+ %assign ARCH_X86_64 1
+%endif
+
+%ifndef ARCH_X86_32
+ %assign ARCH_X86_32 ARCH_X86_64 ^ 1
+%elifnnum ARCH_X86_32
+ %assign ARCH_X86_32 1
+%endif
+
+%ifndef ARCH_X86_64_X32
+ %define ARCH_X86_64_X32 0
+%elifnnum ARCH_X86_64_X32
+ %assign ARCH_X86_64_X32 1
+%endif
+
+%ifndef ARCH_X86_64_X64
+ %define ARCH_X86_64_X64 ARCH_X86_64 ^ ARCH_X86_64_X32
+%elifnnum
+ %assign ARCH_X86_64_X64 1
+%endif
+
%define WIN64 0
%define UNIX64 0
%if ARCH_X86_64
@@ -56,6 +112,12 @@
%define mangle(x) x
%endif
+%ifndef DEBUG
+ %assign DEBUG 0
+%elifnnum
+ %assign DEBUG 1
+%endif
+
; 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,26 +191,37 @@ CPU amdnop
; registers:
; rN and rNq are the native-size register holding function argument N
-; rNd, rNw, rNb are dword, word, and byte size
+; rNp, rNd, rNw, rNb are pointer, 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
+; rNm is the original location of arg N
+; without size attribute if on the stack, dword otherwise
+; rNmq, rNmp, rNmd, rNmw, rNmh, rNmb are native, pointer, dword and byte size of
+; the original location of arg N (a register or on the stack)
%macro DECLARE_REG 2-3
%define r%1q %2
+ IF ARCH_X86_64_X64, %define r%1p, %2, %2d
%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 [rstk + stack_offset + %3]
- %define r%1mp qword r %+ %1 %+ m
+ %define r%1mq %2
+ IF ARCH_X86_64_X64, %define r%1mp, %2, %2d
+ %define r%1md %2d
+ %define r%1mw %2w
+ %define r%1mh %2h
+ %define r%1mb %2b
%else
%define r%1m [rstk + stack_offset + %3]
- %define r%1mp dword r %+ %1 %+ m
+ IF ARCH_X86_64, %define r%1mq, qword [rstk + stack_offset + %3], \
+ dword [rstk + stack_offset + %3]
+ %define r%1mp pword [rstk + stack_offset + %3]
+ %define r%1md dword [rstk + stack_offset + %3]
+ %define r%1mw word [rstk + stack_offset + %3]
+ %define r%1mh byte [rstk + stack_offset + %3 + 1]
+ %define r%1mb byte [rstk + stack_offset + %3]
%endif
%define r%1 %2
%endmacro
@@ -156,6 +229,8 @@ CPU amdnop
%macro DECLARE_REG_SIZE 3
%define r%1q r%1
%define e%1q r%1
+ IF ARCH_X86_64_X64, %define r%1p, r%1, e%1
+ %define e%1p e%1
%define r%1d e%1
%define e%1d e%1
%define r%1w %1
@@ -191,6 +266,7 @@ DECLARE_REG_SIZE bp, bpl, null
%macro DECLARE_REG_TMP_SIZE 0-*
%rep %0
%define t%1q t%1 %+ q
+ IF ARCH_X86_64_X64, %define t%1p, t%1, t%1 %+ d
%define t%1d t%1 %+ d
%define t%1w t%1 %+ w
%define t%1h t%1 %+ h
@@ -207,6 +283,17 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%define gprsize 4
%endif
+IF ARCH_X86_64_X64, %define ptrsize, 8, 4
+IF ARCH_X86_64_X64, %define pword, qword, dword
+IF ARCH_X86_64_X64, %define dp, dq, dd
+IF ARCH_X86_64_X64, %define resp, resq, resd
+
+%if ARCH_X86_64_X32
+ %define preg(reg) reg %+ d
+%else
+ %define preg(reg) reg
+%endif
+
%macro PUSH 1
push %1
%ifidn rstk, rsp
@@ -242,7 +329,7 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%macro LOAD_IF_USED 1-*
%rep %0
%if %1 < num_args
- mov r%1, r %+ %1 %+ mp
+ mov r%1, r %+ %1 %+ mq
%endif
%rotate 1
%endrep
@@ -285,12 +372,18 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%assign %%i 0
%rep n_arg_names
CAT_UNDEF arg_name %+ %%i, q
+ CAT_UNDEF arg_name %+ %%i, p
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, mq
CAT_UNDEF arg_name %+ %%i, mp
+ CAT_UNDEF arg_name %+ %%i, md
+ CAT_UNDEF arg_name %+ %%i, mw
+ CAT_UNDEF arg_name %+ %%i, mh
+ CAT_UNDEF arg_name %+ %%i, mb
CAT_UNDEF arg_name, %%i
%assign %%i %%i+1
%endrep
@@ -301,12 +394,18 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
%assign %%i 0
%rep %0
%xdefine %1q r %+ %%i %+ q
+ %xdefine %1p r %+ %%i %+ p
%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 %1mq r %+ %%i %+ mq
%xdefine %1mp r %+ %%i %+ mp
+ %xdefine %1md r %+ %%i %+ md
+ %xdefine %1mw r %+ %%i %+ mw
+ %xdefine %1mh r %+ %%i %+ mh
+ %xdefine %1mb r %+ %%i %+ mb
CAT_XDEFINE arg_name, %%i, %1
%assign %%i %%i+1
%rotate 1
@@ -698,6 +797,883 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae,
SECTION .note.GNU-stack noalloc noexec nowrite progbits
%endif
+%macro CAT_XDEFINE 3
+ %xdefine %1%2 %3
+%endmacro
+
+%macro CAT_UNDEF 2
+ %undef %1%2
+%endmacro
+
+%macro CAT_ASSIGN 3
+ %assign %1%2 %3
+%endmacro
+
+; PARSEFUN:
+; Takes one string and parses it to determine return type, function name, argument types and names
+; and optionally addition constraints for arguments
+; The Syntax follows ordinary C style declarition, which can be copied verbatim from C sources.
+; Argument names must always be provided, the last cheracter is not considered part of the name,
+; but specifies to width of the argument as used within the asm code: q,p,d,w or b
+;
+; Additional constraints can be speicied for arguments as a comma separated list following
+; the function declartion.
+;
+; constraints:
+; arg_num load_type tests
+; all parts are optional.
+;
+; [num] constraint applies to argument num
+;
+; # - argument will not be moved into a register or possible sign/zero-extended on function entry
+; $ - argument is moved into register if passed on stack, but no zero/sign-extension if passed by register
+;
+; tests (any number, will be applied in order), code is inserted on function entry if DEBUG is true
+; >num - argument must be greater than num (signedness of comparision is taken from argument type)
+; >=num - argument must be greater than or equal to num (signedness of comparision is taken from argument type)
+; if if num is not negative or -1 for >, the algorithm for moving/extending arguments recognizes this and will
+; use zero extension instead of sign-extension
+; <num
+; <=num
+; &num - conjunction, result must be zero, e.g. &15 to test for 16byte alignment of a pointer
+; ~num - conjunction with ~num
+; !num - not equal
+;
+; REGISTERPARSETYPE
+; use to register additional type names
+; %1 type name (string)
+; %2 type specifier for X86_32
+; %3 type specifier for X86_64_X32
+; %4 type specifier for X86_64_X64
+; a type specifier is a string of 2 characters
+; one of q,p,d,w,b - argument width, p is special to be used for pointers (not pointer sized integers)
+; + or - signedness
+;
+; PROLOGUEX like PROLOGUE
+; argument names are taken from the previous invocation of PARSEFUN
+
+; cglobalx
+; %1 = function spec
+; %2 (opt) = function_name, if not given, the one from function spec is used
+; %2/%3 PROLOGUEX args
+
+; e.g.
+; cglobalx "void foo(int q, void* srcq, intptr_t strideq) \
+ [2] !0 &15", 4
+; declares a function (foo), taking three args (unnamed, src and stride) and one local variable
+; the pointer argument is to be 16-byte aligned and not zero
+
+%define cat(x0) x0
+%define cat(x0,x1) x0 %+ x1
+%define cat(x0,x1,x2) x0 %+ x1 %+ x2
+%define cat(x0,x1,x2,x3) x0 %+ x1 %+ x2 %+ x3
+%define cat(x0,x1,x2,x3,x4) x0 %+ x1 %+ x2 %+ x3 %+ x4
+%define cat(x0,x1,x2,x3,x4,x5) x0 %+ x1 %+ x2 %+ x3 %+ x4 %+ x5
+%define cat(x0,x1,x2,x3,x4,x5,x6) x0 %+ x1 %+ x2 %+ x3 %+ x4 %+ x5 %+ x6
+%define cat(x0,x1,x2,x3,x4,x5,x6,x7) x0 %+ x1 %+ x2 %+ x3 %+ x4 %+ x5 %+ x6 %+ x7
+%define cat(x0,x1,x2,x3,x4,x5,x6,x7,x8) x0 %+ x1 %+ x2 %+ x3 %+ x4 %+ x5 %+ x6 %+ x7 %+ x8
+%define cat(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9) x0 %+ x1 %+ x2 %+ x3 %+ x4 %+ x5 %+ x6 %+ x7 %+ x8 %+ x9
+
+%macro STRMATCH 3 ; str, #pos, substr
+ %strlen %%len %3
+ %assign %%pos %2
+ %assign %%pos2 1
+ %assign strmatch_ 1
+ %rep %%len
+ %substr %%x %1 %%pos
+ %substr %%y %3 %%pos2
+ %assign %%pos %%pos + 1
+ %assign %%pos2 %%pos2 + 1
+ %assign strmatch_pos %%pos
+ %if %%x != %%y
+ %assign strmatch_ 0
+ %assign strmatch_pos %2
+ %exitrep
+ %endif
+ %endrep
+%endmacro
+
+%macro SKIPWS 2-3 ; str, #pos #required
+ %strlen %%len %1
+ %assign %%pos %2
+ %if %0 != 2
+ %rep %3
+ %substr %%c %1 %%pos
+ %if %%c != ' ' && %%c != ''
+ %error SKIPWS - missing white space in %1 at pos %2 (%3 required)
+ %endif
+ %assign %%pos %%pos + 1
+ %endrep
+ %endif
+ %rep %%len
+ %substr %%c %1 %%pos
+ %if %%c == ' '
+ %assign %%pos %%pos + 1
+ %else
+ %exitrep
+ %endif
+ %endrep
+ %assign skipws_pos %%pos
+%endmacro
+
+%macro PARSEID_CAT 3-4 ; x, 'c', c
+ %if %1 == %2
+ %xdefine parseid_last_str %2
+ %ifnid parseid_last
+ %if %0 != 4
+ %assign parseid_cat_ 1
+ %endif
+ %else
+ %assign parseid_cat_ 1
+ %ifnid parseid_id
+ %xdefine parseid_id parseid_last
+ %else
+ %xdefine parseid_id cat( parseid_id, parseid_last )
+ %endif
+ %endif
+ %xdefine parseid_last %3
+ %endif
+%endmacro
+
+%macro PARSEID 2 ; str, #pos
+ %strlen %%len %1
+ %assign %%pos %2
+ %define parseid_ 0
+ %define parseid_id
+ %define parseid_last
+ %define parseid_last_str ''
+ %rep %%len
+ %substr %%c %1 %%pos
+ %assign parseid_cat_ 0
+ PARSEID_CAT %%c, '0', 0, x
+ PARSEID_CAT %%c, '1', 1, x
+ PARSEID_CAT %%c, '2', 2, x
+ PARSEID_CAT %%c, '3', 3, x
+ PARSEID_CAT %%c, '4', 4, x
+ PARSEID_CAT %%c, '5', 5, x
+ PARSEID_CAT %%c, '6', 6, x
+ PARSEID_CAT %%c, '7', 7, x
+ PARSEID_CAT %%c, '8', 8, x
+ PARSEID_CAT %%c, '9', 9, x
+ PARSEID_CAT %%c, 'A', A
+ PARSEID_CAT %%c, 'B', B
+ PARSEID_CAT %%c, 'C', C
+ PARSEID_CAT %%c, 'D', D
+ PARSEID_CAT %%c, 'E', E
+ PARSEID_CAT %%c, 'F', F
+ PARSEID_CAT %%c, 'G', G
+ PARSEID_CAT %%c, 'H', H
+ PARSEID_CAT %%c, 'I', I
+ PARSEID_CAT %%c, 'J', J
+ PARSEID_CAT %%c, 'K', K
+ PARSEID_CAT %%c, 'L', L
+ PARSEID_CAT %%c, 'M', M
+ PARSEID_CAT %%c, 'N', N
+ PARSEID_CAT %%c, 'O', O
+ PARSEID_CAT %%c, 'P', P
+ PARSEID_CAT %%c, 'Q', Q
+ PARSEID_CAT %%c, 'R', R
+ PARSEID_CAT %%c, 'S', S
+ PARSEID_CAT %%c, 'T', T
+ PARSEID_CAT %%c, 'U', U
+ PARSEID_CAT %%c, 'V', V
+ PARSEID_CAT %%c, 'W', W
+ PARSEID_CAT %%c, 'X', X
+ PARSEID_CAT %%c, 'Y', Y
+ PARSEID_CAT %%c, 'Z', Z
+ PARSEID_CAT %%c, 'a', a
+ PARSEID_CAT %%c, 'b', b
+ PARSEID_CAT %%c, 'c', c
+ PARSEID_CAT %%c, 'd', d
+ PARSEID_CAT %%c, 'e', e
+ PARSEID_CAT %%c, 'f', f
+ PARSEID_CAT %%c, 'g', g
+ PARSEID_CAT %%c, 'h', h
+ PARSEID_CAT %%c, 'i', i
+ PARSEID_CAT %%c, 'j', j
+ PARSEID_CAT %%c, 'k', k
+ PARSEID_CAT %%c, 'l', l
+ PARSEID_CAT %%c, 'm', m
+ PARSEID_CAT %%c, 'n', n
+ PARSEID_CAT %%c, 'o', o
+ PARSEID_CAT %%c, 'p', p
+ PARSEID_CAT %%c, 'q', q
+ PARSEID_CAT %%c, 'r', r
+ PARSEID_CAT %%c, 's', s
+ PARSEID_CAT %%c, 't', t
+ PARSEID_CAT %%c, 'u', u
+ PARSEID_CAT %%c, 'v', v
+ PARSEID_CAT %%c, 'w', w
+ PARSEID_CAT %%c, 'x', x
+ PARSEID_CAT %%c, 'y', y
+ PARSEID_CAT %%c, 'z', z
+ PARSEID_CAT %%c, '_', _
+ %if parseid_cat_
+ %assign %%pos %%pos + 1
+ %assign parseid_ 1
+ %else
+ %exitrep
+ %endif
+ %endrep
+ %assign parseid_pos %%pos
+%endmacro
+
+%macro PARSENUMBER_CAT 3
+ %if parsenumber_cat_ == 0 && %1 == %2
+ %assign parsenumber_cat_ 1
+ %if parsenumber_ == 0
+ %xdefine parsenumber_x %3
+ %else
+ %xdefine parsenumber_x parsenumber_x %+ %3
+ %endif
+ %endif
+%endmacro
+
+%macro PARSENUMBER 2 ; str, pos
+ %strlen %%len %1
+ %assign %%pos %2
+ %assign %%base 10
+ %assign %%sign 1
+ %substr %%c %1 %%pos
+ %if %%c == '-'
+ %assign %%sign -1
+ %assign %%pos %%pos + 1
+ %endif
+ %assign parsenumber_ 0
+ %assign parsenumber_num 0
+ %rep %%len
+ %substr %%c %1 %%pos
+ %assign %%pos %%pos + 1
+ %if %%c == '0' || %%c == '1' || %%c == '2' || %%c == '3' || %%c == '4' ||\
+ %%c == '5' || %%c == '6' || %%c == '7' || %%c == '8' || %%c == '9'
+ %assign parsenumber_ 1
+ %elif %%c == 'x'
+ %assign %%base 16
+ %elif %%base == 16 && ( %%c == 'a' || %%c == 'b' || %%c == 'c' || %%c == 'd' || %%c == 'e'|| %%c == 'f' )
+ %assign parsenumber_ 1
+ %elif %%c == 'b' && %%base == 10
+ %assign %%base 2
+ %exitrep
+ %elif %%c == 'h' && %%base == 10
+ %assign %%base 16
+ %exitrep
+ %else
+ %exitrep
+ %endif
+ %endrep
+ %if parsenumber_
+ %if %%sign == 1
+ %assign %%pos %2
+ %else
+ %assign %%pos %2 + 1
+ %endif
+ %rep %%len
+ %substr %%c %1 %%pos
+ %assign %%pos %%pos + 1
+ %if %%c == '0'
+ %assign parsenumber_num parsenumber_num * %%base
+ %elif %%c == '1'
+ %assign parsenumber_num parsenumber_num * %%base + 1
+ %elif %%c == '2' && %%base > 2
+ %assign parsenumber_num parsenumber_num * %%base + 2
+ %elif %%c == '3' && %%base > 3
+ %assign parsenumber_num parsenumber_num * %%base + 3
+ %elif %%c == '4' && %%base > 4
+ %assign parsenumber_num parsenumber_num * %%base + 4
+ %elif %%c == '5' && %%base > 5
+ %assign parsenumber_num parsenumber_num * %%base + 5
+ %elif %%c == '6' && %%base > 6
+ %assign parsenumber_num parsenumber_num * %%base + 6
+ %elif %%c == '7' && %%base > 7
+ %assign parsenumber_num parsenumber_num * %%base + 7
+ %elif %%c == '8' && %%base > 8
+ %assign parsenumber_num parsenumber_num * %%base + 8
+ %elif %%c == '9' && %%base > 9
+ %assign parsenumber_num parsenumber_num * %%base + 9
+ %elif %%c == 'a' && %%base > 10
+ %assign parsenumber_num parsenumber_num * %%base + 10
+ %elif %%c == 'b' && %%base > 11
+ %assign parsenumber_num parsenumber_num * %%base + 11
+ %elif %%c == 'c' && %%base > 12
+ %assign parsenumber_num parsenumber_num * %%base + 12
+ %elif %%c == 'd' && %%base > 13
+ %assign parsenumber_num parsenumber_num * %%base + 13
+ %elif %%c == 'e' && %%base > 14
+ %assign parsenumber_num parsenumber_num * %%base + 14
+ %elif %%c == 'f' && %%base > 15
+ %assign parsenumber_num parsenumber_num * %%base + 15
+ %elif %%c == 'x'
+ %else
+ %exitrep
+ %endif
+ %endrep
+ %assign parsenumber_num parsenumber_num * %%sign
+ %assign parsenumber_pos %%pos - 1
+ %else
+ %assign parsenumber_pos %2
+ %endif
+%endmacro
+
+%macro PARSETYPE_INTERNAL 6 ; str, #pos, id, x86_32, x86_64_x32, x86_64_x64
+ %if parsetype_internal_ == 0
+ %xdefine %%str %1
+ SKIPWS %1, %2
+ STRMATCH %1, skipws_pos, %3
+ %assign parsetype_pos strmatch_pos
+ %if strmatch_ && parsetype_internal_ == 0
+ %if ARCH_X86_64
+ %rotate 1
+ %endif
+ %if ARCH_X86_64_X64
+ %rotate 1
+ %endif
+ %ifstr %4
+ %define parsetype_type %4
+ %endif
+ %substr %%c %%str parsetype_pos
+ %if %%c == '*' || %%c == ' '
+ %assign parsetype_internal_ 1
+ %endif
+ %if %%c == ' '
+ %assign parsetype_pos parsetype_pos + 1
+ %endif
+ %endif
+ %endif
+ %if parsetype_internal_ == 0
+ %assign parsetype_pos strmatch_pos
+ %endif
+%endmacro
+
+%assign num_parsetypes 0
+%macro REGISTERPARSETYPE 4
+ CAT_XDEFINE parsetype %+ num_parsetypes, _str, %1
+ CAT_XDEFINE parsetype %+ num_parsetypes, _x86_32, %2
+ CAT_XDEFINE parsetype %+ num_parsetypes, _x86_64_x32, %3
+ CAT_XDEFINE parsetype %+ num_parsetypes, _x86_64_x64, %4
+ %assign num_parsetypes num_parsetypes + 1
+%endmacro
+
+%macro PARSETYPE 2 ; str, pos
+ %strlen %%len %1
+ %assign parsetype_pos %2
+ %assign parsetype_ 0
+ %rep %%len
+ %assign parsetype_internal_ 0
+ %assign %%i 0
+ %rep num_parsetypes
+ PARSETYPE_INTERNAL %1, parsetype_pos, parsetype %+ %%i %+ _str, \
+ parsetype %+ %%i %+ _x86_32, \
+ parsetype %+ %%i %+ _x86_64_x32, \
+ parsetype %+ %%i %+ _x86_64_x64
+ %assign %%i %%i + 1
+ %endrep
+ %if parsetype_internal_
+ %assign parsetype_ 1
+ %else
+ %exitrep
+ %endif
+ %endrep
+%endmacro
+
+%macro PARSEFUN 1 ; str
+ UNDEF_FUN
+; 1. return type
+ PARSETYPE %1, 1 ; ret type
+ %if parsetype_ == 0
+ %error parsing %1 - return type
+ %endif
+ %xdefine ret_type parsetype_type
+; 2. funtion name
+ PARSEID %1, parsetype_pos
+ %if parseid_ == 0
+ %error parsing %1 - function name
+ %endif
+ %xdefine fun_name parseid_id %+ parseid_last
+; 3. (
+ SKIPWS %1, parseid_pos
+ %substr %%c %1 skipws_pos
+ %if %%c != '('
+ %error parsing %1 - missing argument list at skipws_pos
+ %endif
+; 4. argument list
+ %assign %%pos skipws_pos + 1
+ %strlen %%len %1
+ %assign %%arg 0
+ %rep %%len
+; 4.1 type
+ PARSETYPE %1, %%pos
+ %if parsetype_
+ CAT_XDEFINE arg %+ %%arg, _type, parsetype_type
+; 4.2 id
+ PARSEID %1, parsetype_pos
+ %if parseid_ == 0 ; we need at least 1 letter to determine argument size to load
+ %error parsing %1 - argument # %%arg name
+ %endif
+ CAT_XDEFINE arg %+ %%arg, _id, parseid_id
+ CAT_XDEFINE arg %+ %%arg, _last, parseid_last
+ CAT_XDEFINE arg %+ %%arg, _last_str, parseid_last_str
+ CAT_ASSIGN arg %+ %%arg, _load_type, 0
+ CAT_ASSIGN arg %+ %%arg, _num_specifiers, 0
+ SKIPWS %1, parseid_pos
+ %substr %%c %1 skipws_pos
+ %assign %%pos skipws_pos
+ %if %%c == ','
+ %assign %%arg %%arg + 1
+ %assign %%pos %%pos + 1
+ %elif %%c != ')'
+ %error parsing %1 - argument # %%arg trailing characters
+ %endif
+ %else
+ %substr %%c %1 parsetype_pos
+ %if %%c == ')'
+ %exitrep
+ %else
+ %error parsing %1 - argument # %%arg type
+ %endif
+ %endif
+ %endrep
+ %assign num_args %%arg + 1
+; 5 add. specifiers
+ %assign %%pos %%pos + 1 ; skip past ')'
+ %assign %%cur_arg 0
+ %rep %%len
+ %assign %%cur_specifier 0
+ %rep %%len
+ SKIPWS %1, %%pos
+ %assign %%pos skipws_pos
+ %substr %%c %1 %%pos
+ %if %%c == '' || %%c == ','
+ %assign %%pos %%pos + 1
+ %exitrep
+ %elif %%c == '['
+ PARSENUMBER %1, %%pos + 1
+ %if parsenumber_
+ %assign %%cur_arg parsenumber_num
+ %endif
+ %assign %%pos parsenumber_pos
+ %substr %%c %1 %%pos
+ %if %%c != ']'
+ %error parse %1 specifiers: [argnum]
+ %endif
+ SKIPWS %1, %%pos + 1
+ %assign %%pos skipws_pos
+ %elif %%c == '$'
+ CAT_ASSIGN arg %+ %%cur_arg, _load_type, 1
+ SKIPWS %1, %%pos + 1, 1
+ %assign %%pos skipws_pos
+ %elif %%c == '#'
+ CAT_ASSIGN arg %+ %%cur_arg, _load_type, 2
+ SKIPWS %1, %%pos + 1, 1
+ %assign %%pos skipws_pos
+ %elif %%c == '<' || %%c == '>' || %%c == '&' || %%c == '~' || %%c == '!'
+ %substr %%d %1 %%pos + 1
+ %if %%d == '=' && ( %%c == '<' || %%c == '>' )
+ %if %%c == '<'
+ CAT_XDEFINE arg %+ %%cur_arg %+ _specifier %+ %%cur_specifier, _type, '<='
+ %else
+ CAT_XDEFINE arg %+ %%cur_arg %+ _specifier %+ %%cur_specifier, _type, '>='
+ %endif
+ %assign %%pos %%pos + 2
+ %else
+ CAT_XDEFINE arg %+ %%cur_arg %+ _specifier %+ %%cur_specifier, _type, %%c
+ %assign %%pos %%pos + 1
+ %endif
+ PARSENUMBER %1, %%pos
+ %if parsenumber_ == 0
+ %error parse %1 specifiers num
+ %endif
+ CAT_ASSIGN arg %+ %%cur_arg %+ _specifier %+ %%cur_specifier, _value, parsenumber_num
+ %assign %%cur_specifier %%cur_specifier + 1
+ CAT_ASSIGN arg %+ %%cur_arg, _num_specifiers, %%cur_specifier
+ %assign %%pos parsenumber_pos
+ %if ( %%c == '>' && parsenumber_num >= -1 ) || ( %%c == '>' && %%d == 'd' && parsenumber_num >= 0 )
+ ; treat argument as unsigned if it can't be negative
+ %strlen %%f cat( arg, %%cur_arg, _type )
+ %substr %%g cat( arg, %%cur_arg, _type ) 2
+ %if %%f == 2 && %%g == '-'
+ %substr %%e cat( arg, %%cur_arg, _type ) 1
+ %if %%e == 'b'
+ CAT_XDEFINE arg %+ %%cur_arg, _type, "b+-"
+ %elif %%e == 'w'
+ CAT_XDEFINE arg %+ %%cur_arg, _type, "w+-"
+ %elif %%e == 'd'
+ CAT_XDEFINE arg %+ %%cur_arg, _type, "d+-"
+ %elif %%e == 'p'
+ CAT_XDEFINE arg %+ %%cur_arg, _type, "p+-"
+ %elif %%e == 'q'
+ CAT_XDEFINE arg %+ %%cur_arg, _type, "q+-"
+ %endif
+ %endif
+ %endif
+ %else
+ %error parse %1 specifiers type
+ %endif
+ %endrep
+ %if %%c == ''
+ %exitrep
+ %else
+ %assign %%cur_arg %%cur_arg + 1
+ %endif
+ %endrep
+%endmacro
+
+%macro UNDEF_FUN 0
+ %ifdef ret_type
+ %undef ret_type
+ %undef fun_name
+ %assign %%i 0
+ %rep num_args
+ %xdefine %%name arg %+ %%i %+ _id
+ UNDEF_REG_ALIAS %%name
+ %assign %%j 0
+ %rep arg %+ %%i %+ _num_specifiers
+ CAT_UNDEF arg %+ %%i %+ _specifier %+ %%j, _type
+ CAT_UNDEF arg %+ %%i %+ _specifier %+ %%j, _value
+ %assign %%j %%j + 1
+ %endrep
+ CAT_UNDEF arg %+ %%i, _type
+ CAT_UNDEF arg %+ %%i, _load_type
+ CAT_UNDEF arg %+ %%i, _id
+ CAT_UNDEF arg %+ %%i, _last
+ CAT_UNDEF arg %+ %%i, _last_str
+ CAT_UNDEF arg %+ %%i, _num_specifiers
+ %assign %%i %%i+1
+ %endrep
+ %endif
+%endmacro
+
+%macro SUFFIX_FROM_STR 1
+ %if %1 == 'b'
+ %xdefine suffix_from_str_ b
+ %assign suffix_size 1
+ %elif %1 == 'w'
+ %xdefine suffix_from_str_ w
+ %assign suffix_size 2
+ %elif %1 == 'd'
+ %xdefine suffix_from_str_ d
+ %assign suffix_size 4
+ %elif %1 == 'p'
+ %xdefine suffix_from_str_ p
+ %assign suffix_size ptrsize
+ %elif %1 == 'q'
+ %xdefine suffix_from_str_ q
+ %assign suffix_size gprsize
+ %else
+ %error
+ %endif
+%endmacro
+
+%macro LOADX_IF_USED 1-*
+ %rep %0
+ %if %1 < num_args
+ %assign %%load_type cat( arg, %1, _load_type )
+ %if %%load_type == 2 ; deferred
+ %elifnidn cat( r, %1, q ), cat( r, %1, mq )
+ %assign %%load_type 0
+ %endif
+ %if %%load_type == 0
+ %if ARCH_X86_32
+ mov cat( r, %1 ), cat( r, %1, mq )
+ %else
+ %xdefine %%type cat( arg, %1, _type )
+ %xdefine %%id cat( arg, %1, _id )
+ %xdefine %%a cat( arg, %1, _last_str )
+ %substr %%x %%type 1
+ %substr %%y %%type 2
+ %if %%a == 'p'
+ %if ARCH_X86_64_X64
+ %xdefine %%a 'q'
+ %else
+ %xdefine %%a 'd'
+ %endif
+ %endif
+ SUFFIX_FROM_STR %%a
+ %xdefine %%aa suffix_from_str_
+ %assign %%asize suffix_size
+ SUFFIX_FROM_STR %%x
+ %xdefine %%xx cat( m, suffix_from_str_ )
+ %assign %%xsize suffix_size
+ %if %%asize <= %%xsize
+ %ifnidn cat(r, %1, q), cat(r, %1, mq)
+ mov cat(r, %1, %%aa), cat(r, %1, %%aa)
+ %endif
+ %elif %%x == 'p' && %%a == 'q'
+; special provision by x32 abi: if a pointer argument is passed in a register, upper 32 bits are zero
+ %ifnidn cat(r, %1, q), cat(r, %1, mq)
+ mov cat(r, %1, p), cat(r, %1, mp)
+ %endif
+ %elif %%y == '-'
+ %if %%a == 'q' && %%x == 'd'
+ movsxd cat(r, %1, %%aa), cat(r, %1, %%xx)
+ %else
+ movsx cat(r, %1, %%aa), cat(r, %1, %%xx)
+ %endif
+ %else
+ %if %%a == 'q'
+ %xdefine %%a 'd'
+ %endif
+ SUFFIX_FROM_STR %%a
+ %xdefine %%aa suffix_from_str_
+ STRMATCH %%a, 1, %%x
+ %if strmatch_
+ mov cat(r, %1, %%aa), cat(r, %1, %%xx)
+ %else
+ movzx cat(r, %1, %%aa), cat(r, %1, %%xx)
+ %endif
+ %endif
+ %endif
+ %endif
+ %endif
+ %rotate 1
+ %endrep
+%endmacro
+
+%macro DEFINE_REG_ALIAS 2 ; name, #reg
+ %ifid %1
+ CAT_XDEFINE %1, q, cat( r, %2, q )
+ CAT_XDEFINE %1, p, cat( r, %2, p )
+ CAT_XDEFINE %1, d, cat( r, %2, d )
+ CAT_XDEFINE %1, w, cat( r, %2, w )
+ CAT_XDEFINE %1, h, cat( r, %2, h )
+ CAT_XDEFINE %1, b, cat( r, %2, b )
+ CAT_XDEFINE %1, m, cat( r, %2, m )
+ CAT_XDEFINE %1, mq, cat( r, %2, mq )
+ CAT_XDEFINE %1, mp, cat( r, %2, mp )
+ CAT_XDEFINE %1, md, cat( r, %2, md )
+ CAT_XDEFINE %1, mw, cat( r, %2, mw )
+ CAT_XDEFINE %1, mh, cat( r, %2, mh )
+ CAT_XDEFINE %1, mb, cat( r, %2, mb )
+ %endif
+%endmacro
+
+%macro UNDEF_REG_ALIAS 1 ; name
+ %ifid %1
+ CAT_UNDEF %1, q
+ CAT_UNDEF %1, p
+ CAT_UNDEF %1, d
+ CAT_UNDEF %1, w
+ CAT_UNDEF %1, h
+ CAT_UNDEF %1, b
+ CAT_UNDEF %1, m
+ CAT_UNDEF %1, mq
+ CAT_UNDEF %1, mp
+ CAT_UNDEF %1, md
+ CAT_UNDEF %1, mw
+ CAT_UNDEF %1, mh
+ CAT_UNDEF %1, mb
+ %endif
+%endmacro
+
+%macro DEFINE_ARGSX 0
+ %assign %%i 0
+ %rep num_args
+ %xdefine %%name arg %+ %%i %+ _id
+ DEFINE_REG_ALIAS %%name, %%i
+ %assign %%i %%i+1
+ %endrep
+%endmacro
+
+%macro TEST_ARGS 0
+ %if DEBUG
+ %assign %%i 0
+ %assign %%l 0
+ %rep num_args
+ %substr %%c arg %+ %%i %+ _type 1
+ SUFFIX_FROM_STR %%c
+ %assign %%j 0
+ %assign %%k arg %+ %%i %+ _num_specifiers
+ %rep %%k
+ %xdefine %%type arg %+ %%i %+ _specifier %+ %%j %+ _type
+ %xdefine %%value arg %+ %%i %+ _specifier %+ %%j %+ _value
+ %strlen %%len %%type
+ %substr %%d arg %+ %%i %+ _type 2
+ %substr %%e arg %+ %%i %+ _type 3
+ %substr %%g %%type 1
+ %if %%e == '-'
+ %xdefine %%d '-'
+ %endif
+ SECTION_RODATA
+cat( %%val_, %%l ):
+ %if %%g != '~'
+ cat( d, suffix_from_str_ ) %%value
+ %else
+ cat( d, suffix_from_str_ ) ~ %%value
+ %endif
+ __SECT__
+ STRMATCH %%type, 1, '>='
+ %if strmatch_ && %%len == 2
+ cmp cat( r, %%i, suffix_from_str_ ), cat( %%val_, %%l )
+ %if %%d == '-'
+ jge cat( %%ok_, %%l )
+ %else
+ jae cat( %%ok_, %%l )
+ %endif
+ mov dword [0], %%l
+ %endif
+ STRMATCH %%type, 1, '<='
+ %if strmatch_ && %%len == 2
+ cmp cat( r, %%i, suffix_from_str_ ), cat( %%val_, %%l )
+ %if %%d == '-'
+ jle cat( %%ok_, %%l )
+ %else
+ jbe cat( %%ok_, %%l )
+ %endif
+ mov dword [0], %%l
+ %endif
+ STRMATCH %%type, 1, '>'
+ %if strmatch_ && %%len == 1
+ cmp cat( r, %%i, suffix_from_str_ ), cat( %%val_, %%l )
+ %if %%d == '-'
+ jg cat( %%ok_, %%l )
+ %else
+ ja cat( %%ok_, %%l )
+ %endif
+ mov dword [0], %%l
+ %endif
+ STRMATCH %%type, 1, '<'
+ %if strmatch_ && %%len == 1
+ cmp cat( r, %%i, suffix_from_str_ ), cat( %%val_, %%l )
+ %if %%d == '-'
+ jl cat( %%ok_, %%l )
+ %else
+ jb cat( %%ok_, %%l )
+ %endif
+ mov dword [0], %%l
+ %endif
+ STRMATCH %%type, 1, '&'
+ %if strmatch_ && %%len == 1
+ test cat( r, %%i, suffix_from_str_ ), cat( %%val_, %%l )
+ jz cat( %%ok_, %%l )
+ mov dword [0], %%l
+ %endif
+ STRMATCH %%type, 1, '~'
+ %if strmatch_ && %%len == 1
+ test cat( r, %%i, suffix_from_str_ ), cat( %%val_, %%l )
+ jz cat( %%ok_, %%l )
+ mov dword [0], %%l
+ %endif
+ STRMATCH %%type, 1, '!'
+ %if strmatch_ && %%len == 1
+ cmp cat( r, %%i, suffix_from_str_ ), cat( %%val_, %%l )
+ jne cat( %%ok_, %%l )
+ mov dword [0], %%l
+ %endif
+cat( %%ok_, %%l ):
+ %assign %%j %%j + 1
+ %assign %%l %%l + 1
+ %endrep
+ %assign %%i %%i + 1
+ %endrep
+ %endif
+%endmacro
+
+%if WIN64 ; Windows x64 ;=================================================
+
+%macro PROLOGUEX 1-4+ 0 ; #regs, #xmm_regs, [stack_size,]
+ %assign regs_used %1
+ ASSERT regs_used >= num_args
+ TEST_ARGS
+ SETUP_STACK_POINTER %3
+ ASSERT regs_used <= 15
+ PUSH_IF_USED 7, 8, 9, 10, 11, 12, 13, 14
+ ALLOC_STACK %3, %2
+ %if mmsize != 8 && stack_size == 0
+ WIN64_SPILL_XMM %2
+ %endif
+ LOADX_IF_USED 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
+ DEFINE_ARGSX
+%endmacro
+
+%elif ARCH_X86_64 ; *nix x64 ;=============================================
+
+%macro PROLOGUEX 1-4+ ; #regs, #xmm_regs, [stack_size,]
+ %assign regs_used %1
+ ASSERT regs_used >= num_args
+ TEST_ARGS
+ SETUP_STACK_POINTER %3
+ ASSERT regs_used <= 15
+ PUSH_IF_USED 9, 10, 11, 12, 13, 14
+ ALLOC_STACK %3
+ LOADX_IF_USED 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
+ DEFINE_ARGSX
+%endmacro
+
+%else ; X86_32 ;==============================================================
+
+%macro PROLOGUEX 1-4+ ; #regs, #xmm_regs, [stack_size,]
+ %assign regs_used %1
+ ASSERT regs_used >= num_args
+ %if num_args > 7
+ %assign num_args 7
+ %endif
+ %if regs_used > 7
+ %assign regs_used 7
+ %endif
+ TEST_ARGS
+ SETUP_STACK_POINTER %3
+ ASSERT regs_used <= 7
+ PUSH_IF_USED 3, 4, 5, 6
+ ALLOC_STACK %3
+ LOADX_IF_USED 0, 1, 2, 3, 4, 5, 6
+ DEFINE_ARGSX
+%endmacro
+
+%endif
+
+%macro cglobalx 1-2+ ; fun, [PROLOGUE args]
+ PARSEFUN %1
+ %if %0 == 1
+ cglobal fun_name
+ %else
+ %rotate 1
+ %ifnnum %1
+ cglobal %1
+ PROLOGUEX %2
+ %else
+ cglobal fun_name
+ %if %0 == 2
+ PROLOGUEX %1
+ %else
+ PROLOGUEX %1, %2
+ %endif
+ %endif
+ %endif
+%endmacro
+
+; standard types
+
+REGISTERPARSETYPE "unsigned long long", x, "q+", "q+"
+REGISTERPARSETYPE "unsigned short", "w+", "w+", "w+"
+REGISTERPARSETYPE "unsigned char", "b+", "b+", "b+"
+REGISTERPARSETYPE "unsigned", "d+", "d+", "d+"
+REGISTERPARSETYPE "long long", x, "q-", "q-"
+%if WIN64
+REGISTERPARSETYPE "unsigned long", "d+", "d+", "d+"
+REGISTERPARSETYPE "long", "d-", "d-", "d-"
+%else
+REGISTERPARSETYPE "unsigned long", "d+", "d+", "q+"
+REGISTERPARSETYPE "long", "d-", "d-", "q-"
+%endif
+REGISTERPARSETYPE "intptr_t", "d-", "d-", "q-"
+REGISTERPARSETYPE "uintptr_t", "d+", "d+", "q+"
+REGISTERPARSETYPE "ptrdiff_t", "d-", "d-", "q-"
+REGISTERPARSETYPE "size_t", "d+", "d+", "q+"
+REGISTERPARSETYPE "int64_t", x, "q-", "q-"
+REGISTERPARSETYPE "int32_t", "d-", "d-", "d-"
+REGISTERPARSETYPE "int16_t", "w-", "w-", "w-"
+REGISTERPARSETYPE "int8_t", "b-", "b-", "b-"
+REGISTERPARSETYPE "uint64_t", x, "q+", "q+"
+REGISTERPARSETYPE "uint32_t", "d+", "d+", "d+"
+REGISTERPARSETYPE "uint16_t", "w+", "w+", "w+"
+REGISTERPARSETYPE "uint8_t", "b+", "b+", "b+"
+REGISTERPARSETYPE "int", "d-", "d-", "d-"
+REGISTERPARSETYPE "short", "w-", "w-", "w-"
+REGISTERPARSETYPE "char", "b-", "b-", "b-"
+REGISTERPARSETYPE "*", "d+", "p+", "q+"
+REGISTERPARSETYPE "void", x, x, x
+REGISTERPARSETYPE "const", x, x, x
+REGISTERPARSETYPE "volatile", x, x, x
+
; cpuflags
%assign cpuflags_mmx (1<<0)
@@ -765,14 +1741,6 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
; merge mmx and sse*
-%macro CAT_XDEFINE 3
- %xdefine %1%2 %3
-%endmacro
-
-%macro CAT_UNDEF 2
- %undef %1%2
-%endmacro
-
%macro INIT_MMX 0-1+
%assign avx_enabled 0
%define RESET_MM_PERMUTATION INIT_MMX %1
--
1.8.1.2
More information about the x264-devel
mailing list