Custom calling conventions in C code

Hi all,

LLVM supports arbitrary, backend specific calling conventions, besides the
standard predefined ones. I want to be able to compile C programs using some
custom calling conventions, but I couldn't find any way to mark a specific
program in my C source as using some arbitrary, custom calling convention (not
in C itself, clang or gcc extensions).

Is there any way to accomplish this, or should there be one?

Gr.

Matthijs

Hey Matthijs,

There isn't currently a way to do this, you'd have to use specific named conventions like "cdecl" "stdcall" "pascal" etc, along with attributes.

I think it would be a great thing for compiler hackers to have a mechanism to access an arbitrary calling convention, but I also think it would be a disaster to expose this to end user code. The problem is that not all constructs are valid with every calling convention, and if there is ever a large install base of code using "calling convention 19" in their C code, we'd have to support that forever. CC#'s are supposed to be an internal implementation detail of the IR.

-Chris

I think it would be a great thing for compiler hackers to have
a mechanism to access an arbitrary calling convention, but I
also think it would be a disaster to expose this to end user
code.

Maybe via attributes and macros.

#define _CC_WEIRD_EMBEDDED_COMPILER \
  __attribute__(("cc-call-randomly")) \
  __attribute__(("cc-indirect-accumulator-access")) \
  __attribute__(("cc-halt-instruction-after-every-jump"))

And then I write

void weird_function(void) __CC_WEIRD_EMBEDDED_COMPILER
{
    // ...
}

The problem is that not all constructs are valid with
every calling convention, and if there is ever a large install
base of code using "calling convention 19" in their C code,
we'd have to support that forever.

Not with a scheme similar to the like above.

However, you'd need to support the specific attribute forever.
Not sure if that is a win :slight_smile:

Hi Chris,

[Specifiying custom calling conventions from C]

There isn't currently a way to do this, you'd have to use specific named
conventions like "cdecl" "stdcall" "pascal" etc, along with attributes.

The problem is that I'd like to have a completely custom and backend-specific
calling convention, and using one of those keywords would be abuse.

I think it would be a great thing for compiler hackers to have a mechanism
to access an arbitrary calling convention, but I also think it would be a
disaster to expose this to end user code. The problem is that not all
constructs are valid with every calling convention, and if there is ever a
large install base of code using "calling convention 19" in their C code,
we'd have to support that forever. CC#'s are supposed to be an internal
implementation detail of the IR.

In our case, we are working with a specific C variant, which is mostly C
compatible and can therefore be parsed by clang completely. So, I'm looking
for a way to be able to write down a custom calling convention from within
that language, without having to modify clang locally. So, support for a
__attribute__(()) extension would be just fine.

I see something like this in a similar way as the annotate attribute. It's
possible to write it down, but clang won't guarantee anything about how it's
handled. In other words, its only useful when you know beforehand which
backend is going to be handling your code. Support a specific calling
convention is then something for the backend, which might or might not
continue support for a specific calling convention. Doesn't that sound
reasonable?

Gr.

Matthijs

I think it would be a great thing for compiler hackers to have a mechanism
to access an arbitrary calling convention, but I also think it would be a
disaster to expose this to end user code. The problem is that not all
constructs are valid with every calling convention, and if there is ever a
large install base of code using "calling convention 19" in their C code,
we'd have to support that forever. CC#'s are supposed to be an internal
implementation detail of the IR.

In our case, we are working with a specific C variant, which is mostly C
compatible and can therefore be parsed by clang completely. So, I'm looking
for a way to be able to write down a custom calling convention from within
that language, without having to modify clang locally. So, support for a
__attribute__(()) extension would be just fine.

Ok, so you have specific conventions you want to support. Something like:

void foo() __interrupt__ {

}

or whatever. The best way to do this is to have __interrupt__ be a target-specific #define for __attribute__((interrupt)) and then have your target handle the interrupt attribute however you want.

backend is going to be handling your code. Support a specific calling
convention is then something for the backend, which might or might not
continue support for a specific calling convention. Doesn't that sound
reasonable?

Yep, supporting specific calling conventions is fine, I just don't want something like:

__attribute__((callingconv(47)))

-Chris

or whatever. The best way to do this is to have __interrupt__ be a
target-specific #define for __attribute__((interrupt)) and then have your
target handle the interrupt attribute however you want.

Yep, supporting specific calling conventions is fine, I just don't want
something like:

__attribute__((callingconv(47)))

Okay, sounds reasonable. However, is there any generic way to do this in
clang, or will I end up locally patching clang for this?

If the latter is the case, might function annotation be an alternative?
Currently, I can specify __attribute__((annotate("foo"))) for global
variables, but not for functions (both in clang and gcc). I'm not sure where
this limitation comes from, but enabling generic annotation for functions
should also work for me (I can simply add a frontend pass that translates
those annotations into calling conventions for my backend, or leave them as
annotions even).

Gr.

Matthijs

You could use attr(annotate). I think attributes in general can only be put on function forward declarations, not definitions.

-Chris