Module Name: src
Committed By: kalvisd
Date: Sun Sep 29 04:25:17 UTC 2024
Modified Files:
src/external/gpl3/gcc/dist/gcc/config/vax: elf.h vax.cc vax.md
Log Message:
gcc: vax: Implement the "eh_return" instruction
Save %r2..%r5 in the prologue of functions which call __builtin_eh_return().
Implement the eh_return() instruction. Ensure that the CFA is correct
OK rin@
To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/external/gpl3/gcc/dist/gcc/config/vax/elf.h
cvs rdiff -u -r1.3 -r1.4 src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc
cvs rdiff -u -r1.18 -r1.19 src/external/gpl3/gcc/dist/gcc/config/vax/vax.md
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/gpl3/gcc/dist/gcc/config/vax/elf.h
diff -u src/external/gpl3/gcc/dist/gcc/config/vax/elf.h:1.13 src/external/gpl3/gcc/dist/gcc/config/vax/elf.h:1.14
--- src/external/gpl3/gcc/dist/gcc/config/vax/elf.h:1.13 Thu Aug 3 01:36:54 2023
+++ src/external/gpl3/gcc/dist/gcc/config/vax/elf.h Sun Sep 29 04:25:16 2024
@@ -46,7 +46,9 @@ along with GCC; see the file COPYING3.
count pushed by the CALLS and before the start of the saved registers. */
#define INCOMING_FRAME_SP_OFFSET 0
-/* Offset from the frame pointer register value to the top of the stack. */
+/* Offset from the frame pointer register value to the DWARF Canonical Frame
+ Address. */
+#undef FRAME_POINTER_CFA_OFFSET
#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
/* We use R2-R5 (call-clobbered) registers for exceptions. */
@@ -57,14 +59,14 @@ along with GCC; see the file COPYING3.
gen_rtx_MEM (SImode, \
plus_constant (Pmode, \
gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),\
- -4))
+ -1 * UNITS_PER_WORD))
/* Simple store the return handler into the call frame. */
#define EH_RETURN_HANDLER_RTX \
gen_rtx_MEM (Pmode, \
plus_constant (Pmode, \
gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),\
- 16))
+ RETURN_ADDRESS_OFFSET))
/* The VAX wants no space between the case instruction and the jump table. */
Index: src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc
diff -u src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc:1.3 src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc:1.4
--- src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc:1.3 Sun Jun 30 08:38:41 2024
+++ src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc Sun Sep 29 04:25:16 2024
@@ -194,12 +194,22 @@ vax_expand_prologue (void)
if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
mask |= 1 << regno;
+ if (crtl->calls_eh_return)
+ {
+ mask |= 0
+ | ( 1 << EH_RETURN_DATA_REGNO(0) )
+ | ( 1 << EH_RETURN_DATA_REGNO(1) )
+ | ( 1 << EH_RETURN_DATA_REGNO(2) )
+ | ( 1 << EH_RETURN_DATA_REGNO(3) )
+ ;
+ }
+
insn = emit_insn (gen_procedure_entry_mask (GEN_INT (mask)));
RTX_FRAME_RELATED_P (insn) = 1;
/* The layout of the CALLG/S stack frame is follows:
- <- CFA, AP
+ <- AP
r11
r10
... Registers saved as specified by MASK
@@ -209,28 +219,30 @@ vax_expand_prologue (void)
old fp
old ap
old psw
- zero
- <- FP, SP
+ condition handler <- CFA, FP, SP
+ (initially zero)
The rest of the prologue will adjust the SP for the local frame. */
- vax_add_reg_cfa_offset (insn, 4, arg_pointer_rtx);
- vax_add_reg_cfa_offset (insn, 8, frame_pointer_rtx);
- vax_add_reg_cfa_offset (insn, 12, pc_rtx);
+ vax_add_reg_cfa_offset (insn, 8, arg_pointer_rtx);
+ vax_add_reg_cfa_offset (insn, 12, frame_pointer_rtx);
+ vax_add_reg_cfa_offset (insn, 16, pc_rtx);
- offset = 16;
+ offset = 5 * UNITS_PER_WORD; /* PSW, AP &c */
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (mask & (1 << regno))
{
vax_add_reg_cfa_offset (insn, offset, gen_rtx_REG (SImode, regno));
- offset += 4;
+ offset += 1 * UNITS_PER_WORD;
}
/* Because add_reg_note pushes the notes, adding this last means that
it will be processed first. This is required to allow the other
- notes be interpreted properly. */
+ notes to be interpreted properly. */
+ /* The RTX here must match the instantiation of the CFA vreg */
add_reg_note (insn, REG_CFA_DEF_CFA,
- plus_constant (Pmode, frame_pointer_rtx, offset));
+ plus_constant (Pmode, frame_pointer_rtx,
+ FRAME_POINTER_CFA_OFFSET(current_function_decl)));
/* Allocate the local stack frame. */
size = get_frame_size ();
Index: src/external/gpl3/gcc/dist/gcc/config/vax/vax.md
diff -u src/external/gpl3/gcc/dist/gcc/config/vax/vax.md:1.18 src/external/gpl3/gcc/dist/gcc/config/vax/vax.md:1.19
--- src/external/gpl3/gcc/dist/gcc/config/vax/vax.md:1.18 Sun Jul 30 05:51:30 2023
+++ src/external/gpl3/gcc/dist/gcc/config/vax/vax.md Sun Sep 29 04:25:16 2024
@@ -30,6 +30,8 @@
; insn in the code.
VUNSPEC_SYNC_ISTREAM ; sequence of insns to sync the I-stream
VUNSPEC_PEM ; 'procedure_entry_mask' insn.
+
+ VUNSPEC_EH_RETURN
])
;; UNSPEC usage:
@@ -2830,6 +2832,66 @@
DONE;
}")
+;; Exception handling
+;; This is used when compiling the stack unwinding routines.
+(define_expand "eh_return"
+ [(use (match_operand 0 "general_operand"))]
+ ""
+{
+ if (GET_MODE (operands[0]) != word_mode)
+ operands[0] = convert_to_mode (word_mode, operands[0], 0);
+ emit_insn (gen_eh_set_retaddr (operands[0]));
+ DONE;
+})
+
+(define_insn_and_split "eh_set_retaddr"
+ [(unspec [(match_operand:SI 0 "general_operand")] VUNSPEC_EH_RETURN)
+ (clobber (match_scratch:SI 1 "=&r"))
+ ]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+{
+ rtx tmp = RETURN_ADDR_RTX(0, frame_pointer_rtx);
+ MEM_VOLATILE_P(tmp) = 1;
+ tmp = gen_rtx_SET(tmp, operands[0]);
+ emit_insn(tmp);
+ DONE;
+})
+
+
+
+;; Exception handling
+;; This is used when compiling the stack unwinding routines.
+(define_expand "eh_return"
+ [(use (match_operand 0 "general_operand"))]
+ ""
+{
+ if (GET_MODE (operands[0]) != word_mode)
+ operands[0] = convert_to_mode (word_mode, operands[0], 0);
+ emit_insn (gen_eh_set_retaddr (operands[0]));
+ DONE;
+})
+
+(define_insn_and_split "eh_set_retaddr"
+ [(unspec [(match_operand:SI 0 "general_operand")] VUNSPEC_EH_RETURN)
+ (clobber (match_scratch:SI 1 "=&r"))
+ ]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+{
+ rtx tmp = RETURN_ADDR_RTX(0, frame_pointer_rtx);
+ MEM_VOLATILE_P(tmp) = 1;
+ tmp = gen_rtx_SET(tmp, operands[0]);
+ emit_insn(tmp);
+ DONE;
+})
+
+
+
(define_insn "nop"
[(const_int 0)]
""