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 ();