3 ms·
Right. A form of this millicode LDM/STM is implemented in gcc and clang when invoked with the -msave-restore flag. This calls one of a set of (intertwined) fun
by brucehoult 4y ago
Right. A form of this millicode LDM/STM is implemented in gcc and clang when invoked with the -msave-restore flag.
This calls one of a set of (intertwined) functions on function entry. The called function saves N registers s0 .. s[N-1] plus the Return Address register on the stack. The millicode can save the RA from the original function because RISC-V allows using any register for the return address and the save-restore millicode uses a different one: t0 (register 5) instead of ra (register 1).
The corresponding restore function is jumped to (tail called) at the end of the function and restores s0 .. s[N-1] and then returns to the caller of the original function.
The three extra jump instructions involved with using -msave-restore (one each call, return, and tail-call) of course add several clock cycles. But I have seen code using -msave-restore run faster than code not using it because of better utilisation of the icache. In particular, I have seen this with CoreMark on a machine with 16 KB icache where -msave-restore gave a 3% speed improvement.
At one point, the millicode for -msave-restore was 96 bytes of code. I don't know whether anyone has tweaked it since, but that is a pretty minor part of most icaches.