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

dedndave

it might be worth mentioning that.....

the compiler code may depend on the precision and rounding control bits being set a specific way (especially precision)
how you leave these set may affect other calculations - possibly even generate exceptions

you may have to set it to the mode you like, perform your work, then set it back the way it was   :P

one of the reasons i prefer ASM - lol

EDIT: it may be better to alter this behaviour with the proper command-line switch, if available
that way, the compiler code should work with you instead of against you

TouEnMasm


/Fa with vc++ express give the correct result at the first time
Fa is a musical note to play with CL

jcfuller

Quote from: ToutEnMasm on March 31, 2013, 03:08:27 AM

/Fa with vc++ express give the correct result at the first time

Yes I know only the MinGW gcc and Borland 5.5 compilers give a different result.

James

jcfuller

It looks like I'm going to have to do the procedure in Jwasm and link the obj if I want it bad enough because the free Borland 5.5 lacks the tasm assembler so no inline asm

James

MichaelW

You can also use the CRT to control the FPU:

http://msdn.microsoft.com/en-US/library/e9b52ceh(v=vs.80).aspx

I made an attempt to use __control87_2, but MSVCRT.DLL on my XP SP3 system does not export the function.

Also, from the MinGW float.h:

/*
   MSVCRT.dll _fpreset initializes the control register to 0x27f,
   the status register to zero and the tag word to 0FFFFh.
   This differs from asm instruction finit/fninit which set control
   word to 0x37f (64 bit mantissa precison rather than 53 bit).
   By default, the mingw version of _fpreset sets fp control as
   per fninit. To use the MSVCRT.dll _fpreset, include CRT_fp8.o when
   building your application.
*/


And the lib directory includes CRT_fp8.o and CRT_fp10.o
Well Microsoft, here's another nice mess you've gotten us into.

jcfuller

MichaelW,
  Thanks for the information but _fpreset() does not work or I misunderstand it.
My os is Win764.
After re-reading the page from the link in msg #20 I revised my code a bit.
I'm really not sure if these are related or not?
James

using MinGw 4.8.0
output with: gcc fputest.c -ofputest.exe

unexpected result
d =  12.67
rv =  1266


output with: gcc fputest.c -ofputest.exe -DFPRESET

unexpected result
d =  12.67
rv =  1266


output with: gcc fputest.c -ofputest.exe -DDOUBLE

comparison succeeds
d =  12.67
rv =  1267


using TDM-GCC
output with: gcc fputest.c -ofputest.exe

comparison succeeds
d =  12.67
rv =  1267




New test code:



#include <stdio.h>
#include <float.h>

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

int foo (double d)
{
  printf("%s% .15G\n","d = ",(double)d);
return (d*100);
}


int main (int argc,char** argv)
{
  int      rv={0};
  double   d={0};
  double   c={0};
  double   a=3.0;
  double   b=7.0;
 
   
#ifdef DOUBLE
    set_fpu (0x27F);
#endif

#ifdef FPRESET
   _fpreset();   
#endif
  c= a/ b;
  if(c==(a/b))
    {
      printf("%s\n","comparison succeeds");
    }
  else
    {
      printf("%s\n","unexpected result");
    }
  d= 12.67;
  rv= foo( d);
  printf("%s% d\n","rv = ",(int)rv);
  return 0;
}






jcfuller

My bad I forgot to link in crt_fp8.o.

It appears to work as advertised

James