This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]