This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AArch64/GCC][11/N] Unify vector and core register save/restore code as one copy


split save and restore code.

the logic will be easier to understand.

ok for upstream?

thanks.

gcc/
  * config/aarch64/aarch64.md: (aarch64_save_or_restore_callee_saves):
  Rename to aarch64_save_callee_saves, remove restore code.
  (aarch64_restore_callee_saves): New function.
>From b063ab3e22cd1bdd2eb6f2cf5790741e68c7c6e5 Mon Sep 17 00:00:00 2001
From: Jiong Wang <jiong.wang@arm.com>
Date: Tue, 17 Jun 2014 22:14:43 +0100
Subject: [PATCH 11/19] [AArch64/GCC][11/20] Split save and restore code

split save and restore code.

the logic will be easier to understand.

2014-06-16  Jiong Wang <jiong.wang@arm.com>
	    Marcus Shawcroft  <marcus.shawcroft@arm.com>

gcc/
  * config/aarch64/aarch64.md: (aarch64_save_or_restore_callee_save_common):
  Rename to aarch64_save_callee_save_common, remove restore code.
  (aarch64_restore_callee_save_common): New function.
---
 gcc/config/aarch64/aarch64.c |  104 ++++++++++++++++++++++++++++--------------
 1 file changed, 69 insertions(+), 35 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 4e35ebc..9772dc4 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1948,13 +1948,9 @@ aarch64_gen_load_pair (enum machine_mode mode, rtx reg1, rtx mem1, rtx reg2,
 }
 
 
-/* offset from the stack pointer of where the saves and
-   restore's have to happen.  */
 static void
-aarch64_save_or_restore_callee_saves (enum machine_mode mode,
-				      HOST_WIDE_INT start_offset,
-				      unsigned start, unsigned limit,
-				      bool restore)
+aarch64_save_callee_saves (enum machine_mode mode, HOST_WIDE_INT start_offset,
+			   unsigned start, unsigned limit)
 {
   rtx insn;
   rtx (*gen_mem_ref) (enum machine_mode, rtx) = (frame_pointer_needed
@@ -1985,18 +1981,10 @@ aarch64_save_or_restore_callee_saves (enum machine_mode mode,
 	  rtx mem2;
 
 	  offset = start_offset + cfun->machine->frame.reg_offset[regno2];
-	  mem2 = gen_mem_ref (mode,
-			      plus_constant (Pmode, stack_pointer_rtx, offset));
-	  if (restore == false)
-	    insn = emit_insn (aarch64_gen_store_pair (mode, mem, reg, mem2,
-						      reg2));
-	  else
-	    {
-	      insn = emit_insn (aarch64_gen_load_pair (mode, reg, mem, reg2,
-						       mem2));
-	      add_reg_note (insn, REG_CFA_RESTORE, reg);
-	      add_reg_note (insn, REG_CFA_RESTORE, reg2);
-	    }
+	  mem2 = gen_mem_ref (mode, plus_constant (Pmode, stack_pointer_rtx,
+						   offset));
+	  insn = emit_insn (aarch64_gen_store_pair (mode, mem, reg, mem2,
+						    reg2));
 
 	  /* The first part of a frame-related parallel insn is
 	     always assumed to be relevant to the frame
@@ -2006,15 +1994,64 @@ aarch64_save_or_restore_callee_saves (enum machine_mode mode,
 	  regno = regno2;
 	}
       else
+	insn = emit_move_insn (mem, reg);
+
+      RTX_FRAME_RELATED_P (insn) = 1;
+    }
+}
+
+static void
+aarch64_restore_callee_saves (enum machine_mode mode,
+			      HOST_WIDE_INT start_offset, unsigned start,
+			      unsigned limit)
+{
+  rtx insn;
+  rtx base_rtx = stack_pointer_rtx;
+  rtx (*gen_mem_ref) (enum machine_mode, rtx) = (frame_pointer_needed
+						 ? gen_frame_mem : gen_rtx_MEM);
+  unsigned regno;
+  unsigned regno2;
+  HOST_WIDE_INT offset;
+
+  for (regno = aarch64_next_callee_save (start, limit);
+       regno <= limit;
+       regno = aarch64_next_callee_save (regno + 1, limit))
+    {
+      rtx reg = gen_rtx_REG (mode, regno);
+      rtx mem;
+
+      offset = start_offset + cfun->machine->frame.reg_offset[regno];
+      mem = gen_mem_ref (mode, plus_constant (Pmode, base_rtx, offset));
+
+      regno2 = aarch64_next_callee_save (regno + 1, limit);
+
+      if (regno2 <= limit
+	  && ((cfun->machine->frame.reg_offset[regno] + UNITS_PER_WORD)
+	      == cfun->machine->frame.reg_offset[regno2]))
 	{
-	  if (restore == false)
-	    insn = emit_move_insn (mem, reg);
-	  else
-	    {
-	      insn = emit_move_insn (reg, mem);
-	      add_reg_note (insn, REG_CFA_RESTORE, reg);
-	    }
+	  rtx reg2 = gen_rtx_REG (mode, regno2);
+	  rtx mem2;
+
+	  offset = start_offset + cfun->machine->frame.reg_offset[regno2];
+	  mem2 = gen_mem_ref (mode, plus_constant (Pmode, base_rtx, offset));
+	  insn = emit_insn (aarch64_gen_load_pair (mode, reg, mem, reg2,
+						   mem2));
+	  add_reg_note (insn, REG_CFA_RESTORE, reg);
+	  add_reg_note (insn, REG_CFA_RESTORE, reg2);
+
+	  /* The first part of a frame-related parallel insn is
+	     always assumed to be relevant to the frame
+	     calculations; subsequent parts, are only
+	     frame-related if explicitly marked.  */
+	  RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
+	  regno = regno2;
 	}
+      else
+	{
+	  insn = emit_move_insn (reg, mem);
+	  add_reg_note (insn, REG_CFA_RESTORE, reg);
+	}
+
       RTX_FRAME_RELATED_P (insn) = 1;
     }
 }
@@ -2209,11 +2246,10 @@ aarch64_expand_prologue (void)
 	  RTX_FRAME_RELATED_P (insn) = 1;
 	}
 
-      aarch64_save_or_restore_callee_saves (DImode, fp_offset, R0_REGNUM,
-					    frame_pointer_needed
-					    ? R28_REGNUM : R30_REGNUM, false);
-      aarch64_save_or_restore_callee_saves (DFmode, fp_offset, V0_REGNUM,
-					    V31_REGNUM, false);
+      aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM,
+				 frame_pointer_needed
+				 ? R28_REGNUM : R30_REGNUM);
+      aarch64_save_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM);
     }
 
   /* when offset >= 512,
@@ -2284,11 +2320,9 @@ aarch64_expand_epilogue (bool for_sibcall)
       cfa_reg = stack_pointer_rtx;
     }
 
-  aarch64_save_or_restore_callee_saves (DImode, fp_offset, R0_REGNUM,
-					frame_pointer_needed
-					? R28_REGNUM : R30_REGNUM, true);
-  aarch64_save_or_restore_callee_saves (DFmode, fp_offset, V0_REGNUM,
-					V31_REGNUM, true);
+  aarch64_restore_callee_saves (DImode, fp_offset, R0_REGNUM,
+				frame_pointer_needed ? R28_REGNUM : R30_REGNUM);
+  aarch64_restore_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM);
 
   /* Restore the frame pointer and lr if the frame pointer is needed.  */
   if (offset > 0)
-- 
1.7.9.5



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]