Patchwork [ARM] Unify movdi patterns and fix case for mvn in const_ok_for_op.

login
register
mail settings
Submitter Ramana Radhakrishnan
Date June 8, 2011, 2:19 p.m.
Message ID <BANLkTi=zZKuKq1kHZdUazGWj5wKjpCg7uQ@mail.gmail.com>
Download mbox | patch
Permalink /patch/99437/
State New
Headers show

Comments

Ramana Radhakrishnan - June 8, 2011, 2:19 p.m.
Hi,

This fixes a testsuite failure with 20041011-1.c where we are
generating out of range adr instructions because a splitter goes awry
because we didn't consider the mvn case in const_ok_for_op.

So we ended up splitting this

movdi reg:r1 0xffffffff

to

(insn 370 21 371 (set (reg:SI 2 r2)
        (const_int -2147483648 [0xffffffff80000000]))
/home/ramrad01/sources/fsf/trunk/gcc/testsuite/gcc.c-torture/execute/20041011-1.c:56
624 {*arm_movsi_vfp}
     (nil))

(insn 371 370 372 (set (reg:SI 2 r2)
        (ashiftrt:SI (reg:SI 2 r2)
            (const_int 31 [0x1f])))
/home/ramrad01/sources/fsf/trunk/gcc/testsuite/gcc.c-torture/execute/20041011-1.c:56
119 {*arm_shiftsi3}
     (nil))

(insn 372 371 23 (set (reg:SI 3 r3 [+4 ])
        (const_int 0 [0]))
/home/ramrad01/sources/fsf/trunk/gcc/testsuite/gcc.c-torture/execute/20041011-1.c:56
624 {*arm_movsi_vfp}
     (nil))

After this patch we now split this to a mvn 0 followed by a mov 0
which is much better.

I've also taken the opportunity to rejig the *movdi patterns to make
them simpler - unified them with thumb2 movdi patterns and taken out
the check for TARGET_VFP_SINGLE from the cortex-a8 version . Tested
with cross on armv7-a for qemu in both ARM and Thumb2 state using
arm-linux-gnueabi.

I will commit this in 24 hours if there are no objections.

cheers
Ramana


2011-06-03  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
                  Richard Earnshaw  <rearnsha@arm.com>

        * config/arm/arm.c (const_ok_for_op): Check to see
        if mvn can be used.
        * config/arm/vfp.md (*arm_movdi_vfp): Delete.
        (*thumb2_movdi_vfp): Delete.
        (*arm_movdi_vfp_cortexa8): Delete.
        (*movdi_vfp): Consolidate from *arm_movdi_vfp and *thumb2_movdi_vfp.
        (*movdi_vfp_cortexa8): Likewise.

Patch

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 57c5238..c2d69c8 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -2210,7 +2210,8 @@  const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
       if (arm_arch_thumb2 && (i & 0xffff0000) == 0)
 	return 1;
       else
-	return 0;
+	/* Otherwise, try mvn.  */
+	return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
 
     case PLUS:
     case COMPARE:
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index d257cb8..42be2ff 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -133,127 +133,92 @@ 
 
 ;; DImode moves
 
