digitalmars.D.learn - Setting the FPU control word?
- Bill Baxter (4/4) Mar 10 2008 Anyone know how to translate these instructions to D? (specifically
- Neil Vice (20/24) Mar 10 2008 Something along the following lines seems to do the trick, by which I me...
- Bill Baxter (11/41) Mar 10 2008 Hmm, yeh. Those crazy computational geometry guys always assume you're
- Bill Baxter (49/49) Mar 10 2008 Here's a more cleaned up version. If you see anything that could be
- Neil Vice (9/58) Mar 10 2008 Well short of the method return value being undefined if DO_FPU_CONTROL ...
- Bill Baxter (14/88) Mar 10 2008 It is defined (http://www.digitalmars.com/d/1.0/enum.html)
- Jarrett Billingsley (3/7) Mar 10 2008 Would std.c.fenv (or tango.stdc.fenv, same module) be of any use here?
- Bill Baxter (31/41) Mar 10 2008 Ah, fsetprec(FE_DOUBLE) does indeed seem to be intended to be the thing.
- Don Clugston (6/60) Mar 12 2008 I've got something similar in tango.math.IEEE.
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
Mar 10 2008
"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 --bbSomething 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
Mar 10 2008
Neil Vice wrote:"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:fr3k2f$30b5$1 digitalmars.com...Ooh, thanks!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 --bbSomething 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#fldcwHmm, 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
Mar 10 2008
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); }
Mar 10 2008
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); }
Mar 10 2008
Neil Vice wrote:Well short of the method return value being undefined if DO_FPU_CONTROL is not setIt 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. --bbNeil "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); }
Mar 10 2008
"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 --bbWould std.c.fenv (or tango.stdc.fenv, same module) be of any use here?
Mar 10 2008
Jarrett Billingsley wrote:"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:fr3k2f$30b5$1 digitalmars.com...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 } --bbAnyone 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 --bbWould std.c.fenv (or tango.stdc.fenv, same module) be of any use here?
Mar 10 2008
Bill Baxter wrote:Jarrett Billingsley wrote:I've got something similar in tango.math.IEEE. reduceRealPrecision() setIeeeRounding() ieeeFlags(); Mostly only works for x86 (no inline asm yet for other CPUs?)"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:fr3k2f$30b5$1 digitalmars.com...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 } --bbAnyone 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 --bbWould std.c.fenv (or tango.stdc.fenv, same module) be of any use here?
Mar 12 2008