Page 1 of 1

Defining a Calling Convention

Posted: Fri Aug 26, 2011 3:20 pm
by Nessphoro
Hey guys is it possible to define your own calling convention, in G++.

And if yes, how?

Thanks in advance.

Re: Defining a Calling Convention

Posted: Fri Aug 26, 2011 4:09 pm
by Assembler
AFAIK there is no way to define your own calling convention in gcc or g++ without patching it with your own code.
However, gcc supports the following calling conventions via __attribute__((CONVENTION)):
  1. cdecl
  2. stdcall
  3. fastcall
Best Regards

Re: Defining a Calling Convention

Posted: Fri Aug 26, 2011 4:22 pm
by Nessphoro
Hmm, well thanks, I knew that GCC had some calling conventions.

Re: Defining a Calling Convention

Posted: Mon Aug 29, 2011 12:03 am
by lemonyii
i wanted to do this too, for i don't like gcc calling conventions in x64, and i hope to pass args through r8-r15, which fits my system call convention, instead of rdi, rsi or so.

but i think i'm writing an os, no a compiler, so i would use embedded assembly to get rid of it.
believe me, it will take you the time of writing a good kernel to modify gcc with a new convention.

forget it and go forward.

Re: Defining a Calling Convention

Posted: Mon Aug 29, 2011 12:51 am
by zity
lemonyii wrote:i wanted to do this too, for i don't like gcc calling conventions in x64, and i hope to pass args through r8-r15, which fits my system call convention, instead of rdi, rsi or so.
I pass parameter values in r8-r15 in my system calls. It's pretty straight forward using gcc's register variable.

Code: Select all

register int foo asm ("r8") = 0xC0DE;
It eliminates the need of assembly and change of calling convention.

Re: Defining a Calling Convention

Posted: Mon Aug 29, 2011 1:54 am
by torshie
I cannot find any good reason to define your own calling conventions. If you don't like the register names, #define something like ARG_REG0, ARG_REG1, ARG_REG2. If you don't have enough registers for argument passing, pass them on the stack like G++. Change the number of registers used for argument passing may cause performance overhead.

Re: Defining a Calling Convention

Posted: Mon Aug 29, 2011 2:29 am
by Nessphoro
To be honest, I wanted to add some extra managing stuff before and after the function, but to do that after and before every function call was kind of...rather stupid, I guess.

Re: Defining a Calling Convention

Posted: Mon Aug 29, 2011 10:39 am
by Owen
The AMD64 SystemV ABI calling convention was designed for
  • Minimal code size (rdi, rsi, rcx -> less functions need to move data around, no need for REX bytes for 32-bit values)
  • Optimal number of registers per purpose (Optimal has experimentally been determined to be ~1:1:1 arguments:callee save:callee scratch)
  • Maximum performance (again, the precise register sequence chosen)
Note that the first three register sequence (RDI, RSI, RCX) is such that often string instructions can be embedded without need to move any data around(e.g. if a memset is embedded as the first call of an initialization function - or the compiler generates an implicit one)

A lot of thought and experimentation went into the ABI. It is very close to optimal in both space and time.

That said, I am tempted towards implementing a custom calling convention (much easier for me as I use clang) for C++ in my OS, in which the this pointer is always passed in RAX. This provides advantages when
  • Call chaining (e.g. a->getSomething()->getSomethingElse();)
  • Returning this; for example, the pattern

    Code: Select all

    SomeClass* SomeClass::retain()
    {
        __sync_add_and_fetch(&m_refCount, 1);
        return this;
    }
    
(I've also been tempted to use the same calling convention in Objective-C)

My personal advice? Follow the system calling convention closely for your OS' system call convention. One is easy to change; the other is hard.

Re: Defining a Calling Convention

Posted: Mon Aug 29, 2011 11:39 pm
by torshie
Nessphoro wrote:To be honest, I wanted to add some extra managing stuff before and after the function, but to do that after and before every function call was kind of...rather stupid, I guess.
Try -finstrument-functions, I haven't tried this option myself though. IMO, it's perfectly ok to do something before and after every function for debugging/profiling/logging reasons.

Re: Defining a Calling Convention

Posted: Tue Aug 30, 2011 12:11 am
by Nessphoro
Well, it's rather a part of my OS.

The way threads work in my OS is that you pass a function that is gonna be executed on the other thread, to the kernel. So I was thinking to incorporate some of thread managing stuff into the calling convention itself .