News:

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

Main Menu

Simple floating point macros.

Started by hutch--, August 13, 2018, 04:36:54 PM

Previous topic - Next topic

jj2007

Quote from: hutch-- on August 15, 2018, 12:30:14 PMI am yet to see what the problem is using fldz. If I comment out fldz I get incorrect results.

Which definitely means there is a problem. Can you post an exe that shows these incorrect results?

hutch--

It meant that the calculation before it did not clean up the stack, uncomment the fldz and the error in the first did not effect the second calculation.

HSE

Hi Hutch!

Quote from: hutch-- on August 15, 2018, 12:30:14 PM
The reason why I have used "fldz" is due to testing

No problem then. But remember that out of test You will have one more register. Like say Raymond, macros hide how many FPU registers were used.

:t
Equations in Assembly: SmplMath

Siekmanski

another one

.const

fpercent MACRO num,pcnt     ;; Get Percentage of number
.const
F8_100 real8 100.0
.code
    fld     num             ;; load the number
    fdiv    F8_100
    fld     pcnt            ;; load required percentage
    fmulp                   ;; multiple by percentage
    EXITM   <st(0)>
    ENDM

.code

    fld     fpercent(FLT8(33.333),FLT8(90.0))
Creative coders use backward thinking techniques as a strategy.

RuiLoureiro

Quote from: hutch-- on August 15, 2018, 05:47:44 PM
It meant that the calculation before it did not clean up the stack, uncomment the fldz and the error in the first did not effect the second calculation.
Hi Hutch,
             I understood why you use fldz and there is no problem in using that fpinit. The FPU has 8 registers st(7),st(6),st(5),st(4),st(3),st(2),st(1),st(0). If we use fpinit we may have have 8 registers to work (if we start with fpadd or fpsub with 1 argument ) or we have only 7: [ st(6),st(5),st(4),st(3),st(2),st(1),st(0) ], but we cannot get any error due to that fldz. I would like to know how we get an error if we use the macros correctly and normal arguments. Is this what i think.

RuiLoureiro

Quote from: Siekmanski on August 16, 2018, 12:29:16 AM
another one

.const

fpercent MACRO num,pcnt     ;; Get Percentage of number
.const
F8_100 real8 100.0
.code
    fld     pcnt            ;; st(1)
    fld     num             ;; load the number
    fdiv    F8_100       ;; st(0)= num/100
    ;fld     pcnt            ;; load required percentage
    fmulp                   ;; st(0)= multiple by percentage
    EXITM   <st(0)>
    ENDM

.code

    fld     fpercent(FLT8(33.333),FLT8(90.0))

Or this one

daydreamer

Quote from: RuiLoureiro on August 16, 2018, 12:39:07 AM
Quote from: hutch-- on August 15, 2018, 05:47:44 PM
It meant that the calculation before it did not clean up the stack, uncomment the fldz and the error in the first did not effect the second calculation.
Hi Hutch,
             I understood why you use fldz and there is no problem in using that fpinit. The FPU has 8 registers st(7),st(6),st(5),st(4),st(3),st(2),st(1),st(0). If we use fpinit we may have have 8 registers to work (if we start with fpadd or fpsub with 1 argument ) or we have only 7: [ st(6),st(5),st(4),st(3),st(2),st(1),st(0) ], but we cannot get any error due to that fldz. I would like to know how we get an error if we use the macros correctly and normal arguments. Is this what i think.
FDECSTP/FINCSTP, works with MMX on one cpu at least,but maybe something I you can't trust on all cpus?


FPRCP macro x ;reciprocal macro with full precision compared to SSE RCP** instructions
fld1
fdiv x
endm

Marinus, why don't you go FMUL by 0.01 instead?faster, I don't know 64bit,if it works the same way using FIDIV  Word 100 smaller?

if you really want smallest floating Point code isnt fpu best choice?,just use st0-7 as much as possible and first code like you using st0,st1 etc for specific use,two:singlestep thru debugger to correct the right values get used and you get in 32bit mode 2byte/fpu opcode compared to 3-4 bytes for SSE etc

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

jj2007

Re fldz: It normally does no harm if you don't fully use the fpu. The point here is that ST(0) is not "cleared" by fldz; it is indeed set to zero, and therefore contains a valid number. If subsequently you load 7 more values onto the fpu, then all 8 registers are occupied and valid. Now if you try to fld onemore, it chokes!

Normally you don't load 7 more values, so that is a rare scenario. But you can reach this limit very quickly in a loop, if that loop doesn't respect the rule that at the end of an operation the fpu should return to its initial state.

An elegant way to test this is as follows:
finit ; optional, the OS does it anyway
fldpi
... your code ...
int 3

When you hit the breakpoint, and ST(0) does not contain 3.14159, then you have a bug.

Siekmanski

Magnus you are right, totally overlooked the reciprocal technique.  :t
And in Rui's order.



fpercent MACRO num,pcnt     ;; Get Percentage of number
.const
F8_100 real8 0.01
.code
    fld     pcnt            ;; load required percentage
    fld     num             ;; load the number
    fmul    F8_100
    fmulp                   ;; multiple by percentage
    EXITM   <st(0)>
    ENDM

.code

    fld     fpercent(FLT8(33.333),FLT8(90.0))

[/[code]
Creative coders use backward thinking techniques as a strategy.

RuiLoureiro

#54
Quote from: Siekmanski on August 16, 2018, 03:34:18 AM
Magnus you are right, totally overlooked the reciprocal technique.  :t
And in Rui's order.



fpercent MACRO num,pcnt     ;; Get Percentage of number
.const
F8_100 real8 0.01
.code
    fld     pcnt            ;; load required percentage
    fld     num             ;; load the number
    fmul    F8_100
    fmulp                   ;; multiple by percentage
    EXITM   <st(0)>
    ENDM

.code

    fld     fpercent(FLT8(33.333),FLT8(90.0))


Siekmanski, we are close of writing it by all ways of doing it
Dont forget multiply by 0.01 !!!
So we should call fpercent_v1, fpercent_v2, fpercent_v3...
What version is faster ? Is it hard to do ?
Do you want to write a test for it ?
See you

jj2007

If you use fld fpercent(FLT8(33.333),FLT8(90.0)) a second time, you'll get Error A2056: Symbol already defined: F8_100

There is also the Percent macro:
  Print Str$("pc(srcdd, ebx)=%f\n", Percent(srcdd, ebx)) ; with DWORD source and reg32 percentage
  Print Str$("pc(12345, 20)=%f\n", Percent(12345, 20)) ; with immediate integer source and percentage


hutch--

This solves the repeat problem, each call gets a unique address.

      FLT8 MACRO fpimm
        LOCAL vname
        .data
          align 8
          vname REAL8 fpimm
        .code
        EXITM < vname>
      ENDM

It requires a register to load the result into.

nidud

#57
deleted

hutch--

nidud,

What is the string processing in your macro for ? The FP argument is simple enough to understand but I don't recognise the notation for the text you are constructing with it.

nidud

#59
deleted