[llvm-commits] [llvm-gcc-4.2] r54178 - in /llvm-gcc-4.2/trunk/gcc: config/arm/arm.md config/arm/cirrus.md config/arm/constraints.md config/arm/predicates.md config/i386/i386.md config/i386/sse.md testsuite/g++.dg/ext/interface4.h

Bill Wendling isanbard at gmail.com
Tue Jul 29 15:54:46 PDT 2008


Author: void
Date: Tue Jul 29 17:54:46 2008
New Revision: 54178

URL: http://llvm.org/viewvc/llvm-project?rev=54178&view=rev
Log:
Merge .md files from Apple GCC's 4.2 branch.

Added:
    llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/ext/interface4.h
Modified:
    llvm-gcc-4.2/trunk/gcc/config/arm/arm.md
    llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md
    llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md
    llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md
    llvm-gcc-4.2/trunk/gcc/config/i386/i386.md
    llvm-gcc-4.2/trunk/gcc/config/i386/sse.md

Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/arm.md?rev=54178&r1=54177&r2=54178&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/arm.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/arm.md Tue Jul 29 17:54:46 2008
@@ -95,6 +95,8 @@
                          ; instruction stream.
    ; APPLE LOCAL ARM setjmp/longjmp interworking
    (UNSPEC_JMP_XCHG 22) ; Indirect jump with possible change in ARM/Thumb state.
+   ; APPLE LOCAL ARM UXTB support
+   (UNSPEC_UXTB16   27) ; The UXTB16 instruction (ARM only)
   ]
 )
 
