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:
parent
cdfda6686e
commit
4a085d2edd
2 changed files with 75 additions and 22 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue