m68k.md (movsi_cfv4): New pattern to allow mov3q.
authorPeter Barada <peter@the-baradas.com>
Wed, 16 Jun 2004 21:53:46 +0000 (21:53 +0000)
committerBernardo Innocenti <bernie@gcc.gnu.org>
Wed, 16 Jun 2004 21:53:46 +0000 (23:53 +0200)
* config/m68k/m68k.md (movsi_cfv4): New pattern to allow mov3q.
(movsi_cf): Make named, don't match TARGET_CFV4.
(pushexthisi_const): Use mov3q if possible.
(extendhisi2, cvf4_extendhisi2): Split extendhisi2 pattern
to special case mvz.w for ColdFire V4.
(extendqisi2, cvf4_extendqisi2): Split extendhisi2 pattern
to special case mvz.b for ColdFire V4.
(udivmodhi4, divmodhi4): Use mvz to zero extend arg for
divide.
(iorsi3, xorsi3, andsi3): Use bitfield instructions if possible.
* config/m68k/m68k.c(valid_mov3q_const):  New function.
(const_method): SWAP is valid for ColdFire.
(MULL_COST, MULW_COST): Fix costs for ColdFire V3/V4.
* config/m68k/m68k-protos.h (valid_mov3q_const): Prototype here.

From-SVN: r83266

gcc/ChangeLog
gcc/config/m68k/m68k-protos.h
gcc/config/m68k/m68k.c
gcc/config/m68k/m68k.md

index 02bd3ba8ff6b800172b963f9b9a5ea14102238c8..cb18ad6ea5bdaf47d6e409f8e00ba1a77d30b45a 100644 (file)
@@ -1,3 +1,20 @@
+2004-06-15  Peter Barada  <peter@the-baradas.com>
+
+       * config/m68k/m68k.md (movsi_cfv4): New pattern to allow mov3q.
+       (movsi_cf): Make named, don't match TARGET_CFV4.
+       (pushexthisi_const): Use mov3q if possible.
+       (extendhisi2, cvf4_extendhisi2): Split extendhisi2 pattern
+       to special case mvz.w for ColdFire V4.
+       (extendqisi2, cvf4_extendqisi2): Split extendhisi2 pattern
+       to special case mvz.b for ColdFire V4.
+       (udivmodhi4, divmodhi4): Use mvz to zero extend arg for
+       divide.
+       (iorsi3, xorsi3, andsi3): Use bitfield instructions if possible.
+       * config/m68k/m68k.c(valid_mov3q_const):  New function.
+       (const_method): SWAP is valid for ColdFire.
+       (MULL_COST, MULW_COST): Fix costs for ColdFire V3/V4.
+       * config/m68k/m68k-protos.h (valid_mov3q_const): Prototype here.
+
 2004-06-16  Richard Henderson  <rth@redhat.com>
 
        * c-common.def (CASE_LABEL): Remove.
index 47afcb3762c18c30a3740383b783db18055b10ec..73810d72f82934e40fc94890372e327a6e1e9bab 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler.  Sun 68000/68020 version.
-   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA.  */
 #ifdef RTX_CODE
 extern HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to);
 extern const char *output_move_const_into_data_reg (rtx *);
+extern int valid_mov3q_const (rtx);
 extern const char *output_move_simode_const (rtx *);
 extern const char *output_move_simode (rtx *);
 extern const char *output_move_himode (rtx *);
index da17f65f9cd34547f9fd1a092c1deffad2b48ea4..8ad252f91fa1806db833cc4ab4eb1429766771c7 100644 (file)
@@ -1447,12 +1447,13 @@ const_method (rtx constant)
       /* This is the only value where neg.w is useful */
       if (i == -65408)
        return NEGW;
-      /* Try also with swap */
-      u = i;
-      if (USE_MOVQ ((u >> 16) | (u << 16)))
-       return SWAP;
     }
 
+  /* Try also with swap.  */
+  u = i;
+  if (USE_MOVQ ((u >> 16) | (u << 16)))
+    return SWAP;
+
   if (TARGET_CFV4)
     {
       /* Try using MVZ/MVS with an immediate value to load constants.  */
@@ -1524,9 +1525,9 @@ m68k_rtx_costs (rtx x, int code, int outer_code, int *total)
        for add and the time for shift, taking away a little more because
        sometimes move insns are needed.  */
     /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms.  */
-#define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : TARGET_CFV3 ? 3 : TARGET_COLDFIRE ? 10 : 13)
+#define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : (TARGET_COLDFIRE && !TARGET_5200) ? 3 : TARGET_COLDFIRE ? 10 : 13)
 #define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : \
-                       TARGET_CFV3 ? 2 : 5)
+                       (TARGET_COLDFIRE && !TARGET_5200) ? 2 : 5)
 #define DIVW_COST (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12)
 
     case PLUS:
