	2010-04-08  Bernd Schmidt  <bernds@codesourcery.com>

	Issue #6952

	gcc/
	* ira-costs.c (record_reg_classes): Ignore alternatives that are 
	not enabled. 
	* config/arm/vfp.md (arm_movdi_vfp): Enable only when not tuning
	for Cortex-A8.
	(arm_movdi_vfp_cortexa8): New pattern.
	* config/arm/neon.md (adddi3_neon, subdi3_neon, anddi3_neon,
	iordi3_neon, xordi3_neon): Add alternatives to discourage Neon
	instructions when tuning for Cortex-A8.  Set attribute "alt_tune".
	* config/arm/arm.md (define_attr "alt_tune", define_attr "enabled"):
	New.

2010-07-26  Julian Brown  <julian@codesourcery.com>

	Merge from Sourcery G++ 4.4:

 	2010-04-07  Thomas Schwinge  <thomas@codesourcery.com>
 		    Daniel Jacobowitz  <dan@codesourcery.com>
 

=== modified file 'gcc/config/arm/arm.md'
--- old/gcc/config/arm/arm.md	2010-08-13 10:30:35 +0000
+++ new/gcc/config/arm/arm.md	2010-08-13 11:40:17 +0000
@@ -432,6 +432,20 @@
 	  (const_string "yes")
 	  (const_string "no"))))
 
+; Specifies which machine an alternative is tuned for.  Used to compute
+; attribute ENABLED.
+(define_attr "alt_tune" "all,onlya8,nota8" (const_string "all"))
+
+(define_attr "enabled" ""
+  (cond [(and (eq_attr "alt_tune" "onlya8")
+	      (not (eq_attr "tune" "cortexa8")))
+	 (const_int 0)
+
+	 (and (eq_attr "alt_tune" "nota8")
+	      (eq_attr "tune" "cortexa8"))
+	 (const_int 0)]
+	(const_int 1)))
+
 (include "arm-generic.md")
 (include "arm926ejs.md")
 (include "arm1020e.md")

