This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: bit shifting CQImode values
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: Richard Henderson <rth at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Jul 2003 10:23:07 +0930
- Subject: Re: bit shifting CQImode values
- References: <20030721130639.GQ27145@bubble.sa.bigpond.net.au><20030721134304.GR27145@bubble.sa.bigpond.net.au><20030721171805.GC17862@redhat.com>
On Mon, Jul 21, 2003 at 10:18:05AM -0700, Richard Henderson wrote:
> On Mon, Jul 21, 2003 at 11:13:04PM +0930, Alan Modra wrote:
> > Forgot to add one more detail. "mem" might not actually be a MEM. We
> > need to handle a reg too. Is this simplistic approach correct?
>
> It looks correct-ish.
It even works. The following is the patch in
http://gcc.gnu.org/ml/gcc/2003-07/msg01497.html (regression tested
powerpc64-linux with AGGREGATES_PAD_UPWARD_ALWAYS set to 1), plus moving
the code to where it really belongs (regression test in progress).
Assuming this passes the test, OK to install mainline?
* calls.c (load_register_parameters): When shifting reg sized values
to the msb, move the value to a reg first.
Index: gcc/calls.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/calls.c,v
retrieving revision 1.289
diff -u -p -r1.289 calls.c
--- gcc/calls.c 19 Jul 2003 14:47:00 -0000 1.289
+++ gcc/calls.c 21 Jul 2003 23:59:25 -0000
@@ -1622,14 +1622,27 @@ load_register_parameters (struct arg_dat
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_dat
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));
--
Alan Modra
IBM OzLabs - Linux Technology Centre