aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2003-07-30 07:30:16 +0000
committerAlan Modra <amodra@gcc.gnu.org>2003-07-30 17:00:16 +0930
commit9206d7362fa9bff2b451bbd92ff906483e46af0e (patch)
treea5308a80fda752a31d80baba06c127666631c6b0
parent9074464c14b99872a7ce360c883c1b0dc20c75be (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/calls.c43
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));