Author Topic: fpu example  (Read 29341 times)

dedndave

  • Member
  • *****
  • Posts: 8827
  • Still using Abacus 2.0
    • DednDave
Re: fpu example
« Reply #45 on: March 30, 2013, 11:51:30 PM »
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

  • Member
  • *****
  • Posts: 1342
    • EditMasm
Re: fpu example
« Reply #46 on: March 31, 2013, 03:08:27 AM »

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

jcfuller

  • Member
  • **
  • Posts: 187
Re: fpu example
« Reply #47 on: March 31, 2013, 03:41:04 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

  • Member
  • **
  • Posts: 187
Re: fpu example
« Reply #48 on: March 31, 2013, 03:43:00 AM »
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

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: fpu example
« Reply #49 on: March 31, 2013, 04:43:13 AM »
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:
Code: [Select]
/*
   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

  • Member
  • **
  • Posts: 187
Re: fpu example
« Reply #50 on: March 31, 2013, 07:06:12 AM »
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
Code: [Select]
unexpected result
d =  12.67
rv =  1266

output with: gcc fputest.c -ofputest.exe -DFPRESET
Code: [Select]
unexpected result
d =  12.67
rv =  1266

output with: gcc fputest.c -ofputest.exe -DDOUBLE
Code: [Select]
comparison succeeds
d =  12.67
rv =  1267

using TDM-GCC
output with: gcc fputest.c -ofputest.exe
Code: [Select]
comparison succeeds
d =  12.67
rv =  1267



New test code:

Code: [Select]

#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

  • Member
  • **
  • Posts: 187
Re: fpu example
« Reply #51 on: March 31, 2013, 09:25:25 AM »
My bad I forgot to link in crt_fp8.o.

It appears to work as advertised

James