diff options
author | Alan Modra <amodra@bigpond.net.au> | 2003-07-30 07:30:16 +0000 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2003-07-30 17:00:16 +0930 |
commit | 9206d7362fa9bff2b451bbd92ff906483e46af0e (patch) | |
tree | a5308a80fda752a31d80baba06c127666631c6b0 | |
parent | 9074464c14b99872a7ce360c883c1b0dc20c75be (diff) | |
download | gcc-9206d7362fa9bff2b451bbd92ff906483e46af0e.zip gcc-9206d7362fa9bff2b451bbd92ff906483e46af0e.tar.gz gcc-9206d7362fa9bff2b451bbd92ff906483e46af0e.tar.bz2 |
calls.c (load_register_parameters): When shifting reg sized values to the msb, move the value to a reg first.
* calls.c (load_register_parameters): When shifting reg sized values
to the msb, move the value to a reg first.
From-SVN: r69953
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/calls.c | 43 |
2 files changed, 26 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4bc73f3..7a856a8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2003-07-30 Alan Modra <amodra@bigpond.net.au> + + * calls.c (load_register_parameters): When shifting reg sized values + to the msb, move the value to a reg first. + 2003-07-29 Geoffrey Keating <geoffk@apple.com> * cppfiles.c (stack_file): Leave filename as "" rather than "<stdin>". diff --git a/gcc/calls.c b/gcc/calls.c index 135b333..26937c3 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1622,14 +1622,27 @@ load_register_parameters (struct arg_data *args, int num_actuals, has already loaded the register for us. In all other cases, load the register(s) from memory. */ - else if (nregs == -1 + else if (nregs == -1) + { + emit_move_insn (reg, args[i].value); #ifdef BLOCK_REG_PADDING - && !(size < UNITS_PER_WORD - && (args[i].locate.where_pad - == (BYTES_BIG_ENDIAN ? upward : downward))) + /* Handle case where we have a value that needs shifting + up to the msb. eg. a QImode value and we're padding + upward on a BYTES_BIG_ENDIAN machine. */ + if (size < UNITS_PER_WORD + && (args[i].locate.where_pad + == (BYTES_BIG_ENDIAN ? upward : downward))) + { + rtx ri = gen_rtx_REG (word_mode, REGNO (reg)); + rtx x; + int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT; + x = expand_binop (word_mode, ashl_optab, ri, + GEN_INT (shift), ri, 1, OPTAB_WIDEN); + if (x != ri) + emit_move_insn (ri, x); + } #endif - ) - emit_move_insn (reg, args[i].value); + } /* If we have pre-computed the values to put in the registers in the case of non-aligned structures, copy them in now. */ @@ -1644,23 +1657,9 @@ load_register_parameters (struct arg_data *args, int num_actuals, rtx mem = validize_mem (args[i].value); #ifdef BLOCK_REG_PADDING - /* Handle case where we have a value that needs shifting - up to the msb. eg. a QImode value and we're padding - upward on a BYTES_BIG_ENDIAN machine. */ - if (nregs == -1) - { - rtx ri = gen_rtx_REG (word_mode, REGNO (reg)); - rtx x; - int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT; - x = expand_binop (word_mode, ashl_optab, mem, - GEN_INT (shift), ri, 1, OPTAB_WIDEN); - if (x != ri) - emit_move_insn (ri, x); - } - /* Handle a BLKmode that needs shifting. */ - else if (nregs == 1 && size < UNITS_PER_WORD - && args[i].locate.where_pad == downward) + if (nregs == 1 && size < UNITS_PER_WORD + && args[i].locate.where_pad == downward) { rtx tem = operand_subword_force (mem, 0, args[i].mode); rtx ri = gen_rtx_REG (word_mode, REGNO (reg)); |