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
This commit is contained in:
Hans-Peter Nilsson 2002-03-12 02:17:30 +00:00 committed by Hans-Peter Nilsson
parent cdfda6686e
commit 4a085d2edd
2 changed files with 75 additions and 22 deletions

View file

@ -1,3 +1,10 @@
2002-03-12 Hans-Peter Nilsson <hp@axis.com>
* 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 <rth@redhat.com>
* rtlanal.c: Include recog.h.

View file

@ -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)
{
tree type_ptr = build_pointer_type (type);
addr_tree = build1 (INDIRECT_REF, type_ptr, addr_tree);
passed_size = 4;
}
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
passed_size = (CRIS_FUNCTION_ARG_SIZE (mode, type) > 4) ? 8 : 4;
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))
{
/* 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));
}
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;
}