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)]
   ""

Reply via email to