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