cdecl and floating points

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

cdecl and floating points

Post by ~ »

The 32-bit cdecl calling convention says that the primitive data types, except for floating point values, are returned in EAX or EDX:EAX, depending on its size. EBX, ESI, EDI and EBP are preserved. EAX, ECX and EDX can be destroyed and aren't preserved. ESP and EBP are used for stack access, specially EBP which will hold the original base address of parameters in the stack, and ESP can be modified to create a stack frame, as an example here:

http://en.wikibooks.org/wiki/X86_Disass ... ack_Frames

Everything seems to be well until there. It seems that a cdecl function could be coded like this:

Code: Select all

some_function:
 push ebp        ;save EBP
 mov ebp,esp     ;point EBP to current stack position
 add ebp,8       ;discard, in EBP, the saved EBP size to point directly to parameters
                 ;and also the return addres that was pushed by near CALL instruction
   push ebx
   push esi
   push edi


   pop edi
   pop esi
   pop ebx
 pop ebp
ret

Now, what seems strange are the floating point values and how to handle them, which are said to be returned as a single return value in FP0 register of the FPU. First of all there doesn't seem to be a convention to save anything from the FPU state. Is this supposition correct?

The other problem is, how can a program using floating point values run in a machine without FPU, like a 386DX. How can a "float" type routine return value and "float" arguments in stack be handled at compile time?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: cdecl and floating points

Post by Combuster »

What it says is that upon entry, the FPU stack must be empty, and on return, the stack may at most contain one item - the return value, if it is a floating point number.

In ancient times there were three ways of dealing with floats:
1: don't use them; use fixed point or software floats.
2: use them, and blame the user's hardware if it stops working
3: use them, but emulate them when necessary (via the EM exception)

in case #1, there's no float to pass on-stack. In case #2 you'd want to pass as efficiently as possible - i.e. leave them on the stack to avoid a 4x bus sized read and 4x bus sized write - doubles over a 16 bit bus is not smart.
In case #3, you back up the corner case, such that when you do access the FPU, the result gets emulated, and you can still pass it "on the stack" (in that case, a virtual one), which is again more efficient than adding another pair of exceptions and memory writes for storing the result which will get used directly after...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Craze Frog
Member
Member
Posts: 368
Joined: Sun Sep 23, 2007 4:52 am

Re: cdecl and floating points

Post by Craze Frog »

First of all there doesn't seem to be a convention to save anything from the FPU state. Is this supposition correct?
You must preserve fpu state like rounding mode, unless the whole point of the called function IS to change the fpu state.
Post Reply