From 4a085d2edd429d20f04d5dffa7ec89acf2005a82 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Tue, 12 Mar 2002 02:17:30 +0000 Subject: [PATCH] cris.c (cris_target_asm_function_prologue): Do not emit pic register load if "internal" visibility. * config/cris/cris.c (cris_target_asm_function_prologue): Do not emit pic register load if "internal" visibility. (cris_print_operand): Avoid traditional-warning for 0xffffffff. (cris_expand_builtin_va_arg): Do all computations on trees. From-SVN: r50627 --- gcc/ChangeLog | 7 ++++ gcc/config/cris/cris.c | 88 ++++++++++++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd962349c0f..4502a2a7217 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-03-12 Hans-Peter Nilsson + + * config/cris/cris.c (cris_target_asm_function_prologue): Do not + emit pic register load if "internal" visibility. + (cris_print_operand): Avoid traditional-warning for 0xffffffff. + (cris_expand_builtin_va_arg): Do all computations on trees. + 2002-03-11 Richard Henderson * rtlanal.c: Include recog.h. diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 94568742f3e..d1c6f5b4b11 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -857,11 +857,19 @@ cris_target_asm_function_prologue (file, size) framesize += size + cfoa_size; } - /* Set up the PIC register. */ + /* Set up the PIC register. Not needed for a function marked with + visibility "internal". */ if (current_function_uses_pic_offset_table) - asm_fprintf (file, "\tmove.d $pc,$%s\n\tsub.d .:GOTOFF,$%s\n", - reg_names[PIC_OFFSET_TABLE_REGNUM], - reg_names[PIC_OFFSET_TABLE_REGNUM]); + { + tree vis = lookup_attribute ("visibility", DECL_ATTRIBUTES (cfun->decl)); + + if (!vis + || strcmp ("internal", + TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (vis))))) + asm_fprintf (file, "\tmove.d $pc,$%s\n\tsub.d .:GOTOFF,$%s\n", + reg_names[PIC_OFFSET_TABLE_REGNUM], + reg_names[PIC_OFFSET_TABLE_REGNUM]); + } if (TARGET_PDEBUG) fprintf (file, @@ -1452,7 +1460,8 @@ cris_print_operand (file, x, code) } else if (HOST_BITS_PER_WIDE_INT > 32 && GET_CODE (operand) == CONST_INT) { - fprintf (file, "0x%x", (unsigned int)(INTVAL (x) & 0xffffffff)); + fprintf (file, "0x%x", + INTVAL (x) & ((unsigned int) 0x7fffffff * 2 + 1)); return; } /* Otherwise the least significant part equals the normal part, @@ -2612,32 +2621,69 @@ cris_expand_builtin_va_arg (valist, type) { tree addr_tree, t; rtx addr; - enum machine_mode mode = TYPE_MODE (type); - int passed_size; + tree passed_size = size_zero_node; + tree type_size = NULL; + tree size3 = size_int (3); + tree size4 = size_int (4); + tree size8 = size_int (8); + tree rounded_size; /* Get AP. */ addr_tree = valist; - /* Check if the type is passed by value or by reference. */ - if (MUST_PASS_IN_STACK (mode, type) - || CRIS_FUNCTION_ARG_SIZE (mode, type) > 8) + 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, size3)), + size4)), + size4)); + + if (!integer_zerop (rounded_size)) { - tree type_ptr = build_pointer_type (type); - addr_tree = build1 (INDIRECT_REF, type_ptr, addr_tree); - passed_size = 4; + /* Check if the type is passed by value or by reference. This test must + be different than the call-site test and be done at run-time: + gcc.c-torture/execute/20020307-2.c. Hence the tree stuff. + + Values up to 8 bytes are passed by-value, padded to register-size + (4 bytes). Larger values are passed by-reference. */ + passed_size + = fold (build (COND_EXPR, sizetype, + fold (build (GT_EXPR, sizetype, + rounded_size, + size8)), + size4, + rounded_size)); + + addr_tree + = fold (build (COND_EXPR, TREE_TYPE (addr_tree), + fold (build (GT_EXPR, sizetype, + rounded_size, + size8)), + build1 (INDIRECT_REF, build_pointer_type (type), + addr_tree), + addr_tree)); } - else - passed_size = (CRIS_FUNCTION_ARG_SIZE (mode, type) > 4) ? 8 : 4; addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); addr = copy_to_reg (addr); - /* Compute new value for AP. */ - t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, - build (PLUS_EXPR, TREE_TYPE (valist), valist, - build_int_2 (passed_size, 0))); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); + if (!integer_zerop (rounded_size)) + { + /* Compute new value for AP. */ + t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, + build (PLUS_EXPR, TREE_TYPE (valist), valist, + passed_size)); + TREE_SIDE_EFFECTS (t) = 1; + expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); + } return addr; } -- 2.30.2