How to make C function compiled by OpenWatcom return a double in ST(0)?

108 Views Asked by At

The C function

double retfp(void) { return 42; }

, when compiled with OpenWatcom C compiler for Linux i386:

owcc -blinux -fno-stack-check -fsigned-char -march=i386 -Os -W -Wall -Wextra -Werror -mregparm=0 -c -o retfp.owcc.obj retfp.c

has code which returns the double in EDX:EAX. However, I want to get it in ST(0) instead, like how GCC does it. Is thiss possible with OpenWatcom, maybe via a command-line flag?

2

There are 2 best solutions below

0
dimich On BEST ANSWER

You should specify calling convention which returns floating point values in ST(0), for example cdecl:

double __cdecl retfp(void) {  return 42; }

Dissassembler output:

Segment: _TEXT BYTE USE32 00000007 bytes
0000                            _retfp:
0000  DD 05 00 00 00 00                 fld             qword ptr L$1
0006  C3                                ret
...
Segment: CONST DWORD USE32 00000008 bytes
0000                            L$1:
0000  00 00 00 00 00 00 45 40                         ......E@

Also you can specify default calling convention to owcc with -mabi flag.

0
pts On

TL;DR Use owcc -mabi=cdecl instead of owcc -mregparm=0.

Extending the answer of @dimich:

  • The owcc -mabi=... and owcc =mregparm=... flag values together determine the calling convention, and the calling convention determines (e.g.) in which registers values are returned.
  • The owcc -mabi=... flag corresponds to the wcc386 -ec... flag, e.g. owcc -mabi=cdecl is the same as wcc386 -ecc.
  • The owcc -mregparm=... flag corresponds to the undocumented (!) wcc386 -3... flag, e.g. owcc -mregparm=0 is the same as wcc386 -3s, and owcc -mregparm=3 is the same as wcc386 -3r.
  • The default is owcc -mregparm=3 -mabi=watcall.
  • doubles are returned in EDX:EAX with owcc -mregparm=0 -mabi=pascal, owcc -mregparm=0 -mabi=fortran, owcc -mregparm=0 -mabi=watcall, owcc -mregparm=0.
  • doubles are returned in ST(0) with owcc -mregparm=0 -mabi=cdecl, owcc -mregparm=0 -mabi=stdcall, owcc -mregparm=0 -mabi=fastcall, -mregparm=0 -mabi=syscall, owcc -mregparm=3, and also with owcc -mregparm=3 -mabi=... (any -mabi=... value).