tkchia / gcc-ia16

Fork of Lambertsen & Jenner (& al.)'s IA-16 (Intel 16-bit x86) port of GNU compilers ― added far pointers & more • use https://github.com/tkchia/build-ia16 to build • Ubuntu binaries at https://launchpad.net/%7Etkchia/+archive/ubuntu/build-ia16/ • DJGPP/MS-DOS binaries at https://gitlab.com/tkchia/build-ia16/-/releases • mirror of https://gitlab.com/tkchia/gcc-ia16
GNU General Public License v2.0
168 stars 12 forks source link

Feature request: -mrtd #13

Closed bartoldeman closed 6 years ago

bartoldeman commented 6 years ago

It would be nice and may not be too hard to implement -mrtd (as already implemented for i386) where functions issue "ret n" instructions, so the callee pops the stack. The FreeDOS kernel saves space using that.

Most DOS compilers implement this via the Pascal calling convention which also reverts the order and capitalizes symbols but that would be another project and more difficult I think. Capitalizing symbols is easily done using asm("SYMBOLNAME") but I don't know if GCC is set up at all for reversing stack argument order.

tkchia commented 6 years ago

Hello @bartoldeman ,

I have (finally) implemented -mrtd --- and also took the opportunity to tidy up the multilib settings in the project (and turn off some unneeded C++ ABI compatibility stuff).

I found that the main challenge in properly implementing -mrtd turned out to come from an unexpected place --- libgcc. The problem is GCC might generate calls to internal routines such as __umoddi3, and these will be assumed to have the same -mrtd convention (unless I do some messy special-casing), so linking to a standard libgcc.a will give the wrong results.

In the end I decided to add an extra multilib setting to the IA-16 back-end, so that additional sets of libgcc.a binaries can be compiled with -mrtd and be linkable to -mrtd code. (I think the i386 port simply ignores this whole issue.)

As for reversing the argument push order à la Turbo Pascal, the GCC internals documentation suggests that it might actually have the infrastructure to support such a thing --- though I have not used it yet.

PUSH_ARGS_REVERSED [Macro] A C expression. If nonzero, function arguments will be evaluated from last to first, rather than from first to last. If this macro is not defined, it defaults to PUSH_ARGS on targets where the stack and args grow in opposite directions, and 0 otherwise.

Thank you!

bartoldeman commented 6 years ago

just wondering if __attribute__((cdecl)) could also be supported in tandem. This compiles but gives a warning at the moment. I've been working around that by making the functions varargs with ...

$ cat tst18.c
void __attribute__((cdecl)) foo(int bar) {}
$ ia16-elf-gcc -c -mrtd tst18.c 
tst18.c:1:1: warning: ‘cdecl’ attribute directive ignored [-Wattributes]
 void __attribute__((cdecl)) foo(int bar) {}
 ^~~~
tkchia commented 6 years ago

Hello @bartoldeman,

Indeed, __attribute__ ((cdecl)) will be good to have, but from what I see, the back-end uses separate mechanisms for handling __attribute__ ((.)) and handling compiler flags, so this may take some time to do.

(I also hope to get something like i386's __attribute__ ((regparm (.))) implemented, some day. I found that Watcom not only implements callee-pops-stack, but also passes some function arguments in registers, which helps in no small way to reduce code size.)

Thank you!

tkchia commented 6 years ago

Hello @bartoldeman ,

Now that I have implemented __attribute__ ((cdecl)) and __attribute__ ((stdcall)), I hope to add some proper support for far functions to GCC, but this seems non-trivial.

I have opened an issue for this, and I would like to know if you have any thoughts and advice on how to go about it.

Thank you!