[PATCH v3 09/11] s390: Store SFrame CFA offset adjusted and scaled down
Indu Bhagat
indu.bhagat@oracle.com
Sat Jul 5 23:25:03 GMT 2025
On 6/27/25 4:08 AM, Jens Remus wrote:
> In SFrame V2 the size of the offsets following an SFrame FRE can be
> either signed 8-bit, 16-bit, or 32-bit integer, which the largest offset
Typo: "with" the largest offset
> determining their size:
> 1. CFA offset from CFA base register
> 2. RA (stack save slot) offset from CFA, usually -48 on s390x if saved
> 3. FP (stack save slot) offset from CFA, usually -72 on s390x if saved
> The FP and RA offsets from CFA, when FP/RA saved on the stack, usually
> have fixed values that fit into signed 8-bit SFrame offsets. Likewise
> the DWARF register numbers on s390x of general registers (GR; 0-15) and
> floating-point registers (FPR; 16-31), when FP/RA saved in registers.
> With that the CFA offset from CFA base register has the greatest impact
> on the signed SFrame offset size.
>
> The s390x ELF ABI defines the stack pointer (SP) to be 8-byte aligned
> [1] and the CFA as SP at call site + 160 [2]. The CFA offset from CFA
> base register is therefore always a multiple of 8.
>
> On s390x store the SFrame CFA offset from CFA base register scaled down
> by the s390x-specific CFA alignment factor of 8, in addition to the
> adjustment by the s390x-specific CFA adjustment of -160, to further
> improve the use of signed 8-bit SFrame offsets. This is similar to the
> DWARF data alignment factor getting factored out from certain offsets
> stored in DWARF CFI.
>
> [1]: s390x ELF ABI, sections "Register Roles" and "Stack Frame
> Allocation", https://github.com/IBM/s390x-abi/releases
> [2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
> https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88
>
> include/
> * sframe.h (SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR): Define
> s390x-specific CFA offset alignment factor.
> (SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE,
> SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE): Scale down/up by
> SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR.
>
> libsframe/
> * doc/sframe-spec.texi (s390x,
> SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR): Document s390x-
> specific CFA offset alignment factor.
>
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
One comment below for sframe-spec.texi.
Other than that, LGTM.
Reviewed-by: Indu Bhagat <indu.bhagat@oracle.com>
> ---
>
> Notes (jremus):
> Changes in V3:
> - Update "Changes from Version 1 to Version 2" in SFrame spec. (Indu)
> - Regenerate statistics in patch notes below. Differences to V2 due
> to change in min/max N-bit offset accounting (was unusual in V1/V2)
> and use in newer GCC.
>
> Changes in V2:
> - Reword commit message (s390 to s390x, offsets, FDE to FRE). (Indu)
> - Rename s390x-specific macros from *_S390_* to *_S390X_*. (Indu)
> - Use "s390x" instead of "S390" in comments and SFrame spec. (Indu)
> - Change order of CFA restore instructions in SFrame spec. (Indu)
>
> A test build of Glibc tag 2.41 on s390x libc.so shows an additional ~9%
> reduction in .sframe section size due to storing the SFrame CFA offsets
> scaled down by 8 in addition to the adjustment by -160. In total
> adjusting and scaling down reduces the .sframe size by ~17%. The
> overall number of offsets larger than 8-bit is effectively reduced down
> to ~2.4%.
>
> Statistics for libc.so - base (no CFA offset adjustment nor scaling):
>
> .sframe size: 169,697 bytes
>
> VALUE TOTAL MIN MAX AVG
> FDEs: 3651 - - -
> FREs/FDE: 15237 1 20 4
> Offsets/FDE: 29795 1 38 8
> 8-bit: 0 0 0 0
> 16-bit: 29795 1 38 8
> 32-bit: 0 0 0 0
> Offsets/FRE: 29795 1 3 1
> 8-bit: - 0 0 0
> 16-bit: - 1 3 1
> 32-bit: - 0 0 0
> O_Padd/FDE: 345 - - 0
> 8-bit: 0
> 16-bit: 345
> 32-bit: 0
>
> Statistics for libc.so - CFA offset adjustment (no scaling):
>
> .sframe size: 154,698 bytes
>
> VALUE TOTAL MIN MAX AVG
> FDEs: 3651 - - -
> FREs/FDE: 15237 1 20 4
> Offsets/FDE: 29795 1 38 8
> 8-bit: 14999 1 38 4
> 16-bit: 14796 0 21 4
> 32-bit: 0 0 0 0
> Offsets/FRE: 29795 1 3 1
> 8-bit: - 1 3 0
> 16-bit: - 1 3 0
> 32-bit: - 0 0 0
> O_Padd/FDE: 345 - - 0
> 8-bit: 286
> 16-bit: 59
> 32-bit: 0
>
> Statistics for libc.so - CFA offset adjustment and scaling:
>
> .sframe size: 140,604 bytes
>
> VALUE TOTAL MIN MAX AVG
> FDEs: 3651 - - -
> FREs/FDE: 15237 1 20 4
> Offsets/FDE: 29795 1 38 8
> 8-bit: 29093 1 38 7
> 16-bit: 702 0 15 0
> 32-bit: 0 0 0 0
> Offsets/FRE: 29795 1 3 1
> 8-bit: - 1 3 1
> 16-bit: - 2 3 0
> 32-bit: - 0 0 0
> O_Padd/FDE: 345 - - 0
> 8-bit: 345
> 16-bit: 0
> 32-bit: 0
>
> include/sframe.h | 11 ++++++++---
> libsframe/doc/sframe-spec.texi | 23 ++++++++++++++---------
> 2 files changed, 22 insertions(+), 12 deletions(-)
>
> diff --git a/include/sframe.h b/include/sframe.h
> index f2f4de952407..4dcd4bf94d0d 100644
> --- a/include/sframe.h
> +++ b/include/sframe.h
> @@ -366,12 +366,17 @@ typedef struct sframe_frame_row_entry_addr4
> (1ULL << ((SFRAME_FRE_TYPE_ADDR4 * 2) * 8))
>
> /* On s390x, the CFA offset from CFA base register is by definition a minimum
> - of 160. Store it adjusted by -160 to enable use of 8-bit SFrame offsets. */
> + of 160. Store it adjusted by -160 to enable use of 8-bit SFrame offsets.
> + Additionally scale by an alignment factor of 8, as the SP and thus CFA
> + offset on s390x is always 8-byte aligned. */
> #define SFRAME_S390X_CFA_OFFSET_ADJUSTMENT SFRAME_S390X_SP_VAL_OFFSET
> +#define SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR 8
> #define SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE(offset) \
> - ((offset) + SFRAME_S390X_CFA_OFFSET_ADJUSTMENT)
> + (((offset) + SFRAME_S390X_CFA_OFFSET_ADJUSTMENT) \
> + / SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR)
> #define SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE(offset) \
> - ((offset) - SFRAME_S390X_CFA_OFFSET_ADJUSTMENT)
> + (((offset) * SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR) \
> + - SFRAME_S390X_CFA_OFFSET_ADJUSTMENT)
>
> /* On s390x, the CFA is defined as SP at call site + 160. Therefore the
> SP value offset from CFA is -160. */
> diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi
> index 9c6d3d726c50..c8db3add372f 100644
> --- a/libsframe/doc/sframe-spec.texi
> +++ b/libsframe/doc/sframe-spec.texi
> @@ -146,10 +146,12 @@ SFRAME_CFA_FIXED_RA_INVALID). Used on s390x as padding offset to represent
> FP without RA saved.
> @item SFRAME_S390X_CFA_OFFSET_ADJUSTMENT: CFA offset (from CFA base register)
> adjustment value. Used to enable use of 8-bit SFrame offsets on s390x.
> +@item SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR: CFA offset alignment factor.
> +Used to scale down the CFA offset to improve the use of 8-bit SFrame offsets.
> @item SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE: Encode CFA offset (i.e. apply
> -CFA offset adjustment).
> -@item SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE: Decode CFA offset (i.e. unapply
> -CFA offset adjustment).
> +CFA offset adjustment and then scale down by CFA offset alignment factor).
> +@item SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE: Decode CFA offset (i.e. scale up
> +by CFA offset alignment factor and then unapply CFA offset adjustment).
Comma after i.e. : "i.e.,"
Instead of unapply, perhaps "revert the CFA offset adjustment" may be
better.
> @end itemize
> @end itemize
>
> @@ -872,14 +874,17 @@ in any stack frame.
>
> Irrespective of the ABI, the first stack offset is always used to locate the
> CFA. On s390x the value of the offset is stored adjusted by the s390x-specific
> -@code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT} to enable the use of signed 8-bit
> -offsets on s390x.
> +@code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT} and scaled down by the s390x-specific
> +@code{SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR}, to enable and improve the use
> +of signed 8-bit offsets on s390x.
> s390x-specific helpers @code{SFRAME_V2_FRE_S390X_CFA_OFFSET_ENCODE} and
> -@code{SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE} are provided to perform and undo
> -the adjustment. The CFA offset can therefore be interpreted as:
> -CFA = @code{BASE_REG} + @code{SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE(offset1)}
> +@code{SFRAME_V2_FRE_S390X_CFA_OFFSET_DECODE} are provided to perform or undo
> +the adjustment and scaling. The CFA offset can therefore be interpreted as:
> +CFA = @code{BASE_REG} + offset1 - @code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT}
> or
> -CFA = @code{BASE_REG} + offset1 - @code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT}.
> +CFA = @code{BASE_REG}
> + + (offset1 * @code{SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR})
> + - @code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT}.
> The identification of the @code{BASE_REG} is done by using the
> @code{fre_cfa_base_reg_id} field in the SFrame FRE info word.
>
More information about the Binutils
mailing list