mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-18 23:51:08 +08:00
sparc.c (sparc_gimplify_va_arg): New fn.
* config/sparc/sparc.c (sparc_gimplify_va_arg): New fn. (TARGET_GIMPLIFY_VA_ARG_EXPR): Define. From-SVN: r82963
This commit is contained in:
parent
b092552d60
commit
5f393b252e
@ -1,3 +1,8 @@
|
||||
2004-06-11 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* config/sparc/sparc.c (sparc_gimplify_va_arg): New fn.
|
||||
(TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
|
||||
|
||||
2004-06-11 Jerry Quinn <jlquinn@optonline.net>
|
||||
|
||||
* typeclass.h: Add GPL plus exception license. Add include
|
||||
|
@ -47,6 +47,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "target.h"
|
||||
#include "target-def.h"
|
||||
#include "cfglayout.h"
|
||||
#include "tree-gimple.h"
|
||||
|
||||
/* Global variables for machine-dependent things. */
|
||||
|
||||
@ -181,6 +182,7 @@ static bool sparc_promote_prototypes (tree);
|
||||
static rtx sparc_struct_value_rtx (tree, int);
|
||||
static bool sparc_return_in_memory (tree, tree);
|
||||
static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *);
|
||||
static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *);
|
||||
|
||||
/* Option handling. */
|
||||
|
||||
@ -289,6 +291,9 @@ enum processor_type sparc_cpu;
|
||||
#undef TARGET_STRICT_ARGUMENT_NAMING
|
||||
#define TARGET_STRICT_ARGUMENT_NAMING sparc_strict_argument_naming
|
||||
|
||||
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
|
||||
#define TARGET_GIMPLIFY_VA_ARG_EXPR sparc_gimplify_va_arg
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Validate and override various options, and do some machine dependent
|
||||
@ -6041,6 +6046,96 @@ sparc_va_arg (tree valist, tree type)
|
||||
|
||||
return addr_rtx;
|
||||
}
|
||||
|
||||
tree
|
||||
sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
|
||||
{
|
||||
HOST_WIDE_INT size, rsize, align;
|
||||
tree addr, incr;
|
||||
bool indirect;
|
||||
tree ptrtype = build_pointer_type (type);
|
||||
|
||||
if (function_arg_pass_by_reference (0, TYPE_MODE (type), type, 0))
|
||||
{
|
||||
indirect = true;
|
||||
size = rsize = UNITS_PER_WORD;
|
||||
align = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
indirect = false;
|
||||
size = int_size_in_bytes (type);
|
||||
rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
|
||||
align = 0;
|
||||
|
||||
if (TARGET_ARCH64)
|
||||
{
|
||||
/* For SPARC64, objects requiring 16-byte alignment get it. */
|
||||
if (TYPE_ALIGN (type) >= 2 * (unsigned) BITS_PER_WORD)
|
||||
align = 2 * UNITS_PER_WORD;
|
||||
|
||||
/* SPARC-V9 ABI states that structures up to 16 bytes in size
|
||||
are given whole slots as needed. */
|
||||
if (AGGREGATE_TYPE_P (type))
|
||||
{
|
||||
if (size == 0)
|
||||
size = rsize = UNITS_PER_WORD;
|
||||
else
|
||||
size = rsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
incr = valist;
|
||||
if (align)
|
||||
{
|
||||
incr = fold (build2 (PLUS_EXPR, ptr_type_node, incr,
|
||||
ssize_int (align - 1)));
|
||||
incr = fold (build2 (BIT_AND_EXPR, ptr_type_node, incr,
|
||||
ssize_int (-align)));
|
||||
}
|
||||
|
||||
gimplify_expr (&incr, pre_p, post_p, is_gimple_val, fb_rvalue);
|
||||
addr = incr;
|
||||
|
||||
if (BYTES_BIG_ENDIAN && size < rsize)
|
||||
addr = fold (build2 (PLUS_EXPR, ptr_type_node, incr,
|
||||
ssize_int (rsize - size)));
|
||||
|
||||
if (indirect)
|
||||
{
|
||||
addr = fold_convert (build_pointer_type (ptrtype), addr);
|
||||
addr = build_fold_indirect_ref (addr);
|
||||
}
|
||||
/* If the address isn't aligned properly for the type,
|
||||
we may need to copy to a temporary.
|
||||
FIXME: This is inefficient. Usually we can do this
|
||||
in registers. */
|
||||
else if (align == 0
|
||||
&& TYPE_ALIGN (type) > BITS_PER_WORD)
|
||||
{
|
||||
tree tmp = create_tmp_var (type, "va_arg_tmp");
|
||||
tree dest_addr = build_fold_addr_expr (tmp);
|
||||
|
||||
tree copy = build_function_call_expr
|
||||
(implicit_built_in_decls[BUILT_IN_MEMCPY],
|
||||
tree_cons (NULL_TREE, dest_addr,
|
||||
tree_cons (NULL_TREE, addr,
|
||||
tree_cons (NULL_TREE, size_int (rsize),
|
||||
NULL_TREE))));
|
||||
|
||||
gimplify_and_add (copy, pre_p);
|
||||
addr = dest_addr;
|
||||
}
|
||||
else
|
||||
addr = fold_convert (ptrtype, addr);
|
||||
|
||||
incr = fold (build2 (PLUS_EXPR, ptr_type_node, incr, ssize_int (rsize)));
|
||||
incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
|
||||
gimplify_and_add (incr, post_p);
|
||||
|
||||
return build_fold_indirect_ref (addr);
|
||||
}
|
||||
|
||||
/* Return the string to output a conditional branch to LABEL, which is
|
||||
the operand number of the label. OP is the conditional expression.
|
||||
|
Loading…
x
Reference in New Issue
Block a user