Choosing registers for assembly snippets
Zixian Cai
zixian.cai at anu.edu.au
Wed Oct 5 11:26:40 UTC 2022
Hi Ludovic,
Thanks for the information. Regarding using the registers passed in, is there any guarantee in terms of register conflict or we should handle all corner cases?
One example I mentioned earlier is, again in TLAB allocate, https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L155.
The code handles the case where var_size_in_bytes is the same register as tmp2. And I can confirm that such conflict indeed happens in practice, and if not handled, causes issues, for example, in java.util.Arrays.copyOfRange, where the object size register is used after allocation to perform the copying.
Sincerely,
Zixian
On 5/10/2022, 20:10, "Ludovic Henry" <ludovic at rivosinc.com> wrote:
Hi,
My understanding is it's quite a mixed-bag. There are some places where it is assumed which register is used (ex: StubGenerator::generate_zero_blocks assumes x28 and x29 are used in MacroAssembler::zero_words) while other places pass the registers to be used. It's surprising that the TLAB allocation passes the registers to be used (tmp1 and tmp2) but there are cases where tmp1 is noreg (like templateTable_riscv.cpp [1]).
In that specific case of TLAB allocation, it seems to me the right approach is to make sure `tmp1` is always valid (AFAIU, the only required change is to pass `t0` in [1]), and use `tmp1` in place of `t0` in BarrierSetAssembler::tlab_allocate. It would also require asserting that both tmp1 and tmp2 are not noreg.
Finally, on always using t0 and t1 as temporary registers, it's the case most of the time, but there are cases where you can't (StubGenerator::generate_zero_blocks and MacroAssembler::zero_words for example).
So IMHO the best practice is to pass the registers you can use. The exception is when you can't (like the StubGenerator which generates the code at startup); then it's a tradeoff between passing the parameters as normal arguments (c_rarg0, c_rarg1, etc.) or make an assumption or where the value is currently stored (x28. x29 in MacroAssembler::zero_words case for example).
Cheers,
Ludovic
[1] https://github.com/openjdk/jdk/blob/953ce8da2c7ddd60b09a18c7875616a2477e5ba5/src/hotspot/cpu/riscv/templateTable_riscv.cpp#L3406
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/riscv-port-dev/attachments/20221005/ea2e68ff/attachment-0001.htm>
More information about the riscv-port-dev
mailing list