[v1,2/2] LoongArch: Add call and tail pseudo instructions

Message ID 20231130111328.3236602-3-mengqinggang@loongson.cn
State Unresolved
Headers
Series Add new relocation R_LARCH_CALL36 |

Checks

Context Check Description
snail/binutils-gdb-check warning Git am fail log

Commit Message

mengqinggang Nov. 30, 2023, 11:13 a.m. UTC
  ---
 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(-)
  

Comments

Xi Ruoyao Nov. 30, 2023, 4:10 p.m. UTC | #1
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.

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.  */
>  };
  
WANG Xuerui Nov. 30, 2023, 7:08 p.m. UTC | #2
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.  */
>>   };
  
mengqinggang Dec. 1, 2023, 2:26 a.m. UTC | #3
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.  */
>>>   };
  
Xi Ruoyao Dec. 1, 2023, 2:31 a.m. UTC | #4
On Fri, 2023-12-01 at 10:26 +0800, mengqinggang wrote:
> We consider generating call and tail by default in the normal code model 
> in the future,
> and supporting relax to b/bl.

Should be fine for call, but for tail it may not be a good idea.  The
problem is the compiler have to reserve a temporary register for tail,
thus increasing register pressure and this cannot be solved by relax. 
So IMO call/tail (or call36/tail36) should still be limited to -
mcmodel=medium.

> 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.

Naming them different: call64.pcrel and call64.got ?

> 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.  */
> > > >   };
>
  
mengqinggang Dec. 1, 2023, 2:44 a.m. UTC | #5
在 2023/12/1 上午10:31, Xi Ruoyao 写道:
> On Fri, 2023-12-01 at 10:26 +0800, mengqinggang wrote:
>> We consider generating call and tail by default in the normal code model
>> in the future,
>> and supporting relax to b/bl.
> Should be fine for call, but for tail it may not be a good idea.  The
> problem is the compiler have to reserve a temporary register for tail,
> thus increasing register pressure and this cannot be solved by relax.
> So IMO call/tail (or call36/tail36) should still be limited to -
> mcmodel=medium.
This may require some performance testing before make a decision.
>> 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.
> Naming them different: call64.pcrel and call64.got ?
>
>> 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.  */
>>>>>    };
  

Patch

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.  */
 };