From 784d5a936a73f0f0676fef782422c54ed280f599 Mon Sep 17 00:00:00 2001 From: mengqinggang Date: Thu, 23 Nov 2023 15:42:49 +0800 Subject: LoongArch: Add call36 and tail36 pseudo instructions for medium code model For tail36, it is necessary to explicitly indicate the temporary register. Therefore, the compiler and users will know that the tail will use a register. call36 func pcalau18i $ra, %call36(func) jirl $ra, $ra, 0; tail36 $t0, func pcalau18i $t0, %call36(func) jirl $zero, $t0, 0; --- 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 4183818..3491760 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 f2977d1..74d1507 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. + call36 a pcaddu18i $r1, %call36(a) jirl $r1, $r1, 0 # tail .L1, r12(t0) temp register, r0(zero) return register. + tail36 $r12, 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 4d1888b..50a6b8e 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. + call36 .L1 pcaddu18i $r1, %call36(.L1) jirl $r1, $r1, 0 # tail .L1, r12(t0) temp register, r0(zero) return register. + tail36 $r12, .L1 pcaddu18i $r12, %call36(.L1) jirl $r0, $r12, 0 diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c index 15c7da6..b47817f 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;", \ + 0, 0 + +#define INSN_LA_TAIL \ + "pcaddu18i %1,%%call36(%2);" \ + "jirl $zero,%1,0;", \ + 0, 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, "call36", "la", INSN_LA_CALL, 0 }, + { 0, 0, "tail36", "r,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. */ }; -- cgit v1.1