@@ -127,6 +129,10 @@
    (VUNSPEC_WCMP_GT  13) ; Used by the iwMMXT WCMPGT instructions
    (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
 			 ; handling.
+			    ; APPLE LOCAL begin ARM strings in code
+   (VUNSPEC_POOL_STRING 21) ; `pool-entry(string)'.  An entry in the constant
+			    ;   pool for a string.
+			    ; APPLE LOCAL end ARM strings in code
   ]
 )
 
@@ -352,11 +358,12 @@
 ;; Cirrus 64bit additions should not be split because we have a native
 ;; 64bit addition instructions.
 
+;; APPLE LOCAL begin 5831562 long long constants
 (define_expand "adddi3"
  [(parallel
    [(set (match_operand:DI           0 "s_register_operand" "")
 	  (plus:DI (match_operand:DI 1 "s_register_operand" "")
-	           (match_operand:DI 2 "s_register_operand" "")))
+	           (match_operand:DI 2 "arm_add64_operand" "")))
     (clobber (reg:CC CC_REGNUM))])]
   "TARGET_EITHER"
   "
@@ -377,8 +384,19 @@
       if (GET_CODE (operands[2]) != REG)
         operands[2] = force_reg (SImode, operands[2]);
      }
+
+  if (TARGET_ARM 
+      && (GET_CODE (operands[2]) == CONST_INT
+          || GET_CODE (operands[2]) == CONST_DOUBLE)
+      && !const64_ok_for_arm_immediate (operands[2]))
+    {
+      emit_insn (gen_subdi3 (operands[0], operands[1],
+			    negate_rtx (DImode, operands[2])));
+      DONE;
+    }
   "
 )
+;; APPLE LOCAL end 5831562 long long constants
 
 (define_insn "*thumb_adddi3"
   [(set (match_operand:DI          0 "register_operand" "=l")
@@ -391,10 +409,11 @@
   [(set_attr "length" "4")]
 )
 
+;; APPLE LOCAL begin 5831562 long long constants
 (define_insn_and_split "*arm_adddi3"
-  [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
-	(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
-		 (match_operand:DI 2 "s_register_operand" "r,  0")))
+  [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r")
+	(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0")
+		 (match_operand:DI 2 "arm_rhs64_operand" "r,  0, Dd,Dd")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
   "#"
@@ -411,12 +430,13 @@
     operands[0] = gen_lowpart (SImode, operands[0]);
     operands[4] = gen_highpart (SImode, operands[1]);
     operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[5] = gen_highpart (SImode, operands[2]);
+    operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
     operands[2] = gen_lowpart (SImode, operands[2]);
   }"
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
+;; APPLE LOCAL end 5831562 long long constants
 
 (define_insn_and_split "*adddi_sesidi_di"
   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -573,6 +593,22 @@
   ""
 )
 
+;; APPLE LOCAL begin ARM peephole
+;; And sometimes greg will generate the same thing this way...
+
+(define_peephole2
+  [(set (match_operand:SI 0 "arm_general_register_operand" "")
+	(reg:SI SP_REGNUM))
+   (set (match_dup 0)
+	(plus:SI (match_dup 0) (match_operand:SI 1 "const_int_operand" "")))]
+  "TARGET_THUMB
+   && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
+   && (INTVAL (operands[1]) & 3) == 0"
+  [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
+  ""
+)
+;; APPLE LOCAL end ARM peephole
+
 (define_insn "*addsi3_compare0"
   [(set (reg:CC_NOOV CC_REGNUM)
 	(compare:CC_NOOV
@@ -830,11 +866,12 @@
     operands[2] = force_reg (DFmode, operands[2]);
 ")
 
+;; APPLE LOCAL begin 5831562 long long constants
 (define_expand "subdi3"
  [(parallel
    [(set (match_operand:DI            0 "s_register_operand" "")
 	  (minus:DI (match_operand:DI 1 "s_register_operand" "")
-	            (match_operand:DI 2 "s_register_operand" "")))
+	            (match_operand:DI 2 "arm_add64_operand" "")))
     (clobber (reg:CC CC_REGNUM))])]
   "TARGET_EITHER"
   "
@@ -854,19 +891,38 @@
       if (GET_CODE (operands[2]) != REG)
         operands[2] = force_reg (SImode, operands[2]);
      }	
-  "
+
+  if (TARGET_ARM 
+      && (GET_CODE (operands[2]) == CONST_INT
+          || GET_CODE (operands[2]) == CONST_DOUBLE)
+      && !const64_ok_for_arm_immediate (operands[2]))
+    {
+      emit_insn (gen_adddi3 (operands[0], operands[1],
+			    negate_rtx (DImode, operands[2])));
+      DONE;
+    }
+   "
 )
 
 (define_insn "*arm_subdi3"
-  [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
-	(minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
-		  (match_operand:DI 2 "s_register_operand" "r,0,0")))
+  [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r,&r,&r")
+	(minus:DI (match_operand:DI 1 "s_register_operand"   "0, r, 0, r ,0")
+		  (match_operand:DI 2 "arm_rhs64_operand"   "r, 0, 0,Dd,Dd")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
+  "*
+   if (which_alternative <= 2)
+     return \"subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2\";
+   else
+     {
+       operands[3] = gen_lowpart (SImode, operands[2]);
+       operands[2] = gen_highpart_mode (SImode, DImode, operands[2]);
+       return \"subs\\t%Q0, %Q1, %3\;sbc\\t%R0, %R1, %2\";
+     }"
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
+;; APPLE LOCAL end 5831562 long long constants
 
 (define_insn "*thumb_subdi3"
   [(set (match_operand:DI           0 "register_operand" "=l")
@@ -1336,6 +1392,57 @@
   [(set_attr "insn" "smlalxy")
    (set_attr "predicable" "yes")])
 
+;; APPLE LOCAL begin DImode multiply enhancement 
+;; No DI * DI instruction exists (except on Cirrus), but leave this in 
+;; the RTL stream through the early optimization phases
+;; to give them a chance to generate the mulsidi3, etc., patterns.
+
+(define_expand "muldi3"
+  [(parallel
+    [(set (match_operand:DI          0 "s_register_operand" "")
+	   (mult:DI (match_operand:DI 1 "s_register_operand" "")
+		    (match_operand:DI 2 "s_register_operand" "")))
+    (clobber (match_scratch:SI 3 ""))
+    (clobber (match_scratch:SI 4 ""))])]
+  "TARGET_ARM"
+  "
+    if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
+      {
+	if (!cirrus_fp_register (operands[0], DImode))
+	  operands[0] = force_reg (DImode, operands[0]);
+	if (!cirrus_fp_register (operands[1], DImode))
+	  operands[1] = force_reg (DImode, operands[1]);
+	emit_insn (gen_cirrus_muldi3 (operands[0], operands[1], operands[2]));
+	DONE;
+      }
+  "
+)
+
+; Input and output registers cannot overlap in this pattern.
+
+(define_insn_and_split "*soft_muldi3"
+  [(set (match_operand:DI          0 "s_register_operand" "=&r")
+	(mult:DI (match_operand:DI 1 "s_register_operand" "%0")
+		 (match_operand:DI 2 "s_register_operand" "r")))
+   (clobber (match_scratch:SI 3 "=&r"))
+   (clobber (match_scratch:SI 4 "=&r"))]
+  "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
+  ""
+  "&& reload_completed"
+  [(set (match_dup 3) (subreg:SI (match_dup 1) 0))
+   (set (match_dup 4) (subreg:SI (match_dup 1) 4))
+   (set (match_dup 0) (mult:DI (zero_extend:DI (match_dup 3))
+                               (zero_extend:DI (subreg:SI (match_dup 2) 0))))
+   (set (subreg:SI (match_dup 0) 4) (plus:SI
+            (mult:SI (match_dup 4) (subreg:SI (match_dup 2) 0))
+            (subreg:SI (match_dup 0) 4)))
+   (set (subreg:SI (match_dup 0) 4) (plus:SI
+            (mult:SI (match_dup 3) (subreg:SI (match_dup 2) 4))
+            (subreg:SI (match_dup 0) 4)))]
+  ""
+)
+;; APPLE LOCAL end DImode multiply enhancement 
+
 (define_expand "mulsf3"
   [(set (match_operand:SF          0 "s_register_operand" "")
 	(mult:SF (match_operand:SF 1 "s_register_operand" "")
@@ -1394,13 +1501,14 @@
 
 ;; Split up double word logical operations
 
+;; APPLE LOCAL begin 5831562 long long constants
 ;; Split up simple DImode logical operations.  Simply perform the logical
 ;; operation on the upper and lower halves of the registers.
 (define_split
   [(set (match_operand:DI 0 "s_register_operand" "")
 	(match_operator:DI 6 "logical_binary_operator"
 	  [(match_operand:DI 1 "s_register_operand" "")
-	   (match_operand:DI 2 "s_register_operand" "")]))]
+	   (match_operand:DI 2 "arm_rhs64_operand" "")]))]
   "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
@@ -1410,10 +1518,11 @@
     operands[0] = gen_lowpart (SImode, operands[0]);
     operands[4] = gen_highpart (SImode, operands[1]);
     operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[5] = gen_highpart (SImode, operands[2]);
+    operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
     operands[2] = gen_lowpart (SImode, operands[2]);
   }"
 )
+;; APPLE LOCAL end 5831562 long long constants
 
 (define_split
   [(set (match_operand:DI 0 "s_register_operand" "")
@@ -1474,14 +1583,17 @@
   }"
 )
 
+;; APPLE LOCAL begin 5831562 long long constants
 (define_insn "anddi3"
-  [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
-	(and:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
-		(match_operand:DI 2 "s_register_operand"   "r,r")))]
+  [(set (match_operand:DI         0 "s_register_operand" "=&r,&r,&r,&r")
+	(and:DI (match_operand:DI 1 "s_register_operand"  "%0,r, 0, r")
+		(match_operand:DI 2 "arm_rhs64_operand"    "r,r,Dd,Dd")))]
   "TARGET_ARM && ! TARGET_IWMMXT"
   "#"
-  [(set_attr "length" "8")]
+  [(set_attr "length" "8")
+   (set_attr "predicable" "yes")]
 )
+;; APPLE LOCAL end 5831562 long long constants
 
 (define_insn_and_split "*anddi_zesidi_di"
   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -1576,28 +1688,19 @@
   "
 )
 
-(define_insn_and_split "*arm_andsi3_insn"
-  [(set (match_operand:SI         0 "s_register_operand" "=r,r,r")
-	(and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
-		(match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
+;; APPLE LOCAL begin ARM 4673027 suboptimal loop codegen
+(define_insn "*arm_andsi3_insn"
+  [(set (match_operand:SI         0 "s_register_operand" "=r,r")
+	(and:SI (match_operand:SI 1 "s_register_operand" "r,r")
+		(match_operand:SI 2 "arm_not_operand" "rI,K")))]
   "TARGET_ARM"
   "@
    and%?\\t%0, %1, %2
-   bic%?\\t%0, %1, #%B2
-   #"
-  "TARGET_ARM
-   && GET_CODE (operands[2]) == CONST_INT
-   && !(const_ok_for_arm (INTVAL (operands[2]))
-	|| const_ok_for_arm (~INTVAL (operands[2])))"
-  [(clobber (const_int 0))]
-  "
-  arm_split_constant  (AND, SImode, curr_insn, 
-	               INTVAL (operands[2]), operands[0], operands[1], 0);
-  DONE;
-  "
-  [(set_attr "length" "4,4,16")
+   bic%?\\t%0, %1, #%B2"
+  [(set_attr "length" "4,4")
    (set_attr "predicable" "yes")]
 )
+;; APPLE LOCAL end ARM 4673027 suboptimal loop codegen
 
 (define_insn "*thumb_andsi3_insn"
   [(set (match_operand:SI         0 "register_operand" "=l")
@@ -1867,21 +1970,22 @@
 ;;; bit-field insert instruction, we would have to emit code here to truncate
 ;;; the value before we insert.  This loses some of the advantage of having
 ;;; this insv pattern, so this pattern needs to be reevalutated.
+;;; APPLE LOCAL begin ARM insv for Thumb
 
 (define_expand "insv"
   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
                          (match_operand:SI 1 "general_operand" "")
                          (match_operand:SI 2 "general_operand" ""))
         (match_operand:SI 3 "reg_or_int_operand" ""))]
-  "TARGET_ARM"
+  "TARGET_EITHER"
   "
   {
     int start_bit = INTVAL (operands[2]);
     int width = INTVAL (operands[1]);
     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
-    rtx target, subtarget;
+    rtx target, subtarget, orig_target;
 
-    target = operands[0];
+    target = orig_target = operands[0];
     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
        subreg as the final target.  */
     if (GET_CODE (target) == SUBREG)
@@ -1912,7 +2016,8 @@
 	emit_insn (gen_iorsi3 (subtarget, op1,
 			       gen_int_mode (op3_value << start_bit, SImode)));
       }
-    else if (start_bit == 0
+    else if (TARGET_ARM
+	     && start_bit == 0
 	     && !(const_ok_for_arm (mask)
 		  || const_ok_for_arm (~mask)))
       {
@@ -1925,21 +2030,24 @@
 	rtx op0 = gen_reg_rtx (SImode);
 	rtx op1 = gen_reg_rtx (SImode);
 
-	emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
+	emit_insn (gen_ashlsi3 (op0, operands[3],
+				gen_int_mode (32 - width, SImode)));
 	emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
 	emit_insn (gen_iorsi3  (op1, op1, op0));
 	emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
       }
-    else if ((width + start_bit == 32)
-	     && !(const_ok_for_arm (mask)
-		  || const_ok_for_arm (~mask)))
+    else if (width + start_bit == 32
+	     && (TARGET_THUMB
+		 || !(const_ok_for_arm (mask)
+		      || const_ok_for_arm (~mask))))
       {
 	/* Similar trick, but slightly less efficient.  */
 
 	rtx op0 = gen_reg_rtx (SImode);
 	rtx op1 = gen_reg_rtx (SImode);
 
-	emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
+	emit_insn (gen_ashlsi3 (op0, operands[3],
+				gen_int_mode (32 - width, SImode)));
 	emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
 	emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
 	emit_insn (gen_iorsi3 (subtarget, op1, op0));
@@ -1950,7 +2058,8 @@
 	rtx op1 = gen_reg_rtx (SImode);
 	rtx op2 = gen_reg_rtx (SImode);
 
-	if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
+	if (TARGET_THUMB 
+	    || !(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
 	  {
 	    rtx tmp = gen_reg_rtx (SImode);
 
@@ -1959,6 +2068,7 @@
 	  }
 
 	/* Mask out any bits in operand[3] that are not needed.  */
+	if (!TARGET_THUMB)
 	   emit_insn (gen_andsi3 (op1, operands[3], op0));
 
 	if (GET_CODE (op0) == CONST_INT
@@ -1984,9 +2094,33 @@
 	    emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
 	  }
 
-	if (start_bit != 0)
+	if (!TARGET_THUMB && start_bit != 0)
           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
 
+	/* The default code uses AND with constant which is an extra insn on thumb. */
+	if (TARGET_THUMB)
+	  {
+	    /* If we only want a low subreg, we don't need to worry about
+	       bits beyond that. */
+	    if (GET_CODE (orig_target) == SUBREG
+	        && SUBREG_BYTE (orig_target) == 0
+	        && GET_MODE_SIZE (GET_MODE (SUBREG_REG (orig_target))) 
+			< GET_MODE_SIZE (SImode)
+		&& width + start_bit 
+			>= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (orig_target))))
+	      emit_insn (gen_ashlsi3 (op1, operands[3],
+				      gen_int_mode (start_bit, SImode)));
+	    else
+	      {
+		/* Mask unneeded bits in operand[3], and simultaneously move
+		   input to the right place in the word.  */
+		emit_insn (gen_ashlsi3 (op1, operands[3],
+					gen_int_mode (32 - width, SImode)));
+		emit_insn (gen_lshrsi3 (op1, op1,
+					gen_int_mode (32 - width - start_bit, SImode)));
+	      }
+	  }
+
 	emit_insn (gen_iorsi3 (subtarget, op1, op2));
       }
 
@@ -2003,6 +2137,7 @@
     DONE;
   }"
 )
+;;; APPLE LOCAL end ARM insv for Thumb
 
 ; constants for op 2 will never be given to these patterns.
 (define_insn_and_split "*anddi_notdi_di"
@@ -2135,15 +2270,17 @@
   [(set_attr "conds" "set")]
 )
 
+;; APPLE LOCAL begin 5831562 long long constants
 (define_insn "iordi3"
-  [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
-	(ior:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
-		(match_operand:DI 2 "s_register_operand"   "r,r")))]
+  [(set (match_operand:DI         0 "s_register_operand" "=&r,&r,&r,&r")
+	(ior:DI (match_operand:DI 1 "s_register_operand"  "%0,r, 0, r")
+		(match_operand:DI 2 "arm_rhs64_operand"   "r,r,Dd,Dd")))]
   "TARGET_ARM && ! TARGET_IWMMXT"
   "#"
   [(set_attr "length" "8")
    (set_attr "predicable" "yes")]
 )
+;; APPLE LOCAL end 5831562 long long constants
 
 (define_insn "*iordi_zesidi_di"
   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -2190,26 +2327,17 @@
   "
 )
 
-(define_insn_and_split "*arm_iorsi3"
-  [(set (match_operand:SI         0 "s_register_operand" "=r,r")
-	(ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
-		(match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
+;; APPLE LOCAL begin ARM 4673027 suboptimal loop codegen
+(define_insn "*arm_iorsi3"
+  [(set (match_operand:SI         0 "s_register_operand" "=r")
+	(ior:SI (match_operand:SI 1 "s_register_operand" "r")
+		(match_operand:SI 2 "arm_rhs_operand" "rI")))]
   "TARGET_ARM"
-  "@
-   orr%?\\t%0, %1, %2
-   #"
-  "TARGET_ARM
-   && GET_CODE (operands[2]) == CONST_INT
-   && !const_ok_for_arm (INTVAL (operands[2]))"
-  [(clobber (const_int 0))]
-  "
-  arm_split_constant (IOR, SImode, curr_insn, 
-                      INTVAL (operands[2]), operands[0], operands[1], 0);
-  DONE;
-  "
-  [(set_attr "length" "4,16")
+  "orr%?\\t%0, %1, %2"
+  [(set_attr "length" "4")
    (set_attr "predicable" "yes")]
 )
+;; APPLE LOCAL end ARM 4673027 suboptimal loop codegen
 
 (define_insn "*thumb_iorsi3"
   [(set (match_operand:SI         0 "register_operand" "=l")
@@ -2256,15 +2384,17 @@
   [(set_attr "conds" "set")]
 )
 
+;; APPLE LOCAL begin 5831562 long long constants
 (define_insn "xordi3"
-  [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
-	(xor:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
-		(match_operand:DI 2 "s_register_operand"   "r,r")))]
+  [(set (match_operand:DI         0 "s_register_operand" "=&r,&r,&r,&r")
+	(xor:DI (match_operand:DI 1 "s_register_operand"  "%0,r, 0, r")
+		(match_operand:DI 2 "arm_rhs64_operand"   "r,r,Dd,Dd")))]
   "TARGET_ARM && !TARGET_IWMMXT"
   "#"
   [(set_attr "length" "8")
    (set_attr "predicable" "yes")]
 )
+;; APPLE LOCAL end 5831562 long long constants
 
 (define_insn "*xordi_zesidi_di"
   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -3335,7 +3465,8 @@
   }"
 )
 
-(define_insn "*thumb_zero_extendhisi2"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_zero_extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=l")
 	(zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
   "TARGET_THUMB && !arm_arch6"
@@ -3377,7 +3508,8 @@
    (set_attr "pool_range" "60")]
 )
 
-(define_insn "*thumb_zero_extendhisi2_v6"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_zero_extendhisi2_v6"
   [(set (match_operand:SI 0 "register_operand" "=l,l")
 	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
   "TARGET_THUMB && arm_arch6"
@@ -3694,7 +3826,8 @@
 ;; we try to verify the operands.  Fortunately, we don't really need
 ;; the early-clobber: we can always use operand 0 if operand 2
 ;; overlaps the address.
-(define_insn "*thumb_extendhisi2_insn_v6"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_extendhisi2_insn_v6"
   [(set (match_operand:SI 0 "register_operand" "=l,l")
 	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
    (clobber (match_scratch:SI 2 "=X,l"))]
@@ -3925,7 +4058,8 @@
    (set_attr "predicable" "yes")]
 )
 
-(define_insn "*thumb_extendqisi2"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=l,l")
 	(sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
   "TARGET_THUMB && !arm_arch6"
@@ -4003,7 +4137,8 @@
    (set_attr "pool_range" "32,32")]
 )
 
-(define_insn "*thumb_extendqisi2_v6"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_extendqisi2_v6"
   [(set (match_operand:SI 0 "register_operand" "=l,l,l")
 	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
   "TARGET_THUMB && arm_arch6"
@@ -4218,12 +4353,14 @@
 ; offsets in a LDR which means we get better chances of sharing the pool
 ; entries.  Finally, we can normally do a better job of scheduling
 ; LDR instructions than we can with LDM.
-; This pattern will only match if the one above did not.
+;; APPLE LOCAL begin ARM split 64-bit constants on Thumb 
+; On ARM, This pattern will only match if the one above did not.
+; On Thumb, use this form always; don't try to do inline expansions.
 (define_split
   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
 	(match_operand:ANY64 1 "const_double_operand" ""))]
-  "TARGET_ARM && reload_completed
-   && arm_const_double_by_parts (operands[1])"
+  "TARGET_EITHER && reload_completed
+   && (TARGET_THUMB || arm_const_double_by_parts (operands[1]))"
   [(set (match_dup 0) (match_dup 1))
    (set (match_dup 2) (match_dup 3))]
   "
@@ -4234,6 +4371,7 @@
   operands[1] = gen_lowpart (SImode, operands[1]);
   "
 )
+;; APPLE LOCAL end ARM split 64-bit constants on Thumb 
 
 (define_split
   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
@@ -4281,11 +4419,12 @@
   "
 )
 
+;; APPLE LOCAL begin compact switch tables
 ;;; ??? This should have alternatives for constants.
 ;;; ??? This was originally identical to the movdf_insn pattern.
 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
 ;;; thumb_reorg with a memory reference.
-(define_insn "*thumb_movdi_insn"
+(define_insn "adjustable_thumb_movdi_insn"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
 	(match_operand:DI 1 "general_operand"      "l, I,J,>,l,mi,l,*r"))]
   "TARGET_THUMB
@@ -4323,10 +4462,11 @@
       return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
     }
   }"
-  [(set_attr "length" "4,4,6,2,2,6,4,4")
+  [(set_attr "length" "4,4,6,2,2,4,4,4")
    (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
-   (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
+   (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
 )
+;; APPLE LOCAL end compact switch tables
 
 (define_expand "movsi"
   [(set (match_operand:SI 0 "general_operand" "")
@@ -4506,7 +4646,7 @@
   "TARGET_THUMB && (flag_pic || (TARGET_MACHO && MACHO_DYNAMIC_NO_PIC_P))"
   "ldr\\t%0, %1"
   [(set_attr "type" "load1")
-   (set (attr "pool_range") (const_int 1024))
+   (set (attr "pool_range") (const_int 1022))
    (set_attr "length" "2")]
 )
 ;; APPLE LOCAL end ARM pic support
@@ -4520,6 +4660,7 @@
   "operands[2] = cfun->machine->pic_reg;"
 )
 
+;; APPLE LOCAL begin ARM compact switch tables
 (define_insn "*pic_load_addr_based_insn"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
 	(unspec:SI [(match_operand 1 "" "")
@@ -4536,13 +4677,18 @@
   [(set_attr "type" "load1")
    (set (attr "pool_range")
 	(if_then_else (eq_attr "is_thumb" "yes")
-		      (const_int 1024)
+		      (const_int 1020)
 		      (const_int 4096)))
    (set (attr "neg_pool_range")
 	(if_then_else (eq_attr "is_thumb" "yes")
 		      (const_int 0)
-		      (const_int 4084)))]
+		      (const_int 4084)))
+   (set (attr "length")
+	(if_then_else (eq_attr "is_thumb" "yes")
+		      (const_int 2)
+		      (const_int 4)))]
 )
+;; APPLE LOCAL end ARM compact switch tables
 
 ;; APPLE LOCAL begin ARM pic support
 (define_insn "pic_add_dot_plus_four"
@@ -4611,6 +4757,42 @@
   ""
 )
 
+;; APPLE LOCAL begin ARM 4224487
+;; These short forms work for addresses of scalar globals.  They
+;; are produced by combine.  There is no Thumb counterpart, as
+;; [Rn+PC] is not a valid addressing mode on Thumb.
+
+(define_insn "*arm_pic_ldrsi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(mem:SI (unspec:SI [(label_ref (match_operand 1 "" ""))
+		    (plus:SI (match_operand:SI 2 "register_operand" "r")
+			     (const (plus:SI (pc) (const_int 8))))]
+		   UNSPEC_PIC_BASE)))]
+  "TARGET_ARM && (flag_pic || (TARGET_MACHO && MACHO_DYNAMIC_NO_PIC_P))"
+  "*
+    (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
+			       CODE_LABEL_NUMBER (operands[1]));
+    return \"ldr%?\\t%0, [%|pc, %2]\";
+  "
+  [(set_attr "predicable" "yes")]
+)
+
+(define_insn "*arm_pic_strsi"
+  [(set (mem:SI (unspec:SI [(label_ref (match_operand 1 "" ""))
+		    (plus:SI (match_operand:SI 2 "register_operand" "r")
+			     (const (plus:SI (pc) (const_int 8))))]
+		   UNSPEC_PIC_BASE))
+	(match_operand:SI 0 "register_operand" "r"))]
+  "TARGET_ARM && (flag_pic || (TARGET_MACHO && MACHO_DYNAMIC_NO_PIC_P))"
+  "*
+    (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
+			       CODE_LABEL_NUMBER (operands[1]));
+    return \"str%?\\t%0, [%|pc, %2]\";
+  "
+  [(set_attr "predicable" "yes")]
+)
+;; APPLE LOCAL end ARM 4224487
+
 ;; APPLE LOCAL begin ARM setjmp/longjmp interworking
 ;; If we'll be  returning to thumb code, we need to set the low-order
 ;; bit of the resume address.  builtin_setjmp_setup doesn't handle all
@@ -4979,7 +5161,8 @@
   "
 )
 
-(define_insn "*thumb_movhi_insn"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_movhi_insn"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
 	(match_operand:HI 1 "general_operand"       "l,m,l,*h,*r,I"))]
   "TARGET_THUMB
@@ -5409,6 +5592,7 @@
    (set_attr "neg_pool_range" "1008")]
 )
 
+;; APPLE LOCAL begin ARM compact switch tables
 ;;; ??? This should have alternatives for constants.
 ;;; ??? This was originally identical to the movdi_insn pattern.
 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
@@ -5444,10 +5628,11 @@
       return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
     }
   "
-  [(set_attr "length" "4,2,2,6,4,4")
+  [(set_attr "length" "4,2,2,4,4,4")
    (set_attr "type" "*,load2,store2,load2,store2,*")
-   (set_attr "pool_range" "*,*,*,1020,*,*")]
+   (set_attr "pool_range" "*,*,*,1018,*,*")]
 )
+;; APPLE LOCAL end ARM compact switch tables
 
 (define_expand "movxf"
   [(set (match_operand:XF 0 "general_operand" "")
@@ -5531,6 +5716,7 @@
    (set_attr "predicable" "yes")]
 )
 
+;; APPLE LOCAL begin ARM compact switch tables
 (define_insn "*ldmsi_postinc4_thumb"
   [(match_parallel 0 "load_multiple_operation"
     [(set (match_operand:SI 1 "s_register_operand" "=l")
@@ -5546,8 +5732,10 @@
 	  (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
   "TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
   "ldmia\\t%1!, {%3, %4, %5, %6}"
-  [(set_attr "type" "load4")]
+  [(set_attr "type" "load4")
+   (set_attr "length" "2")]
 )
+;; APPLE LOCAL end ARM compact switch tables
 
 (define_insn "*ldmsi_postinc3"
   [(match_parallel 0 "load_multiple_operation"
@@ -5670,6 +5858,7 @@
    (set_attr "type" "store4")]
 )
 
+;; APPLE LOCAL begin ARM compact switch tables
 (define_insn "*stmsi_postinc4_thumb"
   [(match_parallel 0 "store_multiple_operation"
     [(set (match_operand:SI 1 "s_register_operand" "=l")
@@ -5685,8 +5874,10 @@
 	  (match_operand:SI 6 "arm_hard_register_operand" ""))])]
   "TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
   "stmia\\t%1!, {%3, %4, %5, %6}"
-  [(set_attr "type" "store4")]
+  [(set_attr "type" "store4")
+   (set_attr "length" "2")]
 )
+;; APPLE LOCAL end ARM compact switch tables
 
 (define_insn "*stmsi_postinc3"
   [(match_parallel 0 "store_multiple_operation"
@@ -5787,6 +5978,17 @@
           || INTVAL (operands[2]) > 48)
         FAIL;
 
+      /* APPLE LOCAL begin ARM use memcpy more at -Os */
+      if (optimize_size
+	  && INTVAL (operands[2]) != 1
+	  && INTVAL (operands[2]) != 2
+	  && INTVAL (operands[2]) != 4
+	  && INTVAL (operands[2]) != 8
+	  && INTVAL (operands[2]) != 12
+	  && INTVAL (operands[2]) != 16)
+	FAIL;
+      /* APPLE LOCAL end ARM use memcpy more at -Os */
+
       thumb_expand_movmemqi (operands);
       DONE;
     }
@@ -6013,6 +6215,32 @@
 	   (const_int 10)))))]
 )
 
+;; APPLE LOCAL begin ARM add this peephole
+;; The above pattern is produced by combine in some cases, but not
+;; when one of the regs involved is hard, e.g. a function return value.
+;; This peephole catches that case.  Valid only for low regs.
+
+(define_peephole2
+  [(set (match_operand:SI 0 "thumb_low_register_operand" "")
+	(match_operand:SI 1 "thumb_low_register_operand" ""))
+   (set (pc) (if_then_else
+	      (match_operator 2 "arm_comparison_operator"
+	       [(match_dup 0) (const_int 0)])
+	      (label_ref (match_operand 3 "" ""))
+	      (pc)))]
+  "TARGET_THUMB"
+  [(parallel
+     [(set (pc)
+	(if_then_else
+	 (match_op_dup 2
+	  [(match_dup 1) (const_int 0)])
+	 (label_ref (match_dup 3 ))
+	 (pc)))
+     (set (match_dup 0) (match_dup 1))])]
+   ""
+)
+;; APPLE LOCAL end ARM add this peephole
+
 (define_insn "*negated_cbranchsi4"
   [(set (pc)
 	(if_then_else
@@ -6998,6 +7226,7 @@
   "
 )
 
+;; APPLE LOCAL begin ARM enhance conditional insn generation
 (define_insn "*arm_cmpsi_insn"
   [(set (reg:CC CC_REGNUM)
 	(compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
@@ -7006,8 +7235,10 @@
   "@
    cmp%?\\t%0, %1
    cmn%?\\t%0, #%n1"
-  [(set_attr "conds" "set")]
+  [(set_attr "conds" "set")
+   (set_attr "predicable" "yes")]
 )
+;; APPLE LOCAL end ARM enhance conditional insn generation
 
 (define_insn "*cmpsi_shiftsi"
   [(set (reg:CC CC_REGNUM)
@@ -7715,16 +7946,16 @@
     rtx callee;
     
     /* APPLE LOCAL begin ARM dynamic */
-#if TARGET_MACHO
-    if (MACHOPIC_INDIRECT)
-      operands[0] = machopic_indirect_call_target (operands[0]);
-#endif
-    /* APPLE LOCAL end ARM dynamic */
-
     /* In an untyped call, we can get NULL for operand 2.  */
     if (operands[2] == NULL_RTX)
       operands[2] = const0_rtx;
       
+#if TARGET_MACHO
+    if (MACHOPIC_INDIRECT
+	&& !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
+      operands[0] = machopic_indirect_call_target (operands[0]);
+#endif
+
     /* This is to decide if we should generate indirect calls by loading the
        32 bit address of the callee into a register before performing the
        branch and link.  operand[2] encodes the long_call/short_call
@@ -7736,6 +7967,7 @@
        parameter to arm_is_longcall_p is used to tell it which pattern
        invoked it.  */
     callee  = XEXP (operands[0], 0);
+    /* APPLE LOCAL end ARM dynamic */
     
     if ((GET_CODE (callee) == SYMBOL_REF
 	 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
@@ -7745,6 +7977,7 @@
   }"
 )
 
+;; APPLE LOCAL begin 5831528 make calls predicable
 (define_insn "*call_reg_armv5"
   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
          (match_operand 1 "" ""))
@@ -7752,7 +7985,8 @@
    (clobber (reg:SI LR_REGNUM))]
   "TARGET_ARM && arm_arch5"
   "blx%?\\t%0"
-  [(set_attr "type" "call")]
+  [(set_attr "type" "call")
+   (set_attr "predicable" "yes")]
 )
 
 (define_insn "*call_reg_arm"
@@ -7766,7 +8000,8 @@
   "
   ;; length is worst case, normally it is only two
   [(set_attr "length" "12")
-   (set_attr "type" "call")]
+   (set_attr "type" "call")
+   (set_attr "predicable" "yes")]
 )
 
 (define_insn "*call_mem"
@@ -7779,7 +8014,8 @@
   return output_call_mem (operands);
   "
   [(set_attr "length" "12")
-   (set_attr "type" "call")]
+   (set_attr "type" "call")
+   (set_attr "predicable" "yes")]
 )
 
 (define_insn "*call_reg_thumb_v5"
@@ -7825,18 +8061,19 @@
     /* APPLE LOCAL begin ARM dynamic */
     rtx callee;
 
+    /* In an untyped call, we can get NULL for operand 2.  */
+    if (operands[3] == 0)
+      operands[3] = const0_rtx;
+
 #if TARGET_MACHO
-    if (MACHOPIC_INDIRECT)
+    if (MACHOPIC_INDIRECT
+	&& !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
       operands[1] = machopic_indirect_call_target (operands[1]);
 #endif
 
     callee = XEXP (operands[1], 0);
     /* APPLE LOCAL end ARM dynamic */
     
-    /* In an untyped call, we can get NULL for operand 2.  */
-    if (operands[3] == 0)
-      operands[3] = const0_rtx;
-      
     /* See the comment in define_expand \"call\".  */
     if ((GET_CODE (callee) == SYMBOL_REF
 	 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
@@ -7854,7 +8091,8 @@
    (clobber (reg:SI LR_REGNUM))]
   "TARGET_ARM && arm_arch5"
   "blx%?\\t%1"
-  [(set_attr "type" "call")]
+  [(set_attr "type" "call")
+   (set_attr "predicable" "yes")]
 )
 
 (define_insn "*call_value_reg_arm"
@@ -7868,7 +8106,8 @@
   return output_call (&operands[1]);
   "
   [(set_attr "length" "12")
-   (set_attr "type" "call")]
+   (set_attr "type" "call")
+   (set_attr "predicable" "yes")]
 )
 
 (define_insn "*call_value_mem"
@@ -7882,7 +8121,8 @@
   return output_call_mem (&operands[1]);
   "
   [(set_attr "length" "12")
-   (set_attr "type" "call")]
+   (set_attr "type" "call")
+   (set_attr "predicable" "yes")]
 )
 
 (define_insn "*call_value_reg_thumb_v5"
@@ -7927,12 +8167,30 @@
 ;; of questionnable value, as these patterns are not generally used
 ;; for dynamic code anyway (see rdar://4514281 for an example of what it
 ;; takes to get here).
-(define_insn "*call_symbol"
+(define_insn "*call_symbol_predicable"
   [(call (mem:SI (match_operand:SI 0 "arm_branch_target" ""))
 	 (match_operand 1 "" ""))
    (use (match_operand 2 "" ""))
    (clobber (reg:SI LR_REGNUM))]
   "TARGET_ARM
+   && !TARGET_INTERWORK
+   && (GET_CODE (operands[0]) == SYMBOL_REF)
+   && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
+  "*
+  {
+    return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
+  }"
+  [(set_attr "type" "call")
+   (set_attr "predicable" "yes")]
+)
+
+(define_insn "*call_symbol"
+  [(call (mem:SI (match_operand:SI 0 "arm_branch_target" ""))
+        (match_operand 1 "" ""))
+   (use (match_operand 2 "" ""))
+   (clobber (reg:SI LR_REGNUM))]
+  "TARGET_ARM
+   && TARGET_INTERWORK
    && (GET_CODE (operands[0]) == SYMBOL_REF)
    && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
   "*
@@ -7942,13 +8200,32 @@
   [(set_attr "type" "call")]
 )
 
-(define_insn "*call_value_symbol"
+(define_insn "*call_value_symbol_predicable"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:SI 1 "arm_branch_target" ""))
 	(match_operand:SI 2 "" "")))
    (use (match_operand 3 "" ""))
    (clobber (reg:SI LR_REGNUM))]
   "TARGET_ARM
+   && !TARGET_INTERWORK
+   && (GET_CODE (operands[1]) == SYMBOL_REF)
+   && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
+  "*
+  {
+    return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
+  }"
+  [(set_attr "type" "call")
+   (set_attr "predicable" "yes")]
+)
+
+(define_insn "*call_value_symbol"
+  [(set (match_operand 0 "" "")
+        (call (mem:SI (match_operand:SI 1 "arm_branch_target" ""))
+        (match_operand:SI 2 "" "")))
+   (use (match_operand 3 "" ""))
+   (clobber (reg:SI LR_REGNUM))]
+  "TARGET_ARM
+   && TARGET_INTERWORK
    && (GET_CODE (operands[1]) == SYMBOL_REF)
    && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
   "*
@@ -7957,6 +8234,7 @@
   }"
   [(set_attr "type" "call")]
 )
+;; APPLE LOCAL end 5831528 make calls predicable
 ;; APPLE LOCAL end ARM pic support
 
 ;; APPLE LOCAL begin ARM dynamic
@@ -8046,30 +8324,38 @@
   }"
 )
 
+;; APPLE LOCAL begin ARM indirect sibcalls
 (define_insn "*sibcall_insn"
- [(call (mem:SI (match_operand:SI 0 "" "X"))
-	(match_operand 1 "" ""))
+ [(call (mem:SI (match_operand:SI 0 "arm_branch_target" "X"))
+        (match_operand 1 "" ""))
   (return)
   (use (match_operand 2 "" ""))]
-  "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
+  "TARGET_ARM && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
   "*
-  return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
+  if (GET_CODE (operands[0]) == REG)
+    return \"bx%?\\t%0\";
+  else
+    return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
   "
   [(set_attr "type" "call")]
 )
 
 (define_insn "*sibcall_value_insn"
  [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:SI 1 "" "X"))
-	     (match_operand 2 "" "")))
+       (call (mem:SI (match_operand:SI 1 "arm_branch_target" "X"))
+             (match_operand 2 "" "")))
   (return)
   (use (match_operand 3 "" ""))]
-  "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
+  "TARGET_ARM && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == REG)"
   "*
-  return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
+  if (GET_CODE (operands[1]) == REG)
+    return \"bx%?\\t%1\";
+  else
+    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
   "
   [(set_attr "type" "call")]
 )
+;; APPLE LOCAL end ARM indirect sibcalls
 
 ;; Often the return insn will be the same as loading from memory, so set attr
 (define_insn "return"
@@ -8296,7 +8582,8 @@
    (match_operand:SI 2 "const_int_operand" "")	; total range
    (match_operand:SI 3 "" "")			; table label
    (match_operand:SI 4 "" "")]			; Out of range label
-  "TARGET_ARM"
+;; APPLE LOCAL compact switch tables
+  "TARGET_EITHER"
   "
   {
     rtx reg;
@@ -8309,12 +8596,33 @@
 	operands[0] = reg;
       }
 
+    /* APPLE LOCAL begin compact switch tables */
+    if (TARGET_ARM)
+      {
+    /* APPLE LOCAL end compact switch tables */
     if (!const_ok_for_arm (INTVAL (operands[2])))
       operands[2] = force_reg (SImode, operands[2]);
 
     emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
 					 operands[4]));
     DONE;
+    /* APPLE LOCAL begin compact switch tables */
+      }
+    else
+      {
+	/* Containing function must be 4-byte aligned, else we won't know what the
+	   various .align directives do, e.g. around constant tables. */
+	cfun->needs_4byte_alignment = 1;
+	/* This is a function call, but the semantics are not the same as a normal
+	   function call, so we put the parameter in R0 explicitly and hide the
+	   call as a casesi node.  The USE of R0 in the casesi_internal pattern
+	   causes the value to be retained. */
+	emit_move_insn (gen_rtx_REG (Pmode, 0), operands[0]);
+	emit_jump_insn (gen_thumb_casesi_internal (operands[0], operands[2], operands[3],
+						   operands[4]));
+	DONE;
+      }
+    /* APPLE LOCAL end compact switch tables */
   }"
 )
 
@@ -8340,6 +8648,86 @@
    (set_attr "length" "12")]
 )
 
+;; APPLE LOCAL begin compact switch tables
+;; This pattern represents the library call for Thumb switch tables.
+;; The functions' (sparse) register usage is recorded as clobbers.
+
+(define_insn "thumb_casesi_internal"
+  [(parallel [(set (pc)
+	       (if_then_else
+		(leu (match_operand:SI 0 "s_register_operand" "l")
+		     (match_operand:SI 1 "const_int_operand" "i"))
+		(mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 2))
+				 (label_ref (match_operand 2 "" ""))))
+		(label_ref (match_operand 3 "" ""))))
+	      (clobber (reg:CC CC_REGNUM))
+	      (clobber (reg:SI LR_REGNUM))
+	      (clobber (reg:SI IP_REGNUM))
+	      (use (reg:SI 0))
+	      (use (label_ref (match_dup 2)))])]
+  "TARGET_THUMB"
+  "*
+    {
+      rtx body = PATTERN (next_real_insn (insn));
+      static char buf[255];
+      gcc_assert (GET_CODE (body) == ADDR_DIFF_VEC);
+      strcpy(buf, \"bl\\t\");
+      if (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+	  strcat(buf, \"L\");
+      if (GET_MODE (body) == QImode
+	  && ADDR_DIFF_VEC_FLAGS (body).offset_unsigned)
+	{
+	  register_switchu8_libfunc ();
+	  strcat(buf, \"___switchu8\");
+	}
+      else if (GET_MODE (body) == QImode)
+	{
+	  register_switch8_libfunc ();
+	  strcat(buf, \"___switch8\");
+	}
+      else if (GET_MODE (body) == HImode)
+	{
+	  register_switch16_libfunc ();
+	  strcat(buf, \"___switch16\");
+	}
+      else
+	{
+	  register_switch32_libfunc ();
+	  /* The table is 4-byte aligned, and the call should
+	     immediately precede the table.  To do this, align
+	     here; as it happens, 0x0000 is a NOP insn.  The
+	     insn_length is still 4 even if a NOP is inserted;
+	     however, the computation in shorten_branches
+	     comes out right because that 4 is counted against
+	     the following label, which is marked as 4-byte
+	     aligned.  I.e. the shorten_branch code thinks it's
+	     going to looks like
+		      call
+		      .align 2
+		      zero padding
+		   label:
+	     when in fact it is
+		      .align 2
+		      NOP
+		      call
+		      .align 2
+		      never any padding here
+		    label:
+	     and it gets the right address for the label.
+	     Yes, this is overly tricky. */
+	  assemble_align (32);
+	  strcat(buf, \"___switch32\");
+	}
+      if (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+	  strcat(buf, \"$stub\");
+      return buf;
+    }
+  "
+  [(set_attr "conds" "clob")
+   (set_attr "length" "4")]
+)
+;; APPLE LOCAL end compact switch tables
+
 ;; APPLE LOCAL begin ARM setjmp/longjmp interworking
 ;; Indirect jump with possible change between ARM/Thumb state
 (define_expand "indirect_jump_exchange"
@@ -10200,6 +10588,7 @@
 
 ;; Special patterns for dealing with the constant pool
 
+;; APPLE LOCAL begin ARM compact switch tables
 (define_insn "align_4"
   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
   "TARGET_EITHER"
@@ -10207,6 +10596,7 @@
   assemble_align (32);
   return \"\";
   "
+  [(set (attr "length") (const_int 0))]
 )
 
 (define_insn "align_8"
@@ -10216,6 +10606,7 @@
   assemble_align (64);
   return \"\";
   "
+  [(set (attr "length") (const_int 0))]
 )
 
 (define_insn "consttable_end"
@@ -10225,7 +10616,9 @@
   making_const_table = FALSE;
   return \"\";
   "
+  [(set_attr "length" "0")]
 )
+;; APPLE LOCAL end ARM compact switch tables
 
 (define_insn "consttable_1"
   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
@@ -10395,11 +10788,14 @@
   ""
 )
 
+;; APPLE LOCAL begin ARM compact switch tables
 (define_insn "prologue_use"
   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
   ""
   "%@ %0 needed for prologue"
+  [(set_attr "length" "0")]
 )
+;; APPLE LOCAL end ARM compact switch tables
 
 
 ;; Patterns for exception handling
@@ -10448,6 +10844,86 @@
   }"
 )
 
+;; APPLE LOCAL begin ARM 4382996 improve assignments of NE
+
+;; Handle ((x op y) != 0)
+(define_insn_and_split "*arm_binary_ne_0"
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+	(ne:SI (match_operator:SI 3 "binary_cc_noclobber_operator"
+		  [(match_operand:SI 1 "s_register_operand" "r,r")
+	           (match_operand:SI 2 "arm_not_operand" "rI,K")])
+	       (const_int 0)))
+   (clobber (reg:CC_NOOV CC_REGNUM))]
+  "TARGET_ARM"
+  "#"
+  "TARGET_ARM && reload_completed"
+  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
+		    (compare:CC_NOOV
+		     (match_op_dup:SI 3 [(match_dup 1) (match_dup 2)])
+		     (const_int 0)))
+	       (set (match_dup 0) 
+		     (match_op_dup:SI 3 [(match_dup 1) (match_dup 2)]))])
+   (set (match_dup 0) 
+	(if_then_else:SI
+	 (ne:SI (reg:CC_NOOV CC_REGNUM) (const_int 0))
+	 (const_int 1) (match_dup 0)))]
+  ""
+  [(set_attr "conds" "clob")
+   (set_attr "length" "8")]
+)
+
+;; A special pattern for ADD, because compare_scc gets recognized first,
+;; preventing the above form from being tried.
+
+(define_insn_and_split "*arm_add_ne_0"
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+	(ne:SI (neg:SI (match_operand:SI 1 "s_register_operand" "r,r"))
+	       (match_operand:SI 2 "arm_not_operand" "rI,K")))
+   (clobber (reg:CC_NOOV CC_REGNUM))]
+  "TARGET_ARM"
+  "#"
+  "TARGET_ARM && reload_completed"
+  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
+		    (compare:CC_NOOV
+		     (plus:SI (match_dup 1) (match_dup 2))
+		     (const_int 0)))
+	       (set (match_dup 0) 
+		     (plus:SI (match_dup 1) (match_dup 2)))])
+   (set (match_dup 0) 
+	(if_then_else:SI
+	 (ne:SI (reg:CC_NOOV CC_REGNUM) (const_int 0))
+	 (const_int 1) (match_dup 0)))]
+  ""
+  [(set_attr "conds" "clob")
+   (set_attr "length" "8")]
+)
+
+;; A special pattern for MULT, since it requires early clobber semantics.
+
+(define_insn_and_split "*arm_mul_ne_0"
+  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,r,r")
+	(ne:SI (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
+			(match_operand:SI 1 "arm_not_operand" "%?r,0,I,K"))
+	       (const_int 0)))
+   (clobber (reg:CC_NOOV CC_REGNUM))]
+  "TARGET_ARM"
+  "#"
+  "TARGET_ARM && reload_completed"
+  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
+		    (compare:CC_NOOV
+		     (mult:SI (match_dup 2) (match_dup 1))
+		     (const_int 0)))
+	       (set (match_dup 0) 
+		     (mult:SI (match_dup 2) (match_dup 1)))])
+   (set (match_dup 0) 
+	(if_then_else:SI
+	 (ne:SI (reg:CC_NOOV CC_REGNUM) (const_int 0))
+	 (const_int 1) (match_dup 0)))]
+  ""
+  [(set_attr "conds" "clob")
+   (set_attr "length" "8")]
+)
+;; APPLE LOCAL end ARM 4382996 improve assignments of NE
 
 ;; TLS support
 
@@ -10479,7 +10955,65 @@
   ""
   "trap")
 ;; APPLE LOCAL end ARM builtin_trap
- 
+
+;; APPLE LOCAL begin bswap UXTB16 support
+(define_expand "bswapsi2"
+  [(set (match_operand:SI 0 "s_register_operand" "")
+	(bswap:SI (match_operand:SI 1 "s_register_operand" "")))]
+  "TARGET_EITHER && arm_arch6"
+  ""
+)
+
+(define_insn "*arm_bswapsi2"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+	(bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
+  "TARGET_ARM && arm_arch6"
+  "rev%?\\t%0, %1"
+  [(set_attr "predicable" "yes")]
+) 
+
+(define_insn "*thumb_bswapsi2"
+  [(set (match_operand:SI 0 "register_operand" "=l")
+	(bswap:SI (match_operand:SI 1 "register_operand" "l")))]
+  "TARGET_THUMB && arm_arch6"
+  "rev\\t%0, %1"
+  [(set_attr "length" "2")]
+)
+
+(define_expand "bswapdi2"
+  [(set (match_operand:DI 0 "s_register_operand" "")
+	(bswap:DI (match_operand:DI 1 "s_register_operand" "")))]
+  "TARGET_EITHER && arm_arch6"
+  ""
+)
+
+(define_insn "*arm_bswapdi2"
+  [(set (match_operand:DI 0 "s_register_operand" "=&r")
+	(bswap:DI (match_operand:DI 1 "s_register_operand" "r")))]
+  "TARGET_ARM && arm_arch6"
+  "rev%?\\t%Q0, %R1\;rev%?\\t%R0, %Q1"
+  [(set_attr "predicable" "yes")
+   (set_attr "length" "8")]
+) 
+
+(define_insn "*thumb_bswapdi2"
+  [(set (match_operand:DI 0 "register_operand" "=&l")
+	(bswap:DI (match_operand:DI 1 "register_operand" "l")))]
+  "TARGET_THUMB && arm_arch6"
+  "rev\\t%Q0, %R1\;rev\\t%R0, %Q1"
+  [(set_attr "length" "4")]
+)
+
+(define_insn "uxtb16"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
+                    (match_operand:SI 2 "const_int_operand" "M")] UNSPEC_UXTB16))]
+  "TARGET_ARM && arm_arch6"
+  "uxtb16%?\\t%0, %1, ror %2"
+  [(set_attr "predicable" "yes")]
+)
+;; APPLE LOCAL end bswap UXTB16 support
+
 ;; Load the FPA co-processor patterns
 (include "fpa.md")
 ;; Load the Maverick co-processor patterns

Modified: llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md?rev=54178&r1=54177&r2=54178&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md Tue Jul 29 17:54:46 2008
@@ -120,7 +120,8 @@
    (set_attr "cirrus" "normal")]
 )
 
-(define_insn "muldi3"
+;; APPLE LOCAL DImode multiply enhancement 
+(define_insn "cirrus_muldi3"
   [(set (match_operand:DI          0 "cirrus_fp_register" "=v")
 	(mult:DI (match_operand:DI 2 "cirrus_fp_register"  "v")
 		 (match_operand:DI 1 "cirrus_fp_register"  "v")))]

Modified: llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md?rev=54178&r1=54177&r2=54178&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md Tue Jul 29 17:54:46 2008
@@ -30,7 +30,8 @@
 ;; in Thumb state: I, J, K, L, M, N, O
 
 ;; The following multi-letter normal constraints have been used:
-;; in ARM state: Da, Db, Dc
+;; APPLE LOCAL 5831562 long long constants
+;; in ARM state: Da, Db, Dc, Dd
 
 ;; The following memory constraints have been used:
 ;; in ARM state: Q, Uq, Uv, Uy
@@ -152,6 +153,15 @@
       (match_test "TARGET_ARM && arm_const_double_inline_cost (op) == 4
 		   && !(optimize_size || arm_ld_sched)")))
 
+;; APPLE LOCAL begin 5831562 long long constants
+(define_constraint "Dd"
+ "@internal
+  In ARM state a const_int, const_double or const_vector that can
+  used directly in arithmetic instructions as two 32-bit immediates."
+ (and (match_code "const_double,const_int,const_vector")
+      (match_test "TARGET_ARM && const64_ok_for_arm_immediate (op)")))
+;; APPLE LOCAL end 5831562 long long constants
+
 (define_memory_constraint "Uv"
  "@internal
   In ARM state a valid VFP load/store address."

Modified: llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md?rev=54178&r1=54177&r2=54178&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md Tue Jul 29 17:54:46 2008
@@ -51,6 +51,19 @@
 	      || REGNO (op) >= FIRST_PSEUDO_REGISTER));
 })
 
+;; APPLE LOCAL begin ARM add this peephole
+;; Any Thumb low register.
+(define_predicate "thumb_low_register_operand"
+  (match_code "reg,subreg")
+{
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  return (GET_CODE (op) == REG
+	  && REGNO (op) <= LAST_LO_REGNUM);
+})
+;; APPLE LOCAL end ARM add this peephole
+
 (define_predicate "f_register_operand"
   (match_code "reg,subreg")
 {
@@ -73,6 +86,16 @@
   (and (match_code "const_int")
        (match_test "const_ok_for_arm (INTVAL (op))")))
 
+;; APPLE LOCAL begin 5831562 long long constants
+(define_predicate "arm_immediate64_operand"
+  (and (match_code "const_int,const_double")
+       (match_test "const64_ok_for_arm_immediate (op)")))
+
+(define_predicate "arm_add_immediate64_operand"
+  (and (match_code "const_int,const_double")
+       (match_test "const64_ok_for_arm_add (op)")))
+;; APPLE LOCAL end 5831562 long long constants
+
 (define_predicate "arm_neg_immediate_operand"
   (and (match_code "const_int")
        (match_test "const_ok_for_arm (-INTVAL (op))")))
@@ -86,6 +109,16 @@
   (ior (match_operand 0 "s_register_operand")
        (match_operand 0 "arm_immediate_operand")))
 
+;; APPLE LOCAL begin 5831562 long long constants
+(define_predicate "arm_rhs64_operand"
+  (ior (match_operand 0 "s_register_operand")
+       (match_operand 0 "arm_immediate64_operand")))
+
+(define_predicate "arm_add64_operand"
+  (ior (match_operand 0 "s_register_operand")
+       (match_operand 0 "arm_add_immediate64_operand")))
+;; APPLE LOCAL end 5831562 long long constants
+
 (define_predicate "arm_rhsm_operand"
   (ior (match_operand 0 "arm_rhs_operand")
        (match_operand 0 "memory_operand")))
@@ -159,6 +192,14 @@
   (and (match_code "plus,minus,ior,xor,and")
        (match_test "mode == GET_MODE (op)")))
 
+;; APPLE LOCAL begin ARM 4382996 improve assignments of NE
+;; True for binary operators that can set the condition codes as a side effect,
+;; and that don't have early clobber semantics.
+(define_special_predicate "binary_cc_noclobber_operator"
+  (and (match_code "plus,minus,ior,xor,and,ashift,ashiftrt,lshiftrt")
+       (match_test "mode == GET_MODE (op)")))
+;; APPLE LOCAL end ARM 4382996 improve assignments of NE
+
 ;; True for logical binary operators.
 (define_special_predicate "logical_binary_operator"
   (and (match_code "ior,xor,and")

Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.md?rev=54178&r1=54177&r2=54178&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/i386.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.md Tue Jul 29 17:54:46 2008
@@ -12137,6 +12137,24 @@
   "#"
   [(set_attr "type" "multi")])
 
+;; APPLE LOCAL begin mainline 5951842
+;; This pattern must be defined before *lshrti3_2 to prevent
+;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
+
+(define_insn "sse2_lshrti3"
+  [(set (match_operand:TI 0 "register_operand" "=x")
+ 	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
+		     (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
+  "TARGET_SSE2"
+{
+  operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
+  return "psrldq\t{%2, %0|%0, %2}";
+}
+  [(set_attr "type" "sseishft")
+   (set_attr "prefix_data16" "1")
+   (set_attr "mode" "TI")])
+;; APPLE LOCAL end mainline 5951842
+
 (define_insn "*lshrti3_2"
   [(set (match_operand:TI 0 "register_operand" "=r")
 	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
@@ -19236,7 +19254,7 @@
 
 (define_insn "x86_movdicc_0_m1_rex64"
   [(set (match_operand:DI 0 "register_operand" "=r")
-	(if_then_else:DI (match_operand:DI 1 "ix86_carry_flag_operator" "")
+	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
 	  (const_int -1)
 	  (const_int 0)))
    (clobber (reg:CC FLAGS_REG))]
@@ -19279,7 +19297,7 @@
 
 (define_insn "x86_movsicc_0_m1"
   [(set (match_operand:SI 0 "register_operand" "=r")
-	(if_then_else:SI (match_operand:SI 1 "ix86_carry_flag_operator" "")
+	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
 	  (const_int -1)
 	  (const_int 0)))
    (clobber (reg:CC FLAGS_REG))]

Modified: llvm-gcc-4.2/trunk/gcc/config/i386/sse.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/sse.md?rev=54178&r1=54177&r2=54178&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/sse.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/sse.md Tue Jul 29 17:54:46 2008
@@ -3069,17 +3069,9 @@
   operands[1] = gen_lowpart (TImode, operands[1]);
 })
 
-(define_insn "sse2_lshrti3"
-  [(set (match_operand:TI 0 "register_operand" "=x")
- 	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
-		     (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
-  "TARGET_SSE2"
-{
-  operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
-  return "psrldq\t{%2, %0|%0, %2}";
-}
-  [(set_attr "type" "sseishft")
-   (set_attr "mode" "TI")])
+;; APPLE LOCAL begin mainline 5951842
+;; moved sse2_lshrti3 to i386.md
+;; APPLE LOCAL end mainline 5951842
 
 (define_expand "vec_shr_<mode>"
   [(set (match_operand:SSEMODEI 0 "register_operand" "")

Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/ext/interface4.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.dg/ext/interface4.h?rev=54178&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/ext/interface4.h (added)
+++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/ext/interface4.h Tue Jul 29 17:54:46 2008
@@ -0,0 +1,8 @@
+#pragma interface
+namespace N {
+        typedef int A;
+}
+inline void g ( ) {
+        static N :: A a = 0;
+        a = a;
+}





More information about the llvm-commits mailing list