diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50804adb076..7e5a078adec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2003-05-08 DJ Delorie + + * config/stormy16/stormy16.c (xstormy16_expand_builtin_va_arg): Fix + to handle arguments for which MUST_PASS_IN_STACK is true (e.g., + variable-sized types). + (xstormy16_function_arg): New. Pass them that way too. + * config/stormy16/stormy16-protos.h (xstormy16_function_arg): New. + * config/stormy16/stormy16.h (FUNCTION_ARG): Call it. + 2003-05-08 Aldy Hernandez * mklibgcc.in: Use mkinstalldirs when installing multilib diff --git a/gcc/config/stormy16/stormy16-protos.h b/gcc/config/stormy16/stormy16-protos.h index 1c4c3ce5e4e..77ad20afb4e 100644 --- a/gcc/config/stormy16/stormy16-protos.h +++ b/gcc/config/stormy16/stormy16-protos.h @@ -35,6 +35,8 @@ extern void xstormy16_function_profiler PARAMS ((void)); # if defined (HAVE_MACHINE_MODES) extern CUMULATIVE_ARGS xstormy16_function_arg_advance PARAMS ((CUMULATIVE_ARGS, enum machine_mode, tree, int)); +extern rtx xstormy16_function_arg + PARAMS ((CUMULATIVE_ARGS, enum machine_mode, tree, int)); # endif extern void xstormy16_setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS, int, tree, int *)); diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c index e244a0ca5b4..2979dd063ac 100644 --- a/gcc/config/stormy16/stormy16.c +++ b/gcc/config/stormy16/stormy16.c @@ -1260,6 +1260,21 @@ xstormy16_function_arg_advance (cum, mode, type, named) return cum; } +rtx +xstormy16_function_arg (cum, mode, type, named) + CUMULATIVE_ARGS cum; + enum machine_mode mode; + tree type; + int named ATTRIBUTE_UNUSED; +{ + if (mode == VOIDmode) + return const0_rtx; + if (MUST_PASS_IN_STACK (mode, type) + || cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS) + return 0; + return gen_rtx_REG (mode, cum + 2); +} + /* Do any needed setup for a variadic function. CUM has not been updated for the last named argument which has type TYPE and mode MODE. */ void @@ -1354,7 +1369,7 @@ xstormy16_expand_builtin_va_arg (valist, type) rtx count_rtx, addr_rtx, r; rtx lab_gotaddr, lab_fromstack; tree t; - int size, size_of_reg_args; + int size, size_of_reg_args, must_stack; tree size_tree, count_plus_size; rtx count_plus_size_rtx; @@ -1364,7 +1379,7 @@ xstormy16_expand_builtin_va_arg (valist, type) base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base); count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count); - size = PUSH_ROUNDING (int_size_in_bytes (type)); + must_stack = MUST_PASS_IN_STACK (TYPE_MODE (type), type); size_tree = round_up (size_in_bytes (type), UNITS_PER_WORD); size_of_reg_args = NUM_ARGUMENT_REGISTERS * UNITS_PER_WORD; @@ -1374,24 +1389,28 @@ xstormy16_expand_builtin_va_arg (valist, type) lab_fromstack = gen_label_rtx (); addr_rtx = gen_reg_rtx (Pmode); - count_plus_size = build (PLUS_EXPR, TREE_TYPE (count), count, size_tree); - count_plus_size_rtx = expand_expr (count_plus_size, NULL_RTX, HImode, EXPAND_NORMAL); - emit_cmp_and_jump_insns (count_plus_size_rtx, GEN_INT (size_of_reg_args), - GTU, const1_rtx, HImode, 1, lab_fromstack); + if (!must_stack) + { + count_plus_size = build (PLUS_EXPR, TREE_TYPE (count), count, size_tree); + count_plus_size_rtx = expand_expr (count_plus_size, NULL_RTX, HImode, EXPAND_NORMAL); + emit_cmp_and_jump_insns (count_plus_size_rtx, GEN_INT (size_of_reg_args), + GTU, const1_rtx, HImode, 1, lab_fromstack); - t = build (PLUS_EXPR, ptr_type_node, base, count); - r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); - if (r != addr_rtx) - emit_move_insn (addr_rtx, r); + t = build (PLUS_EXPR, ptr_type_node, base, count); + r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); + if (r != addr_rtx) + emit_move_insn (addr_rtx, r); - emit_jump_insn (gen_jump (lab_gotaddr)); - emit_barrier (); - emit_label (lab_fromstack); + emit_jump_insn (gen_jump (lab_gotaddr)); + emit_barrier (); + emit_label (lab_fromstack); + } /* Arguments larger than a word might need to skip over some registers, since arguments are either passed entirely in registers or entirely on the stack. */ - if (size > 2 || size < 0) + size = PUSH_ROUNDING (int_size_in_bytes (type)); + if (size > 2 || size < 0 || must_stack) { rtx lab_notransition = gen_label_rtx (); emit_cmp_and_jump_insns (count_rtx, GEN_INT (NUM_ARGUMENT_REGISTERS diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h index 8281356850c..a0a78cdd377 100644 --- a/gcc/config/stormy16/stormy16.h +++ b/gcc/config/stormy16/stormy16.h @@ -1245,10 +1245,8 @@ enum reg_class returns nonzero for such an argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the stack and then loaded into a register. */ -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ - ((MODE) == VOIDmode ? const0_rtx \ - : (CUM) + XSTORMY16_WORD_SIZE (TYPE, MODE) > NUM_ARGUMENT_REGISTERS ? 0 \ - : gen_rtx_REG (MODE, (CUM) + 2)) +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ + xstormy16_function_arg (CUM, MODE, TYPE, NAMED) /* Define this macro if the target machine has "register windows", so that the register in which a function sees an arguments is not necessarily the same