News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

FPU newb alert!

Started by LimoDriver, March 31, 2007, 09:22:04 AM

Previous topic - Next topic

LimoDriver

I'm writing a tiny routine in C, and I'd like to perform some simple FPU arithmetic without invoking CRT's libraries...

Wil this code do what I need it to do, and if so, are the waits included in finit and fwait really necessary?
The code is being inlined in a place where there are no floating point operations around for a few million clocks.

I've put one below fist because I read in the masm32 FPU tutorial that I should do this after float->int conversions
due to FPU being uber-slow, but since I've never written anything for the damn thing, I have no clue o.0


// chaosF = 3.0f;
// chaosI = (DWORD) ( chaosF * CS_PLASMA_MAX_COLORS );

__asm
{
    finit
    fld     DWORD PTR[ chaosF ]
    push    CS_PLASMA_MAX_COLORS
    fimul   [ esp ]
    fist    [ esp ]
    fwait
    pop     DWORD PTR[ chaosI ]
}

TNick

QuoteCPU enters wait state until the coprocessor signals it has finished
ts operation.  This instruction is used to prevent the CPU from
accessing memory that may be temporarily in use by the coprocessor
.
WAIT and FWAIT are identical

So, if you don't use FWAIT there, at the same time, FPU may try to store the converted floating point number at esp position, while CPU may try to copy the value at esp to chaosI.

And about FINIT, if you don't want a FWAIT to be issued, why don't you use FNINIT? But be shure that you understand what you are doing!

Nick

LimoDriver

Thanx mate. I guess I'll just leave everything as it is. Including FINIT... for sheer paranoia :)

TNick

Just some final smartass remarks :bdg

The key here is the word "UNDERSTAND" and not "NOT"

In the previous example, right after you store the value at esp using FPU, you get the value using CPU. FWAIT is needed. But if you insert some code between:
    fist    [ esp ]
    pop     DWORD PTR[ chaosI ]
you may lose the FWAIT thing.

Nick

LimoDriver

The problem is that this is an isolated inline sement, I cannot insert any code inside. There isn't one.
And if I split the thing in two and call some api in between ... that's just .. ugh ... :P

MichaelW

AFAIK the fwait is necessary here. I think using finit in inline asm surrounded by compiler generated code could cause some problems, and it looks to me like the fist should be a fistp.
eschew obfuscation

LimoDriver

Thanx MichaelW... Forgot to cleanup again :P

I managed to get the thing working without the CRT in pure C by using


(DWORD) ( floatingPoint * integer );


instead of


(int) ( floatingPoint * integer );


I'm not fooling...
Whenever I use (int) it attaches the SetUnhandledExceptionHandler... crt_debugger_hook ... and so on...

Only GOD knows what's going on in there... :|

raymond

A few comments.

If you are going to use "finit" everytime you are going to access the FPU, you don't need to bother cleaning up the FPU when you don't use many FPU registers (although I would strongly suggest that you do in order to get into a good habit).

When you load some value to the FPU from memory (and also when you store a value from the FPU to memory), the FPU needs to know the size of that value, regardless if it is a float or an integer. If you are using a declared variable name as the source (or destination), the declared size of that variable may be used without further qualification with some assemblers/compilers. However, when you are using indirect addressing, you MUST define the size (such as fimul dword ptr[esp]).

When you declared that chaosF = 3.0f  in C, you need to be sure that it was initialized as a single-precision float (32-bit) in order to refer to it as a DWORD. If it were to be initialized as a double-precision float, and then used as a single-precision, your result would be erroneous regarless of how you refer to it in the fld instruction.

Welcome to the world of the FPU and its intricacies. However, it's still SIMPLE to learn.

Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com