On 6/24/23 19:40, Stefan O'Rear wrote:
On Sat, Jun 24, 2023, at 11:01 AM, Jeff Law via Gcc-patches wrote:
On 6/21/23 02:14, Wang, Yanzhang wrote:
Hi Jeff, sorry for the late reply.
The long branch handling is done at the assembler level. So the clobbering
of $ra isn't visible to the compiler. Thus the compiler has to be
extremely careful to not hold values in $ra because the assembler may
clobber $ra.
If assembler will modify the $ra behavior, it seems the rules we defined in
the riscv.cc will be ignored. For example, the $ra saving generated by this
patch may be modified by the assmebler and all others depends on it will be
wrong. So implementing the long jump in the compiler is better.
Basically correct. The assembler potentially clobbers $ra. That's why
in the long jump patches $ra becomes a fixed register -- the compiler
doesn't know when it's clobbered by the assembler.
Even if this were done in the compiler, we'd still have to do something
special with $ra. The point at which decisions about register
allocation and such are made is before the point where we know the final
positions of jumps/labels. It's a classic problem in GCC's design.
Do you have a reference for more information on the long jump patches?
I can extract the patch Andrew wrote if that would be helpful.
I'm particularly curious about why $ra was selected as the temporary instead
of $t1 like the tail pseudoinstruction uses.
$ra would be less disruptive from a code generation standpoint.
Essentially whatever register is selected has to become a fixed
register, meaning it's unavailable to the allocator. Thus $t1 would be
a horrible choice. Ultimately this is defined by the assembler.
jeff