=== modified file 'gcc/config/arm/neon.md'
--- old/gcc/config/arm/neon.md	2010-08-10 13:31:21 +0000
+++ new/gcc/config/arm/neon.md	2010-08-13 11:40:17 +0000
@@ -827,23 +827,25 @@
 )
 
 (define_insn "adddi3_neon"
-  [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
-        (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0")
-                 (match_operand:DI 2 "s_register_operand" "w,r,0")))
+  [(set (match_operand:DI 0 "s_register_operand" "=w,?w,?&r,?&r")
+        (plus:DI (match_operand:DI 1 "s_register_operand" "%w,w,0,0")
+                 (match_operand:DI 2 "s_register_operand" "w,w,r,0")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_NEON"
 {
   switch (which_alternative)
     {
-    case 0: return "vadd.i64\t%P0, %P1, %P2";
-    case 1: return "#";
+    case 0: /* fall through */
+    case 1: return "vadd.i64\t%P0, %P1, %P2";
     case 2: return "#";
+    case 3: return "#";
     default: gcc_unreachable ();
     }
 }
-  [(set_attr "neon_type" "neon_int_1,*,*")
-   (set_attr "conds" "*,clob,clob")
-   (set_attr "length" "*,8,8")]
+  [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*")
+   (set_attr "conds" "*,*,clob,clob")
+   (set_attr "length" "*,*,8,8")
+   (set_attr "alt_tune" "nota8,onlya8,*,*")]
 )
 
 (define_insn "*sub<mode>3_neon"
@@ -861,24 +863,26 @@
 )
 
 (define_insn "subdi3_neon"
-  [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
-        (minus:DI (match_operand:DI 1 "s_register_operand" "w,0,r,0")
-                  (match_operand:DI 2 "s_register_operand" "w,r,0,0")))
+  [(set (match_operand:DI 0 "s_register_operand" "=w,?w,?&r,?&r,?&r")
+        (minus:DI (match_operand:DI 1 "s_register_operand" "w,w,0,r,0")
+                  (match_operand:DI 2 "s_register_operand" "w,w,r,0,0")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_NEON"
 {
   switch (which_alternative)
     {
-    case 0: return "vsub.i64\t%P0, %P1, %P2";
-    case 1: /* fall through */ 
-    case 2: /* fall through */
-    case 3: return  "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2";
+    case 0: /* fall through */
+    case 1: return "vsub.i64\t%P0, %P1, %P2";
+    case 2: /* fall through */ 
+    case 3: /* fall through */
+    case 4: return  "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2";
     default: gcc_unreachable ();
     }
 }
-  [(set_attr "neon_type" "neon_int_2,*,*,*")
-   (set_attr "conds" "*,clob,clob,clob")
-   (set_attr "length" "*,8,8,8")]
+  [(set_attr "neon_type" "neon_int_2,neon_int_2,*,*,*")
+   (set_attr "conds" "*,*,clob,clob,clob")
+   (set_attr "length" "*,*,8,8,8")
+   (set_attr "alt_tune" "nota8,onlya8,*,*,*")]
 )
 
 (define_insn "*mul<mode>3_neon"
@@ -964,23 +968,26 @@
 )
 
 (define_insn "iordi3_neon"
-  [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r")
-        (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r")
-		(match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r")))]
+  [(set (match_operand:DI 0 "s_register_operand" "=w,?w,w,?w,?&r,?&r")
+        (ior:DI (match_operand:DI 1 "s_register_operand" "%w,w,0,0,0,r")
+		(match_operand:DI 2 "neon_logic_op2" "w,w,Dl,Dl,r,r")))]
   "TARGET_NEON"
 {
   switch (which_alternative)
     {
-    case 0: return "vorr\t%P0, %P1, %P2";
-    case 1: return neon_output_logic_immediate ("vorr", &operands[2],
+    case 0: /* fall through */
+    case 1: return "vorr\t%P0, %P1, %P2";
+    case 2: /* fall through */
+    case 3: return neon_output_logic_immediate ("vorr", &operands[2],
 		     DImode, 0, VALID_NEON_QREG_MODE (DImode));
-    case 2: return "#";
-    case 3: return "#";
+    case 4: return "#";
+    case 5: return "#";
     default: gcc_unreachable ();
     }
 }
-  [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*")
-   (set_attr "length" "*,*,8,8")]
+  [(set_attr "neon_type" "neon_int_1,neon_int_1,neon_int_1,neon_int_1,*,*")
+   (set_attr "length" "*,*,*,*,8,8")
+   (set_attr "alt_tune" "nota8,onlya8,nota8,onlya8,*,*")]
 )
 
 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
@@ -1006,23 +1013,26 @@
 )
 
 (define_insn "anddi3_neon"
-  [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r")
-        (and:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r")
-		(match_operand:DI 2 "neon_inv_logic_op2" "w,DL,r,r")))]
+  [(set (match_operand:DI 0 "s_register_operand" "=w,?w,w,?w,?&r,?&r")
+        (and:DI (match_operand:DI 1 "s_register_operand" "%w,w,0,0,0,r")
+		(match_operand:DI 2 "neon_inv_logic_op2" "w,w,DL,DL,r,r")))]
   "TARGET_NEON"
 {
   switch (which_alternative)
     {
-    case 0: return "vand\t%P0, %P1, %P2";
-    case 1: return neon_output_logic_immediate ("vand", &operands[2],
+    case 0: /* fall through */
+    case 1: return "vand\t%P0, %P1, %P2";
+    case 2: /* fall through */
+    case 3: return neon_output_logic_immediate ("vand", &operands[2],
     		     DImode, 1, VALID_NEON_QREG_MODE (DImode));
-    case 2: return "#";
-    case 3: return "#";
+    case 4: return "#";
+    case 5: return "#";
     default: gcc_unreachable ();
     }
 }
-  [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*")
-   (set_attr "length" "*,*,8,8")]
+  [(set_attr "neon_type" "neon_int_1,neon_int_1,neon_int_1,neon_int_1,*,*")
+   (set_attr "length" "*,*,*,*,8,8")
+   (set_attr "alt_tune" "nota8,onlya8,nota8,onlya8,*,*")]
 )
 
 (define_insn "orn<mode>3_neon"
@@ -1080,16 +1090,18 @@
 )
 
 (define_insn "xordi3_neon"
-  [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
-        (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r")
-	        (match_operand:DI 2 "s_register_operand" "w,r,r")))]
+  [(set (match_operand:DI 0 "s_register_operand" "=w,?w,?&r,?&r")
+        (xor:DI (match_operand:DI 1 "s_register_operand" "%w,w,0,r")
+	        (match_operand:DI 2 "s_register_operand" "w,w,r,r")))]
   "TARGET_NEON"
   "@
    veor\t%P0, %P1, %P2
+   veor\t%P0, %P1, %P2
    #
    #"
-  [(set_attr "neon_type" "neon_int_1,*,*")
-   (set_attr "length" "*,8,8")]
+  [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*")
+   (set_attr "length" "*,*,8,8")
+   (set_attr "alt_tune" "nota8,onlya8,*,*")]
 )
 
 (define_insn "one_cmpl<mode>2"

=== modified file 'gcc/config/arm/vfp.md'
--- old/gcc/config/arm/vfp.md	2010-08-13 10:59:06 +0000
+++ new/gcc/config/arm/vfp.md	2010-08-13 11:40:17 +0000
@@ -133,9 +133,51 @@
 ;; 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
+  [(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))"
+  "*
+  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\";
+    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 "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,*")]
+)
+
+(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))"
   "*

=== modified file 'gcc/ira-costs.c'
--- old/gcc/ira-costs.c	2009-11-25 10:55:54 +0000
+++ new/gcc/ira-costs.c	2010-08-13 11:40:17 +0000
@@ -224,6 +224,14 @@
       int alt_fail = 0;
       int alt_cost = 0, op_cost_add;
 
+      if (!recog_data.alternative_enabled_p[alt])
+	{
+	  for (i = 0; i < recog_data.n_operands; i++)
+	    constraints[i] = skip_alternative (constraints[i]);
+
+	  continue;
+	}
+
       for (i = 0; i < n_ops; i++)
 	{
 	  unsigned char c;

