[PATCH 2/4] LoongArch: Represent FP without RA saved in SFrame
Huang Pei
huangpei@loongson.cn
Thu Sep 25 12:48:29 GMT 2025
Similar to s390, this should work on MIPS/RISC-V too.
gas/
* gen-sframe.c (get_fre_num_offsets): For loongarch account padding
RA offset, if FP without RA saved.
(sframe_get_fre_offset_size0: Likewise.
(output_sframe_row_entry): For loongarch write a padding RA
offset, if FP without RA needs to be reprented.
(sframe_do_fde): Enable FP without RA saved to be represented on
loongarch.
libsframe/
* sframe.c: adjust comment.
Signed-off-by: Huang Pei <huangpei@loongson.cn>
---
gas/gen-sframe.c | 21 ++++++++++------
.../gas/cfi-sframe/cfi-sframe-loongarch-4.d | 25 +++++++++++++++++++
...garch-err-1.s => cfi-sframe-loongarch-4.s} | 0
.../cfi-sframe/cfi-sframe-loongarch-err-1.d | 15 -----------
gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 2 +-
libsframe/sframe.c | 4 +--
6 files changed, 41 insertions(+), 26 deletions(-)
create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-4.d
rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-loongarch-err-1.s => cfi-sframe-loongarch-4.s} (100%)
delete mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-err-1.d
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index f5cf9bd8594..90cdab1fc36 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -357,9 +357,11 @@ get_fre_num_offsets (const struct sframe_row_entry *sframe_fre)
fre_num_offsets++;
if (sframe_ra_tracking_p ()
&& (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK
- /* For s390x account padding RA offset, if FP without RA saved. */
- || (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
- && sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)))
+ /* For s390x and loongarch, account padding RA offset,
+ if FP without RA saved. */
+ || ((sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
+ || sframe_get_abi_arch () == SFRAME_ABI_LOONGARCH_ENDIAN_LITTLE)
+ && sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)))
fre_num_offsets++;
return fre_num_offsets;
}
@@ -602,9 +604,11 @@ output_sframe_row_entry (symbolS *fde_start_addr,
fre_offset_func_map[idx].out_func (sframe_fre->ra_offset);
fre_write_offsets++;
}
- /* For s390x write padding RA offset, if FP without RA saved. */
- else if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
- && sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
+ /* For s390x and loongarch, write padding RA offset,
+ if FP without RA saved. */
+ else if ((sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
+ || sframe_get_abi_arch () == SFRAME_ABI_LOONGARCH_ENDIAN_LITTLE)
+ && sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
{
fre_offset_func_map[idx].out_func (SFRAME_FRE_RA_OFFSET_INVALID);
fre_write_offsets++;
@@ -1845,9 +1849,10 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
= get_dw_fde_end_addrS (xlate_ctx->dw_fde);
}
- /* ABI/arch except s390x cannot represent FP without RA saved. */
+ /* ABI/arch except s390x/loongarch cannot represent FP without RA saved. */
if (sframe_ra_tracking_p ()
- && sframe_get_abi_arch () != SFRAME_ABI_S390X_ENDIAN_BIG)
+ && sframe_get_abi_arch () != SFRAME_ABI_S390X_ENDIAN_BIG
+ && sframe_get_abi_arch () != SFRAME_ABI_LOONGARCH_ENDIAN_LITTLE)
{
struct sframe_row_entry *fre;
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-4.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-4.d
new file mode 100644
index 00000000000..4557102568a
--- /dev/null
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-4.d
@@ -0,0 +1,25 @@
+#name: SFrame generation on loongarch -- FP without RA saved in register
+#as: --gsframe
+#objdump: --sframe=.sframe
+#...
+
+Contents of the SFrame section .sframe:
+ Header :
+
+ Version: SFRAME_VERSION_2
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
+ Num FDEs: 1
+ Num FREs: 7
+
+ Function Index :
+
+ func idx \[0\]: pc = 0x0, size = 116 bytes
+ STARTPC +CFA +FP +RA +
+ 0+0000 +sp\+0 +u +u +
+ 0+0004 +sp\+96 +u +u +
+ 0+002c +sp\+96 +c\-16 +U +
+ 0+0034 +fp\+96 +c\-16 +U +
+ 0+0044 +sp\+96 +c\-16 +U +
+ 0+006c +sp\+96 +u +u +
+ 0+0070 +sp\+0 +u +u +
+#pass
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-err-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-4.s
similarity index 100%
rename from gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-err-1.s
rename to gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-4.s
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-err-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-err-1.d
deleted file mode 100644
index a62e56cc4a1..00000000000
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-loongarch-err-1.d
+++ /dev/null
@@ -1,15 +0,0 @@
-#name: SFrame generation on loongarch -- FP without RA saved in register
-#as: --gsframe
-#warning: FP without RA on stack
-#objdump: --sframe=.sframe
-#...
-
-Contents of the SFrame section .sframe:
- Header :
-
- Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_FUNC_START_PCREL
- Num FDEs: 0
- Num FREs: 0
-
-#pass
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
index 6509713974f..6cf792b5f5a 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
@@ -96,5 +96,5 @@ if { [istarget "loongarch64-*-*"] && [gas_sframe_check] } then {
run_dump_test "cfi-sframe-loongarch-1"
run_dump_test "cfi-sframe-loongarch-2"
run_dump_test "cfi-sframe-loongarch-3"
- run_dump_test "cfi-sframe-loongarch-err-1"
+ run_dump_test "cfi-sframe-loongarch-4"
}
diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index c064b722d23..a7a5017b985 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -740,8 +740,8 @@ sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
/* Get the RA offset from the FRE. If the offset is invalid, sets errp.
- For s390x an RA offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates
- that the RA is not saved, which is only valid in the topmost frame.
+ For s390x/loongarch an RA offset value of SFRAME_FRE_RA_OFFSET_INVALID
+ indicates that the RA is not saved, which is only valid in the topmost frame.
For s390x the offset may be an encoded register number, indicated by
LSB set to one, which is only valid in the topmost frame. */
--
2.45.2
More information about the Binutils
mailing list