[Coco] Calling convention used by older 6809 C compilers

William Astle lost at l-w.ca
Fri Jun 7 23:53:42 EDT 2024


According to its makefile, platoterm is using gcc6809 so this is the 
gcc6809 calling convention. It works as follows:

* char is 8 bits, int is 16 bits, long is 32 bits and floating points 
are 32 bit IEEE floats (float, double, and long double). long long is 
also 32 bits.

* Y and U are call preserved, all others are call clobbered

* all arguments go on the stack for variadic functions; otherwise see below

* the *first* 8 bit argument is passed in B; the *first* 16 bit argument 
is passed in X. Those may not be the first argument to the function. If 
the only 8 bit argument is the last one of 15, that 15th argument would 
be passed in B.

* an 8 bit return value is returned in B; a 16 bit return value is 
returned in X

* Functions with larger return values receive a pointer argument that 
specifies where the return value goes; which includes long and float. 
This will be the first argument so it will usually end up in X.

* Based on some experimentation with structs, it looks like it passes a 
pointer for the return value for structs and unions of any size but it 
passes 8 and 16 bit structs in B, X, or the stack as it would for other 
arguments.

The reasoning behind the B/X/Stack convention was that the majority of 8 
bit arguments are probably char and a great many 16 bit arguments are 
either pointers or will be compared with something or otherwise do 
something that LEAX can handle. (CMPX being smaller and faster than CMPD.)

If you grab the gcc6809 patch against gcc 4.6.4 from the lwtools source 
and build it, you should be able to test any corner cases.

On 2024-06-07 20:27, Pierre Sarrazin via Coco wrote:
> Hi. I'm in the process of adding a second calling convention to CMOC,
> a C-like compiler that targets the 6809.
> 
> I have seen C programs for the 6809 that had some code written in
> assembly that assumed a calling convention where the first parameter
> of a function is received in register B or X, depending on its size,
> instead of on the stack, as in CMOC's default convention.
> 
> platotermCoCo is such a program:
> https://github.com/beretta42/platotermCoCo/tree/master/src/coco2
> 
> I'm looking for a detailed description of that calling convention,
> with the goal of clarifying a few questions that I have on corner cases.
> 
> 1. Is the first parameter still passed in B or X when the parameter is
>     a 1- or 2-byte struct or union?
> 
> 2. When the return value is one or two bytes, which register is it
>     returned in?
> 
> 3. When the function must return a struct, a union, a long, a float
>     or a double, does it receive a hidden first parameter that points
>     to the location to be filled with the return value?
>     If so, is that hidden parameter received in X?
>     What if the return type is a 1- or 2-byte struct or union?
> 
> Thanks for any leads...
> 
> The CMOC home page: http://sarrazip.com/dev/cmoc.html
> 

-- 
William Astle



More information about the Coco mailing list