summary refs log tree commit diff
path: root/pkgs/development/tools/misc/binutils/as-pr10856.patch
blob: 695d3e3567065e20ac59634e379e25ed9f5dde0e (plain) (blame)
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
Fix a regression in GNU as:
http://sourceware.org/bugzilla/show_bug.cgi?id=10856 .

The bug appears to be responsible for invalid code generated for
Crypto++:
http://groups.google.com/group/cryptopp-users/browse_thread/thread/7ce734e479586640/29c6649b7c7adee2?#29c6649b7c7adee2 .

diff -u -r1.77.2.1 -r1.77.2.2
--- a/gas/expr.c	2009/09/11 15:28:43	1.77.2.1
+++ b/gas/expr.c	2009/10/28 08:23:48	1.77.2.2
@@ -1997,6 +1997,7 @@
   /* Help out with CSE.  */
   valueT final_val = expressionP->X_add_number;
   symbolS *add_symbol = expressionP->X_add_symbol;
+  symbolS *orig_add_symbol = add_symbol;
   symbolS *op_symbol = expressionP->X_op_symbol;
   operatorT op = expressionP->X_op;
   valueT left, right;
@@ -2078,6 +2079,7 @@
 	      left = right;
 	      seg_left = seg_right;
 	      add_symbol = op_symbol;
+	      orig_add_symbol = expressionP->X_op_symbol;
 	      op = O_symbol;
 	      break;
 	    }
@@ -2122,18 +2124,19 @@
 	    {
 	      if (op == O_bit_exclusive_or || op == O_bit_inclusive_or)
 		{
-		  if (seg_right != absolute_section || right != 0)
+		  if (!(seg_right == absolute_section && right == 0))
 		    {
 		      seg_left = seg_right;
 		      left = right;
 		      add_symbol = op_symbol;
+		      orig_add_symbol = expressionP->X_op_symbol;
 		    }
 		  op = O_symbol;
 		  break;
 		}
 	      else if (op == O_left_shift || op == O_right_shift)
 		{
-		  if (seg_left != absolute_section || left != 0)
+		  if (!(seg_left == absolute_section && left == 0))
 		    {
 		      op = O_symbol;
 		      break;
@@ -2149,6 +2152,7 @@
 	      seg_left = seg_right;
 	      left = right;
 	      add_symbol = op_symbol;
+	      orig_add_symbol = expressionP->X_op_symbol;
 	      op = O_symbol;
 	      break;
 	    }
@@ -2158,11 +2162,11 @@
 	      op = O_symbol;
 	      break;
 	    }
-	  else if (left != right
-		   || ((seg_left != reg_section || seg_right != reg_section)
-		       && (seg_left != undefined_section
-			   || seg_right != undefined_section
-			   || add_symbol != op_symbol)))
+	  else if (!(left == right
+		     && ((seg_left == reg_section && seg_right == reg_section)
+			 || (seg_left == undefined_section
+			     && seg_right == undefined_section
+			     && add_symbol == op_symbol))))
 	    return 0;
 	  else if (op == O_bit_and || op == O_bit_inclusive_or)
 	    {
@@ -2233,7 +2237,8 @@
 	op = O_constant;
       else if (seg_left == reg_section && final_val == 0)
 	op = O_register;
-      else if (add_symbol != expressionP->X_add_symbol)
+      else if (seg_left == undefined_section
+	       && add_symbol != orig_add_symbol)
 	final_val += left;
       expressionP->X_add_symbol = add_symbol;
     }