[PATCH 12/28] mn10300: Re-write move patterns.

Richard Henderson rth@redhat.com
Mon Jan 10 20:33:00 GMT 2011


From: Richard Henderson <rth@twiddle.net>

Use the "D" and "A" constraints, and the enabled attribute to
unify all ofthe integer move patterns.  Delete the fake double
word move patterns; let the middle-end generate subregs as required.

Unfortunately, this somehow exposes a register pressure problem
with the udivmod pattern.  This is properly fixed with subsequent
patches that expose the MDR register.

In the meantime it is highly desirable to to preserve bisect-ability
of the patch series, so disable this pattern for AM30.
---
 gcc/config/mn10300/mn10300.md |  930 ++++++++---------------------------------
 1 files changed, 166 insertions(+), 764 deletions(-)

diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md
index 04ec1b1..6e0e1a2 100644
--- a/gcc/config/mn10300/mn10300.md
+++ b/gcc/config/mn10300/mn10300.md
@@ -181,107 +181,42 @@
   [(set (match_operand:QI 0 "nonimmediate_operand")
 	(match_operand:QI 1 "general_operand"))]
   ""
-  "
 {
   /* One of the ops has to be in a register.  */
   if (!register_operand (operand0, QImode)
       && !register_operand (operand1, QImode))
-    operands[1] = copy_to_mode_reg (QImode, operand1);
-}")
-
-(define_insn "*am33_movqi"
-  [(set (match_operand:QI 0 "nonimmediate_operand"
-			  ;; 0       1      2      3     4       5
-			  "=d*x*a*f, d*x*a, d*x*a, m,   *f,      d*x*a")
-	(match_operand:QI 1 "general_operand"
-			   "0,       d*xai, m,     d*xa, d*xa*f, *f"))]
-  "TARGET_AM33
-   && (register_operand (operands[0], QImode)
-       || register_operand (operands[1], QImode))"
-  "*
-  {
-    switch (which_alternative)
-      {
-      case 0:
-        return \"nop\";
-      case 1:
-        gcc_assert (! CONST_DOUBLE_P (operands[1]));
-
-        if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
-	    && CONST_INT_P (operands[1]))
-	  {
-	    HOST_WIDE_INT val = INTVAL (operands[1]);
-
-	    if (((val & 0x80) && ! (val & 0xffffff00))
-	        || ((val & 0x800000) && ! (val & 0xff000000)))
-	      return \"movu %1,%0\";
-	  }
-        return \"mov %1,%0\";
-      case 2:
-      case 3:
-        return \"movbu %1,%0\";
-      case 4:
-      case 5:
-        return \"fmov %1,%0\";
-      default:
-        gcc_unreachable ();
-      }
-  }"
-  [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 11) (const_int 22))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 47) (const_int 25))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 47) (const_int 25))
-			 ])
-  ]
-)
+    operands[1] = force_reg (QImode, operand1);
+})
 
-(define_insn "*mn10300_movqi"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
-	(match_operand:QI 1 "general_operand"       "0,  I,i,i,  da, m,d"))]
-  "register_operand (operands[0], QImode)
-   || register_operand (operands[1], QImode)"
-  "*
+(define_insn "*movqi_internal"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m")
+	(match_operand:QI 1 "general_operand"      "  0,D*r,  i,m,D"))]
+  "(register_operand (operands[0], QImode)
+    || register_operand (operands[1], QImode))"
 {
   switch (which_alternative)
     {
     case 0:
-      return \"nop\";
+      return "";
     case 1:
     case 2:
+      return "mov %1,%0";
     case 3:
     case 4:
-      gcc_assert (! CONST_DOUBLE_P (operands[1]));
-      return \"mov %1,%0\";
-    case 5:
-    case 6:
-      return \"movbu %1,%0\";
+      return "movbu %1,%0";
     default:
       gcc_unreachable ();
     }
-}"
+}
   [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (const_int 11)
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 11) (const_int 22))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 11) (const_int 22))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 11) (const_int 22))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 13) (const_int 24))
-			 ])
-  ]
+	 [(const_int 11)
+	  (const_int 11)
+	  (const_int 11)
+	  (if_then_else (eq_attr "cpu" "am34")
+			(const_int 13) (const_int 24))
+	  (if_then_else (eq_attr "cpu" "am34")
+			(const_int 11) (const_int 22))
+	 ])]
 )
 
 ;; movhi
