[binutils-gdb/jremus/sframe-v3-s390x] fixup! [SFrame-V3] gas: sframe: add handling for .cfi_register for FP and RA

Jens Remus jremus@sourceware.org
Mon Dec 15 16:25:26 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=93d6ae285871cc929f4de67f9bc67bf775394e00

commit 93d6ae285871cc929f4de67f9bc67bf775394e00
Author: Jens Remus <jremus@linux.ibm.com>
Date:   Mon Dec 15 16:29:54 2025 +0100

    fixup! [SFrame-V3] gas: sframe: add handling for .cfi_register for FP and RA

Diff:
---
 gas/gen-sframe.c | 50 +++++++++++++++++++++++++++++++++++++++-----------
 gas/gen-sframe.h |  7 ++++---
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index f542e25c21a..d794f2a79ec 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -410,14 +410,14 @@ get_fre_num_offsets (const struct sframe_row_entry *sframe_fre,
   if (flex_topmost_p)
     fre_num_offsets += count;
   else if (sframe_ra_tracking_p ()
-	   && (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK
+	   && (sframe_fre->ra_loc != SFRAME_FRE_ELEM_LOC_RETAIN
 	       /* For s390x account padding RA offset, if FP without RA
 		  saved.  */
 	       || (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
-		   && sframe_fre->fp_loc == SFRAME_FRE_ELEM_LOC_STACK)))
+		   && sframe_fre->fp_loc != SFRAME_FRE_ELEM_LOC_RETAIN)))
     fre_num_offsets++;
 
-  if (sframe_fre->fp_loc == SFRAME_FRE_ELEM_LOC_STACK)
+  if (sframe_fre->fp_loc != SFRAME_FRE_ELEM_LOC_RETAIN)
     fre_num_offsets += count;
 
   return fre_num_offsets;
