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

Reply via email to