This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: bit shifting CQImode values
On Mon, Jul 21, 2003 at 10:36:39PM +0930, Alan Modra wrote:
> This hunk of code I added to calls.c around line 1646 is buggy.
>
> #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);
> }
>
> The problem being that expand_binop doesn't handle the case when "mem"
> is something like (mem/s:CQI (reg/f:DI 118) [0 g1sScc1+0 S2 A8]). I
> guess it's not reasonable to expect expand_binop to do what I want here,
> and that I need to somehow "flatten" the mem to HImode. Either that,
> or load the mem to a CQI reg then change the reg mode. What's the
> right way to do this?
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?
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 13:36:17 -0000
@@ -1652,7 +1652,8 @@ load_register_parameters (struct arg_dat
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,
+ emit_move_insn (reg, mem);
+ x = expand_binop (word_mode, ashl_optab, ri,
GEN_INT (shift), ri, 1, OPTAB_WIDEN);
if (x != ri)
emit_move_insn (ri, x);
--
Alan Modra
IBM OzLabs - Linux Technology Centre