-(define_insn "*arm_movdi_vfp"
-  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, m,w,r,w,w, Uv")
-	(match_operand:DI 1 "di_operand"              "rIK,mi,r,r,w,w,Uvi,w"))]
-  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune != cortexa8
+(define_insn "*movdi_vfp"
+  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,r,w,w, Uv")
+       (match_operand:DI 1 "di_operand"              "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))]
+  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune != cortexa8
    && (   register_operand (operands[0], DImode)
        || register_operand (operands[1], DImode))"
   "*
   switch (which_alternative)
     {
     case 0: 
-      return \"#\";
     case 1:
     case 2:
-      return output_move_double (operands);
     case 3:
-      return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
+      return \"#\";
     case 4:
-      return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
     case 5:
+    case 6:
+      return output_move_double (operands);
+    case 7:
+      return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
+    case 8:
+      return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
+    case 9:
       if (TARGET_VFP_SINGLE)
 	return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
       else
 	return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
-    case 6: case 7:
+    case 10: case 11:
       return output_move_vfp (operands);
     default:
       gcc_unreachable ();
     }
   "
-  [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
-   (set_attr "neon_type" "*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
-   (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8)
-			       (eq_attr "alternative" "5")
-				(if_then_else
-				 (eq (symbol_ref "TARGET_VFP_SINGLE") (const_int 1))
-				 (const_int 8)
-				 (const_int 4))]
-			      (const_int 4)))
-   (set_attr "pool_range"     "*,1020,*,*,*,*,1020,*")
-   (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
+  [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
+   (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
+   (set (attr "length") (cond [(eq_attr "alternative" "1,4,5,6") (const_int 8)
+                              (eq_attr "alternative" "2") (const_int 12)
+                              (eq_attr "alternative" "3") (const_int 16)
+                              (eq_attr "alternative" "9")
+                               (if_then_else
+                                 (eq (symbol_ref "TARGET_VFP_SINGLE") (const_int 1))
+                                 (const_int 8)
+                                 (const_int 4))]
+                              (const_int 4)))
+   (set_attr "pool_range"     "*,*,*,*,1020,4096,*,*,*,*,1020,*")
+   (set_attr "neg_pool_range" "*,*,*,*,1008,0,*,*,*,*,1008,*")
+   (set_attr "arch"           "t2,any,any,any,a,t2,any,any,any,any,any,any")]
 )
 
-(define_insn "*arm_movdi_vfp_cortexa8"
-  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,!r,w,w, Uv")
-	(match_operand:DI 1 "di_operand"              "rIK,mi,r,r,w,w,Uvi,w"))]
-  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune == cortexa8
-   && (   register_operand (operands[0], DImode)
-       || register_operand (operands[1], DImode))"
+(define_insn "*movdi_vfp_cortexa8"
+  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,!r,w,w, Uv")
+       (match_operand:DI 1 "di_operand"              "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))]
+  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune == cortexa8
+    && (   register_operand (operands[0], DImode)
+        || register_operand (operands[1], DImode))"
   "*
   switch (which_alternative)
     {
     case 0: 
-      return \"#\";
     case 1:
     case 2:
-      return output_move_double (operands);
     case 3:
-      return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
+      return \"#\";
     case 4:
-      return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
     case 5:
-      if (TARGET_VFP_SINGLE)
-	return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
-      else
-	return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
-    case 6: case 7:
-      return output_move_vfp (operands);
-    default:
-      gcc_unreachable ();
-    }
-  "
-  [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
-   (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8)
-			       (eq_attr "alternative" "5")
-				(if_then_else
-				 (eq (symbol_ref "TARGET_VFP_SINGLE")
-				     (const_int 1))
-				 (const_int 8)
-				 (const_int 4))]
-			      (const_int 4)))
-   (set_attr "predicable"    "yes")
-   (set_attr "pool_range"     "*,1020,*,*,*,*,1020,*")
-   (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
-)
-
-(define_insn "*thumb2_movdi_vfp"
-  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
-	(match_operand:DI 1 "di_operand"              "rIK,mi,r,r,w,w,Uvi,w"))]
-  "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
-  "*
-  switch (which_alternative)
-    {
-    case 0: case 1: case 2:
-      return (output_move_double (operands));
-    case 3:
+    case 6:
+      return output_move_double (operands);
+    case 7:
       return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
-    case 4:
+    case 8:
       return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
-    case 5:
-      if (TARGET_VFP_SINGLE)
-	return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
-      else
-	return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
-    case 6: case 7:
+    case 9:
+      return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
+    case 10: case 11:
       return output_move_vfp (operands);
     default:
-      abort ();
+      gcc_unreachable ();
     }
   "
-  [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
-   (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8)
-			       (eq_attr "alternative" "5")
-				(if_then_else
-				 (eq (symbol_ref "TARGET_VFP_SINGLE")
-				     (const_int 1))
-				 (const_int 8)
-				 (const_int 4))]
-			      (const_int 4)))
-   (set_attr "pool_range"     "*,4096,*,*,*,*,1020,*")
-   (set_attr "neg_pool_range" "*,   0,*,*,*,*,1008,*")]
-)
+  [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
+   (set_attr "length" "4,8,12,16,8,8,8,4,4,4,4,4")
+   (set_attr "predicable"    "yes")
+   (set_attr "pool_range"     "*,*,*,*,1020,4096,*,*,*,*,1020,*")
+   (set_attr "neg_pool_range" "*,*,*,*,1008,0,*,*,*,*,1008,*")
+   (set_attr "arch"           "t2,any,any,any,a,t2,any,any,any,any,any,any")]
+ )
 
 ;; HFmode moves
 (define_insn "*movhf_vfp_neon"