diff options
author | Fariborz Jahanian <fjahanian@gcc.gnu.org> | 2003-11-14 20:05:34 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@gcc.gnu.org> | 2003-11-14 20:05:34 +0000 |
commit | 5985c7a6f98e57ae61caca014aa668966f29f135 (patch) | |
tree | b3715676311e7295d9559424ffeda2afa4d54a77 | |
parent | e6d98cb0a1ac15cb463b0711a2177ef7de1f5941 (diff) | |
download | gcc-5985c7a6f98e57ae61caca014aa668966f29f135.zip gcc-5985c7a6f98e57ae61caca014aa668966f29f135.tar.gz gcc-5985c7a6f98e57ae61caca014aa668966f29f135.tar.bz2 |
Fix bug saving vararg registers on stack in -mpowerpc64 mode.
Approved by: David Edelsohn.
From-SVN: r73616
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5ca7842..0b2c3bd 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -395,6 +395,7 @@ static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree); static rtx rs6000_mixed_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); +static void rs6000_move_block_from_reg(int regno, rtx x, int nregs); static void setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); @@ -4374,6 +4375,37 @@ function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, } return type && int_size_in_bytes (type) < 0; } + +static void +rs6000_move_block_from_reg(int regno, rtx x, int nregs) +{ + int i; + enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode; + + if (nregs == 0) + return; + + for (i = 0; i < nregs; i++) + { + rtx tem = adjust_address_nv (x, reg_mode, i*GET_MODE_SIZE(reg_mode)); + if (reload_completed) + { + if (! strict_memory_address_p (reg_mode, XEXP (tem, 0))) + tem = NULL_RTX; + else + tem = simplify_gen_subreg (reg_mode, x, BLKmode, + i * GET_MODE_SIZE(reg_mode)); + } + else + tem = replace_equiv_address (tem, XEXP (tem, 0)); + + if (tem == NULL_RTX) + abort (); + + emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i)); + } +} + /* Perform any needed actions needed for a function that is receiving a variable number of arguments. @@ -4431,8 +4463,8 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, set_mem_alias_set (mem, set); set_mem_align (mem, BITS_PER_WORD); - move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem, - GP_ARG_NUM_REG - first_reg_offset); + rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem, + GP_ARG_NUM_REG - first_reg_offset); } /* Save FP registers if needed. */ |