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]

[RFC PATCH 7/9] [SH] Modify movsi_ie and movsf_ie patterns for LRA


This patch is discussed in PR55212

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55212#c40
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55212#c41

and is to fix reload loop issues which happen with movsf_ie/movsi_ie.
It seems that LRA behaves differently from old reload with the choice
of alternative and how scratch register is handled.  The patch adds
another movsf_ie pattern which is enabled only when lra_in_progress
is true.
One unified movsf_ie is clealy better as oled pointed out in the trails
and it's a future issue.

--
	* config/sh/sh-protos.h (sh_movsf_ie_ra_split_p): Declare.
	* config/sh/sh.c (sh_movsf_ie_ra_split_p): New function.
	* config/sh/sh.md (movsi_ie): Use "mr" constraint for the 8-th
	altarnative of operand 0.
	(movesf_ie): Use "X" constraint instead of "Bsc".
	(movsf_ie_ra): New insn_and_split.
	(movsf): Use movsfie_ra when lra_in_progress is true.

diff --git a/config/sh/sh-protos.h b/config/sh/sh-protos.h
index 7697c4c..b0fc67a 100644
--- a/config/sh/sh-protos.h
+++ b/config/sh/sh-protos.h
@@ -159,6 +159,7 @@ extern rtx sh_find_equiv_gbr_addr (rtx_insn* cur_insn, rtx mem);
 extern int sh_eval_treg_value (rtx op);
 extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op);
 extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a);
+extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx);
 
 /* Result value of sh_find_set_of_reg.  */
 struct set_of_reg
diff --git a/config/sh/sh.c b/config/sh/sh.c
index 6c79340..db9226e 100644
--- a/config/sh/sh.c
+++ b/config/sh/sh.c
@@ -13291,6 +13291,35 @@ sh_legitimize_address_displacement (rtx *disp, rtx *offs,
   return false;
 }
 