@@ -290,107 +225,48 @@
   [(set (match_operand:HI 0 "nonimmediate_operand")
 	(match_operand:HI 1 "general_operand"))]
   ""
-  "
 {
   /* One of the ops has to be in a register.  */
   if (!register_operand (operand1, HImode)
       && !register_operand (operand0, HImode))
-    operands[1] = copy_to_mode_reg (HImode, operand1);
-}")
-
-(define_insn "*am33_movhi"
-  [(set (match_operand:HI 0 "nonimmediate_operand"
-			  ;; 0       1       2      3     4         5
-			  "=d*x*a*f, d*x*a,  d*x*a, m,    *f,       d*x*a")
-	(match_operand:HI 1 "general_operand"
-			  "0,        d*x*ai, m,     d*x*a, d*x*a*f, *f"))]
-  "TARGET_AM33
-   && (register_operand (operands[0], HImode)
-       || register_operand (operands[1], HImode))"
-  "*
-{
-  switch (which_alternative)
-    {
-    case 0:
-      return \"nop\";
-    case 1:
-      gcc_assert (! CONST_DOUBLE_P (operands[1]));
-
-      if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
-	  && CONST_INT_P (operands[1]))
-	{
-	  HOST_WIDE_INT val = INTVAL (operands[1]);
-
-	  if (((val & 0x80) && ! (val & 0xffffff00))
-	      || ((val & 0x800000) && ! (val & 0xff000000)))
-	    return \"movu %1,%0\";
-	}
-      return \"mov %1,%0\";
-    case 2:
-    case 3:
-      return \"movhu %1,%0\";
-    case 4:
-    case 5:
-      return \"fmov %1,%0\";
-    default:
-      gcc_unreachable ();
-    }
-}"
-  [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 11) (const_int 22))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 47) (const_int 25))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 47) (const_int 25))
-			 ])
-  ]
-)
+    operands[1] = force_reg (HImode, operand1);
+})
 
-(define_insn "*mn10300_movhi"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
-	(match_operand:HI 1 "general_operand"       "0,  I,i,i,  da, m,d"))]
-  "register_operand (operands[0], HImode)
-   || register_operand (operands[1], HImode)"
-  "*
+(define_insn "*movhi_internal"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m")
+	(match_operand:HI 1 "general_operand"      "  0,  i,D*r,m,D"))]
+  "(register_operand (operands[0], HImode)
+    || register_operand (operands[1], HImode))"
 {
   switch (which_alternative)
     {
     case 0:
-      return \"nop\";
+      return "";
     case 1:
+      if (TARGET_AM33
+	  && CONST_INT_P (operands[1])
+	  && IN_RANGE (INTVAL (operands[1]), 0x80, 0xff))
+	return "movu %1,%0";
+      /* FALLTHRU */
     case 2:
+      return "mov %1,%0";
     case 3:
     case 4:
-      gcc_assert (! CONST_DOUBLE_P (operands[1]));
-      return \"mov %1,%0\";
-    case 5:
-    case 6:
-      return \"movhu %1,%0\";
+      return "movhu %1,%0";
     default:
       gcc_unreachable ();
     }
-}"
+}
   [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (const_int 11)
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 11) (const_int 22))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 11) (const_int 22))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 11) (const_int 22))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-			  		(const_int 13) (const_int 24))
-			 ])
-  ]
+	 [(const_int 11)
+	  (const_int 11)
+	  (if_then_else (eq_attr "cpu" "am34")
+	  		(const_int 11) (const_int 22))
+	  (if_then_else (eq_attr "cpu" "am34")
+	  		(const_int 13) (const_int 24))
+	  (if_then_else (eq_attr "cpu" "am34")
+	  		(const_int 11) (const_int 22))
+	 ])]
 )
 
 ;; movsi and helpers
