aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99502.patch
blob: 59bf01cc5639236dbd6844f0941e557ff671fe64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
2011-04-26  Chung-Lin Tang  <cltang@codesourcery.com>

	Backport from mainline:

	2011-03-21  Chung-Lin Tang  <cltang@codesourcery.com>

	gcc/
	* simplify-rtx.c (simplify_binary_operation_1): Handle
	(xor (and A B) C) case when B and C are both constants.

	gcc/testsuite/
	* gcc.target/arm/xor-and.c: New.

	2011-03-18  Chung-Lin Tang  <cltang@codesourcery.com>

	gcc/
	* combine.c (try_combine): Do simplification only call of
	subst() on i2 even when i1 is present. Update comments.

	gcc/testsuite/
	* gcc.target/arm/unsigned-extend-1.c: New.

=== modified file 'gcc/combine.c'
--- old/gcc/combine.c	2011-01-06 11:02:44 +0000
+++ new/gcc/combine.c	2011-04-14 13:58:12 +0000
@@ -2939,7 +2939,7 @@
       /* It is possible that the source of I2 or I1 may be performing
 	 an unneeded operation, such as a ZERO_EXTEND of something
 	 that is known to have the high part zero.  Handle that case
-	 by letting subst look at the innermost one of them.
+	 by letting subst look at the inner insns.
 
 	 Another way to do this would be to have a function that tries
 	 to simplify a single insn instead of merging two or more
@@ -2964,11 +2964,9 @@
 	      subst_low_luid = DF_INSN_LUID (i1);
 	      i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0, 0);
 	    }
-	  else
-	    {
-	      subst_low_luid = DF_INSN_LUID (i2);
-	      i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0, 0);
-	    }
+
+	  subst_low_luid = DF_INSN_LUID (i2);
+	  i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0, 0);
 	}
 
       n_occurrences = 0;		/* `subst' counts here */

=== modified file 'gcc/simplify-rtx.c'
--- old/gcc/simplify-rtx.c	2010-06-25 20:11:56 +0000
+++ new/gcc/simplify-rtx.c	2011-04-14 13:58:12 +0000
@@ -2413,6 +2413,46 @@
 							XEXP (op0, 1), mode),
 				    op1);
 
+      /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
+	 we can transform like this:
+            (A&B)^C == ~(A&B)&C | ~C&(A&B)
+                    == (~A|~B)&C | ~C&(A&B)    * DeMorgan's Law
+                    == ~A&C | ~B&C | A&(~C&B)  * Distribute and re-order
+	 Attempt a few simplifications when B and C are both constants.  */
+      if (GET_CODE (op0) == AND
+	  && CONST_INT_P (op1)
+	  && CONST_INT_P (XEXP (op0, 1)))
+	{
+	  rtx a = XEXP (op0, 0);
+	  rtx b = XEXP (op0, 1);
+	  rtx c = op1;
+	  HOST_WIDE_INT bval = INTVAL (b);
+	  HOST_WIDE_INT cval = INTVAL (c);
+
+	  rtx na_c
+	    = simplify_binary_operation (AND, mode,
+					 simplify_gen_unary (NOT, mode, a, mode),
+					 c);
+	  if ((~cval & bval) == 0)
+	    {
+	      /* Try to simplify ~A&C | ~B&C.  */
+	      if (na_c != NULL_RTX)
+		return simplify_gen_binary (IOR, mode, na_c,
+					    GEN_INT (~bval & cval));
+	    }
+	  else
+	    {
+	      /* If ~A&C is zero, simplify A&(~C&B) | ~B&C.  */
+	      if (na_c == const0_rtx)
+		{
+		  rtx a_nc_b = simplify_gen_binary (AND, mode, a,
+						    GEN_INT (~cval & bval));
+		  return simplify_gen_binary (IOR, mode, a_nc_b,
+					      GEN_INT (~bval & cval));
+		}
+	    }
+	}
+
       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
 	 comparison if STORE_FLAG_VALUE is 1.  */
       if (STORE_FLAG_VALUE == 1

=== added file 'gcc/testsuite/gcc.target/arm/unsigned-extend-1.c'
--- old/gcc/testsuite/gcc.target/arm/unsigned-extend-1.c	1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.target/arm/unsigned-extend-1.c	2011-04-14 13:58:12 +0000
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv6" } */
+
+unsigned char foo (unsigned char c)
+{
+  return (c >= '0') && (c <= '9');
+}
+
+/* { dg-final { scan-assembler-not "uxtb" } } */

=== added file 'gcc/testsuite/gcc.target/arm/xor-and.c'
--- old/gcc/testsuite/gcc.target/arm/xor-and.c	1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.target/arm/xor-and.c	2011-04-14 13:58:12 +0000
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -march=armv6" } */
+
+unsigned short foo (unsigned short x)
+{
+  x ^= 0x4002;
+  x >>= 1;
+  x |= 0x8000;
+  return x;
+}
+
+/* { dg-final { scan-assembler "orr" } } */
+/* { dg-final { scan-assembler-not "mvn" } } */
+/* { dg-final { scan-assembler-not "uxth" } } */