[PATCH] LoongArch: Add new relocation R_LARCH_CALL36

chenglulu chenglulu@loongson.cn
Fri Nov 17 09:00:09 GMT 2023


在 2023/11/17 下午12:44, WANG Xuerui 写道:
> On 11/17/23 09:40, mengqinggang wrote:
>> We will add call36 and tail36 pseudo instructions in gas:
>>     call36 f -> pcaddu18i $ra, %call36(f) + jirl $ra, $ra, 0
>>     tail36 f -> pcaddu18i $t0, %call36(f) + jirl $zero, $t0, 0
>>
>>
>> 在 2023/11/8 下午7:04, Xi Ruoyao 写道:
>>> On Wed, 2023-11-08 at 01:34 +0800, WANG Xuerui wrote:
>>>> On 11/7/23 20:16, Xi Ruoyao wrote:
>>>>> I'd like to have some pseudo instructions:
>>>>>
>>>>> - call36 r0, t0, func -> pcaddu18i t0, func + jirl r0, t0, func
>>>>> - call36 t0, func -> pcaddu18i t0, func + jirl t0, t0, func
>>>>> - call36 func -> pcaddu18i ra, func + jirl ra, ra, func
>>>>>
>>>>> These will make the work of the compiler (or assembly programmer)
>>>>> easier.  Anyway with R_LARCH_CALL36 the pcaddu18i instruction and the
>>>>> jirl instruction must be adjacent, so there is no benefit for the
>>>>> compiler or programmer to use them separately to make a function 
>>>>> call.
>>>>>
>>>>> And the last one can be annotated with R_LARCH_RELAX so we may 
>>>>> relax it
>>>>> into a bl instruction if possible.
>>>> The suggestion sounds reasonable! Although IMO a name like "call.36"
>>>> might look better, the name "call36" also works for me.
>>>>
>>>> And regarding the proposed "call36 func" reusing the $ra for the
>>>> temporary -- IIUC this will break the subroutine return prediction. I
>>>> think we've been hit by similar regalloc in GCC and have since fixed
>>>> that: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11013.
>>> The URL is wrong, PR 11013 is 20-years old.
>>>
>>>> So maybe it's necessary to specify a different temp register after
>>>> all...
>>> I think for a normal call (call36 $ra, $ra, func or just call36 $ra) it
>>> should be OK, but for a sibcall (call36 $zero, $ra, func) it will
>>> confuse the return predictor and we better use another temp register.
>
> Hmm I found out the correct bug number (it was a copy-paste mistake): 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110136
>
> So the main point is: is any jirl in the "jirl <any>, $ra, <any>" form 
> able to trigger the return stack optimization, or is it just "jirl 
> $zero, $ra, 0" i.e. "ret"? If the branch predictors in popular 
> LoongArch models are smart enough to not consider "jirl $ra, $ra, 0" 
> also as a "ret", then re-using the $ra as scratch space is okay. 
> Otherwise we have to make the pseudo-insn take another temp register 
> (and optionally disallow/warn usage of $ra in that place).

I don't quite understand the circumstances of this worrying sequence of 
instructions.

Now we have two scenarios:

1. call36 (pcaddu18i $ra, %call36(func)+jirl $ra, $ra,0)

2. tail36 (pcaddu18i $t0, %call36(func)+jirl $r0,$t0,0)

In neither case will 'jirl $r0,$ra,0' be generated.

>
> BTW, could we have the RISC-V-like bare "call" and "tail" too? It 
> could be useful for more uniform asm among different code models ("bl" 
> vs "pcaddu18i + jirl" vs "lu12i + addi + lu32i + lu52i + jirl"), apart 
> from lowering learning curve for those with some RISC-V asm 
> background. We could make "call" and "tail" behavior vary based on the 
> code model chosen, and also provide explicit control via more 
> pseudo-insns like "{call,tail}26" and "{call,tail}64" apart from 
> "{call,tail}36".
>
> (The above is a suggestion for you to consider; it's not immediately 
> necessary for the medium code model work at hand, just for symmetry 
> and enabling users to gain more control over their asm.)



More information about the Binutils mailing list