@@ -450,12 +326,11 @@
   [(set (match_operand:SI 0 "nonimmediate_operand")
 	(match_operand:SI 1 "general_operand"))]
   ""
-  "
 {
   /* One of the ops has to be in a register.  */
   if (!register_operand (operand1, SImode)
       && !register_operand (operand0, SImode))
-    operands[1] = copy_to_mode_reg (SImode, operand1);
+    operands[1] = force_reg (SImode, operand1);
   if (flag_pic)
     {
       rtx temp;
@@ -486,594 +361,118 @@
 				      0, OPTAB_LIB_WIDEN);
 	}
     }
-}")
+})
 
 (define_insn "*movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand"
-			  "=dax, dax,  m,   dax, ax,!*y")
+			  "=r,r,r,m,r, A,*y,*y")
 	(match_operand:SI 1 "general_operand"
-			  "0,    Idax, dax, im, !*y, ax"))
-  ]
+			  " 0,i,r,r,m,*y, A, i"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)"
-  "*
-  {
-    if (which_alternative == 0)
-      return \"nop\";
-
-    gcc_assert (! CONST_DOUBLE_P (operands[1]));
-
-    if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
-        && CONST_INT_P (operands[1]))
-      {
-        HOST_WIDE_INT val = INTVAL (operands[1]);
-
-        if (((val & 0x80) && ! (val & 0xffffff00))
-            || ((val & 0x800000) && ! (val & 0xff000000)))
-          return \"movu %1, %0\";
-      }
-
-    return \"mov %1, %0\";
-  }"
-  [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			 ])
-  ]
+{
+  switch (which_alternative)
+    {
+    case 0:
+      return "";
+    case 1: /* imm-reg*/
+      if (TARGET_AM33 && CONST_INT_P (operands[1]))
+	{
+	  HOST_WIDE_INT val = INTVAL (operands[1]);
+	  if (IN_RANGE (val, 0x80, 0xff)
+	      || IN_RANGE (val, 0x800000, 0xffffff))
+	    return "movu %1,%0";
+	}
+      /* FALLTHRU */
+    case 2:  /* reg-reg */
+    case 3:  /* reg-mem */
+    case 4:  /* mem-reg */
+    case 5:  /* sp-reg */
+    case 6:  /* reg-sp */
+    case 7:  /* imm-sp */
+      return "mov %1,%0";
+    default:
+      gcc_unreachable ();
+    }
+}
+  [(set_attr "isa" "*,*,*,*,*,*,*,am33")
+   (set_attr_alternative "timings"
+	 [(const_int 11)
+	  (const_int 22)
+	  (const_int 11)
+	  (if_then_else (eq_attr "cpu" "am34")
+			(const_int 11) (const_int 22))
+	  (if_then_else (eq_attr "cpu" "am34")
+			(const_int 13) (const_int 24))
+	  (if_then_else (eq_attr "cpu" "am34")
+			(const_int 11) (const_int 22))
+	  (if_then_else (eq_attr "cpu" "am34")
+			(const_int 13) (const_int 24))
+	  (const_int 11)
+	 ])]
 )
 
 (define_expand "movsf"
   [(set (match_operand:SF 0 "nonimmediate_operand")
 	(match_operand:SF 1 "general_operand"))]
-  ""
-  "
+  "TARGET_AM33_2"
 {
   /* One of the ops has to be in a register.  */
   if (!register_operand (operand1, SFmode)
       && !register_operand (operand0, SFmode))
-    operands[1] = copy_to_mode_reg (SFmode, operand1);
-}")
+    operands[1] = force_reg (SFmode, operand1);
+})
 
 (define_insn "*movsf_internal"
-  [(set (match_operand:SF 0 "nonimmediate_operand"
-			  ;; 0    1    2       3     4     5
-			  "=fdxa, dxa, f,      dxaQ, daxm, dax")
-	(match_operand:SF 1 "general_operand"
-			  " 0,    G,   fdxaQF, f,    dax,  daxFm"))
-  ]
-  "register_operand (operands[0], SFmode)
-   || register_operand (operands[1], SFmode)"
-  "*
-  {
-    switch (which_alternative)
-      {
-      case 0:
-        return \"nop\";
-      /* case 1: below.  */
-      case 2:
-      case 3:
-        return \"fmov %1, %0\";
-      case 1:
-      case 4:
-      case 5:
-        if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
-	    && CONST_INT_P (operands[1]))
-	  {
-	    HOST_WIDE_INT val = INTVAL (operands[1]);
-
-	    if (((val & 0x80) && ! (val & 0xffffff00))
-	        || ((val & 0x800000) && ! (val & 0xff000000)))
-	      return \"movu %1, %0\";
-	  }
-        return \"mov %1, %0\";
-      default:
-        gcc_unreachable ();
-      }
-  }"
-  [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 47) (const_int 25))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 47) (const_int 25))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			  (if_then_else (eq_attr "cpu" "am34")
-					(const_int 13) (const_int 24))
-			 ])
-  ]
-)
-
-(define_expand "movdi"
-  [(set (match_operand:DI 0 "nonimmediate_operand")
-	(match_operand:DI 1 "general_operand"))]
-  ""
-  "
-{
-  /* One of the ops has to be in a register.  */
-  if (!register_operand (operand1, DImode)
-      && !register_operand (operand0, DImode))
-    operands[1] = copy_to_mode_reg (DImode, operand1);
-}")
-
-
-(define_insn "*movdi_internal"                   ;;   0 1  2  3 4   5   6  7 8  9
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=dx,ax,dx,a,dxm,dxm,a, a,dx,a")
-	(match_operand:DI 1 "general_operand"        "0,0, I, I,dx, a,  dx,a,im,im"))]
-  "register_operand (operands[0], DImode)
-   || register_operand (operands[1], DImode)"
-  "*
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q")
+	(match_operand:SF 1 "general_operand"	   "  0,F,F,r,f,f,r,m,r,Q,f"))]
+  "TARGET_AM33_2
+   && (register_operand (operands[0], SFmode)
+       || register_operand (operands[1], SFmode))"
 {
-  long val[2];
-  REAL_VALUE_TYPE rv;
-
   switch (which_alternative)
     {
-      case 0:
-      case 1:
-	return \"nop\";
-
-      case 2:
-	return \"mov 0, %L0\;mov 0, %H0\";
-
-      case 3:
-	if (rtx_equal_p (operands[0], operands[1]))
-	  return \"sub %L1,%L0\;mov %L0,%H0\";
-	else
-	  return \"mov %1,%L0\;mov %L0,%H0\";
-      case 4:
-      case 5:
-      case 6:
-      case 7:
-      case 8:
-      case 9:
-	if (CONST_INT_P (operands[1]))
-	  {
-	    rtx low, high;
-	    split_double (operands[1], &low, &high);
-	    val[0] = INTVAL (low);
-	    val[1] = INTVAL (high);
-	  }
-	if (CONST_DOUBLE_P (operands[1]))
-	  {
-	    if (GET_MODE (operands[1]) == DFmode)
-	      {
-		REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-		REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
-	      }
-	    else if (GET_MODE (operands[1]) == VOIDmode
-		     || GET_MODE (operands[1]) == DImode)
-	      {
-		val[0] = CONST_DOUBLE_LOW (operands[1]);
-		val[1] = CONST_DOUBLE_HIGH (operands[1]);
-	      }
-	  }
-
-	if (MEM_P (operands[1])
-	    && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
-	  {
-	    rtx temp = operands[0];
-
-	    while (GET_CODE (temp) == SUBREG)
-	      temp = SUBREG_REG (temp);
-
-	    gcc_assert (REG_P (temp));
-
-	    if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
-					 XEXP (operands[1], 0)))
-	      return \"mov %H1,%H0\;mov %L1,%L0\";
-	    else
-	      return \"mov %L1,%L0\;mov %H1,%H0\";
-
-	  }
-	else if (MEM_P (operands[1])
-		 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
-		 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
-	  {
-	    rtx xoperands[2];
-
-	    xoperands[0] = operands[0];
-	    xoperands[1] = XEXP (operands[1], 0);
-
-	    output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
-			     xoperands);
-	    return \"\";
-	  }
-	else
-	  {
-	    if ((CONST_INT_P (operands[1])
-		 || CONST_DOUBLE_P (operands[1]))
-		&& val[0] == 0)
-	      {
-		if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-		  output_asm_insn (\"mov 0, %L0\", operands);
-		else
-		  output_asm_insn (\"mov %L1,%L0\", operands);
-	      }
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && (REGNO_REG_CLASS (true_regnum (operands[0]))
-			 == EXTENDED_REGS)
-		     && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
-			 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
-	      output_asm_insn (\"movu %L1,%L0\", operands);
-	    else
-	      output_asm_insn (\"mov %L1,%L0\", operands);
-
-	    if ((CONST_INT_P (operands[1])
-		 || CONST_DOUBLE_P (operands[1]))
-		&& val[1] == 0)
-	      {
-		if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-		  output_asm_insn (\"mov 0, %H0\", operands);
-		else
-		  output_asm_insn (\"mov %H1,%H0\", operands);
-	      }
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && val[0] == val[1])
-	      output_asm_insn (\"mov %L0,%H0\", operands);
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && (REGNO_REG_CLASS (true_regnum (operands[0]))
-			 == EXTENDED_REGS)
-		     && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
-			 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
-	      output_asm_insn (\"movu %H1,%H0\", operands);
-	    else
-	      output_asm_insn (\"mov %H1,%H0\", operands);
-	    return \"\";
-	  }
-    default:
-      gcc_unreachable ();
-    }
-  }"
-  ;; The timing of "37" is an approximation of the worst case sceanario.
-  [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (const_int 11)
-			  (const_int 22)
-			  (const_int 22)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			 ])
-  ]
-)
-
-(define_expand "movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand")
-	(match_operand:DF 1 "general_operand"))]
-  ""
-  "
-{
-  /* One of the ops has to be in a register.  */
-  if (!register_operand (operand1, DFmode)
-      && !register_operand (operand0, DFmode))
-    operands[1] = copy_to_mode_reg (DFmode, operand1);
-}")
-
-(define_insn "*am33_2_movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand"
-			  ;; 0   1   2    3    4 5 6   7   8  9 10 11
-			  "=fdax,dax,fdxa,f,   f,Q,dxm,dxm,a, a,dx,a")
-	(match_operand:DF 1 "general_operand"
-			  " 0,   G,  f,   dxaF,Q,f,dx, a,  dx,a,Fm,Fm"))]
-  "TARGET_AM33_2
-   && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode))"
-  "*
-  {
-    long val[2];
-    REAL_VALUE_TYPE rv;
-
-    switch (which_alternative)
-      {
-      case 0:
-	return \"nop\";
-
-      case 1:
-	return \"mov 0, %L0\; mov 0, %H0\";
-
-      case 2:
-      case 3:
-        return \"fmov %L1, %L0\; fmov %H1, %H0\";
-
-      case 4:
-	if (MEM_P (operands[1])
-	    && CONST_INT_P (XEXP (operands[1], 0))
-	    && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
-	  return \"fmov %D1, %D0\";
-	else
-          return \"fmov %L1, %L0\; fmov %H1, %H0\";
-
-      case 5:
-	if (MEM_P (operands[0])
-	    && CONST_INT_P (XEXP (operands[0], 0))
-	    && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
-	  return \"fmov %D1, %D0\";
-	else
-          return \"fmov %L1, %L0\; fmov %H1, %H0\";
-
-      case 6:
-      case 7:
-      case 8:
-      case 9:
-      case 10:
-      case 11:
-	if (CONST_INT_P (operands[1]))
-	  {
-	    rtx low, high;
-	    split_double (operands[1], &low, &high);
-	    val[0] = INTVAL (low);
-	    val[1] = INTVAL (high);
-	  }
-	if (CONST_DOUBLE_P (operands[1]))
-	  {
-	    if (GET_MODE (operands[1]) == DFmode)
-	      {
-		REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-		REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
-	      }
-	    else if (GET_MODE (operands[1]) == VOIDmode
-		     || GET_MODE (operands[1]) == DImode)
-	      {
-		val[0] = CONST_DOUBLE_LOW (operands[1]);
-		val[1] = CONST_DOUBLE_HIGH (operands[1]);
-	      }
-	  }
-
-	if (MEM_P (operands[1])
-	    && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
-	  {
-	    rtx temp = operands[0];
-
-	    while (GET_CODE (temp) == SUBREG)
-	      temp = SUBREG_REG (temp);
-
-	    gcc_assert (REG_P (temp));
-
-	    if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
-					 XEXP (operands[1], 0)))
-	      return \"mov %H1, %H0\; mov %L1, %L0\";
-	    else
-	      return \"mov %L1, %L0\; mov %H1, %H0\";
-
-	  }
-	else if (MEM_P (operands[1])
-		 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
-		 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
-	  {
-	    rtx xoperands[2];
-
-	    xoperands[0] = operands[0];
-	    xoperands[1] = XEXP (operands[1], 0);
-
-	    output_asm_insn (\"mov %1, %L0\; mov (4, %L0), %H0\; mov (%L0), %L0\",
-			     xoperands);
-	    return \"\";
-	  }
-	else
-	  {
-	    if ((CONST_INT_P (operands[1])
-		 || CONST_DOUBLE_P (operands[1]))
-		&& val[0] == 0)
-	      {
-		if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-		  output_asm_insn (\"mov 0, %L0\", operands);
-		else
-		  output_asm_insn (\"mov %L1,%L0\", operands);
-	      }
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && (REGNO_REG_CLASS (true_regnum (operands[0]))
-			 == EXTENDED_REGS)
-		     && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
-			 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
-	      output_asm_insn (\"movu %L1, %L0\", operands);
-	    else
-	      output_asm_insn (\"mov %L1, %L0\", operands);
-
-	    if ((CONST_INT_P (operands[1])
-		 || CONST_DOUBLE_P (operands[1]))
-		&& val[1] == 0)
-	      {
-		if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-		  output_asm_insn (\"mov 0, %H0\", operands);
-		else
-		  output_asm_insn (\"mov %H1, %H0\", operands);
-	      }
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && val[0] == val[1])
-	      output_asm_insn (\"mov %L0,%H0\", operands);
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && (REGNO_REG_CLASS (true_regnum (operands[0]))
-			 == EXTENDED_REGS)
-		     && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
-			 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
-	      output_asm_insn (\"movu %H1, %H0\", operands);
-	    else
-	      output_asm_insn (\"mov %H1, %H0\", operands);
-	    return \"\";
-	  }
+    case 0:
+      return "";
+    case 1:
+    case 3:
+    case 7:
+    case 8:
+      return "mov %1,%0";
+    case 2:
+    case 4:
+    case 5:
+    case 6:
+    case 9:
+    case 10:
+      return "fmov %1,%0";
     default:
       gcc_unreachable ();
     }
-  }"
-  ;; The timing of "37" is an approximation of the worst case sceanario.
+}
   [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (const_int 22)
-			  (const_int 22)
-			  (const_int 22)
-			  (const_int 22)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			 ])
-  ]
+		 [(const_int 11)
+		  (const_int 22)
+		  (if_then_else (eq_attr "cpu" "am34")
+				(const_int 47) (const_int 25))
+		  (const_int 11)
+		  (if_then_else (eq_attr "cpu" "am34")
+				(const_int 13) (const_int 14))
+		  (if_then_else (eq_attr "cpu" "am34")
+				(const_int 13) (const_int 12))
+		  (if_then_else (eq_attr "cpu" "am34")
+				(const_int 13) (const_int 14))
+		  (if_then_else (eq_attr "cpu" "am34")
+				(const_int 13) (const_int 24))
+		  (if_then_else (eq_attr "cpu" "am34")
+				(const_int 13) (const_int 24))
+		  (if_then_else (eq_attr "cpu" "am34")
+				(const_int 13) (const_int 24))
+		  (if_then_else (eq_attr "cpu" "am34")
+				(const_int 13) (const_int 24))
+		 ])]
 )
 
-(define_insn "*mn10300_movdf"
-  [(set (match_operand:DF 0 "nonimmediate_operand"
-			  ;;0    1    2    3    4   5  6   7
-			  "=dxa, dax, dxm, dxm, a,  a, dx, a")
-	(match_operand:DF 1 "general_operand"
-			  " 0,   G,   dx,  a,   dx, a, Fm, Fm"))]
-  "register_operand (operands[0], DFmode)
-   || register_operand (operands[1], DFmode)"
-  "*
-  {
-    long val[2];
-    REAL_VALUE_TYPE rv;
-
-    switch (which_alternative)
-      {
-      case 0:
-	return \"nop\";
-
-      case 1:
-	return \"mov 0, %L0\; mov 0, %H0\";
-
-      case 2:
-      case 3:
-      case 4:
-      case 5:
-      case 6:
-      case 7:
-	if (CONST_INT_P (operands[1]))
-	  {
-	    rtx low, high;
-	    split_double (operands[1], &low, &high);
-	    val[0] = INTVAL (low);
-	    val[1] = INTVAL (high);
-	  }
-        if (CONST_DOUBLE_P (operands[1]))
-	  {
-	    if (GET_MODE (operands[1]) == DFmode)
-	      {
-		REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
-		REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
-	      }
-	    else if (GET_MODE (operands[1]) == VOIDmode
-		     || GET_MODE (operands[1]) == DImode)
-	      {
-		val[0] = CONST_DOUBLE_LOW (operands[1]);
-		val[1] = CONST_DOUBLE_HIGH (operands[1]);
-	      }
-	  }
-
-	if (MEM_P (operands[1])
-	    && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
-	  {
-	    rtx temp = operands[0];
-
-	    while (GET_CODE (temp) == SUBREG)
-	      temp = SUBREG_REG (temp);
-
-	    gcc_assert (REG_P (temp));
-
-	    if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
-					 XEXP (operands[1], 0)))
-	      return \"mov %H1, %H0\; mov %L1, %L0\";
-	    else
-	      return \"mov %L1, %L0\; mov %H1, %H0\";
-	  }
-	else if (MEM_P (operands[1])
-		 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
-		 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
-	  {
-	    rtx xoperands[2];
-
-	    xoperands[0] = operands[0];
-	    xoperands[1] = XEXP (operands[1], 0);
-
-	    output_asm_insn (\"mov %1, %L0\; mov (4, %L0), %H0\; mov (%L0), %L0\",
-			     xoperands);
-	    return \"\";
-	  }
-	else
-	  {
-	    if ((CONST_INT_P (operands[1])
-		 || CONST_DOUBLE_P (operands[1]))
-		&& val[0] == 0)
-	      {
-		if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-		  output_asm_insn (\"mov 0, %L0\", operands);
-		else
-		  output_asm_insn (\"mov %L1, %L0\", operands);
-	      }
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && (REGNO_REG_CLASS (true_regnum (operands[0]))
-			 == EXTENDED_REGS)
-		     && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
-			 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
-	      output_asm_insn (\"movu %L1, %L0\", operands);
-	    else
-	      output_asm_insn (\"mov %L1, %L0\", operands);
-
-	    if ((CONST_INT_P (operands[1])
-		 || CONST_DOUBLE_P (operands[1]))
-		&& val[1] == 0)
-	      {
-		if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-		  output_asm_insn (\"mov 0, %H0\", operands);
-		else
-		  output_asm_insn (\"mov %H1, %H0\", operands);
-	      }
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && val[0] == val[1])
-	      output_asm_insn (\"mov %L0, %H0\", operands);
-	    else if ((CONST_INT_P (operands[1])
-		      || CONST_DOUBLE_P (operands[1]))
-		     && (REGNO_REG_CLASS (true_regnum (operands[0]))
-			 == EXTENDED_REGS)
-		     && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
-			 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
-	      output_asm_insn (\"movu %H1, %H0\", operands);
-	    else
-	      output_asm_insn (\"mov %H1, %H0\", operands);
-	    return \"\";
-	  }
-    default:
-      gcc_unreachable ();
-    }
-  }"
-  ;; Timings of "37" is approximation of the worst case sceanario.
-  [(set_attr_alternative "timings"
-			 [(const_int 11)
-			  (const_int 22)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			  (const_int 37)
-			 ])
-  ]
-)
 
 ;; ----------------------------------------------------------------------
 ;; ADD INSTRUCTIONS
@@ -1363,42 +762,23 @@
   	      		 	       (const_int 24) (const_int 23)))]
 )
 
-(define_expand "udivmodsi4"
-  [(parallel [(set (match_operand:SI          0 "register_operand")
-		   (udiv:SI (match_operand:SI 1 "general_operand")
-			    (match_operand:SI 2 "general_operand")))
-	      (set (match_operand:SI          3 "register_operand")
-		   (umod:SI (match_dup 1) (match_dup 2)))
-	      (clobber (reg:CC CC_REG))
-	     ])
-  ]
-  ""
-  "{
-    if (!register_operand (operands[1], SImode))
-      operands[1] = copy_to_mode_reg (SImode, operands[1]);
-    if (!register_operand (operands[2], SImode))
-      operands[2] = copy_to_mode_reg (SImode, operands[2]);
-   }"
-)
-
-(define_insn "*udivmodsi4"
-  [(set (match_operand:SI          0 "register_operand" "=dx")
+;; ??? This pattern causes too-high register pressure for MN103.
+;; ??? To be fixed by exposing the MDR register properly.
+(define_insn "udivmodsi4"
+  [(set (match_operand:SI          0 "register_operand" "=D")
 	(udiv:SI (match_operand:SI 1 "register_operand" "0")
-		 (match_operand:SI 2 "register_operand" "dx")))
+		 (match_operand:SI 2 "register_operand" "D")))
    (set (match_operand:SI          3 "register_operand" "=&d")
 	(umod:SI (match_dup 1) (match_dup 2)))
-   (clobber (reg:CC CC_REG))
-  ]
-  ""
-  "*
+   (clobber (reg:CC CC_REG))]
+  "TARGET_AM33"
 {
-  output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
-
+  output_asm_insn ("clr %3\;ext %3", operands);
   if (find_reg_note (insn, REG_UNUSED, operands[3]))
-    return \"divu %2,%0\";
+    return "divu %2,%0";
   else
-    return \"divu %2,%0\;mov mdr,%3\";
-}"
+    return "divu %2,%0\;mov mdr,%3";
+}
   ;; Timings:  AM33   AM34
   ;;  SUB       1/1    1/1
   ;;  MOV       1/1    1/1
@@ -1410,6 +790,28 @@
   	      		 	       (const_int 4546) (const_int 4142)))]
 )
 
+;; ??? In the meantime MN103 can use these two patterns,
+;; which reduce the register pressure by one.
+(define_insn "udivsi3"
+  [(set (match_operand:SI          0 "register_operand" "=&d")
+	(udiv:SI (match_operand:SI 1 "register_operand" "d")
+		 (match_operand:SI 2 "register_operand" "d")))
+   (clobber (reg:CC CC_REG))]
+  "!TARGET_AM33"
+  "clr %0\;ext %0\;mov %1,%0\;divu %2,%0"
+  [(set_attr "timings" "4142")]
+)
+
+(define_insn "umodsi3"
+  [(set (match_operand:SI          0 "register_operand" "=&d")
+	(umod:SI (match_operand:SI 1 "register_operand" "d")
+		 (match_operand:SI 2 "register_operand" "d")))
+   (clobber (reg:CC CC_REG))]
+  "!TARGET_AM33"
+  "clr %0\;ext %0\;mov %1,%0\;divu %2,%0\;mov mdr,%0"
+  [(set_attr "timings" "4142")]
+)
+
 (define_insn "divmodsi4"
   [(set (match_operand:SI          0 "register_operand" "=dx")
 	(div:SI (match_operand:SI  1 "register_operand"  "0")
-- 
1.7.3.4



More information about the Gcc-patches mailing list