[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