Module Name: src
Committed By: rin
Date: Sat Oct 7 11:57:01 UTC 2023
Modified Files:
src/external/gpl3/gcc.old/dist/gcc/config/vax: elf.h vax.c vax.md
Log Message:
gcc.old: vax: PR port-vax/57646 patch provided by Kalvis Duckmanton [1/21]
Save %r2..%r5 in the prologue of functions which call __builtin_eh_return().
Implement the eh_return() instruction. Ensure that the CFA is correct
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 \
src/external/gpl3/gcc.old/dist/gcc/config/vax/elf.h \
src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md
cvs rdiff -u -r1.12 -r1.13 \
src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.c
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.old/dist/gcc/config/vax/elf.h
diff -u src/external/gpl3/gcc.old/dist/gcc/config/vax/elf.h:1.11 src/external/gpl3/gcc.old/dist/gcc/config/vax/elf.h:1.12
--- src/external/gpl3/gcc.old/dist/gcc/config/vax/elf.h:1.11 Mon Feb 20 02:11:22 2023
+++ src/external/gpl3/gcc.old/dist/gcc/config/vax/elf.h Sat Oct 7 11:57:01 2023
@@ -45,7 +45,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. */
@@ -56,14 +58,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.old/dist/gcc/config/vax/vax.md
diff -u src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md:1.11 src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md:1.12
--- src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md:1.11 Mon Feb 20 02:11:22 2023
+++ src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md Sat Oct 7 11:57:01 2023
@@ -33,6 +33,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
])
(define_constants
@@ -1470,6 +1472,36 @@
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)]
+{
+ /* the return address for the current frame is always at 0x10(%fp) */
+ rtx tmp = plus_constant(Pmode, frame_pointer_rtx, 4 * UNITS_PER_WORD);
+ tmp = gen_rtx_MEM (word_mode, tmp);
+ MEM_VOLATILE_P(tmp) = 1;
+ tmp = gen_rtx_SET(tmp, operands[0]);
+ emit_insn(tmp);
+ DONE;
+})
+
(define_insn "nop"
[(const_int 0)]
""
Index: src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.c
diff -u src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.c:1.12 src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.c:1.13
--- src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.c:1.12 Mon Feb 20 02:11:22 2023
+++ src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.c Sat Oct 7 11:57:01 2023
@@ -182,20 +182,28 @@ vax_expand_prologue (void)
HOST_WIDE_INT size;
rtx insn;
- offset = 20;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
{
mask |= 1 << regno;
- offset += 4;
}
+ 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
@@ -205,16 +213,11 @@ 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. */
- add_reg_note (insn, REG_CFA_DEF_CFA,
- plus_constant (Pmode, frame_pointer_rtx, offset));
- insn = emit_insn (gen_blockage ());
- RTX_FRAME_RELATED_P (insn) = 1;
-
#ifdef notyet
/*
* We can't do this, the dwarf code asserts and we don't have yet a
@@ -226,14 +229,21 @@ vax_expand_prologue (void)
vax_add_reg_cfa_offset (insn, 12, frame_pointer_rtx);
vax_add_reg_cfa_offset (insn, 16, pc_rtx);
- offset = 20;
+ 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 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,
+ FRAME_POINTER_CFA_OFFSET(current_function_decl)));
/* Allocate the local stack frame. */
size = get_frame_size ();
size -= vax_starting_frame_offset ();