[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [f-cpu] calling conventions



> > 15 registers on the whole right for the passages of the parameters? 
> 13 for the 
> > donnee 1 for the stack of parameters and 1 for the number of
> parameters.  
> 
> Right, although I had something different in mind when I proposed the
> calling conventions: r1-r13 should hold the first 13 parameters,
> r14/r15 length and pointer of *the rest of them*, not all of them as
> the manual states.
The problem in that case is for function like printf and scanf, it complicated
a lot the call convention.

If you want we can say that we only transfert the parameter after the 13th,
into the stack, but we reserved the needed place, so that printf/scanf first
start to save them into the stack and we didn't do any stupid transfert.
It can be a solution to solve our problem with a best result.
 
> > After read this section I have made a small script for scann all my
> source file 
> > and see the average number of parameter used and I obtained
> approximately 3 
> > parameters (a little more or a little less according to the languages)
> what I 
> > want to say that there is ten unused register in each functions.  
> 
> As I mentioned here before, a function is free to use the unused
> parameter registers as local (unsaved) temporary registers.
Right, I forget this mention in the manual, I will fixe that.

> > What I propose has the place : first an observation, as well the
> > caller function as the function to call know at the compile time the number
> > of parameters.

> Not true. In some languages, there are functions taking a variable
> number of arguments - which is of course unknown when the function is
> compiled.
And we can add the problem of the unprototyped function.
 
> > That is to say N the number of parameters:  
> >  * if n inferior to 13
> >      r1         : number of parameters
> >      r2-r(n+1)  : parameters
> >      r(n+2)-r31 : temporari registers
> 
> That was in fact my proposal.
But we always have the problem of the unknow prototype and the variable
number of argument.

What about my proposition ?

> >  * Si n est superieur a 13
> >      r1         : number of parameters
> >      r2-r14     : parameters
> >      r15        : pointer over the parameters list
> >      r16-r31    : temporari registers
> 
> Whether you put the first 13 args in r1-r13 or in r2-r14 doesn't make
> much of a difference. The advantage of using r1-r13 is that functions
> with fixed and variable argument lists remain call-compatible (which
> they won't be if we follow your proposal).
 
> We could drop the `number of arguments' argument completely:
> 
> 	r1-r14 -> first 14 arguments
> 	r15    -> pointer to additional arguments
 
> In most languages there's no need to pass the *number* of arguments
> (unless it's checked at runtime, e.g. in Lisp or Scheme - but those
> languages need different calling conventions anyway).  But if we have
> to do so, r1 is a logical choice (that is, the function has a `hidden'
> or `0th' argument).
I think that r1 is a good choice too.
 
> > In the case of more than 13 parameters I don't know if it is useful to put
> > all the parameters in the list pointed by r15. Indeed to have all the
> > parameters lists some in very practical, for the function such as [printf]
> > in C or [format] in Pascal, but I am not sure time to gain in these function
> > is a superior than time wasted to put in memory parameters which are
> > already in the registers.

> You're right again (and the manual is wrong wrt. this point).
You must at least give enough space to store them in case of you need
a var_args. So you need space, but not always to save them.
 
> BTW: The border between `caller-saved' and `global' registers was at
> r48 in my proposal, not r60. I intentionally left some global
> registers unassigned, for use by applications (and even the current
> assignments for r60-r63 can be debated - e.g. if a language doesn't 
> need stack or frame pointers). That is, the assignment should be:

> 	r0      = always zero
> 	r1      = function return value, and also
> 	r1-r14  = function arguments (call-clobbered)
> 	r15     = pointer to additional function arguments (call-clobbered)
> 	r16-r31 = temporary registers (call-clobbered)
> 	r32-r47 = local registers (saved by callee)
> 	r48-r63 = global registers (shared by all functions)
 
> with the following assignments for C- and Pascal-style languages (but
> not necessarily others):
 
> 	r60 = function return address
> 	r61 = global pointer
> 	r62 = frame pointer
> 	r63 = stack pointer
 
> Note that r48-r63 are *not* callee-saved as the manual states. A
> function *must not* expect them to be unchanged across function calls (but
> *may* save/restore them on entry/exit and use them like the callee-saved
> registers r32-r47 if it doesn't need the global values).  Analogously,
> a function *may* use r1-r15 as temporary registers if there aren't so
> many arguments (or it doesn't need them).

I really think that 12 registers for undefined use and not save it's a lot.
And I really don't see where or in which language you can use them. If you
absolutly want to use not callee-saved register for storing undefined register
why not, but perhaps only 5 and not 15 (I think that we have in a normal
function more callee-saved register than not calle-saved registers, so we need
more space for them, and reserving some area for a not defined-perhaps-in-future
can cause a loose of efficiency).

A+
  Cedric
*************************************************************
To unsubscribe, send an e-mail to majordomo@seul.org with
unsubscribe f-cpu       in the body. http://f-cpu.seul.org/