- /* Otherwise return the number of registers that would be used. */
- return FR30_NUM_ARG_REGS - cum;
-}
-
-static rtx
-fr30_pass_by_reference (valist, type)
- tree valist;
- tree type;
-{
- tree type_ptr;
- tree type_ptr_ptr;
- tree t;
-
- type_ptr = build_pointer_type (type);
- type_ptr_ptr = build_pointer_type (type_ptr);
-
- t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (UNITS_PER_WORD, 0));
- TREE_SIDE_EFFECTS (t) = 1;
- t = build1 (NOP_EXPR, type_ptr_ptr, t);
- TREE_SIDE_EFFECTS (t) = 1;
- t = build1 (INDIRECT_REF, type_ptr, t);
-
- return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
-}
-
-static rtx
-fr30_pass_by_value (valist, type)
- tree valist;
- tree type;
-{
- HOST_WIDE_INT size = int_size_in_bytes (type);
- HOST_WIDE_INT rsize;
- rtx addr_rtx;
- tree t;
-
- if ((size % UNITS_PER_WORD) == 0)
- {
- t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (size, 0));
- TREE_SIDE_EFFECTS (t) = 1;
-
- return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
- }
-
- rsize = (size + UNITS_PER_WORD - 1) & - UNITS_PER_WORD;
-
- /* Care for bigendian correction on the aligned address. */
- t = build (PLUS_EXPR, ptr_type_node, valist, build_int_2 (rsize - size, 0));
- addr_rtx = expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
- addr_rtx = copy_to_reg (addr_rtx);
-
- /* Increment AP. */
- t = build (PLUS_EXPR, va_list_type_node, valist, build_int_2 (rsize, 0));
- t = build (MODIFY_EXPR, va_list_type_node, valist, t);
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
- return addr_rtx;
-}
-
-/* Implement `va_arg'. */
-
-rtx
-fr30_va_arg (valist, type)
- tree valist;
- tree type;
-{
- HOST_WIDE_INT size;
-
- if (AGGREGATE_TYPE_P (type))
- return fr30_pass_by_reference (valist, type);
-
- size = int_size_in_bytes (type);
-
- if ((size % sizeof (int)) == 0
- || size < 4)
- return fr30_pass_by_value (valist, type);
-
- return fr30_pass_by_reference (valist, type);