| Thread overview | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
  | 
March 10, 2008 Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Anyone know how to translate these instructions to D? (specifically DMD/Win flavor of D, but GDC/Win also appreciated if different): http://www.cs.cmu.edu/~quake/robust.pc.html --bb  | ||||
March 10, 2008 Re: Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Bill Baxter  | "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:fr3k2f$30b5$1@digitalmars.com... > Anyone know how to translate these instructions to D? (specifically DMD/Win flavor of D, but GDC/Win also appreciated if different): > > http://www.cs.cmu.edu/~quake/robust.pc.html > > --bb Something along the following lines seems to do the trick, by which I mean it compiles in 2.012 though I believe the syntax should be compatible with D1: enum FPPrecision : short { Single = 4210, Double = 4722 } void setFPCtrlWord(FPPrecision precision) { asm { fldcw precision; } } Having said that it might be advisable to use 'fstcw' and bitwise operations to alter the specifics of the control-word that you require: http://www.website.masmforum.com/tutorials/fptute/fpuchap3.htm#fldcw  | |||
March 10, 2008 Re: Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Bill Baxter  | "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:fr3k2f$30b5$1@digitalmars.com... > Anyone know how to translate these instructions to D? (specifically DMD/Win flavor of D, but GDC/Win also appreciated if different): > > http://www.cs.cmu.edu/~quake/robust.pc.html > > --bb Would std.c.fenv (or tango.stdc.fenv, same module) be of any use here?  | |||
March 11, 2008 Re: Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Jarrett Billingsley  | Jarrett Billingsley wrote: > "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:fr3k2f$30b5$1@digitalmars.com... >> Anyone know how to translate these instructions to D? (specifically DMD/Win flavor of D, but GDC/Win also appreciated if different): >> >> http://www.cs.cmu.edu/~quake/robust.pc.html >> >> --bb > > Would std.c.fenv (or tango.stdc.fenv, same module) be of any use here? Ah, fsetprec(FE_DOUBLE) does indeed seem to be intended to be the thing. Except, it doesn't work. The asm fldcw thing does seem to work though. ---- module fpctrl; import std.c.fenv; import std.stdio; enum FPPrecision : short { Single = 0x0000, Double = 0x0200, Real = 0x0300, Mask = 0x0300, } void setFPControlWord(FPPrecision precision) { FPPrecision oldcw; asm { fstcw oldcw; fwait; fldcw precision; } writefln("oldcw was: 0x%x", oldcw); } void main() { fesetround(FE_FLTPREC); // should set ctrl word to 0x_2__ setFPControlWord(FPPrecision.Double); // prints 0x_3__, the default } --bb  | |||
March 11, 2008 Re: Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Neil Vice  | Neil Vice wrote: > "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:fr3k2f$30b5$1@digitalmars.com... >> Anyone know how to translate these instructions to D? (specifically DMD/Win flavor of D, but GDC/Win also appreciated if different): >> >> http://www.cs.cmu.edu/~quake/robust.pc.html >> >> --bb > > Something along the following lines seems to do the trick, by which I mean it compiles in 2.012 though I believe the syntax should be compatible with D1: > > enum FPPrecision : short > { > Single = 4210, > Double = 4722 > } > > void setFPCtrlWord(FPPrecision precision) > { > asm > { > fldcw precision; > } > } Ooh, thanks! > Having said that it might be advisable to use 'fstcw' and bitwise operations to alter the specifics of the control-word that you require: > > http://www.website.masmforum.com/tutorials/fptute/fpuchap3.htm#fldcw Hmm, yeh. Those crazy computational geometry guys always assume you're writing a command line program whose only purpose in life is to calculate a Delaunay triangulation or something. Oh, you want to use this algorithm in a what?? an application?? What's that? True to form, that page from Shewchuk says nothing about how to put things back the way you found them when you're done with robust predicate happy-fun-time. That page you linked to was great though. Thanks. --bb  | |||
March 11, 2008 Re: Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Bill Baxter  | 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);
}
 | |||
March 11, 2008 Re: Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Bill Baxter  | Well short of the method return value being undefined if DO_FPU_CONTROL is not set 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. Happy to help =) Incidently it was my first use of asm in D also. Neil "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:fr4pb3$1f97$1@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); > }  | |||
March 11, 2008 Re: Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Neil Vice  | 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@billbaxter.com> wrote in message news:fr4pb3$1f97$1@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); >> } > >  | |||
March 12, 2008 Re: Setting the FPU control word? | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Bill Baxter  | Bill Baxter wrote:
> Jarrett Billingsley wrote:
>> "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:fr3k2f$30b5$1@digitalmars.com...
>>> Anyone know how to translate these instructions to D? (specifically DMD/Win flavor of D, but GDC/Win also appreciated if different):
>>>
>>>    http://www.cs.cmu.edu/~quake/robust.pc.html
>>>
>>> --bb
>>
>> Would std.c.fenv (or tango.stdc.fenv, same module) be of any use here? 
> 
> Ah, fsetprec(FE_DOUBLE) does indeed seem to be intended to be the thing.
> 
> Except, it doesn't work.  The asm fldcw thing does seem to work though.
> 
> 
> ----
> module fpctrl;
> import std.c.fenv;
> import std.stdio;
> 
> enum FPPrecision : short
> {
>     Single = 0x0000,
>     Double = 0x0200,
>     Real = 0x0300,
>     Mask = 0x0300,
> }
> 
> void setFPControlWord(FPPrecision precision)
> {
>     FPPrecision oldcw;
> 
>     asm
>     {
>         fstcw oldcw;
>         fwait;
>         fldcw precision;
>     }
>     writefln("oldcw was: 0x%x", oldcw);
> 
> 
> }
> 
> void main()
> {
>     fesetround(FE_FLTPREC); // should set ctrl word to 0x_2__
> 
>     setFPControlWord(FPPrecision.Double); // prints 0x_3__, the default
> }
> 
> 
> --bb
I've got something similar in tango.math.IEEE.
reduceRealPrecision()
setIeeeRounding()
ieeeFlags();
Mostly only works for x86 (no inline asm yet for other CPUs?)
 | |||
Copyright © 1999-2021 by the D Language Foundation
 
Permalink
Reply