Author Topic: Preprocessor question  (Read 7760 times)

Offline shaynox

  • Full Member
  • **
  • Posts: 118
  • Country: gr
Preprocessor question
« on: June 09, 2015, 11:45:35 AM »
Would it be possible to named macro with any character like (+ * / - : , < > ... )* in future, access to char into parameter (%1 %2 ..) for cmp, instead entire word comparison**.

*: it's for translate unprintable ascii with C stuff for example:
Code: [Select]
\\          Literal backslash
\"          Double quote
\'          Single quote
\n          Newline (line feed)
\r          Carriage return
\b          Backspace
\t          Horizontal tab
\f          Form feed
\a          Alert (bell)
\v          Vertical tab
\?          Question mark (used to escape trigraphs)
%%          Percentage mark, printf format strings only (Note \% is non standard and is not always recognised)
\ooo        Character with octal value ooo
\xhh        Character with hexadecimal value hh

and why not generate equation (2 * 3 + [rax] ...) directly/faster in asm code instead use compiler for it, design for complexes calculus.


**: it's for those macro, and I would like to detect if param is a reg/mem/string/label/nbr for doing a monster optimization, cause in that case, I will able to delete some useless mov uses for param passing when it's a label:
Code: [Select]
        ;=============================================================================================.
        ; call_win (call function with Windows ABI x64)
        ;           https://msdn.microsoft.com/en-us/library/ms235286.aspx
        ; %0 = number of parameters received
        ; %1 = call_win.1st parameter
        ; %2 =     func.1st parameter
        ;=============================================================================================.
        %macro      call_win     1-*
       ;{
                    %assign     i  0                                    ; For shrink stack by n bytes

                    sub     rsp, 40
                   ;{
                        %if  (%0 >= 2)                                  ; func.1st
                       ;{
                            %ifidni     %2,                             ; if (string)
                           ;{
                                [section .data]
                                        %%str1:      db  %2, 0
                                [section .code]

                                mov     rcx,  %%str1
                           ;}
                            %else                                       ; else (reg/mem/string/label/nbr)
                                mov     rcx, %6
                            %endif
                       ;}
                        %endif

                        %if  (%0 >= 3)                                  ; func.2nd
                       ;{
                            %ifidni     %3,                             ; if (string)
                           ;{
                                [section .data]
                                        %%str2:      db  %3, 0
                                [section .code]

                                mov     rdx,  %%str2
                           ;}
                            %else                                       ; else (reg/mem/string/label/nbr)
                                mov     rdx, %6
                            %endif
                       ;}
                        %endif

                        %if  (%0 >= 4)                                  ; func.3rd
                       ;{
                            %ifidni     %4,                             ; if (string)
                           ;{
                                [section .data]
                                        %%str3:     db  %4, 0
                                [section .code]

                                mov     r8,  %%str3
                           ;}
                            %else                                       ; else (reg/mem/string/label/nbr)
                                mov     r8, %6
                            %endif
                       ;}
                        %endif

                        %if  (%0 >= 5)                                  ; func.4th
                       ;{
                            %ifidni     %5,                             ; if (string)
                           ;{
                                [section .data]
                                        %%str4:      db  %5, 0
                                [section .code]

                                mov     r9,  %%str4
                           ;}
                            %else                                       ; else (reg/mem/string/label/nbr)
                                mov     r9, %6
                            %endif
                       ;}
                        %endif

                        %if  (%0 >= 6)                                              ; func.5th
                       ;{
                            sub     rsp, ((%0 - 4 - 1) * 8)                         ; ((nbr_param - 4(param_nostack) - 1(func's name)) * 8(byte))

                            %rep (%0 - 4 - 1)                                       ; Repeat block of code until all element are store in stack
                           ;{
                                %ifidni     %6,                                     ; if (reg)
                                    mov     [rsp + (40 + (8 * i))], %6
                                %elifidni   %6,                                     ; if (mem)
                               ;{
                                    mov     rax, %6
                                    mov     [rsp + (40 + (8 * i))], rax
                               ;}
                                %elifidni     %6,                                   ; if (string)
                               ;{
                                    [section .data]
                                            %%str5:      db  %6, 0
                                    [section .code]

                                    mov     [rsp + (40 + (8 * i))], i64 %%str5
                               ;}
                                %else                                               ; else (label/nbr)
                                    mov     [rsp + (40 + (8 * i))], i64 %6
                                %endif

                                %assign i (i + 1)                                  ; Next element of stack: 8 byte

                                %rotate  1                                          ; Rotate element right to left for scanning all element parsing in macro.
                           ;}
                            %endrep

                            %rotate  1                                              ; Return to first param
                       ;}
                        %endif

                        call    %1
                   ;}
                    add     rsp, 40

                    %if  (%0 >= 6)                                                  ; func.5th
                        add      rsp, ((%0 - 4) * 8)
                    %endif
       ;}
        %endmacro
        ;=============================================================================================.
        ; / call_win
        ;=============================================================================================.

*:
Code: [Select]
        %macro      memclr      2
       ;{
            ;==============================================================================================================.
            ; Name    : memclr (ptr dest, ptr limit)                                                                       |
            ; Purpose : Clear all buffer's content untill reach pointer's limit.                                           |
            ; Input   : dest - limit                                                                                       |
            ; Output  : [dest]                                                                                             |
            ; Destoy  : None                                                                                               |
            ; Data    : Stack                                                                                              |
            ; Define  :                                                                                                    |
                        %define    STACK_PARAM      (2 * E64)                                   ; dest/limit               |
                        %define    STACK_REG        (2 * E64) + (1 * E8) + (1 * E256)           ; rdi/rcx + al + ymm0      |
                        %define    STACK_SIZE       (STACK_PARAM + STACK_REG)                                             ;|
            ;                                                                                                             ;|
                        %define    DEST             (rsp - STACK_SIZE) + (E64 * 0)                                        ;|
                        %define    LIMIT            (rsp - STACK_SIZE) + (E64 * 1)                                        ;|
            ;                                                                                                             ;|
                        %define    REG1             (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 0)                          ;|
                        %define    REG2             (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 1)                          ;|
                        %define    REG3             (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 2) + (E8 * 0)               ;|
                        %define    REG4             (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 2) + (E8 * 1) + (E256 * 0)  ;|
            ;==============================================================================================================.
           ;{
                ; Store function's reg in stack
                    mov         [REG1], rdi
                    mov         [REG2], rcx
                    mov         [REG3], al
                    vmovups     [REG4], ymm0

                ; Store function's param in stack
                    m2m         [DEST ], %1, rdi
                    m2m         [LIMIT], %2, rdi

                ; Store function's param in function's reg
                    mov         rdi, [DEST]
                    mov         rcx, [LIMIT]
                    vxorpd      ymm0, ymm0, ymm0        ; For white screen
                    ; vpxor       ymm0, ymm0, ymm0        ; Need avx2
                    ; vmovups     ymm0, [ps_infinit]      ; For the fun, look like freak game due to "random" color equal to texture

                ; Function's core
                    %push   memclr
                    %ifctx  memclr
                   ;{
                        sub     rcx, E256 - 1       ; For data corrupt protect due to avx padding.
                       ;{
                            %$1:
                           ;{
                                vmovups     [rdi], ymm0

                                add     rdi, E256
                           ;}
                            jif  rdi ,<=, rcx, %$1
                       ;}
                        add     rcx, E256 - 1        ; Restore origin address

                        ; Do 1 byte move loop, for fill end memory
                            dec     rdi         ; for avoid to do if(rdi <= rcx) before stosb
                            xor     al, al

                            %$2:
                           ;{
                                stosb           ; [rdi++] = al
                           ;}
                            jif  rdi ,<=, rcx, %$2
                   ;}
                    %endif

                ; Retore function's reg
                    mov         rdi , [REG1]
                    mov         rcx , [REG2]
                    mov         al  , [REG3]
                    vmovups     ymm0, [REG4]
           ;}
            ;===================================================================================================.
            ; / memclr                                                                                          |
            ;===================================================================================================.
       ;}
        %endmacro


Code: [Select]
        %macro      memcpy      3
       ;{
            ;===================================================================================================.
            ; Name    : memcpy (ptr dest, ptr src, ptr limit)                                                   |
            ; Purpose : Copy content of src into dest, while limit isn't reach.                                  |
            ; Input   : dest - src - limit                                                                      |
            ; Output  : [dest]                                                                                  |
            ; Destoy  : None                                                                                    |
            ; Data    : Stack                                                                                   |
                        %define     STACK_PARAM     (3 * E64)                       ; dest/src/limit            |
                        %define     STACK_REG       (3 * E64) + (1 * E256)          ; rdi/rsi/rcx + ymm0        |
                        %define     STACK_SIZE      (STACK_PARAM + STACK_REG)                                  ;|
            ;                                                                                                  ;|
                        %define     DEST            (rsp - STACK_SIZE) + (E64 * 0)                             ;|
                        %define     SRC             (rsp - STACK_SIZE) + (E64 * 1)                             ;|
                        %define     LIMIT           (rsp - STACK_SIZE) + (E64 * 2)                             ;|
            ;                                                                                                  ;|
                        %define     REG1            (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 0)               ;|
                        %define     REG2            (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 1)               ;|
                        %define     REG3            (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 2)               ;|
                        %define     REG4            (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 3) + (E256 * 0)  ;|
            ;===================================================================================================.
           ;{
                ; Store function's reg in stack
                    mov         [REG1], rdi
                    mov         [REG2], rsi
                    mov         [REG3], rcx
                    vmovups     [REG4], ymm0

                ; Store function's param in stack
                    m2m         [DEST ], %1, rdi
                    m2m         [SRC  ], %2, rdi
                    m2m         [LIMIT], %3, rdi

                ; Store function's param in function's reg
                    mov         rdi, [DEST ]
                    mov         rsi, [SRC  ]
                    mov         rcx, [LIMIT]

                ; Function's core
                    %push   memcpy
                    %ifctx  memcpy
                   ;{
                        sub     rcx, E256 - 1       ; For data corrupt protect due to avx padding.
                       ;{
                            %$l:
                           ;{
                                vmovups     ymm0, [rsi]
                                vmovups     [rdi], ymm0

                                add     rdi, E256
                                add     rsi, E256
                           ;}
                            jif  rsi ,<=, rcx, %$l
                       ;}
                        add     rcx, E256 - 1       ; Restore origin address

                        ; Do 1 byte move loop, for fill end memory
                            dec     rdi         ; for avoid to do if(rdi <= rcx) before stosb
                            dec     rsi         ; ...

                            %$2:
                           ;{
                                movsb           ; [rdi++] = [rsi++]
                           ;}
                            jif  rsi ,<=, rcx, %$2
                   ;}
                    %endif

                ; Retore function's reg from stack
                    mov         rdi , [REG1]
                    mov         rsi , [REG2]
                    mov         rcx , [REG3]
                    vmovups     ymm0, [REG4]
           ;}
            ;===================================================================================================.
            ; / memcpy                                                                                          |
            ;===================================================================================================.
       ;}
        %endmacro

sincosps:
http://pastebin.com/x5XvT7pw

I know invoke macro but I prefer to build my own macro for understanding and customize.
« Last Edit: June 26, 2015, 07:36:39 PM by shaynox »