From 39e4b33f94bc943844dca11c1081451da0bafff1 Mon Sep 17 00:00:00 2001 From: hp Date: Mon, 11 Mar 2002 10:44:27 +0000 Subject: [PATCH] * config/mmix/mmix.c (mmix_expand_builtin_va_arg): Do all computations on trees. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50567 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++ gcc/config/mmix/mmix.c | 88 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 62 insertions(+), 31 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6f6d9f2e89f..8bd8b905f83 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-03-11 Hans-Peter Nilsson + + * config/mmix/mmix.c (mmix_expand_builtin_va_arg): Do all + computations on trees. + 2002-03-10 Richard Henderson * reload.c (copy_replacements_1): New. diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index cbec2fcb5bf..6fe02275c6c 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -1246,17 +1246,31 @@ mmix_expand_builtin_va_arg (valist, type) tree valist; tree type; { - tree addr_tree, t; - HOST_WIDE_INT align; - HOST_WIDE_INT rounded_size; + tree ptr_size = size_int (BITS_PER_WORD / BITS_PER_UNIT); + tree addr_tree, type_size = NULL; + tree align, alignm1; + tree rounded_size; rtx addr; /* Compute the rounded size of the type. */ - align = PARM_BOUNDARY / BITS_PER_UNIT; - rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align); /* Get AP. */ addr_tree = valist; + align = size_int (PARM_BOUNDARY / BITS_PER_UNIT); + alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1); + if (type == error_mark_node + || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL + || TREE_OVERFLOW (type_size)) + /* Presumable an error; the size isn't computable. A message has + supposedly been emitted elsewhere. */ + rounded_size = size_zero_node; + else + rounded_size = fold (build (MULT_EXPR, sizetype, + fold (build (TRUNC_DIV_EXPR, sizetype, + fold (build (PLUS_EXPR, sizetype, + type_size, alignm1)), + align)), + align)); if (AGGREGATE_TYPE_P (type) && GET_MODE_UNIT_SIZE (TYPE_MODE (type)) < 8 @@ -1271,38 +1285,50 @@ mmix_expand_builtin_va_arg (valist, type) cheaper than a wider memory access on MMIX.) */ addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree, - build_int_2 ((BITS_PER_WORD / BITS_PER_UNIT) - - GET_MODE_UNIT_SIZE (TYPE_MODE (type)), 0)); + size_int ((BITS_PER_WORD / BITS_PER_UNIT) + - GET_MODE_UNIT_SIZE (TYPE_MODE (type)))); } - else + else if (!integer_zerop (rounded_size)) { - HOST_WIDE_INT adj; - adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT; - if (rounded_size > align) - adj = rounded_size; - - addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree, - build_int_2 (rounded_size - adj, 0)); - - /* If this type is larger than what fits in a register, then it is - passed by reference. */ - if (rounded_size > BITS_PER_WORD / BITS_PER_UNIT) - { - tree type_ptr = build_pointer_type (type); - addr_tree = build1 (INDIRECT_REF, type_ptr, addr_tree); - } - } + /* If the size is less than a register, the we need to pad the + address by adding the difference. */ + tree addend + = fold (build (COND_EXPR, sizetype, + fold (build (GT_EXPR, sizetype, + rounded_size, + align)), + size_zero_node, + fold (build (MINUS_EXPR, sizetype, + rounded_size, + type_size)))); + tree addr_tree1 + = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree, addend)); + + /* If this type is larger than what fits in a register, then it is + passed by reference. */ + addr_tree + = fold (build (COND_EXPR, TREE_TYPE (addr_tree1), + fold (build (GT_EXPR, sizetype, + rounded_size, + ptr_size)), + build1 (INDIRECT_REF, build_pointer_type (type), + addr_tree1), + addr_tree1)); + } addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); addr = copy_to_reg (addr); - /* Compute new value for AP. For MMIX, it is always advanced by the - size of a register. */ - t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, - build (PLUS_EXPR, TREE_TYPE (valist), valist, - build_int_2 (BITS_PER_WORD / BITS_PER_UNIT, 0))); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); + if (!integer_zerop (rounded_size)) + { + /* Compute new value for AP. For MMIX, it is always advanced by the + size of a register. */ + tree t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, + build (PLUS_EXPR, TREE_TYPE (valist), valist, + ptr_size)); + TREE_SIDE_EFFECTS (t) = 1; + expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); + } return addr; } -- 2.11.0