aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-10-07 18:38:02 +0000
committerRichard Stallman <rms@gnu.org>1993-10-07 18:38:02 +0000
commit888aa7a977cde28abe81a0b0714683950bbefab2 (patch)
tree1de62f41e8b8212a1e892054888772bb7481fc0e /gcc
parentcbc580f02bff05c3ff0df52e91a7b330f6d166cb (diff)
downloadgcc-888aa7a977cde28abe81a0b0714683950bbefab2.zip
gcc-888aa7a977cde28abe81a0b0714683950bbefab2.tar.gz
gcc-888aa7a977cde28abe81a0b0714683950bbefab2.tar.bz2
(emit_library_call, emit_library_call_value):
Allocate a temp slot if arg must be passed by reference. From-SVN: r5657
Diffstat (limited to 'gcc')
-rw-r--r--gcc/calls.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 3d29430..da23a6f 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2104,6 +2104,8 @@ emit_library_call (va_alist)
args_size.constant = 0;
args_size.var = 0;
+ push_temp_slots ();
+
for (count = 0; count < nargs; count++)
{
rtx val = va_arg (p, rtx);
@@ -2130,14 +2132,19 @@ emit_library_call (va_alist)
&& ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
val = force_operand (val, NULL_RTX);
- argvec[count].value = val;
- argvec[count].mode = mode;
-
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
- abort ();
+ {
+ rtx slot = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
+ emit_move_insn (slot, val);
+ val = XEXP (slot, 0);
+ mode = SImode;
+ }
#endif
+ argvec[count].value = val;
+ argvec[count].mode = mode;
+
argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
if (argvec[count].reg && GET_CODE (argvec[count].reg) == EXPR_LIST)
abort ();
@@ -2303,6 +2310,8 @@ emit_library_call (va_alist)
outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
old_inhibit_defer_pop + 1, use_insns, no_queue);
+ pop_temp_slots ();
+
/* Now restore inhibit_defer_pop to its actual original value. */
OK_DEFER_POP;
}
@@ -2390,6 +2399,8 @@ emit_library_call_value (va_alist)
count = 0;
+ push_temp_slots ();
+
/* If there's a structure value address to be passed,
either pass it in the special place, or pass it as an extra argument. */
if (mem_value && struct_value_rtx == 0 && ! pcc_struct_value)
@@ -2456,14 +2467,19 @@ emit_library_call_value (va_alist)
&& ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
val = force_operand (val, NULL_RTX);
- argvec[count].value = val;
- argvec[count].mode = mode;
-
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
- abort ();
+ {
+ rtx slot = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
+ emit_move_insn (slot, val);
+ val = XEXP (slot, 0);
+ mode = Pmode;
+ }
#endif
+ argvec[count].value = val;
+ argvec[count].mode = mode;
+
argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
if (argvec[count].reg && GET_CODE (argvec[count].reg) == EXPR_LIST)
abort ();
@@ -2651,6 +2667,8 @@ emit_library_call_value (va_alist)
/* Now restore inhibit_defer_pop to its actual original value. */
OK_DEFER_POP;
+ pop_temp_slots ();
+
/* Copy the value to the right place. */
if (outmode != VOIDmode)
{