[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