@@ -1651,6 +1652,23 @@ output_move_const_into_data_reg (rtx *operands)
     }
 }
 
+/* Return 1 if 'constant' can be represented by
+   mov3q on a ColdFire V4 core.  */
+int
+valid_mov3q_const (rtx constant)
+{
+  int i;
+
+  if (TARGET_CFV4 && GET_CODE (constant) == CONST_INT)
+    {
+      i = INTVAL (constant);
+      if ((i == -1) || (i >= 1 && i <= 7))
+       return 1;
+    }
+  return 0;
+}
+
+
 const char *
 output_move_simode_const (rtx *operands)
 {
@@ -1663,6 +1681,9 @@ output_move_simode_const (rtx *operands)
          || !(GET_CODE (operands[0]) == MEM
               && MEM_VOLATILE_P (operands[0]))))
     return "clr%.l %0";
+  else if ((GET_MODE (operands[0]) == SImode)
+           && valid_mov3q_const (operands[1]))
+      return "mov3q%.l %1,%0";
   else if (operands[1] == const0_rtx
           && ADDRESS_REG_P (operands[0]))
     return "sub%.l %0,%0";
@@ -1671,13 +1692,21 @@ output_move_simode_const (rtx *operands)
   else if (ADDRESS_REG_P (operands[0])
           && INTVAL (operands[1]) < 0x8000
           && INTVAL (operands[1]) >= -0x8000)
-    return "move%.w %1,%0";
+    {
+      if (valid_mov3q_const (operands[1]))
+        return "mov3q%.l %1,%0";
+      return "move%.w %1,%0";
+    }
   else if (GET_CODE (operands[0]) == MEM
       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
           && INTVAL (operands[1]) < 0x8000
           && INTVAL (operands[1]) >= -0x8000)
-    return "pea %a1";
+    {
+      if (valid_mov3q_const (operands[1]))
+        return "mov3q%.l %1,%-";
+      return "pea %a1";
+    }
   return "move%.l %1,%0";
 }
 
index 2603195224dc97f199a62f838ec0641e13336025..2e24c113b2d24995682e0cf288ad90d8d1dae64e 100644 (file)
 {
   if (operands[1] == const0_rtx)
     return "clr%.l %0";
+  if (valid_mov3q_const(operands[1]))
+    return "mov3q%.l %1,%-";
   return "pea %a1";
 })
 
   return output_move_simode (operands);
 })
 
-(define_insn ""
+(define_insn "*movsi_cf"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U")
        (match_operand:SI 1 "general_operand" "g,r<Q>,U"))]
