News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Double Double Stack and SmplMath's backend

Started by HSE, April 01, 2023, 01:21:16 AM

Previous topic - Next topic

HSE

Hi all!!

  Playing with DoubleDouble presicion a little more.

  For SmplMath real8 calculations, values are passed to functions in FPU registers.

  In a previous version values were passed to functions in FPU registers, but that use 2 registers for each value, what left few free FPU registers for calculations. SmplMath's Shunting-Yard storage can exaust registers easily in complex equations.

  In this version, values are passed to functions like for real8 functions, in an emulated FPU stack.

  SmplStack store and retrieve DoubleDouble values. By default there are 16 "registers 128 bits wide", but there is no limit to set number of registers. So far R15 GPR is used to point what in FPU could be st(0). R15 is preserved in the same stack.

  SmplStack is easily thread save.

entry_point proc
    local rrTLS()
   
    rrSTACK on
    · · ·
    Double Double calculations 
    · · ·
    rrSTACK off
    waitkey
    invoke ExitProcess,0
    ret

entry_point endp

  Library of DoubleDouble functions contain basic operations previouly used, and now also trigonometry and exponentiation functions from Taylor's series.

  Functions can be called in a direct mode and in equation mode (yet without constant creation  :biggrin:):

    ; Direct mode

    invoke rr_parse,"350.0"
    invoke rr_parse,"4.31"
    call rr_divide
    invoke rr_toSciNotation, addr buffer
    conout chr$("  "), addr buffer, lf, lf

    ; Equation mode

    fSlvSelectBackEnd RR
   
    fSlvRR dd2 = 350.0/4.31
   
    invoke_rr dd2, toSciNotation, addr buffer
    conout chr$("  "), addr buffer, lf, lf

  Like before, this test is using ML64, and Masm64 extension of Masm32 SDK for string functions.

Regards, HSE.
Equations in Assembly: SmplMath

HSE

#1
Added a little parser to create DoubleDouble precision constants at assembling time:
@ParseRR macro Expression:=< >
   
    prr_text textequ <> 
    prr_textbp textequ <> 
    prr_textap textequ <>
    prr_texte textequ <>
     
    prr_first = 1
    prr_exp  = 0
    ceval val_hi = 0
    ceval val_lo = 0
    numDigits = 0 
    FORC char,<&Expression>
        IF prr_first
            prr_negative INSTR 1,<->,<&char>
            prr_first = 0
            IFE prr_negative
                goto other
            ENDIF
        ELSE
    :other   
            prr_cntr INSTR 1,<0123456789>,<&char>
            IF prr_cntr
                IF prr_exp
                    prr_texte CATSTR prr_texte,<&char>                 
                ELSE
                    mreal_rr_multiply val_hi, val_lo,mreal_TEN_hi, mreal_TEN_lo, val_hi, val_lo
                    ceval d2_hi = <&char>
                    ceval d2_lo = 0
                    mreal_rr_add val_hi, val_lo, d2_hi, d2_lo, val_hi, val_lo
                    numDigits = numDigits + 1
                ENDIF
            ENDIF
            hay_point INSTR 1,<.>,<&char>
            IF hay_point
                numBeforeDec = numDigits
            ENDIF
            hay_e INSTR 1,<e>,<&char>
            IF hay_e
                prr_exp = 1
            ENDIF
        ENDIF
    ENDM
 
    IF @SizeStr(%prr_texte)
        valexp = %prr_texte
    ELSE
        valexp = 0
    ENDIF   
    numDecPlaces = numDigits - numBeforeDec - valexp
    IF numDecPlaces eq 0
        EXITM <@CatStr(<{>,MR_TO_IEEE(<REAL8>,val_hi), <,>, MR_TO_IEEE(<REAL8>,val_lo),<}>)> 
    ELSEIF numDecPlaces gt 0
        mreal_rr_pows mreal_TEN_hi, mreal_TEN_lo, numDecPlaces, scale_hi, scale_lo
        mreal_rr_divide val_hi, val_lo, scale_hi, scale_lo, res_hi, res_lo
    ELSEIF numDecPlaces lt 0
        numDecPlaces = numDecPlaces * -1
        mreal_rr_pows mreal_TEN_hi, mreal_TEN_lo, numDecPlaces, scale_hi, scale_lo
        mreal_rr_multiply val_hi, val_lo, scale_hi, scale_lo, res_hi, res_lo
    ENDIF
    IF prr_negative
        mreal_rr_negate val_hi, val_lo, res_hi, res_lo
        EXITM <@CatStr(<{>,MR_TO_IEEE(<REAL8>,res_hi), <,>, MR_TO_IEEE(<REAL8>,res_lo),<}>)> 
    ENDIF
    ;echo_mreal res_hi,18
    ;echo_mreal res_lo,18
    EXITM <@CatStr(<{>,MR_TO_IEEE(<REAL8>,res_hi), <,>, MR_TO_IEEE(<REAL8>,res_lo),<}>)> 
endm

The parser make DoubleDouble precision calculations using an extension of qWord's MREAL macros, for example:
mreal_rr_multiply macro _this_hi, _this_lo, tmpy_hi, tmpy_lo, res_hi, res_lo
    ceval _C = mreal_SPLIT * _this_hi
    MR_ROUND _C, _C,53,<bits>
    ceval hx = _C - _this_hi
    ceval _c = mreal_SPLIT * tmpy_hi
    ceval hx = _C - hx
    ceval tx = _this_hi - hx
    ceval hy = _c - tmpy_hi
    ceval _C = _this_hi * tmpy_hi
    ceval hy = _c - hy
    ceval ty = tmpy_hi - hy
    ceval _c = hx * hy - _C + hx * ty + tx * hy + tx * ty + (_this_hi * tmpy_lo + _this_lo * tmpy_hi)
    ceval res_hi = _C + _c
    MR_ROUND res_hi, res_hi,53,<bits>
    ceval hx = _C - res_hi
    ceval res_lo = _c + hx
endm

Now you can write constansts in equations (see first post).

:biggrin: 350.0 is easy because you can directly store like <350.0, 0.0>.

But the simple 4.31 is <4.30999999999999960e+000, 3.90798504668055100e-016>

Update in first post.
Equations in Assembly: SmplMath

daydreamer

Great Héctor  :thumbsup:
Possible with 256 bit AVX: quadruple double precision?
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

HSE

Hi daydreamer,

Quote from: daydreamer on April 03, 2023, 02:44:46 PM
Possible with 256 bit AVX: quadruple double precision?

:biggrin: I think quad-double hardly ever was implemented because you increase precision but range (the exponents) always remains that of Real8.

HSE
Equations in Assembly: SmplMath

jj2007

Quote from: HSE on April 03, 2023, 10:58:18 PMI think quad-double hardly ever was implemented because you increase precision but range (the exponents) always remains that of Real8.

±5.0 × 10−324 to ±1.7 × 10308 should be enough for most applications :cool:

HSE

 :thumbsup: Close to Real8 range.
      (if you accept to lost precision)
Equations in Assembly: SmplMath

HSE

Hi all!

A line was missing in Parser Function, failing when there is an exponent:
    invoke rr_parse,chr$("1.256e100")
    pop_rr dd1

And a line messed in Parser Macro, also failing with exponent:
    fSlvRR dd1 = 3.3e17
Updated in first post.

Regards, HSE.
Equations in Assembly: SmplMath