[PATCH v1 2/2] LoongArch: Add call and tail pseudo instructions
mengqinggang
mengqinggang@loongson.cn
Fri Dec 1 02:26:30 GMT 2023
We consider generating call and tail by default in the normal code model
in the future,
and supporting relax to b/bl.
For the extreme code model, the function call are implemented by no-plt.
There are two instruction sequences, the second will use got entry.
One call64 macro instruction can't expand to two instruction sequences.
int f();
pcalau12i $r13,%pc_hi20(f)
addi.d $r12,$r0,%pc_lo12(f)
lu32i.d $r12,%pc64_lo20(f)
lu52i.d $r12,$r12,%pc64_hi12(f)
add.d $r12,$r13,$r12
jirl $r1,$r12,0
extern int f();
pcalau12i $r13,%got_pc_hi20(f)
addi.d $r12,$r0,%got_pc_lo12(f)
lu32i.d $r12,%got64_pc_lo20(f)
lu52i.d $r12,$r12,%got64_pc_hi12(f)
ldx.d $r12,$r13,$r12
jirl $r1,$r12,0
在 2023/12/1 上午3:08, WANG Xuerui 写道:
> On 12/1/23 00:10, Xi Ruoyao wrote:
>> I'd not use a plain "call" or "tail" as the pseudo name. The problem is
>> people not very familiar with LoongArch may use them instead of "bl" or
>> "b" everywhere and regress the code.
>>
>> Esp. the programmers know some RISC-V: in Aug 28 we've noticed several
>> RISC-V developers were attending Loongson user conference and they may
>> contribute some LoongArch code too in the future. In RISC-V assembly
>> call/tail are aliases of jal with rd = ra/r0.
>>
>> Maybe "call_medium"? "call_36"? "call_far"?
>>
>> Or if we can relax call/tail into b/bl it would be even better.
> I'd suggest making "call"/"tail" context-dependent and/or relaxable,
> and maybe providing unambiguous "{call,tail}.{16,36}" for explicit
> control.
>>
>> On Thu, 2023-11-30 at 19:13 +0800, mengqinggang wrote:
>>> ---
>>> gas/testsuite/gas/loongarch/medium-call.d | 10 ++++++++--
>>> gas/testsuite/gas/loongarch/medium-call.s | 2 ++
>>> ld/testsuite/ld-loongarch-elf/medium-call.s | 2 ++
>>> opcodes/loongarch-opc.c | 11 +++++++++++
>>> 4 files changed, 23 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/gas/testsuite/gas/loongarch/medium-call.d
>>> b/gas/testsuite/gas/loongarch/medium-call.d
>>> index 4183818cb4f..3491760b96a 100644
>>> --- a/gas/testsuite/gas/loongarch/medium-call.d
>>> +++ b/gas/testsuite/gas/loongarch/medium-call.d
>>> @@ -10,6 +10,12 @@ Disassembly of section .text:
>>> [ ]+0:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
>>> [ ]+0: R_LARCH_CALL36[ ]+a
>>> [ ]+4:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
>>> -[ ]+8:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
>>> +[ ]+8:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
>>> [ ]+8: R_LARCH_CALL36[ ]+a
>>> -[ ]+c:[ ]+4c000180[ ]+jr[ ]+\$t0
>>> +[ ]+c:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
>>> +[ ]+10:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
>>> +[ ]+10: R_LARCH_CALL36[ ]+a
>>> +[ ]+14:[ ]+4c000180[ ]+jr[ ]+\$t0
>>> +[ ]+18:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
>>> +[ ]+18: R_LARCH_CALL36[ ]+a
>>> +[ ]+1c:[ ]+4c000180[ ]+jr[ ]+\$t0
>>> diff --git a/gas/testsuite/gas/loongarch/medium-call.s
>>> b/gas/testsuite/gas/loongarch/medium-call.s
>>> index f2977d1c6d7..55a2fc6ffff 100644
>>> --- a/gas/testsuite/gas/loongarch/medium-call.s
>>> +++ b/gas/testsuite/gas/loongarch/medium-call.s
>>> @@ -1,6 +1,8 @@
>>> # call .L1, r1(ra) temp register, r1(ra) return register.
>>> + call a
>>> pcaddu18i $r1, %call36(a)
>>> jirl $r1, $r1, 0
>>> # tail .L1, r12(t0) temp register, r0(zero) return register.
>>> + tail a
>>> pcaddu18i $r12, %call36(a)
>>> jirl $r0, $r12, 0
>>> diff --git a/ld/testsuite/ld-loongarch-elf/medium-call.s
>>> b/ld/testsuite/ld-loongarch-elf/medium-call.s
>>> index 4d1888b76a0..31d4c2c1c75 100644
>>> --- a/ld/testsuite/ld-loongarch-elf/medium-call.s
>>> +++ b/ld/testsuite/ld-loongarch-elf/medium-call.s
>>> @@ -1,7 +1,9 @@
>>> .L1:
>>> # call .L1, r1(ra) temp register, r1(ra) return register.
>>> + call .L1
>>> pcaddu18i $r1, %call36(.L1)
>>> jirl $r1, $r1, 0
>>> # tail .L1, r12(t0) temp register, r0(zero) return register.
>>> + tail .L1
>>> pcaddu18i $r12, %call36(.L1)
>>> jirl $r0, $r12, 0
>>> diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
>>> index 15c7da6340c..1d02f020686 100644
>>> --- a/opcodes/loongarch-opc.c
>>> +++ b/opcodes/loongarch-opc.c
>>> @@ -293,6 +293,15 @@ const char *const loongarch_x_normal_name[32] =
>>> &LARCH_opts.ase_lp64, \
>>> &LARCH_opts.ase_gpcr
>>> +#define INSN_LA_CALL \
>>> + "pcaddu18i $ra,%%call36(%1);" \
>>> + "jirl $ra,$ra,0;", \
>>> + &LARCH_opts.ase_lp64, 0
>>> +
>>> +#define INSN_LA_TAIL \
>>> + "pcaddu18i $t0,%%call36(%1);" \
>>> + "jirl $zero,$t0,0;", \
>>> + &LARCH_opts.ase_lp64, 0
>>> static struct loongarch_opcode loongarch_macro_opcodes[] =
>>> {
>>> @@ -340,6 +349,8 @@ static struct loongarch_opcode
>>> loongarch_macro_opcodes[] =
>>> { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64, 0 },
>>> { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64_LARGE_ABS, 0 },
>>> { 0, 0, "la.tls.gd", "r,r,l",
>>> INSN_LA_TLS_GD64_LARGE_PCREL, 0 },
>>> + { 0, 0, "call", "la", INSN_LA_CALL, 0 },
>>> + { 0, 0, "tail", "la", INSN_LA_TAIL, 0 },
>>> { 0, 0, "pcaddi", "r,la", "pcaddi %1,
>>> %%pcrel_20(%2)", &LARCH_opts.ase_ilp32, 0, 0 },
>>> { 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list. */
>>> };
More information about the Binutils
mailing list