@@ -643,10 +643,19 @@ output_sframe_row_entry_offsets (const struct sframe_func_entry *sframe_fde,
       if (sframe_ra_tracking_p ())
 	gas_assert (false);
 
-      /* RA tracking enabled or not, emit two offsets for RA.
-	 Aside, emitting SFRAME_FRE_RA_OFFSET_INVALID is equivalent to emitting
-	 SFRAME_V3_FLEX_FDE_REG_ENCODE (0, 0, 0).  */
+      /* RA tracking enabled or not, emit two offsets for RA.  */
       if (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
+	{
+	  /* Output RA related FRE offsets.  */
+	  reg_data = SFRAME_V3_FLEX_FDE_REG_ENCODE (0, /* reg.  */
+						    sframe_fre->ra_deref_p,
+						    0 /* reg_p.  */);
+	  offset_data = sframe_fre->ra_offset;
+	  fre_offset_func_map[idx].out_func (reg_data);
+	  fre_offset_func_map[idx].out_func (offset_data);
+	  fre_write_offsets += 2;
+	}
+      else if (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_REG)
 	{
 	  /* Output RA related FRE offsets.  */
 	  reg_data = SFRAME_V3_FLEX_FDE_REG_ENCODE (sframe_fre->ra_reg,
@@ -659,13 +668,29 @@ output_sframe_row_entry_offsets (const struct sframe_func_entry *sframe_fde,
 	}
       else
 	{
-	  fre_offset_func_map[idx].out_func (SFRAME_FRE_RA_OFFSET_INVALID);
-	  /* FIXME Offset 0 for now.  */
-	  fre_offset_func_map[idx].out_func (0);
+	  /* Output RA related FRE offsets.  */
+	  /* TODO: Why?!?  */
+	  reg_data = SFRAME_V3_FLEX_FDE_REG_ENCODE (0, /* reg.  */
+						    0, /* deref_p.  */
+						    0 /* reg_p.  */);
+	  offset_data = SFRAME_FRE_RA_OFFSET_INVALID;
+	  fre_offset_func_map[idx].out_func (reg_data);
+	  fre_offset_func_map[idx].out_func (offset_data);
 	  fre_write_offsets += 2;
 	}
 
       if (sframe_fre->fp_loc == SFRAME_FRE_ELEM_LOC_STACK)
+	{
+	  /* Output FP related FRE offsets.  */
+	  reg_data = SFRAME_V3_FLEX_FDE_REG_ENCODE (0 /* reg.  */,
+						    sframe_fre->fp_deref_p,
+						    0 /* reg_p.  */);
+	  offset_data = sframe_fre->fp_offset;
+	  fre_offset_func_map[idx].out_func (reg_data);
+	  fre_offset_func_map[idx].out_func (offset_data);
+	  fre_write_offsets += 2;
+	}
+      else if (sframe_fre->fp_loc == SFRAME_FRE_ELEM_LOC_REG)
 	{
 	  /* Output FP related FRE offsets.  */
 	  reg_data = SFRAME_V3_FLEX_FDE_REG_ENCODE (sframe_fre->fp_reg,
@@ -1489,6 +1514,7 @@ sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx,
       if (cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG)
 	{
 	  sframe_fre_set_fp_track (cur_fre, 0);
+	  cur_fre->fp_loc = SFRAME_FRE_ELEM_LOC_REG;
 	  cur_fre->fp_reg = cfi_insn->u.rr.reg2;
 	  cur_fre->fp_deref_p = false;
 	  cur_fre->merge_candidate = false;
@@ -1497,6 +1523,7 @@ sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx,
       else if (cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG)
 	{
 	  sframe_fre_set_ra_track (cur_fre, 0);
+	  cur_fre->ra_loc = SFRAME_FRE_ELEM_LOC_REG;
 	  cur_fre->ra_reg = cfi_insn->u.rr.reg2;
 	  cur_fre->ra_deref_p = false;
 	  cur_fre->merge_candidate = false;
@@ -1833,6 +1860,7 @@ sframe_xlate_do_escape_expr (struct sframe_xlate_ctx *xlate_ctx,
     {
       xlate_ctx->flex_topmost_p = true;
       sframe_fre_set_fp_track (cur_fre, offset);
+      cur_fre->fp_loc = SFRAME_FRE_ELEM_LOC_REG;
       cur_fre->fp_reg = fp_base_reg;
       cur_fre->fp_deref_p = true;
       cur_fre->merge_candidate = false;
@@ -2158,14 +2186,14 @@ sframe_xlate_do_same_value (const struct sframe_xlate_ctx *xlate_ctx,
 
   if (sframe_ra_tracking_p () && cfi_insn->u.r == SFRAME_CFA_RA_REG)
     {
-      cur_fre->ra_loc = SFRAME_FRE_ELEM_LOC_REG;
+      cur_fre->ra_loc = SFRAME_FRE_ELEM_LOC_RETAIN;
       cur_fre->ra_offset = 0;
       cur_fre->ra_undefined_p = false;
       cur_fre->merge_candidate = false;
     }
   else if (cfi_insn->u.r == SFRAME_CFA_FP_REG)
     {
-      cur_fre->fp_loc = SFRAME_FRE_ELEM_LOC_REG;
+      cur_fre->fp_loc = SFRAME_FRE_ELEM_LOC_RETAIN;
       cur_fre->fp_offset = 0;
       cur_fre->merge_candidate = false;
     }
diff --git a/gas/gen-sframe.h b/gas/gen-sframe.h
index 6c0699dec46..e6fe39090f0 100644
--- a/gas/gen-sframe.h
+++ b/gas/gen-sframe.h
@@ -31,8 +31,9 @@
       as_bad (format, ##__VA_ARGS__);	       \
   } while (0)
 
-#define SFRAME_FRE_ELEM_LOC_REG		0
+#define SFRAME_FRE_ELEM_LOC_RETAIN	0
 #define SFRAME_FRE_ELEM_LOC_STACK	1
+#define SFRAME_FRE_ELEM_LOC_REG		2
 
 /* An invalid register number.  */
 #define SFRAME_FRE_REG_INVALID		((unsigned int)-1)
@@ -78,8 +79,8 @@ struct sframe_row_entry
   bool cfa_deref_p;
 
   /* Track FP location.  Specify whether it is in register or memory.  */
-  unsigned int fp_reg;
   unsigned int fp_loc;
+  unsigned int fp_reg;
   /* If the FP is stashed on stack, note the offset.  */
   offsetT fp_offset;
   /* Whether FP recovery needs dereferencing.  This is tracked for
@@ -87,8 +88,8 @@ struct sframe_row_entry
   bool fp_deref_p;
 
   /* Track RA location.  Specify whether it is in register or memory.  */
-  unsigned int ra_reg;
   unsigned int ra_loc;
+  unsigned int ra_reg;
   /* If RA is stashed on stack, note the offset.  */
   offsetT ra_offset;
  /* Whether RA recovery needs dereferencing.  This is tracked for


More information about the Binutils-cvs mailing list