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