; ------------------------------------------------------
; Macros instructions
; Copyright (c) 2005-2016, Franck Charlet
; All rights reserved.
; Floating point variables redundance checking by savage.
; ------------------------------------------------------

literal_float           macro   lit_float
                        ifidn   @SubStr(<lit_float>, 1, 1), <->
dot_position                    equ     @InStr(2, <lit_float>, <.>)
local_float                     textequ @CatStr(<_FLT__>, @SubStr(<lit_float>, 1, dot_position - 1), <_>, @SubStr(<lit_float>, dot_position + 1))
sgn_location                    equ     @InStr(1, %local_float, <->)
local_float                     textequ @CatStr(<_>, @SubStr(%local_float, 1, sgn_location - 1), @SubStr(%local_float, sgn_location + 1))
                        else
dot_position                    equ     @InStr(2, <lit_float>, <.>)
local_float                     textequ @CatStr(<_FLT_>, @SubStr(<lit_float>, 1, dot_position - 1), <_>, @SubStr(<lit_float>, dot_position + 1))
                        endif
                        %ifndef local_float
                                .data
local_float                     real4   lit_float
                                .code
                        endif
                        exitm   <local_float>
                        endm

CFLT                    macro   lit_float
                        exitm   <literal_float(lit_float)>
                        endm

INT2FLT                 macro   lit_float
                        local   local_int_float

                        .data
                        align   4
local_int_float         real4   0.0

                        .code
                        push    lit_float
                        fild    dword ptr [esp]
                        add     esp, 4
                        fstp    dword ptr [local_int_float]
                        exitm   <local_int_float>
                        endm

FLT2INT                 macro   float_lit
                        local   local_float_int

                        .data
                        align   4
local_float_int         dd      0

                        .code
                        push    float_lit
                        fld     dword ptr [esp]
                        add     esp, 4
                        fistp   dword ptr [local_float_int]
                        exitm   <local_float_int>
                        endm

FLT2DBL                 macro   float_lit
                        local   local_float_double

                        .data
                        align   4
local_float_double      real8   0.0

                        .code
                        push    float_lit
                        fld     dword ptr [esp]
                        add     esp, 4
                        fstp    qword ptr [local_float_double]
                        exitm   <local_float_double>
                        endm

ALLOCMEM                macro   _Size
                        invoke  GlobalAlloc, GMEM_ZEROINIT or GMEM_FIXED, _Size
                        exitm   <eax>
                        endm

FREEMEM                 macro   Datas
                        .if     Datas != NULL
                                invoke  GlobalFree, Datas
                        .endif
                        endm

CMEM                    macro   _Datas
                        mov     eax, _Datas
                        exitm   <eax>
                        endm

INT2DBL                 macro   lit_double
                        local   local_int_double

                        .data
                        align   4
local_int_double        real8   0.0

                        .code
                        push    lit_double
                        fild    dword ptr [esp]
                        add     esp, 4
                        fstp    qword ptr [local_int_double]
                        exitm   <local_int_double>
                        endm

literal_double          macro   lit_double
                        ifidn   @SubStr(<lit_double>, 1, 1), <->
dot_position                    equ     @InStr(2, <lit_double>, <.>)
local_double                    textequ @CatStr(<_DBL__>, @SubStr(<lit_double>, 1, dot_position - 1), <_>, @SubStr(<lit_double>, dot_position + 1))
sgn_location                    equ     @InStr(1, %local_double, <->)
local_double                    textequ @CatStr(<_>, @SubStr(%local_double, 1, sgn_location - 1), @SubStr(%local_double, sgn_location + 1))
                        else
dot_position                    equ     @InStr(2, <lit_double>, <.>)
local_double                    textequ @CatStr(<_DBL_>, @SubStr(<lit_double>, 1, dot_position - 1), <_>, @SubStr(<lit_double>, dot_position + 1))
                        endif
                        %ifndef local_double
                                .data
local_double                    real8   lit_double
                                .code
                        endif
                        exitm   <local_double>
                        endm

CDBL                    macro   lit_double
                        exitm   <literal_double(lit_double)>
                        endm

literal_string          macro   lit_string
                        local   local_string

                        .data
                        align   4
local_string            db      lit_string, 0

                        .code
                        exitm   <local_string>
                        endm

CSTR                    macro   lit_string
                        exitm   <offset literal_string(lit_string)>
                        endm

FCMP                    macro   Float1, Float2
                        fld     Float1
                        fcomp   Float2
                        fnstsw  ax
                        sahf
                        endm

FCMP0                   macro   Float
                        fld     Float
                        ftst
                        fnstsw  ax
                        sahf
                        fstp    st(0)
                        endm
