<div dir="ltr">Hi,<div><br></div><div>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]).</div><div><br></div><div>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.</div><div><br></div><div>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).</div><div><br></div><div>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).</div><div><br></div><div>Cheers,</div><div>Ludovic</div><div><br></div><div>[1] <a href="https://github.com/openjdk/jdk/blob/953ce8da2c7ddd60b09a18c7875616a2477e5ba5/src/hotspot/cpu/riscv/templateTable_riscv.cpp#L3406">https://github.com/openjdk/jdk/blob/953ce8da2c7ddd60b09a18c7875616a2477e5ba5/src/hotspot/cpu/riscv/templateTable_riscv.cpp#L3406</a></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Oct 4, 2022 at 1:01 PM Zixian Cai <<a href="mailto:zixian.cai@anu.edu.au">zixian.cai@anu.edu.au</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="msg9172683996832669541">





<div lang="EN-AU" style="overflow-wrap: break-word;">
<div class="m_1646533269108842186WordSection1">
<p class="MsoNormal"><span style="color:black">Hi all,</span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span style="color:black"> </span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span style="color:black">I’m just wondering what the best practices are in terms of choosing registers.</span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span style="color:black"> </span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span style="color:black">I was looking at the assembly code for tlab allocation (<a href="https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L131" title="https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L131" target="_blank"><span style="color:rgb(4,74,145)">https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L131</span></a>)
 and noticed the following.</span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<ol style="margin-top:0cm;font-variant-caps:normal;text-align:start;word-spacing:0px" start="1" type="1">
<li class="m_1646533269108842186MsoListParagraph" style="color:black;margin-top:0cm;margin-bottom:0cm">
tmp1 register is invalid.<span style="font-size:12pt"><u></u><u></u></span></li><li class="m_1646533269108842186MsoListParagraph" style="color:black;margin-top:0cm;margin-bottom:0cm">
tmp2 register is valid but sometimes clashes with var_size_in_bytes, which requires the workaround here<span class="m_1646533269108842186apple-converted-space"> </span><a href="https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L155" title="https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L155" target="_blank"><span style="color:rgb(4,74,145)">https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L155</span></a><span style="font-size:12pt"><u></u><u></u></span></li><li class="m_1646533269108842186MsoListParagraph" style="color:black;margin-top:0cm;margin-bottom:0cm">
t0 is used as a temporary register despite not passed into the method as a temporary register<span class="m_1646533269108842186apple-converted-space"> </span><a href="https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L149" title="https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L149" target="_blank"><span style="color:rgb(4,74,145)">https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp#L149</span></a><span style="font-size:12pt"><u></u><u></u></span></li></ol>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span style="color:black"> </span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span style="color:black">I’d really appreciate if someone could shed insight on how these decisions are made so that I can avoid common pitfalls when writing assembly code. The only resource I found at the moment is the architecture description file<span class="m_1646533269108842186apple-converted-space"> </span><a href="https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/riscv.ad#L73" title="https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/riscv.ad#L73" target="_blank"><span style="color:rgb(4,74,145)">https://github.com/openjdk/jdk/blob/5a9cd33632862aa2249794902d4168a7fe143054/src/hotspot/cpu/riscv/riscv.ad#L73</span></a><span class="m_1646533269108842186apple-converted-space"> </span>which
 suggests x5(t0)-x6(t1) can always be used as temporary registers.</span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span style="color:black"> </span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span lang="EN-US" style="color:black">Sincerely,</span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
<p class="MsoNormal" style="font-variant-caps:normal;text-align:start;word-spacing:0px">
<span lang="EN-US" style="color:black">Zixian</span><span style="font-size:13.5pt;color:black"><u></u><u></u></span></p>
</div>
</div>

</div></blockquote></div>