From 95847aaba18107b59081d1a800a5910bebd7f75d Mon Sep 17 00:00:00 2001 From: Jens Remus Date: Fri, 11 Jul 2025 10:29:40 +0200 Subject: [PATCH] s390: Store SFrame CFA offset adjusted and scaled down In SFrame V2 the size of the offsets following an SFrame FRE can be either signed 8-bit, 16-bit, or 32-bit integer, 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_S390X_CFA_OFFSET_ENCODE, SFRAME_V2_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 --- 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 640d0029d92..7523adbef3a 100644 --- a/include/sframe.h +++ b/include/sframe.h @@ -377,12 +377,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_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_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 af9202216eb..ecc333df3ae 100644 --- a/libsframe/doc/sframe-spec.texi +++ b/libsframe/doc/sframe-spec.texi @@ -157,10 +157,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_S390X_CFA_OFFSET_ENCODE: Encode CFA offset (i.e., apply -CFA offset adjustment). - @item SFRAME_V2_S390X_CFA_OFFSET_DECODE: Decode CFA offset (i.e., revert -CFA offset adjustment). +CFA offset adjustment and then scale down by CFA offset alignment factor). + @item SFRAME_V2_S390X_CFA_OFFSET_DECODE: Decode CFA offset (i.e., scale up +by CFA offset alignment factor and then revert CFA offset adjustment). @end itemize @end itemize @@ -892,14 +894,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_S390X_CFA_OFFSET_ENCODE} and -@code{SFRAME_V2_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_S390X_CFA_OFFSET_DECODE(offset1)} +@code{SFRAME_V2_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. -- 2.47.2