Setting the FPU control word?

Bill Baxter dnewsgroup at billbaxter.com
Mon Mar 10 23:20:36 PDT 2008


Neil Vice wrote:
> Well short of the method return value being undefined if DO_FPU_CONTROL is 
> not set 

It is defined (http://www.digitalmars.com/d/1.0/enum.html)
to be the first value of the enum.  I decided to add an Undefined 
FPPrecision flag in my current version, and put that as the first thing 
in the enum to serve as a "this is bogus/uninitialized" indicator.

> and the fact that storing the new control word in a variable is 
> unnecessary with the exception of the debug, output it looks fine. If you 
> didn't require the debug output I believe you could simply use AX as the 
> operand to fldcw.

I see.  The code on the page you linked to used push EAX, and [SP] to 
access it, but the [SP] bit wouldn't compile ("invalid addressing 
mode").  That's why I went for the variable.  I'm not too worried about 
the extra cost of the mov.  :-)

> Happy to help =) Incidently it was my first use of asm in D also.

Funny.  :-)

The main thing I was worried about was the portability of those version 
statements.  Does the same FPU mojo work on X86_64?  Does it work with 
GDC?  I've heard GDC doesn't quite implement the inline asm spec.

--bb

> Neil
> 
> 
> "Bill Baxter" <dnewsgroup at billbaxter.com> wrote in message 
> news:fr4pb3$1f97$1 at digitalmars.com...
>> Here's a more cleaned up version.  If you see anything that could be 
>> improved, let me know.  This is my first asm{}.
>>
>> module fpctrl;
>> //import std.c.fenv;
>> import std.stdio;
>>
>> enum FPPrecision : short
>> {
>>     Single = 0x0000,
>>     Double = 0x0200,
>>     Real = 0x0300,
>>     Mask = 0x0300,
>>     InvMask = ~Mask
>> }
>>
>> version(X86) { version = DO_FPU_CONTROL; }
>> version(X86_64) { version = DO_FPU_CONTROL; }
>>
>>
>> FPPrecision setFPControlWord(FPPrecision precision)
>> {
>>     FPPrecision oldcw;
>>
>>     version(DO_FPU_CONTROL) {
>>         FPPrecision newcw;
>>         asm
>>         {
>>             fstcw oldcw;
>>             fwait;
>>             mov AX, oldcw;
>>             and AX,FPPrecision.InvMask;
>>             or AX,precision;
>>             mov newcw,AX;
>>             fldcw newcw;
>>         }
>>         debug
>>         {
>>             writefln("oldcw was: 0x%x", oldcw);
>>             asm
>>             {
>>                 fstcw newcw;
>>             }
>>             writefln("new is: 0x%x", newcw);
>>         }
>>
>>         oldcw &= FPPrecision.Mask;
>>     }
>>
>>     return oldcw;
>> }
>>
>> void main()
>> {
>>     auto orig = setFPControlWord(FPPrecision.Double);
>>
>>     setFPControlWord(FPPrecision.Single);
>>
>>     setFPControlWord(orig);
>> } 
> 
> 


More information about the Digitalmars-d-learn mailing list