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