diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1996-06-06 16:02:02 -0700 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1996-06-06 16:02:02 -0700 |
commit | cacbd53270c2cd3f67d1e3c72ad0f7b5bf5ba124 (patch) | |
tree | 10117a9a4a756e68b55a4cab604d13428c5066b5 /gcc | |
parent | 1853aadde2b24bc529a21a3fbe2b0acb2ba4dde1 (diff) | |
download | gcc-cacbd53270c2cd3f67d1e3c72ad0f7b5bf5ba124.zip gcc-cacbd53270c2cd3f67d1e3c72ad0f7b5bf5ba124.tar.gz gcc-cacbd53270c2cd3f67d1e3c72ad0f7b5bf5ba124.tar.bz2 |
(expand_call): Handle NIL in PARALLEL.
(expand_call): Handle NIL in PARALLEL. Handle PARALLEL
parameter in REG. Handle PARALLEL return value in VALREG.
(emit_library_call, emit_library_call_value): Abort for PARALLEL.
(store_one_arg): Delete code for handling EXPR_LIST.
From-SVN: r12188
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/calls.c | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index 7f18a8f..191e948 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -60,7 +60,7 @@ struct arg_data /* Initially-compute RTL value for argument; only for const functions. */ rtx initial_value; /* Register to pass this argument in, 0 if passed on stack, or an - EXPR_LIST if the arg is to be copied into multiple different + PARALLEL if the arg is to be copied into multiple non-contiguous registers. */ rtx reg; /* If REG was promoted from the actual mode of the argument expression, @@ -1112,12 +1112,12 @@ expand_call (exp, target, ignore) args[i].pass_on_stack = MUST_PASS_IN_STACK (mode, type); - /* If FUNCTION_ARG returned an (expr_list (nil) FOO), it means that - we are to pass this arg in the register(s) designated by FOO, but - also to pass it in the stack. */ - if (args[i].reg && GET_CODE (args[i].reg) == EXPR_LIST - && XEXP (args[i].reg, 0) == 0) - args[i].pass_on_stack = 1, args[i].reg = XEXP (args[i].reg, 1); + /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]), + it means that we are to pass this arg in the register(s) designated + by the PARALLEL, but also to pass it in the stack. */ + if (args[i].reg && GET_CODE (args[i].reg) == PARALLEL + && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0) + args[i].pass_on_stack = 1; /* If this is an addressable type, we must preallocate the stack since we must evaluate the object into its final location. @@ -1846,20 +1846,12 @@ expand_call (exp, target, ignore) for (i = 0; i < num_actuals; i++) { - rtx list = args[i].reg; + rtx reg = args[i].reg; int partial = args[i].partial; + int nregs; - while (list) + if (reg) { - rtx reg; - int nregs; - - /* Process each register that needs to get this arg. */ - if (GET_CODE (list) == EXPR_LIST) - reg = XEXP (list, 0), list = XEXP (list, 1); - else - reg = list, list = 0; - /* Set to non-negative if must move a word at a time, even if just one word (e.g, partial == 1 && mode == DFmode). Set to -1 if we just use a normal move insn. This value can be zero if the @@ -1870,11 +1862,17 @@ expand_call (exp, target, ignore) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) : -1)); + /* Handle calls that pass values in multiple non-contiguous + locations. The Irix 6 ABI has examples of this. */ + + if (GET_CODE (reg) == PARALLEL) + emit_group_load (reg, args[i].value); + /* If simple case, just do move. If normal partial, store_one_arg has already loaded the register for us. In all other cases, load the register(s) from memory. */ - if (nregs == -1) + else if (nregs == -1) emit_move_insn (reg, args[i].value); /* If we have pre-computed the values to put in the registers in @@ -1885,19 +1883,19 @@ expand_call (exp, target, ignore) emit_move_insn (gen_rtx (REG, word_mode, REGNO (reg) + j), args[i].aligned_regs[j]); - else if (args[i].partial == 0 || args[i].pass_on_stack) + else if (partial == 0 || args[i].pass_on_stack) move_block_to_reg (REGNO (reg), validize_mem (args[i].value), nregs, args[i].mode); - if (nregs == -1) + /* Handle calls that pass values in multiple non-contiguous + locations. The Irix 6 ABI has examples of this. */ + if (GET_CODE (reg) == PARALLEL) + use_group_regs (&call_fusage, reg); + else if (nregs == -1) use_reg (&call_fusage, reg); else use_regs (&call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs); - - /* PARTIAL referred only to the first register, so clear it for the - next time. */ - partial = 0; } } @@ -2032,6 +2030,20 @@ expand_call (exp, target, ignore) If they refer to the same register, this move will be a no-op, except when function inlining is being done. */ emit_move_insn (target, valreg); + /* Handle calls that return values in multiple non-contiguous locations. + The Irix 6 ABI has examples of this. */ + else if (GET_CODE (valreg) == PARALLEL) + { + if (target == 0) + { + int bytes = int_size_in_bytes (TREE_TYPE (exp)); + target = assign_stack_temp (BLKmode, bytes, 0); + MEM_IN_STRUCT_P (target) = AGGREGATE_TYPE_P (TREE_TYPE (exp)); + preserve_temp_slots (target); + } + + emit_group_store (target, valreg); + } else if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode) { /* Some machines (the PA for example) want to return all small @@ -2326,7 +2338,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, 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) + if (argvec[count].reg && GET_CODE (argvec[count].reg) == PARALLEL) abort (); #ifdef FUNCTION_ARG_PARTIAL_NREGS argvec[count].partial @@ -2674,7 +2686,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, 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) + if (argvec[count].reg && GET_CODE (argvec[count].reg) == PARALLEL) abort (); #ifdef FUNCTION_ARG_PARTIAL_NREGS argvec[count].partial @@ -3030,12 +3042,6 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl, if (arg->n_aligned_regs != 0) reg = 0; - /* If this is being partially passed in a register, but multiple locations - are specified, we assume that the one partially used is the one that is - listed first. */ - if (reg && GET_CODE (reg) == EXPR_LIST) - reg = XEXP (reg, 0); - /* If this is being passed partially in a register, we can't evaluate it directly into its stack slot. Otherwise, we can. */ if (arg->value == 0) |