1 /* { dg-do compile { target { ! ia32 } } } */
2 /* { dg-require-effective-target maybe_x32 } */
3 /* { dg-options "-O2 -mx32 -maddress-mode=long" } */
4 
5 typedef struct rtx_def *rtx;
6 enum rtx_code { MINUS };
7 union rtunion_def {
8   rtx rt_rtx;
9 };
10 typedef union rtunion_def rtunion;
11 struct rtx_def {
12   enum rtx_code code: 16;
13   union u {
14     rtunion fld[1];
15   }
16   u;
17 };
18 rtx simplify_binary_operation (enum rtx_code code, int mode,
19 			       rtx op0, rtx op1);
20 struct simplify_plus_minus_op_data {
21   rtx op;
22   short neg;
23 };
simplify_plus_minus(enum rtx_code code,int mode,rtx op0,rtx op1)24 void simplify_plus_minus (enum rtx_code code, int mode, rtx op0, rtx op1)
25 {
26   struct simplify_plus_minus_op_data ops[8];
27   rtx tem = (rtx) 0;
28   int n_ops = 2, input_ops = 2;
29   int changed, canonicalized = 0;
30   int i, j;
31   __builtin_memset (ops, 0, sizeof (ops));
32   do
33     {
34       changed = 0;
35       for (i = 0; i < n_ops; i++)
36 	{
37 	  rtx this_op = ops[i].op;
38 	  int this_neg = ops[i].neg;
39 	  enum rtx_code this_code = ((enum rtx_code) (this_op)->code);
40 	  switch (this_code)
41 	    {
42 	    case MINUS:
43 	      if (n_ops == 7)
44 		return;
45 	      n_ops++;
46 	      input_ops++;
47 	      changed = 1;
48 	      canonicalized |= this_neg;
49 	      break;
50 	    }
51 	}
52     }
53   while (changed);
54   do
55     {
56       j =  n_ops - 1;
57       for (i = n_ops - 1; j >= 0; j--)
58 	{
59 	  rtx lhs = ops[j].op, rhs = ops[i].op;
60 	  int lneg = ops[j].neg, rneg = ops[i].neg;
61 	  if (lhs != 0 && rhs != 0)
62 	    {
63 	      enum rtx_code ncode = MINUS;
64 	      if (((enum rtx_code) (lhs)->code) == MINUS)
65 		tem = simplify_binary_operation (ncode, mode, lhs, rhs);
66 	      if (tem && ! (((enum rtx_code) (tem)->code) == MINUS
67 			    && ((((((tem)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx) == lhs
68 			    && ((((((tem)->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx) == rhs))
69 		{
70 		  lneg &= rneg;
71 		  ops[i].op = tem;
72 		  ops[i].neg = lneg;
73 		  ops[j].op = (rtx) 0;
74 		  changed = 1;
75 		  canonicalized = 1;
76 		}
77 	    }
78 	}
79       for (i = 0, j = 0; j < n_ops; j++)
80 	if (ops[j].op)
81 	  {
82 	    ops[i] = ops[j];
83 	    i++;
84 	  }
85     }
86   while (changed);
87 }
88