+/* Return true if movsf insn should be splited with an additional
+   register.  */
+bool
+sh_movsf_ie_ra_split_p (rtx op0, rtx op1, rtx op2)
+{
+  /* op0 == op1 */
+  if (rtx_equal_p (op0, op1))
+    return true;
+  /* fy, FQ, reg */
+  if (GET_CODE (op1) == CONST_DOUBLE
+      && ! satisfies_constraint_G (op1)
+      && ! satisfies_constraint_H (op1)
+      && REG_P (op0)
+      && REG_P (op2))
+    return true;
+  /* f, r, y */
+  if (REG_P (op0) && FP_REGISTER_P (REGNO (op0))
+      && REG_P (op1) && GENERAL_REGISTER_P (REGNO (op1))
+      && REG_P (op2) && (REGNO (op2) == FPUL_REG))
+    return true;
+  /* r, f, y */
+  if (REG_P (op1) && FP_REGISTER_P (REGNO (op1))
+      && REG_P (op0) && GENERAL_REGISTER_P (REGNO (op0))
+      && REG_P (op2) && (REGNO (op2) == FPUL_REG))
+    return true;
+
+  return false;
+}
+
 static void
 sh_conditional_register_usage (void)
 {
diff --git a/config/sh/sh.md b/config/sh/sh.md
index 67c5593..6bc0084 100644
--- a/config/sh/sh.md
+++ b/config/sh/sh.md
@@ -6706,7 +6706,7 @@ label:
 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
 (define_insn "movsi_ie"
   [(set (match_operand:SI 0 "general_movdst_operand"
-	    "=r,r,r,r,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
+	    "=r,r,r,r,r,r,r,r,mr,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
 	(match_operand:SI 1 "general_movsrc_operand"
 	 "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
   "(TARGET_SH2E || TARGET_SH2A)
@@ -8370,7 +8370,7 @@ label:
 	(match_operand:SF 1 "general_movsrc_operand"
 	  "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
    (use (reg:SI FPSCR_MODES_REG))
-   (clobber (match_scratch:SI 2 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
+   (clobber (match_scratch:SI 2 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
   "TARGET_SH2E
    && (arith_reg_operand (operands[0], SFmode) || fpul_operand (operands[0], SFmode)
        || arith_reg_operand (operands[1], SFmode) || fpul_operand (operands[1], SFmode)
@@ -8450,6 +8450,104 @@ label:
       (const_string "none")
       (const_string "none")])])
 
+(define_insn_and_split "movsf_ie_ra"
+  [(set (match_operand:SF 0 "general_movdst_operand"
+	 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
+	(match_operand:SF 1 "general_movsrc_operand"
+	  "f,r,G,H,FQ,m,f,FQ,m,r,y,f,>,fr,y,r,y,>,y"))
+   (use (reg:SI FPSCR_MODES_REG))
+   (clobber (match_scratch:SF 2 "=r,r,X,X,&z,r,r,X,r,r,r,r,r,y,r,r,r,r,r"))
+   (const_int 0)]
+  "TARGET_SH2E
+   && (arith_reg_operand (operands[0], SFmode)
+       || fpul_operand (operands[0], SFmode)
+       || arith_reg_operand (operands[1], SFmode)
+       || fpul_operand (operands[1], SFmode))"
+  "@
+	fmov	%1,%0
+	mov	%1,%0
+	fldi0	%0
+	fldi1	%0
+	#
+	fmov.s	%1,%0
+	fmov.s	%1,%0
+	mov.l	%1,%0
+	mov.l	%1,%0
+	mov.l	%1,%0
+	fsts	fpul,%0
+	flds	%1,fpul
+	lds.l	%1,%0
+	#
+	sts	%1,%0
+	lds	%1,%0
+	sts.l	%1,%0
+	lds.l	%1,%0
+	! move optimized away"
+  "reload_completed
+   && sh_movsf_ie_ra_split_p (operands[0], operands[1], operands[2])"
+  [(const_int 0)]
+{
+  if (! rtx_equal_p (operands[0], operands[1]))
+    {
+      emit_insn (gen_movsf_ie (operands[2], operands[1]));
+      emit_insn (gen_movsf_ie (operands[0], operands[2]));
+    }
+}
+  [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,
+		     store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
+   (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
+   (set_attr_alternative "length"
+     [(const_int 2)
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)
+      (const_int 4)
+      (if_then_else
+	(match_test "TARGET_SH2A")
+	(const_int 4) (const_int 2))
+      (if_then_else
+	(match_test "TARGET_SH2A")
+	(const_int 4) (const_int 2))
+      (const_int 2)
+      (if_then_else
+	(match_test "TARGET_SH2A")
+	(const_int 4) (const_int 2))
+      (if_then_else
+	(match_test "TARGET_SH2A")
+	(const_int 4) (const_int 2))
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)
+      (const_int 4)
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)
+      (const_int 2)
+      (const_int 0)])
+  (set_attr_alternative "fp_mode"
+     [(if_then_else (eq_attr "fmovd" "yes")
+		    (const_string "single") (const_string "none"))
+      (const_string "none")
+      (const_string "single")
+      (const_string "single")
+      (const_string "none")
+      (if_then_else (eq_attr "fmovd" "yes")
+		    (const_string "single") (const_string "none"))
+      (if_then_else (eq_attr "fmovd" "yes")
+		    (const_string "single") (const_string "none"))
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")
+      (const_string "none")])])
+
 (define_split
   [(set (match_operand:SF 0 "register_operand" "")
 	(match_operand:SF 1 "register_operand" ""))
@@ -8480,6 +8578,14 @@ label:
     }
   if (TARGET_SH2E)
     {
+      if (lra_in_progress)
+	{
+	  if (GET_CODE (operands[0]) == SCRATCH)
+	    DONE;
+	  emit_insn (gen_movsf_ie_ra (operands[0], operands[1]));
+	  DONE;
+	}
+
       emit_insn (gen_movsf_ie (operands[0], operands[1]));
       DONE;
     }


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