/* For ABIs not tracking RA, the return address is expected to be in a
specific location. Explicit manourvering to a different offset (than the
- default offset) is non-representable in SFrame. */
- if (!sframe_ra_tracking_p () && cfi_insn->u.ri.reg == SFRAME_CFA_RA_REG
+ default offset) is non-representable in SFrame, unless flex FDE generation
+ is supported for the ABI. */
+ if (!sframe_support_flex_fde_p () && !sframe_ra_tracking_p ()
+ && cfi_insn->u.ri.reg == SFRAME_CFA_RA_REG
&& cfi_insn->u.ri.offset != sframe_cfa_ra_offset ())
{
as_warn (_("no SFrame FDE emitted; %s register %u in .cfi_offset"),
cur_fre->fp_deref_p = true;
cur_fre->merge_candidate = false;
}
- else if (sframe_ra_tracking_p ()
- && cfi_insn->u.ri.reg == SFRAME_CFA_RA_REG)
+ /* Either the ABI has enabled RA tracking, in which case we must process the
+ DW_CFA_offset opcode for REG_RA like usual. Or if the ABI has not enabled
+ RA tracking, but flex FDE generation is supported, distinguish between
+ whether its time to reset the RA tracking state or not. */
+ else if (cfi_insn->u.ri.reg == SFRAME_CFA_RA_REG)
{
- sframe_fre_set_ra_track (cur_fre, cfi_insn->u.ri.offset);
- cur_fre->ra_reg = SFRAME_FRE_REG_INVALID;
- cur_fre->ra_deref_p = true;
- cur_fre->merge_candidate = false;
+ if (!sframe_ra_tracking_p ()
+ && cfi_insn->u.ri.offset == sframe_cfa_ra_offset ())
+ {
+ /* Reset RA tracking info, if fixed offset. */
+ cur_fre->ra_reg = SFRAME_FRE_REG_INVALID;
+ cur_fre->ra_loc = SFRAME_FRE_ELEM_LOC_NONE;
+ cur_fre->ra_deref_p = false;
+ cur_fre->merge_candidate = false;
+ }
+ else
+ {
+ sframe_fre_set_ra_track (cur_fre, cfi_insn->u.ri.offset);
+ cur_fre->ra_reg = SFRAME_FRE_REG_INVALID;
+ cur_fre->ra_loc = SFRAME_FRE_ELEM_LOC_STACK;
+ cur_fre->ra_deref_p = true;
+ cur_fre->merge_candidate = false;
+
+ if (!sframe_ra_tracking_p () && sframe_support_flex_fde_p ())
+ xlate_ctx->flex_p = true;
+ }
}
- /* This is used to track changes to non-rsp registers, skip all others
- except FP / RA for now. */
+
+ /* Skip all other registers. */
return SFRAME_XLATE_OK;
}
--- /dev/null
+#as: --gsframe
+#objdump: --sframe=.sframe
+#name: Flex FDE with RA state transition
+#...
+Contents of the SFrame section .sframe:
+
+ Header :
+
+ Version: SFRAME_VERSION_3
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
+ CFA fixed RA offset: \-8
+ Num FDEs: 1
+ Num FREs: 5
+
+ Function Index :
+
+ func idx \[0\]: pc = 0x0, size = 16 bytes, attr = "F"
+ STARTPC +CFA +FP +RA +
+ 0+0000 +sp\+8 +u +f +
+ 0+0004 +sp\+40 +u +f +
+ 0+0008 +sp\+40 +u +r3\+0 +
+ 0+000b +sp\+40 +u +f +
+ 0+000f +sp\+8 +u +f +
+
+#pass
--- /dev/null
+#as: --gsframe
+#objdump: --sframe=.sframe
+#name: Flex FDE with RA state transition 2
+#...
+Contents of the SFrame section .sframe:
+
+ Header :
+
+ Version: SFRAME_VERSION_3
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
+ CFA fixed RA offset: \-8
+ Num FDEs: 1
+ Num FREs: 5
+
+ Function Index :
+
+ func idx \[0\]: pc = 0x0, size = 20 bytes, attr = "F"
+ STARTPC +CFA +FP +RA +
+ 0+0000 +sp\+8 +u +f +
+ 0+0004 +sp\+40 +u +f +
+ 0+000b +sp\+40 +u +c-16 +
+ 0+000f +sp\+8 +u +c-16 +
+ 0+0013 +sp\+8 +u +f +
+
+#pass