This commit includes the necessary changes to clang and LLVM to support
the ilp32e ABI.
The central changes in this ABI, compared to ilp32 are:
- Only 6 integer argument registers (rather than 8);
- Only 2 callee-saved registers (rather than 12); and
- A Stack Alignment of 32bits (rather than 128bits).
This means there are a variety of changes including to the datalayout
string, to ABI lowering in Clang, to calling convention handling, and
most complex, to stack management.
The difficulty with stack management is compiling for ilp32e with the
standard RISC-V D extension enabled. This is because with the
D-extension, the floating point registers are 8 bytes and have a spill
alignment of 8 bytes.
This becomes a problem if you have assigned an FPR64 virtual register,
as during a call this is not preserved, and will need to be spilled.
This spill is 8-byte aligned, so the stack needs realigning to
accomodate it. With sufficient register pressure (which is not
difficult, as there are only two callee-saved GPRs), fp might have
already been allocated, and so realigning the stack is not possible. To
prevent this, when the D-extension is enabled with ilp32e, and a
function contains any calls, we conservatively force the frame pointer
to be reserved, in case we need it later to realign the stack.
(For background: we have to choose registers to reserve before register
allocation; during register allocation spills may be created; and then
we insert the prolog/epilog (several passes) after register allocation).
One thing this patch fixes, compared to previous ilp32e patches, is that
the ABI does not influence the registers saved during an interrupt. This
choice is made solely based on the architecture extensions available.
This is based upon D59592 by Daliang Xu (xudaliang.pku). I have fixed
the issue with interrupt CSRs, and excessive duplication of the GPR