This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
gimple va_arg for iq2000
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 8 Jul 2004 17:03:51 -0700
- Subject: gimple va_arg for iq2000
Seems there was quite a bit of dead code in there... Oh well, SEP.
r~
* config/iq2000/iq2000-protos.h (iq2000_va_arg): Remove.
* config/iq2000/iq2000.c (TARGET_GIMPLIFY_VA_ARG_EXPR): New.
(iq2000_gimplify_va_arg_expr): Rewrite from iq2000_va_arg.
* config/iq2000/iq2000.h (EXPAND_BUILTIN_VA_ARG): Remove.
Index: iq2000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/iq2000/iq2000-protos.h,v
retrieving revision 1.5
diff -c -p -d -r1.5 iq2000-protos.h
*** iq2000-protos.h 27 Jan 2004 19:20:02 -0000 1.5
--- iq2000-protos.h 8 Jul 2004 23:59:14 -0000
*************** extern void function_arg_adv
*** 52,58 ****
extern struct rtx_def * function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern int function_arg_partial_nregs (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern void iq2000_va_start (tree, rtx);
- extern rtx iq2000_va_arg (tree, tree);
extern rtx iq2000_function_value (tree, tree);
#endif
--- 52,57 ----
Index: iq2000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/iq2000/iq2000.c,v
retrieving revision 1.19
diff -c -p -d -r1.19 iq2000.c
*** iq2000.c 4 Jul 2004 20:58:46 -0000 1.19
--- iq2000.c 8 Jul 2004 23:59:14 -0000
*************** static bool iq2000_rtx_costs (r
*** 171,176 ****
--- 171,177 ----
static int iq2000_address_cost (rtx);
static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
static bool iq2000_return_in_memory (tree, tree);
+ static tree iq2000_gimplify_va_arg_expr (tree, tree, tree *, tree *);
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS iq2000_init_builtins
*************** static bool iq2000_return_in_memory (t
*** 199,204 ****
--- 200,207 ----
#define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
#undef TARGET_STRICT_ARGUMENT_NAMING
#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
+ #undef TARGET_GIMPLIFY_VA_ARG_EXPR
+ #define TARGET_GIMPLIFY_VA_ARG_EXPR iq2000_gimplify_va_arg_expr
#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE hook_int_void_1
*************** iq2000_va_start (tree valist, rtx nextar
*** 1590,1789 ****
/* Implement va_arg. */
! rtx
! iq2000_va_arg (tree valist, tree type)
{
! HOST_WIDE_INT size, rsize;
! rtx addr_rtx;
! tree t;
! int indirect;
! rtx r, lab_over = NULL_RTX, lab_false;
! tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
! tree ovfl, gtop, ftop, goff, foff;
!
! size = int_size_in_bytes (type);
! rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
! indirect
! = function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0);
! if (indirect)
! {
! size = POINTER_SIZE / BITS_PER_UNIT;
! rsize = UNITS_PER_WORD;
! }
!
! addr_rtx = gen_reg_rtx (Pmode);
!
! {
! /* Case of all args in a merged stack. No need to check bounds,
! just advance valist along the stack. */
! tree gpr = valist;
!
! if (! indirect
! && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
! {
! t = build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
! build_int_2 (2*UNITS_PER_WORD - 1, 0));
! t = build (BIT_AND_EXPR, TREE_TYPE (t), t,
! build_int_2 (-2*UNITS_PER_WORD, -1));
! t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
! expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
! }
!
! t = build (POSTINCREMENT_EXPR, TREE_TYPE (gpr), gpr,
! size_int (rsize));
! r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
! if (r != addr_rtx)
! emit_move_insn (addr_rtx, r);
!
! /* Flush the POSTINCREMENT. */
! emit_queue();
!
! if (indirect)
! {
! r = gen_rtx_MEM (Pmode, addr_rtx);
! set_mem_alias_set (r, get_varargs_alias_set ());
! emit_move_insn (addr_rtx, r);
! }
! else
! {
! if (BYTES_BIG_ENDIAN && rsize != size)
! addr_rtx = plus_constant (addr_rtx, rsize - size);
! }
! return addr_rtx;
! }
!
! /* Not a simple merged stack. Need ptrs and indexes left by va_start. */
! f_ovfl = TYPE_FIELDS (va_list_type_node);
! f_gtop = TREE_CHAIN (f_ovfl);
! f_ftop = TREE_CHAIN (f_gtop);
! f_goff = TREE_CHAIN (f_ftop);
! f_foff = TREE_CHAIN (f_goff);
!
! ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl, NULL_TREE);
! gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop, NULL_TREE);
! ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop, NULL_TREE);
! goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff, NULL_TREE);
! foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff, NULL_TREE);
!
! lab_false = gen_label_rtx ();
! lab_over = gen_label_rtx ();
!
! if (TREE_CODE (type) == REAL_TYPE)
! {
! /* Emit code to branch if foff == 0. */
! r = expand_expr (foff, NULL_RTX, TYPE_MODE (TREE_TYPE (foff)),
! EXPAND_NORMAL);
! emit_cmp_and_jump_insns (r, const0_rtx, EQ,
! const1_rtx, GET_MODE (r), 1, lab_false);
!
! /* Emit code for addr_rtx = ftop - foff. */
! t = build (MINUS_EXPR, TREE_TYPE (ftop), ftop, foff );
! r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
! if (r != addr_rtx)
! emit_move_insn (addr_rtx, r);
!
! /* Emit code for foff-=8.
! Advances the offset up FPR save area by one double. */
! t = build (MINUS_EXPR, TREE_TYPE (foff), foff, build_int_2 (8, 0));
! t = build (MODIFY_EXPR, TREE_TYPE (foff), foff, t);
! expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
!
! emit_queue ();
! emit_jump (lab_over);
! emit_barrier ();
! emit_label (lab_false);
!
! /* If a 4-byte int is followed by an 8-byte float, then
! natural alignment causes a 4 byte gap.
! So, dynamically adjust ovfl up to a multiple of 8. */
! t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), ovfl,
! build_int_2 (7, 0));
! t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, t);
! t = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
! expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
!
! /* Emit code for addr_rtx = the ovfl pointer into overflow area.
! Postincrement the ovfl pointer by 8. */
! t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl,
! size_int (8));
! r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
! if (r != addr_rtx)
! emit_move_insn (addr_rtx, r);
!
! emit_queue();
! emit_label (lab_over);
! return addr_rtx;
! }
else
! {
! /* Not REAL_TYPE. */
! int step_size;
!
! if (TREE_CODE (type) == INTEGER_TYPE
! && TYPE_PRECISION (type) == 64)
! {
! /* int takes 32 bits of the GPR save area, but
! longlong takes an aligned 64 bits. So, emit code
! to zero the low order bits of goff, thus aligning
! the later calculation of (gtop-goff) upwards. */
! t = build (BIT_AND_EXPR, TREE_TYPE (goff), goff,
! build_int_2 (-8, -1));
! t = build (MODIFY_EXPR, TREE_TYPE (goff), goff, t);
! expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
! }
!
! /* Emit code to branch if goff == 0. */
! r = expand_expr (goff, NULL_RTX, TYPE_MODE (TREE_TYPE (goff)),
! EXPAND_NORMAL);
! emit_cmp_and_jump_insns (r, const0_rtx, EQ,
! const1_rtx, GET_MODE (r), 1, lab_false);
!
! /* Emit code for addr_rtx = gtop - goff. */
! t = build (MINUS_EXPR, TREE_TYPE (gtop), gtop, goff);
! r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
! if (r != addr_rtx)
! emit_move_insn (addr_rtx, r);
!
! if (TYPE_PRECISION (type) == 64)
! step_size = 8;
! else
! step_size = UNITS_PER_WORD;
!
! /* Emit code for goff = goff - step_size.
! Advances the offset up GPR save area over the item. */
! t = build (MINUS_EXPR, TREE_TYPE (goff), goff,
! build_int_2 (step_size, 0));
! t = build (MODIFY_EXPR, TREE_TYPE (goff), goff, t);
! expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
!
! emit_queue();
! emit_jump (lab_over);
! emit_barrier ();
! emit_label (lab_false);
!
! /* Emit code for addr_rtx -> overflow area, postinc by step_size. */
! t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl,
! size_int (step_size));
! r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
! if (r != addr_rtx)
! emit_move_insn (addr_rtx, r);
!
! emit_queue();
! emit_label (lab_over);
!
! if (indirect)
! {
! r = gen_rtx_MEM (Pmode, addr_rtx);
! set_mem_alias_set (r, get_varargs_alias_set ());
! emit_move_insn (addr_rtx, r);
! }
! else
! {
! if (BYTES_BIG_ENDIAN && rsize != size)
! addr_rtx = plus_constant (addr_rtx, rsize - size);
! }
! return addr_rtx;
! }
}
/* Allocate a chunk of memory for per-function machine-dependent data. */
--- 1593,1605 ----
/* Implement va_arg. */
! static tree
! iq2000_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
{
! if (function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0))
! return ind_gimplify_va_arg_expr (valist, type, pre_p, post_p);
else
! return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
}
/* Allocate a chunk of memory for per-function machine-dependent data. */
Index: iq2000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/iq2000/iq2000.h,v
retrieving revision 1.14
diff -c -p -d -r1.14 iq2000.h
*** iq2000.h 21 May 2004 01:03:18 -0000 1.14
--- iq2000.h 8 Jul 2004 23:59:14 -0000
*************** typedef struct iq2000_args
*** 544,553 ****
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
iq2000_va_start (valist, nextarg)
- /* Implement `va_arg'. */
- #define EXPAND_BUILTIN_VA_ARG(valist, type) \
- iq2000_va_arg (valist, type)
-
/* Trampolines for Nested Functions. */
--- 544,549 ----