summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2003-05-08 20:00:44 -0400
committerDJ Delorie <dj@gcc.gnu.org>2003-05-08 20:00:44 -0400
commit06d22853477dd010d801b6ccceba458e63288524 (patch)
tree162256d5b68437f9aea7c4844dbcec0b7cccc899
parent001db0e0799bbbe3fde805f8c8fdef9dff542d94 (diff)
downloadgcc-06d22853477dd010d801b6ccceba458e63288524.tar.gz
stormy16.c (xstormy16_expand_builtin_va_arg): Fix to handle arguments for which MUST_PASS_IN_STACK is true (e.g....
* 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. From-SVN: r66619
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/stormy16/stormy16-protos.h2
-rw-r--r--gcc/config/stormy16/stormy16.c49
-rw-r--r--gcc/config/stormy16/stormy16.h6
4 files changed, 47 insertions, 19 deletions
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 <dj@redhat.com>
+
+ * 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 <aldyh@redhat.com>
* 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);
-
- emit_jump_insn (gen_jump (lab_gotaddr));
- emit_barrier ();
- emit_label (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);
+
+ 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