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