tree aff_combination_to_tree (aff_tree *comb) { tree type = comb->type; tree expr = NULL_TREE; unsigned i; double_int off, sgn; tree type1 = type; if (POINTER_TYPE_P (type)) type1 = sizetype; gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE); for (i = 0; i < comb->n; i++) expr = add_elt_to_tree (expr, type, comb->elts[i].val, comb->elts[i].coef, comb); if (comb->rest) expr = add_elt_to_tree (expr, type, comb->rest, double_int_one, comb); /* Ensure that we get x - 1, not x + (-1) or x + 0xff..f if x is unsigned. */ if (double_int_negative_p (comb->offset)) { off = double_int_neg (comb->offset); sgn = double_int_minus_one; } else { off = comb->offset; sgn = double_int_one; } return add_elt_to_tree (expr, type, double_int_to_tree (type1, off), sgn, comb); }
static tree add_elt_to_tree (tree expr, tree type, tree elt, double_int scale, aff_tree *comb) { enum tree_code code; tree type1 = type; if (POINTER_TYPE_P (type)) type1 = sizetype; scale = double_int_ext_for_comb (scale, comb); elt = fold_convert (type1, elt); if (double_int_one_p (scale)) { if (!expr) return fold_convert (type, elt); if (POINTER_TYPE_P (type)) return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt); return fold_build2 (PLUS_EXPR, type, expr, elt); } if (double_int_minus_one_p (scale)) { if (!expr) return fold_convert (type, fold_build1 (NEGATE_EXPR, type1, elt)); if (POINTER_TYPE_P (type)) { elt = fold_build1 (NEGATE_EXPR, type1, elt); return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt); } return fold_build2 (MINUS_EXPR, type, expr, elt); } if (!expr) return fold_convert (type, fold_build2 (MULT_EXPR, type1, elt, double_int_to_tree (type1, scale))); if (double_int_negative_p (scale)) { code = MINUS_EXPR; scale = double_int_neg (scale); } else code = PLUS_EXPR; elt = fold_build2 (MULT_EXPR, type1, elt, double_int_to_tree (type1, scale)); if (POINTER_TYPE_P (type)) { if (code == MINUS_EXPR) elt = fold_build1 (NEGATE_EXPR, type1, elt); return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt); } return fold_build2 (code, type, expr, elt); }
static tree add_elt_to_tree (tree expr, tree type, tree elt, double_int scale, aff_tree *comb) { enum tree_code code; tree type1 = type; if (POINTER_TYPE_P (type)) #ifdef TARGET_POINTER_SIZETYPE { /* sizetype is not good enough for pointers in ADDRESS_SPACES on dsPIC; some pointers are larger than 'sizetype' (CAW) */ type1 = TARGET_POINTER_SIZETYPE(type); } #else type1 = sizetype; #endif scale = double_int_ext_for_comb (scale, comb); elt = fold_convert (type1, elt); if (double_int_one_p (scale)) { if (!expr) return fold_convert (type, elt); if (POINTER_TYPE_P (type)) return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt); return fold_build2 (PLUS_EXPR, type, expr, elt); } if (double_int_minus_one_p (scale)) { if (!expr) return fold_convert (type, fold_build1 (NEGATE_EXPR, type1, elt)); if (POINTER_TYPE_P (type)) { elt = fold_build1 (NEGATE_EXPR, type1, elt); return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt); } return fold_build2 (MINUS_EXPR, type, expr, elt); } if (!expr) return fold_convert (type, fold_build2 (MULT_EXPR, type1, elt, double_int_to_tree (type1, scale))); if (double_int_negative_p (scale)) { code = MINUS_EXPR; scale = double_int_neg (scale); } else code = PLUS_EXPR; elt = fold_build2 (MULT_EXPR, type1, elt, double_int_to_tree (type1, scale)); if (POINTER_TYPE_P (type)) { if (code == MINUS_EXPR) elt = fold_build1 (NEGATE_EXPR, type1, elt); return fold_build2 (POINTER_PLUS_EXPR, type, expr, elt); } return fold_build2 (code, type, expr, elt); }