Page 3 of 3

Re: Calling-Conventions

Posted: Tue Jan 19, 2010 12:05 pm
by ErikVikinger
Hello,

Owen wrote:OK, but how do you mangle a name provided without parameters?
In the same way as

Code: Select all

void foo(void);
I can not see any problem with name-mangling. see http://en.wikipedia.org/wiki/Name_mangling
Owen wrote:You can't even mangle at the call site because there may be subtle mismatches (Int vs short vs char, etc) which will make it mangle incorrectly.
I can. Name-mangling enforce that caller (in module A) and the callee (in module B) use the exactly identical function declaration. If it is not true than the linker can not link this modules together and the user see an error-message.
Owen wrote:Does the C standard even permit name mangling?
I do not know this, i thing this details are below the C standard.
Owen wrote:And do you really want to implement some non-standard variant of C?
I can not see any problem. Okay i am losing some rarely and old libraries (or i have the work for updating the header files) but the very most C code use correct function declarations.

Combuster wrote:So the idiot who gets a linker error over a K&R function IMO deserves that title.
ACK!
Combuster wrote:I'm a bit late with explaining the register distribution argument of last week
I will use the following function header and footer (attention: my stack grows upwards)

Code: Select all

void foo(long a, long b, _____ , int u, int v); //assuming that u and v must be passed at the stack
{
    //u is at [R62 - 4] and v at [R62 - 8]
    PUSH.W   R61  //save the link-register
    PUSHM.W  R48,8 //save the registers R48 ... R55 (callee-save area)
    ADD.W   R62,100  //allocate 100 Bytes stack-frame
    //u is at [R62 - 140] and v at [R62 - 144] ; the stack-frame is at [R62 - 100] .... [R62 - 1]

    /* function code */

    SUB.W    R62,100  //free 100 Bytes stack-frame
    POPM.W  R48,8 //restore the registers R48 ... R55 (callee-save area)
    POP.W   R63  //restore the link-register direct into the instruction-pointer and do the RET
}
This are in both places 3 instructions (that do not modify any other resources). Yes there exist dependencies with the stack-pointer (R62) but this are only 3 instructions and they must not be back-to-back.
I will create, extra for the function header and footer, 2 additional instructions ENTER and LEAVE that do this two jobs each in one instruction.


Greetings
Erik

Re: Calling-Conventions

Posted: Tue Jan 19, 2010 1:06 pm
by Owen
One of the reasons I implement ENTER/LEAVE is because two stack ops back to back would cause the second instruction to stall for 3 cycles in my microarch (4 stage pipeline, register writes occur on the last stage. While I'll likely do data forwarding, it's unlikely for SFRs)

Re: Calling-Conventions

Posted: Tue Jan 19, 2010 1:09 pm
by Combuster
ErikVikinger wrote:I will use the following function header and footer (attention: my stack grows upwards)

Code: Select all

void foo(long a, long b, _____ , int u, int v); //assuming that u and v must be passed at the stack
{
    (...)
    PUSHM.W  R48,8 //save the registers R48 ... R55 (callee-save area)
    (...)
    POPM.W  R48,8 //restore the registers R48 ... R55 (callee-save area)
    (...)
}
This are in both places 3 instructions (that do not modify any other resources). Yes there exist dependencies with the stack-pointer (R62) but this are only 3 instructions and they must not be back-to-back.
I will create, extra for the function header and footer, 2 additional instructions ENTER and LEAVE that do this two jobs each in one instruction.
You know that that wastes 8, mostly unnecessary, read and write cycles, while most of the time you can use the unused argument space as free registers? Also, while you can optimize past the push multiple thanks to register renaming, but not past the pop multiple, so you get a big stall on each function call, rather large compared to whatever code might be in there.

Of course, if that prologue/epilogue is only used for many-argument functions, you should ignore this.

Re: Calling-Conventions

Posted: Tue Jan 19, 2010 2:03 pm
by ErikVikinger
Hello,

Owen wrote:One of the reasons I implement ENTER/LEAVE is because two stack ops back to back would cause the second instruction to stall for ...
Me too.

Combuster wrote:You know that that wastes ...
This sample assumes a big parameter list, the saved registers are only a example too. If the function does not use any register of the callee-save area (R36...R55) it must not do this step. If the function is a leaf function it must not save the link-register (R61) and if no stack-frame needed the function must not allocate it. The ENTER/LEAVE instructions are only useful for big functions that need all registers. If not all 3 steps required the compiler should try to avoid the back-to-back position of the 2 header/footer instructions.


Greetings
Erik

Re: Calling-Conventions

Posted: Tue Feb 23, 2010 2:48 pm
by js
@ErikVikinger
ErikVikinger wrote:
js wrote: Some FPU's have similar regiser banks , If you want to know which, I can tell you once
Yes, please.
Sorry I didn't answer earlier, I was working on other stuff and didn't notice your reply (and now I have two pages of 10-ft long posts to read to catch up... aaaarg).

It's in the IIT variants of the 387 FPU.

http://www.cpu-collection.de/?l0=co&l1=IIT&l2=FPU
In the section FPU for 386DX CPU (after the four first CPU pictures) :
It has 24 user-accessible floating-point registers organized into three register banks. Three additional instructions (FSBP0, FSBP1, FSBP2) allow switching from one bank to another.
[OT]
Your english is quite good, but you often use "ever" instead of "always", and you should put "always" before the verb.
Like in your first post : "call-by-reference use ever a pointer", should be "call-by-reference always use a pointer".
Just thought I'd let you know. (English isn't my native language either, so I surely make some mistakes too).
[/OT]