This is the mail archive of the gcc-patches@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: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


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