Hi,
I've been spending time again looking at calling convention issues
recently, which in many cases involves looking at what GCC currently
does. I notice that when there is an argument split between the stack
and registers, GCC will have the callee allocate extra space at
positive offsets of the frame pointer to hold the part passed via the
stack.
e.g. the following function will see the a7_s0 argument split between
an argument register and the stack when compiled for RV32 soft-float:
void callee(int a0, int a1, int a2, int a3, int a4, int a5, int
a6, double a7_s0, int64_t s1, float s2, struct large_struct s3) {
...
}
When compiling a simple function like this, gcc might produce a stack
frame where sp = oldsp - 32, and fp = oldsp - 16. [fp+12] is used to
store a7, while the [fp], [fp+4], [fp+8] are unused. As pointed out in
this bug report, this approach can actually lead to misaligned memory
accesses when you might prefer to avoid them
<
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82106>. Is there a
justification for this save area beyond possibly avoiding an extra
store to reassemble a split argument? It's much clearer with the
vararg save area - which is required to ensure that varargs passed in
registers are stored on the stack contiguously with stack arguments
(i.e. ensuring stdarg.h helpers can work). I couldn't see a similar
sort of justification here, but thought it was worth double checking
that I'm not missing something obvious.
Best,
Alex