-  "TARGET_COLDFIRE"
+  "TARGET_COLDFIRE && !TARGET_CFV4"
+  "* return output_move_simode (operands);")
+
+(define_insn "*movsi_cfv4"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U")
+       (match_operand:SI 1 "general_operand" "Rg,Rr<Q>,U"))]
+  "TARGET_CFV4"
   "* return output_move_simode (operands);")
 
 ;; Special case of fullword move, where we need to get a non-GOT PIC
 {
   if (DATA_REG_P (operands[0]))
     {
+      if (TARGET_CFV4)
+        return "mvz%.w %1,%0";
       if (GET_CODE (operands[1]) == REG
          && REGNO (operands[0]) == REGNO (operands[1]))
        return "and%.l #0xFFFF,%0";
     {
       if (GET_CODE (operands[1]) == REG
          && REGNO (operands[0]) == REGNO (operands[1]))
-       return (!TARGET_COLDFIRE ? "and%.w #0xFF,%0" : "and%.l #0xFF,%0");
+       {
+         if (TARGET_CFV4)
+           return "mvz%.b %0,%0";      
+         return (!TARGET_COLDFIRE ? "and%.w #0xFF,%0" : "and%.l #0xFF,%0");
+       }
       if (reg_mentioned_p (operands[0], operands[1]))
-       return (!TARGET_COLDFIRE ? "move%.b %1,%0\;and%.w #0xFF,%0" 
-                            : "move%.b %1,%0\;and%.l #0xFF,%0");
+        {
+         if (TARGET_CFV4)
+           return "mvz%.b %1,%0";      
+         return (!TARGET_COLDFIRE ? "move%.b %1,%0\;and%.w #0xFF,%0" 
+                              : "move%.b %1,%0\;and%.l #0xFF,%0");
+       }
       return "clr%.w %0\;move%.b %1,%0";
     }
   else if (GET_CODE (operands[0]) == MEM
 {
   if (DATA_REG_P (operands[0]))
     {
+      if (TARGET_CFV4)
+        return "mvz%.b %1,%0";
       if (GET_CODE (operands[1]) == REG
          && REGNO (operands[0]) == REGNO (operands[1]))
        return "and%.l #0xFF,%0";
 {
   CC_STATUS_INIT;
   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
+  if (TARGET_CFV4)
+    return "mvs%.b %1,%2\;smi %0\;extb%.l %0";
   if (TARGET_68020 || TARGET_COLDFIRE)
     return "move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0";
   else
 {
   CC_STATUS_INIT;
   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
+  if (TARGET_CFV4)
+    return "mvs%.w %1,%2\;smi %0\;extb%.l %0";
   if (TARGET_68020 || TARGET_COLDFIRE)
     return "move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0";
   else
     return "smi %0\;ext%.w %0\;ext%.l %0";
 })
 
-(define_insn "extendhisi2"
+(define_expand "extendhisi2"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+       (sign_extend:SI
+        (match_operand:HI 1 "nonimmediate_src_operand" "")))]
+  ""
+  "")
+
+(define_insn "*cfv4_extendhisi2"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+       (sign_extend:SI
+        (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
+  "TARGET_CFV4"
+  "mvs%.w %1,%0")
+
+(define_insn "*68k_extendhisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
        (sign_extend:SI
         (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
-  ""
+  "!TARGET_CFV4"
 {
   if (ADDRESS_REG_P (operands[0]))
     return "move%.w %1,%0";
   ""
   "ext%.w %0")
 
-(define_insn "extendqisi2"
+(define_expand "extendqisi2"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+       (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
+  "TARGET_68020 || TARGET_COLDFIRE"
+  "")
+
+(define_insn "*cfv4_extendqisi2"
+  [(set (match_operand:SI 0 "general_operand" "=d")
+       (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))]
+  "TARGET_CFV4"
+  "mvs%.b %1,%0")
+
+(define_insn "*68k_extendqisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
-  "TARGET_68020 || TARGET_COLDFIRE"
+  "TARGET_68020 || (TARGET_COLDFIRE && !TARGET_CFV4)"
   "extb%.l %0")
 \f
 ;; Conversions between float and double.
        (umod:HI (match_dup 1) (match_dup 2)))]
   "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
 {
-  output_asm_insn (MOTOROLA ?
-    "and%.l #0xFFFF,%0\;divu%.w %2,%0" :
-    "and%.l #0xFFFF,%0\;divu %2,%0",
-    operands);
+  if (TARGET_CFV4)
+    output_asm_insn (MOTOROLA ?
+      "mvz%.w %0,%0\;divu%.w %2,%0" :
+      "mvz%.w %0,%0\;divu %2,%0",
+      operands);
+  else
+    output_asm_insn (MOTOROLA ?
+      "and%.l #0xFFFF,%0\;divu%.w %2,%0" :
+      "and%.l #0xFFFF,%0\;divu %2,%0",
+      operands);
+
   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
     {
       CC_STATUS_INIT;
        (and:SI (match_operand:SI 1 "general_operand" "%0,0")
                (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
   "TARGET_COLDFIRE"
-  "and%.l %2,%0")
+{
+  if (TARGET_CFV4 && DATA_REG_P (operands[0])
+      && GET_CODE (operands[2]) == CONST_INT)
+    {
+      if (INTVAL (operands[2]) == 0x000000ff)
+        return \"mvz%.b %0,%0\";
+      else if (INTVAL (operands[2]) == 0x0000ffff)
+        return \"mvz%.w %0,%0\";
+    }
+  return output_andsi3 (operands);
+})
 
 (define_insn "andhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
        (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
                (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
   "TARGET_COLDFIRE"
-  "or%.l %2,%0")
+{
+  return output_iorsi3 (operands);
+})
 
 (define_insn "iorhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
        (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
                (match_operand:SI 2 "general_operand" "d,Ks")))]
   "TARGET_COLDFIRE"
-  "eor%.l %2,%0")
+{
+  return output_xorsi3 (operands);
+})
 
 (define_insn "xorhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")