News:

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

Main Menu

fpu example

Started by jcfuller, March 26, 2013, 11:10:51 PM

Previous topic - Next topic

jcfuller

Just to muddy the waters a bit more - if compiled as a 64bit app (-m64) with no other options,  4.8.0  displays 1267

James

Gunther

James,

I think it's inside the asmlib. It's 32 bit code, round to nearest and truncate. Please check it out.

Quote from: jcfuller on March 29, 2013, 01:00:59 AM
Just to muddy the waters a bit more - if compiled as a 64bit app (-m64) with no other options,  4.8.0  displays 1267

That's not very surprising for me: different developer teams, different implementations. You should write a simple test bed and contact the developers. It could be important.

Gunther
You have to know the facts before you can distort them.

qWord

Quote from: Gunther on March 29, 2013, 03:36:14 AMI think it's inside the asmlib. It's 32 bit code, round to nearest and truncate. Please check it out.
why should he use a platform specific solution whereas the language itself hold a simple one?
MREAL macros - when you need floating point arithmetic while assembling!

jcfuller

I did find Round in asmlib but as QWord points out; From the asmlib-instructions.pdf:

Compilers with C99 or C++0x support have the identical functions lrint and lrintf

So by using return lrint(d*100) all should display the same.

James

dedndave

conditional assembly ?   :P

    IFDEF lrint
        return lrint(d*100)
    ELSE
        return d*100
    ENDIF


just a thought

jcfuller

The issue for me was MinGW not working the same as most  other compilers.
I don't like the original MinGW distro anyway as it does not statically link needed libraries as does TDM-GCC and the nuwen distro.

QWords nearest macro works on ALL 32/64 bit compilers I've tried so I am satisfied.

I don't know if this is an actual issue that should be reported? The c forum post from above seems to indicate it's perfectly valid.

James

qWord

James,

the point is that you must realize that the precision of calculation is implementation specific per definition of the standard - therefore all compiler do it the right way.
The problem was or is that you are not aware of this typecast-pitfall, which is, BTW, also present in many other HLLs (c++, c#, java,...).
MREAL macros - when you need floating point arithmetic while assembling!

MichaelW

James,

The attachment contains my test source, the batch file I compiled with, and the -std=gnu99 EXE. The compiler is reported as:

GNU C (GCC) version 4.7.2 (mingw32)

Well Microsoft, here's another nice mess you've gotten us into.

jcfuller

MichaelW,
  drop the -Os . I cannot use any optimizations. I think it was gcc 4.5 where the -O started clobbering some of my bc9 library code.

James

MichaelW

Yep, the 1267 result was apparently an unintended side effect of the optimization.
Well Microsoft, here's another nice mess you've gotten us into.

KeepingRealBusy

Quote from: qWord on March 29, 2013, 05:23:51 AM
James,

the point is that you must realize that the precision of calculation is implementation specific per definition of the standard - therefore all compiler do it the right way.
The problem was or is that you are not aware of this typecast-pitfall, which is, BTW, also present in many other HLLs (c++, c#, java,...).

See also the prior thread http://masm32.com/board/index.php?topic=1155.msg11385#msg11385

Dave.

jcfuller

Thanks for the thread Dave.

I have decided on message #20 approach.

Would some kind person translate this to intel syntax please. I need it for Borland 5.5


void set_fpu (unsigned int mode)
{
asm ("fldcw %0" : : "m" (*&mode));
}


Thanks again for all your insights.

James

dedndave

that code looks a little iffy   :P
it does not appear to mask off the rounding control bits, which is what you really want
you do not want to alter the other bits (i guess they build the entire control word, external to the function)

i already mentioned the bits used
http://masm32.com/board/index.php?topic=1700.msg17328#msg17328

and, you can use the stack as a temporary holding place
    push    eax        ;create a temporary variable on the stack
    fstcw word ptr [esp]
    fwait
    pop     eax        ;AX now holds the current control word

;manipulate bits, as desired - bits 10 and 11 hold the rounding control

    push    eax        ;put new control word on the stack
    fldcw word ptr [esp]
    fwait
    pop     eax        ;clean up the stack

jcfuller

Dave,
  Did you read the gcc information in the link from that message?
I am not one to question anyone on what is iffy but it sounded like exactly the same thing as QWord pointed out with gcc using 64bit precision as opposed to everyone (maybe not Borland ) using 53bit?

James

dedndave

ok - the code is basically the same - you just need to alter bits 8 and 9   :biggrin:

again, from Ray's tutorial...
QuoteThe PC field ( bits 9 and 8 ) or Precision Control determines to what precision
the FPU rounds results after each arithmetic instruction in one of three ways:

00 = 24 bits (REAL4)
01 = Not used
10 = 53 bits (REAL8)
11 = 64 bits (REAL10) (this is the initialized state)

the "initialized state" means "after FINIT"
the OS hands it over to you in 53-bit precision, i think
as you know, the compiler start-up code may alter this