gcc m68k: calling a "-mshort" API from non-mshort code

C and PASCAL (or any other high-level languages) in here please

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

czietz
Hardware Guru
Hardware Guru
Posts: 766
Joined: Tue May 24, 2016 6:47 pm

gcc m68k: calling a "-mshort" API from non-mshort code

Postby czietz » Sun Jun 03, 2018 6:01 pm

Hello,

I have existing code that is compiled with gcc's default settings of 32-bit ints, i.e. without "-mshort". However, from this code I want to call an API that uses "-mshort", i.e. 16-bit ints. At first I thought: easy, just make sure that when writing the function prototypes only "short" and "long" are used, no ambiguous "int" and it should be fine.

However, without "-mshort" gcc also aligns the parameters on the stack on 32-bit boundaries upon a function call. Hence parameters don't get passed correctly to the API function.

Is there a way (e.g. function attribute, pragma, etc.) to tell gcc to align function arguments to 16-bit on the stack while calling my API function from "-mno-short" code? Or do I really have to write inline assembler wrappers for all API functions to get the correct calling convention?

ThorstenOtto
Captain Atari
Captain Atari
Posts: 402
Joined: Sun Aug 03, 2014 5:54 pm

Re: gcc m68k: calling a "-mshort" API from non-mshort code

Postby ThorstenOtto » Sun Jun 03, 2018 6:17 pm

czietz wrote:However, without "-mshort" gcc also aligns the parameters on the stack on 32-bit boundaries upon a function call. Hence parameters don't get passed correctly to the API function.


It's not the alignment that matters here, but the promotion to int. That's why eg. all the gemdos/bios/xbios bindings are implement with inline assembler. There is no way to tell a gcc that defaults to 32bit ints, to push only a word to the stack.

do I really have to write inline assembler wrappers for all API functions to get the correct calling convention?


Unless the functions take variable arguments, you can declare a structure that describe the arguments on the stack, and call the function by passing the structure as value. For example

Code: Select all

/* extern short foo(short x, short y); */

short call_foo(short x, short y)
{
    struct { short x; short y; } foo_args;
    foo_args.x = x;
    foo_args.y = y;
    foo(foo_args);
}


Not really optimal, since the parameters are copied around several times, but works.

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 762
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: gcc m68k: calling a "-mshort" API from non-mshort code

Postby mfro » Sun Jun 03, 2018 6:24 pm

czietz wrote:...Is there a way (e.g. function attribute, pragma, etc.) to tell gcc to align function arguments to 16-bit on the stack while calling my API function from "-mno-short" code? Or do I really have to write inline assembler wrappers for all API functions to get the correct calling convention?


I don't think there is an "officially supported" way to do that.

But at least on earlier gcc versions, it was possible to call such functions using a trick: instead of declaring a parameter list, prepare a structure with the intended function parameters and a suitable "fake" function prototype passing this struct (by value). Default structure alignment in gcc happens to fit the parameter passing ABI of -mshort.

This worked for gcc 4.6.4. I never tested this on later versions (YMMV), but I don't see a reason why it shouldn't work there as well.

joska
Hardware Guru
Hardware Guru
Posts: 4149
Joined: Tue Oct 30, 2007 2:55 pm
Location: Florø, Norway
Contact:

Re: gcc m68k: calling a "-mshort" API from non-mshort code

Postby joska » Mon Jun 04, 2018 2:22 pm

mfro wrote:Default structure alignment in gcc happens to fit the parameter passing ABI of -mshort.


Where can I find details about gcc structure alignment? I'm trying to access structs in gcc-compiled code (gcc 2.95) from PureC, and clearly PureC and gcc does not align structure members the same way :D
Jo Even

VanillaMiNT - Firebee - Falcon060 - Milan060 - Falcon040 - MIST - Mega ST - STM - STE - Amiga 600 - Sharp MZ700 - MSX - Amstrad CPC - C64

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 762
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: gcc m68k: calling a "-mshort" API from non-mshort code

Postby mfro » Mon Jun 04, 2018 5:25 pm

joska wrote:
mfro wrote:Default structure alignment in gcc happens to fit the parameter passing ABI of -mshort.


Where can I find details about gcc structure alignment? I'm trying to access structs in gcc-compiled code (gcc 2.95) from PureC, and clearly PureC and gcc does not align structure members the same way :D


I'm not anymore familar with these old compilers, but would assume as long as you gcc-compile with -mshort, structure alignment should be the same. Probably the offsetof()-macro (that both implement in stddef.h) is your best friend.

ThorstenOtto
Captain Atari
Captain Atari
Posts: 402
Joined: Sun Aug 03, 2014 5:54 pm

Re: gcc m68k: calling a "-mshort" API from non-mshort code

Postby ThorstenOtto » Tue Jun 05, 2018 12:06 am

joska wrote:Where can I find details about gcc structure alignment? I'm trying to access structs in gcc-compiled code (gcc 2.95) from PureC, and clearly PureC and gcc does not align structure members the same way :D


I think structure alignment in gcc 4.6.4 should be the same. At least the trick mentioned above, passing structures by value, also works the other way around, which is for example needed when declaring callback functions from wdialog: you then declare your callback function (which is called from Pure-C compiled code, or maybe assembler) as taking that structure as only argument.

I'm not sure though wether gcc 2.95 was different. What is also different IIRC is the order of assignment of bitfield members.

joska
Hardware Guru
Hardware Guru
Posts: 4149
Joined: Tue Oct 30, 2007 2:55 pm
Location: Florø, Norway
Contact:

Re: gcc m68k: calling a "-mshort" API from non-mshort code

Postby joska » Tue Jun 05, 2018 7:16 am

mfro wrote:[I'm not anymore familar with these old compilers, but would assume as long as you gcc-compile with -mshort, structure alignment should be the same.


Quite possible, but I'm afraid that the code in question does not compile with -mshort.

mfro wrote:Probably the offsetof()-macro (that both implement in stddef.h) is your best friend.


Thanks, I was not aware of this macro :) I "solved" this problem by figuring out the offset for each structure member using both compilers, and then pad the struct accordingly when using PureC. Not very clean, but it works for now.
Jo Even

VanillaMiNT - Firebee - Falcon060 - Milan060 - Falcon040 - MIST - Mega ST - STM - STE - Amiga 600 - Sharp MZ700 - MSX - Amstrad CPC - C64


Social Media

     

Return to “C / PASCAL etc.”

Who is online

Users browsing this forum: No registered users and 2 guests