diff -rcN gcc-3.0.2-original/gcc/config/h8300/h8300-protos.h gcc-3.0.2/gcc/config/h8300/h8300-protos.h
*** gcc-3.0.2-original/gcc/config/h8300/h8300-protos.h	Thu Sep  7 18:24:33 2000
--- gcc-3.0.2/gcc/config/h8300/h8300-protos.h	Mon Oct 29 20:31:42 2001
***************
*** 37,42 ****
--- 37,43 ----
  extern void final_prescan_insn PARAMS ((rtx, rtx *, int));
  extern int do_movsi PARAMS ((rtx[]));
  extern void notice_update_cc PARAMS ((rtx, rtx));
+ extern const char *output_logical_op PARAMS ((enum machine_mode, int, rtx *));
  extern int expand_a_shift PARAMS ((enum machine_mode, int, rtx[]));
  extern int expand_a_rotate PARAMS ((int, rtx[]));
  extern int fix_bit_operand PARAMS ((rtx *, int, enum rtx_code));
diff -rcN gcc-3.0.2-original/gcc/config/h8300/h8300.c gcc-3.0.2/gcc/config/h8300/h8300.c
*** gcc-3.0.2-original/gcc/config/h8300/h8300.c	Thu Aug 30 14:06:05 2001
--- gcc-3.0.2/gcc/config/h8300/h8300.c	Mon Oct 29 20:31:50 2001
***************
*** 465,471 ****
  {
    fprintf (file, ";\tGCC For the Hitachi H8/300\n");
    fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
-   fprintf (file, ";\trelease F-1\n");
    if (optimize)
      fprintf (file, "; -O%d\n", optimize);
    if (TARGET_H8300H)
--- 465,470 ----
***************
*** 712,720 ****
       rtx op;
       enum machine_mode mode;
  {
!   /* We can except any general operand, expept that MEM operands must
!      be limited to those that use addresses valid for the 'U' constraint.  */
!   if (!general_operand (op, mode))
      return 0;
  
    /* Accept any mem during RTL generation.  Otherwise, the code that does
--- 711,727 ----
       rtx op;
       enum machine_mode mode;
  {
!   int save_volatile_ok = volatile_ok;
!   int gen_op;
! 
!   /* We can except any general operand, including volatile one, expept
!      that MEM operands must be limited to those that use addresses
!      valid for the 'U' constraint.  */
!   volatile_ok = 1;
!   gen_op = general_operand (op, mode);
!   volatile_ok = save_volatile_ok;
! 
!   if (!gen_op)
      return 0;
  
    /* Accept any mem during RTL generation.  Otherwise, the code that does
***************
*** 1572,1577 ****
--- 1579,1728 ----
  	  || code == IOR);
  }
  
+ const char *
+ output_logical_op (mode, code, operands)
+      enum machine_mode mode;
+      int code;
+      rtx *operands;
+ {
+   /* Pretend that every byte is affected if both operands are registers.  */
+   unsigned HOST_WIDE_INT intval =
+     (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
+ 			      ? INTVAL (operands[2]) : 0x55555555);
+   /* The determinant of the algorithm.  If we perform an AND, 0
+      affects a bit.  Otherwise, 1 affects a bit.  */
+   unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
+   /* The name of an insn.  */
+   const char *opname;
+   char insn_buf[100];
+ 
+   switch (code)
+     {
+     case AND:
+       opname = "and";
+       break;
+     case IOR:
+       opname = "or";
+       break;
+     case XOR:
+       opname = "xor";
+       break;
+     default:
+       abort ();
+     }
+ 
+   switch (mode)
+     {
+     case HImode:
+       /* First, see if we can finish with one insn.  */
+       if ((TARGET_H8300H || TARGET_H8300S)
+ 	  && ((det & 0x00ff) != 0)
+ 	  && ((det & 0xff00) != 0))
+ 	{
+ 	  sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
+ 	  output_asm_insn (insn_buf, operands);
+ 	}
+       else
+ 	{
+ 	  /* Take care of the lower byte.  */
+ 	  if ((det & 0x00ff) != 0)
+ 	    {
+ 	      sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
+ 	      output_asm_insn (insn_buf, operands);
+ 	    }
+ 	  /* Take care of the upper byte.  */
+ 	  if ((det & 0xff00) != 0)
+ 	    {
+ 	      sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
+ 	      output_asm_insn (insn_buf, operands);
+ 	    }
+ 	}
+       break;
+     case SImode:
+       /* First, see if we can finish with one insn.
+ 
+ 	 If code is either AND or XOR, we exclude two special cases,
+ 	 0xffffff00 and 0xffff00ff, because insns like sub.w or neg.w
+ 	 can do a better job.  */
+       if ((TARGET_H8300H || TARGET_H8300S)
+ 	  && ((det & 0x0000ffff) != 0)
+ 	  && ((det & 0xffff0000) != 0)
+ 	  && (code == IOR || det != 0xffffff00)
+ 	  && (code == IOR || det != 0xffff00ff))
+ 	{
+ 	  sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
+ 	  output_asm_insn (insn_buf, operands);
+ 	}
+       else
+ 	{
+ 	  /* Take care of the lower and upper words individually.  For
+ 	     each word, we try different methods in the order of
+ 
+ 	     1) the special insn (in case of AND or XOR),
+ 	     2) the word-wise insn, and
+ 	     3) The byte-wise insn.  */
+ 	  if ((TARGET_H8300H || TARGET_H8300S)
+ 	      && ((det & 0x0000ffff) == 0x0000ffff)
+ 	      && code != IOR)
+ 	    output_asm_insn ((code == AND)
+ 			     ? "sub.w\t%f0,%f0" : "neg.w\t%f0",
+ 			     operands);
+ 	  else if ((TARGET_H8300H || TARGET_H8300S)
+ 		   && ((det & 0x000000ff) != 0)
+ 		   && ((det & 0x0000ff00) != 0))
+ 	    {
+ 	      sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
+ 	      output_asm_insn (insn_buf, operands);
+ 	    }
+ 	  else
+ 	    {
+ 	      if ((det & 0x000000ff) != 0)
+ 		{
+ 		  sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
+ 		  output_asm_insn (insn_buf, operands);
+ 		}
+ 	      if ((det & 0x0000ff00) != 0)
+ 		{
+ 		  sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
+ 		  output_asm_insn (insn_buf, operands);
+ 		}
+ 	    }
+ 
+ 	  if ((TARGET_H8300H || TARGET_H8300S)
+ 	      && ((det & 0xffff0000) == 0xffff0000)
+ 	      && code != IOR)
+ 	    output_asm_insn ((code == AND)
+ 			     ? "sub.w\t%e0,%e0" : "neg.w\t%e0",
+ 			     operands);
+ 	  else if (TARGET_H8300H || TARGET_H8300S)
+ 	    {
+ 	      if ((det & 0xffff0000) != 0)
+ 		{
+ 		  sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
+ 		  output_asm_insn (insn_buf, operands);
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      if ((det & 0x00ff0000) != 0)
+ 		{
+ 		  sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
+ 		  output_asm_insn (insn_buf, operands);
+ 		}
+ 	      if ((det & 0xff000000) != 0)
+ 		{
+ 		  sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
+ 		  output_asm_insn (insn_buf, operands);
+ 		}
+ 	    }
+ 	}
+       break;
+     default:
+       abort ();
+     }
+   return "";
+ }
+ 
  /* Shifts.
  
     We devote a fair bit of code to getting efficient shifts since we can only
***************
*** 1971,1976 ****
--- 2122,2263 ----
      }
  };
  
+ /* Macros to keep the shift algorithm tables small.  */
+ #define INL SHIFT_INLINE
+ #define ROT SHIFT_ROT_AND
+ #define LOP SHIFT_LOOP
+ #define SPC SHIFT_SPECIAL
+ 
+ /* The shift algorithms for each machine, mode, shift type, and shift
+    count are defined below.  The three tables below correspond to
+    QImode, HImode, and SImode, respectively.  Each table is organized
+    by, in the order of indecies, machine, shift type, and shift count.  */
+ 
+ static const enum shift_alg shift_alg_qi[3][3][8] = {
+   {
+     /* TARGET_H8300  */
+     /* 0    1    2    3    4    5    6    7  */
+     { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, INL, INL, LOP, LOP, SPC }  /* SHIFT_ASHIFTRT */
+   },
+   {
+     /* TARGET_H8300H  */
+     /* 0    1    2    3    4    5    6    7  */
+     { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, INL, INL, LOP, LOP, SPC }  /* SHIFT_ASHIFTRT */
+   },
+   {
+     /* TARGET_H8300S  */
+     /*  0    1    2    3    4    5    6    7  */
+     { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, INL, INL, INL, INL, SPC }  /* SHIFT_ASHIFTRT */
+   }
+ };
+ 
+ static const enum shift_alg shift_alg_hi[3][3][16] = {
+   {
+     /* TARGET_H8300  */
+     /*  0    1    2    3    4    5    6    7  */
+     /*  8    9   10   11   12   13   14   15  */
+     { INL, INL, INL, INL, INL, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, INL, INL, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, INL, INL, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+   },
+   {
+     /* TARGET_H8300H  */
+     /*  0    1    2    3    4    5    6    7  */
+     /*  8    9   10   11   12   13   14   15  */
+     { INL, INL, INL, INL, INL, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, INL, INL, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, INL, INL, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+   },
+   {
+     /* TARGET_H8300S  */
+     /*  0    1    2    3    4    5    6    7  */
+     /*  8    9   10   11   12   13   14   15  */
+     { INL, INL, INL, INL, INL, INL, INL, INL,
+       SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, INL, INL, INL, INL, INL,
+       SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, INL, INL, INL, INL, INL,
+       SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+   }
+ };
+ 
+ static const enum shift_alg shift_alg_si[3][3][32] = {
+   {
+     /* TARGET_H8300  */
+     /*  0    1    2    3    4    5    6    7  */
+     /*  8    9   10   11   12   13   14   15  */
+     /* 16   17   18   19   20   21   22   23  */
+     /* 24   25   26   27   28   29   30   31  */
+     { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
+       LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
+       LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
+       LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+   },
+   {
+     /* TARGET_H8300H  */
+     /*  0    1    2    3    4    5    6    7  */
+     /*  8    9   10   11   12   13   14   15  */
+     /* 16   17   18   19   20   21   22   23  */
+     /* 24   25   26   27   28   29   30   31  */
+     { INL, INL, INL, INL, INL, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, INL, INL, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, INL, INL, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
+       SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
+       SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+   },
+   {
+     /* TARGET_H8300S  */
+     /*  0    1    2    3    4    5    6    7  */
+     /*  8    9   10   11   12   13   14   15  */
+     /* 16   17   18   19   20   21   22   23  */
+     /* 24   25   26   27   28   29   30   31  */
+     { INL, INL, INL, INL, INL, INL, INL, INL,
+       INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
+       SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT   */
+     { INL, INL, INL, INL, INL, INL, INL, INL,
+       INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
+       SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
+       SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
+     { INL, INL, INL, INL, INL, INL, INL, INL,
+       INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
+       SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
+       SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+   }
+ };
+ 
+ #undef INL
+ #undef ROT
+ #undef LOP
+ #undef SPC
+ 
  struct shift_info {
    /* Shift algorithm.  */
    enum shift_alg alg;
***************
*** 1994,2002 ****
    int cc_valid_p;
  };
  
! static enum shift_alg get_shift_alg PARAMS ((enum shift_type,
! 					     enum shift_mode, int,
! 					     struct shift_info *));
  
  /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
     best algorithm for doing the shift.  The assembler code is stored
--- 2281,2289 ----
    int cc_valid_p;
  };
  
! static void get_shift_alg PARAMS ((enum shift_type,
! 				   enum shift_mode, int,
! 				   struct shift_info *));
  
  /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
     best algorithm for doing the shift.  The assembler code is stored
***************
*** 2011,2281 ****
     WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
     1,2,3,4 will be inlined (1,2 for SI).  */
  
! static enum shift_alg
  get_shift_alg (shift_type, shift_mode, count, info)
       enum shift_type shift_type;
       enum shift_mode shift_mode;
       int count;
       struct shift_info *info;
  {
!   /* Assume either SHIFT_LOOP or SHIFT_INLINE.
!      It is up to the caller to know that looping clobbers cc.  */
!   info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
!   if (TARGET_H8300S)
!     info->shift2 = shift_two[shift_type][shift_mode].assembler;
!   else
!     info->shift2 = NULL;
!   info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
  
!   /* Now look for cases we want to optimize.  */
  
    switch (shift_mode)
      {
      case QIshift:
!       if (count <= 4)
! 	return SHIFT_INLINE;
        else
! 	{
! 	  /* Shift by 5/6 are only 3 insns on the H8/S, so it's just as
! 	     fast as SHIFT_ROT_AND, plus CC is valid.  */
! 	  if (TARGET_H8300S && count <= 6)
! 	    return SHIFT_INLINE;
! 
! 	  /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
! 	     through the entire value.  */
! 	  if (shift_type == SHIFT_ASHIFTRT && count == 7)
! 	    {
! 	      info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 
! 	  /* Other ASHIFTRTs are too much of a pain.  */
! 	  if (shift_type == SHIFT_ASHIFTRT)
! 	    return SHIFT_LOOP;
! 
! 	  /* Other shifts by 5, 6, or 7 bits use SHIFT_ROT_AND.  */
! 	  info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
! 	  if (TARGET_H8300S)
! 	    info->shift2 = rotate_two[shift_type][shift_mode];
! 	  info->cc_valid_p = 0;
! 	  return SHIFT_ROT_AND;
! 	}
  
      case HIshift:
!       if (count <= 4)
! 	return SHIFT_INLINE;
!       else if (TARGET_H8300S && count <= 7)
! 	return SHIFT_INLINE;
!       else if (count == 7)
! 	{
! 	  if (shift_type == SHIFT_ASHIFT && TARGET_H8300)
! 	    {
! 	      info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.b\t%t0\n\trotr.b\t%s0\n\tand.b\t#0x80,%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
  
! 	  if (shift_type == SHIFT_ASHIFT && TARGET_H8300H)
! 	    {
! 	      info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
  
! 	  if (shift_type == SHIFT_LSHIFTRT && TARGET_H8300)
! 	    {
! 	      info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\trotl.b\t%t0\n\tand.b\t#0x01,%t0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
  
! 	  if (shift_type == SHIFT_LSHIFTRT && TARGET_H8300H)
! 	    {
! 	      info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
  
! 	  if (shift_type == SHIFT_ASHIFTRT)
! 	    {
! 	      info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 	}
!       else if (count == 8)
  	{
! 	  switch (shift_type)
! 	    {
! 	    case SHIFT_ASHIFT:
! 	      info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_LSHIFTRT:
! 	      info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_ASHIFTRT:
! 	      if (TARGET_H8300)
! 		info->special = "mov.b\t%t0,%s0\n\tshll\t%t0\n\tsubx\t%t0,%t0";
! 	      else
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
  	}
!       else if (count == 9)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
- 	      info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0";
- 	      info->cc_valid_p = 0;
- 	      return SHIFT_SPECIAL;
- 	    case SHIFT_LSHIFTRT:
- 	      info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0";
- 	      info->cc_valid_p = 0;
- 	      return SHIFT_SPECIAL;
- 	    case SHIFT_ASHIFTRT:
  	      if (TARGET_H8300)
! 		info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0";
  	      else
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 	}
!       else if (count == 10)
! 	{
! 	  switch (shift_type)
! 	    {
! 	    case SHIFT_ASHIFT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0";
! 	      else
! 		info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_LSHIFTRT:
- 	      if (TARGET_H8300S)
- 		info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0";
- 	      else
- 		info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
- 	      info->cc_valid_p = 0;
- 	      return SHIFT_SPECIAL;
- 	    case SHIFT_ASHIFTRT:
  	      if (TARGET_H8300)
! 		info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0";
! 	      else if (TARGET_H8300H)
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0";
! 	      else if (TARGET_H8300S)
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 	}
!       else if (count == 11)
! 	{
! 	  switch (shift_type)
! 	    {
! 	    case SHIFT_ASHIFT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t%t0";
! 	      else
! 		info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_LSHIFTRT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t%s0";
  	      else
! 		info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_ASHIFTRT:
! 	      if (TARGET_H8300)
! 		info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
! 	      else if (TARGET_H8300H)
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
! 	      else if (TARGET_H8300S)
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    }
  	}
!       else if (count == 12)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t#2,%t0";
! 	      else
! 		info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_LSHIFTRT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t#2,%s0";
! 	      else
! 		info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_ASHIFTRT:
  	      if (TARGET_H8300)
! 		info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
! 	      else if (TARGET_H8300H)
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
! 	      else if (TARGET_H8300S)
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t#2,%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    }
  	}
!       else if ((!TARGET_H8300 && (count == 13 || count == 14))
! 	       || count == 15)
  	{
! 	  if (count == 15 && shift_type == SHIFT_ASHIFTRT)
! 	    {
! 	      info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 	  else if (shift_type != SHIFT_ASHIFTRT)
! 	    {
! 	      info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
! 	      if (TARGET_H8300S)
! 	        info->shift2 = rotate_two[shift_type][shift_mode];
! 	      else
! 		info->shift2 = NULL;
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_ROT_AND;
! 	    }
  	}
!       break;
  
      case SIshift:
!       if (count <= (TARGET_H8300 ? 2 : 4))
! 	return SHIFT_INLINE;
!       else if (TARGET_H8300S && count <= 10)
! 	return SHIFT_INLINE;
!       else if (count == 8 && TARGET_H8300)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
  	      info->special = "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_LSHIFTRT:
  	      info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_ASHIFTRT:
  	      info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    }
  	}
        else if (count == 8 && !TARGET_H8300)
--- 2298,2459 ----
     WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
     1,2,3,4 will be inlined (1,2 for SI).  */
  
! static void
  get_shift_alg (shift_type, shift_mode, count, info)
       enum shift_type shift_type;
       enum shift_mode shift_mode;
       int count;
       struct shift_info *info;
  {
!   int cpu;
  
!   /* Find the target CPU.  */
!   if (TARGET_H8300)
!     cpu = 0;
!   else if (TARGET_H8300H)
!     cpu = 1;
!   else
!     cpu = 2;
  
+   /* Find the shift algorithm.  */
    switch (shift_mode)
      {
      case QIshift:
!       if (GET_MODE_BITSIZE (QImode) <= count)
! 	info->alg = SHIFT_LOOP;
        else
! 	info->alg = shift_alg_qi[cpu][shift_type][count];
!       break;
  
      case HIshift:
!       if (GET_MODE_BITSIZE (HImode) <= count)
! 	info->alg = SHIFT_LOOP;
!       else
! 	info->alg = shift_alg_hi[cpu][shift_type][count];
!       break;
  
!     case SIshift:
!       if (GET_MODE_BITSIZE (SImode) <= count)
! 	info->alg = SHIFT_LOOP;
!       else
! 	info->alg = shift_alg_si[cpu][shift_type][count];
!       break;
  
!     default:
!       abort ();
!     }
  
!   /* Fill in INFO.  Return unless we have SHIFT_SPECIAL.  */
!   switch (info->alg)
!     {
!     case SHIFT_INLINE:
!       info->remainder = count;
!       /* Fall through.  */
!       
!     case SHIFT_LOOP:
!       /* It is up to the caller to know that looping clobbers cc.  */
!       info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
!       info->shift2 = shift_two[shift_type][shift_mode].assembler;
!       info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
!       goto end;
! 
!     case SHIFT_ROT_AND:
!       info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
!       info->shift2 = rotate_two[shift_type][shift_mode];
!       info->cc_valid_p = 0;
!       goto end;
! 
!     case SHIFT_SPECIAL:
!       /* REMAINDER is 0 for most cases, so initialize it to 0.  */
!       info->remainder = 0;
!       info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
!       info->shift2 = shift_two[shift_type][shift_mode].assembler;
!       info->cc_valid_p = 0;
!       break;
!     }
  
!   /* Here we only deal with SHIFT_SPECIAL.  */
!   switch (shift_mode)
!     {
!     case QIshift:
!       /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
! 	 through the entire value.  */
!       if (shift_type == SHIFT_ASHIFTRT && count == 7)
  	{
! 	  info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
! 	  goto end;
  	}
!       abort ();
! 
!     case HIshift:
!       if (count == 7)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
  	      if (TARGET_H8300)
! 		info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.b\t%t0\n\trotr.b\t%s0\n\tand.b\t#0x80,%s0";
  	      else
! 		info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
! 	      goto end;
  	    case SHIFT_LSHIFTRT:
  	      if (TARGET_H8300)
! 		info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\trotl.b\t%t0\n\tand.b\t#0x01,%t0";
  	      else
! 		info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
! 	      goto end;
  	    case SHIFT_ASHIFTRT:
! 	      info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
! 	      goto end;
  	    }
  	}
!       else if (8 <= count && count <= 12)
  	{
+ 	  info->remainder = count - 8;
+ 
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
! 	      info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
! 	      info->shift1  = "shal.b\t%t0";
! 	      info->shift2  = "shal.b\t#2,%t0";
! 	      goto end;
  	    case SHIFT_LSHIFTRT:
! 	      info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
! 	      info->shift1  = "shlr.b\t%s0";
! 	      info->shift2  = "shlr.b\t#2,%s0";
! 	      goto end;
  	    case SHIFT_ASHIFTRT:
  	      if (TARGET_H8300)
! 		info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
! 	      else
! 		info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
! 	      info->shift1 = "shar.b\t%s0";
! 	      info->shift2 = "shar.b\t#2,%s0";
! 	      goto end;
  	    }
  	}
!       else if (count == 15 && shift_type == SHIFT_ASHIFTRT)
  	{
! 	  info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
! 	  goto end;
  	}
!       abort ();
  
      case SIshift:
!       if (count == 8 && TARGET_H8300)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
  	      info->special = "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0";
! 	      goto end;
  	    case SHIFT_LSHIFTRT:
  	      info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0";
! 	      goto end;
  	    case SHIFT_ASHIFTRT:
  	      info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0";
! 	      goto end;
  	    }
  	}
        else if (count == 8 && !TARGET_H8300)
***************
*** 2284,2489 ****
  	    {
  	    case SHIFT_ASHIFT:
  	      info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_LSHIFTRT:
  	      info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_ASHIFTRT:
  	      info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 	}
!       else if (count == 16)
! 	{
! 	  switch (shift_type)
! 	    {
! 	    case SHIFT_ASHIFT:
! 	      info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_LSHIFTRT:
! 	      info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_ASHIFTRT:
! 	      if (TARGET_H8300)
! 		info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
! 	      else
! 		info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 	}
!       else if (count == 17 && !TARGET_H8300)
! 	{
! 	  switch (shift_type)
! 	    {
! 	    case SHIFT_ASHIFT:
! 	      info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_LSHIFTRT:
! 	      info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_ASHIFTRT:
! 	      info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    }
  	}
!       else if (count == 18 && !TARGET_H8300)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0";
! 	      else
! 		info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_LSHIFTRT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0";
! 	      else
! 		info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_ASHIFTRT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0";
! 	      else
! 		info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    }
  	}
!       else if (count == 19 && !TARGET_H8300)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t%S0";
! 	      else
! 		info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0\n\tshll.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_LSHIFTRT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t%S0";
! 	      else
! 		info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_ASHIFTRT:
! 	      if (TARGET_H8300S)
! 		info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t%S0";
  	      else
! 		info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 	}
!       else if (count == 20 && TARGET_H8300S)
! 	{
! 	  switch (shift_type)
! 	    {
! 	    case SHIFT_ASHIFT:
! 	      info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t#2,%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_LSHIFTRT:
! 	      info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t#2,%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    case SHIFT_ASHIFTRT:
! 	      info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t#2,%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    }
  	}
!       else if (count == 24 && !TARGET_H8300)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
  	      info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_LSHIFTRT:
  	      info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    case SHIFT_ASHIFTRT:
  	      info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
! 	    }
! 	}
!       else if (count >= 28 && count <= 30 && !TARGET_H8300)
! 	{
! 	  if (shift_type == SHIFT_ASHIFTRT)
! 	    {
! 	      return SHIFT_LOOP;
! 	    }
! 	  else
! 	    {
! 	      info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
! 	      if (TARGET_H8300S)
! 		info->shift2 = rotate_two[shift_type][shift_mode];
! 	      else
! 		info->shift2 = NULL;
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_ROT_AND;
  	    }
  	}
        else if (count == 31)
  	{
! 	  if (shift_type == SHIFT_ASHIFTRT)
  	    {
! 	      if (TARGET_H8300)
! 		info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
! 	      else
! 		info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
! 	      info->cc_valid_p = 0;
! 	      return SHIFT_SPECIAL;
  	    }
  	  else
  	    {
! 	      if (TARGET_H8300)
  		{
! 		  if (shift_type == SHIFT_ASHIFT)
! 		    info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
! 		  else
! 		    info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
! 		  info->cc_valid_p = 0;
! 		  return SHIFT_SPECIAL;
! 		}
! 	      else
! 		{
! 		  info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
! 		  if (TARGET_H8300S)
! 		    info->shift2 = rotate_two[shift_type][shift_mode];
! 		  else
! 		    info->shift2 = NULL;
! 		  info->cc_valid_p = 0;
! 		  return SHIFT_ROT_AND;
  		}
  	    }
  	}
-       break;
- 
-     default:
        abort ();
      }
  
!   /* No fancy method is available.  Just loop.  */
!   return SHIFT_LOOP;
  }
  
  /* Emit the assembler code for doing shifts.  */
--- 2462,2577 ----
  	    {
  	    case SHIFT_ASHIFT:
  	      info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0";
! 	      goto end;
  	    case SHIFT_LSHIFTRT:
  	      info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0";
! 	      goto end;
  	    case SHIFT_ASHIFTRT:
  	      info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0";
! 	      goto end;
  	    }
  	}
!       else if (count == 15 && !TARGET_H8300)
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
! 	      info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
! 	      goto end;
  	    case SHIFT_LSHIFTRT:
! 	      info->special = "shll.w\t%e0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
! 	      goto end;
  	    }
  	}
!       else if ((TARGET_H8300 && count == 16)
! 	       || (TARGET_H8300H && 16 <= count && count <= 19)
! 	       || (TARGET_H8300S && 16 <= count && count <= 21))
  	{
+ 	  info->remainder = count - 16;
+ 
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
! 	      info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
! 	      info->shift1  = "shll.l\t%S0";
! 	      info->shift2  = "shll.l\t#2,%S0";
! 	      goto end;
  	    case SHIFT_LSHIFTRT:
! 	      info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
! 	      info->shift1  = "shlr.l\t%S0";
! 	      info->shift2  = "shlr.l\t#2,%S0";
! 	      goto end;
  	    case SHIFT_ASHIFTRT:
! 	      if (TARGET_H8300)
! 		info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
  	      else
! 		info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
! 	      info->shift1 = "shar.l\t%S0";
! 	      info->shift2 = "shar.l\t#2,%S0";
! 	      goto end;
  	    }
  	}
!       else if ((TARGET_H8300H && count == 24)
! 	       || (TARGET_H8300S && 24 <= count && count <= 25))
  	{
  	  switch (shift_type)
  	    {
  	    case SHIFT_ASHIFT:
  	      info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
! 	      info->shift1  = "shll.l\t%S0";
! 	      info->shift2  = "shll.l\t#2,%S0";
! 	      goto end;
  	    case SHIFT_LSHIFTRT:
  	      info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
! 	      info->shift1  = "shlr.l\t%S0";
! 	      info->shift2  = "shlr.l\t#2,%S0";
! 	      goto end;
  	    case SHIFT_ASHIFTRT:
  	      info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
! 	      info->shift1 = "shar.l\t%S0";
! 	      info->shift2 = "shar.l\t#2,%S0";
! 	      goto end;
  	    }
  	}
        else if (count == 31)
  	{
! 	  if (TARGET_H8300)
  	    {
! 	      switch (shift_type)
! 		{
! 		case SHIFT_ASHIFT:
! 		  info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
! 		  goto end;
! 		case SHIFT_LSHIFTRT:
! 		  info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
! 		  goto end;
! 		case SHIFT_ASHIFTRT:
! 		  info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
! 		  goto end;
! 		}
  	    }
  	  else
  	    {
! 	      switch (shift_type)
  		{
! 		case SHIFT_ASHIFT:
! 		  info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
! 		  goto end;
! 		case SHIFT_LSHIFTRT:
! 		  info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
! 		  goto end;
! 		case SHIFT_ASHIFTRT:
! 		  info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
! 		  goto end;
  		}
  	    }
  	}
        abort ();
      }
  
!  end:
!   if (!TARGET_H8300S)
!     info->shift2 = NULL;
  }
  
  /* Emit the assembler code for doing shifts.  */
***************
*** 2553,2559 ****
    else
      {
        int n = INTVAL (operands[2]);
-       enum shift_alg alg;
  
        /* If the count is negative, make it 0.  */
        if (n < 0)
--- 2641,2646 ----
***************
*** 2564,2587 ****
        else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
  	n = GET_MODE_BITSIZE (mode);
  
!       alg = get_shift_alg (shift_type, shift_mode, n, &info);
  
!       switch (alg)
  	{
  	case SHIFT_INLINE:
  	  /* Emit two bit shifts first.  */
! 	  while (n > 1 && info.shift2 != NULL)
  	    {
! 	      output_asm_insn (info.shift2, operands);
! 	      n -= 2;
  	    }
  
  	  /* Now emit one bit shifts for any residual.  */
! 	  while (n > 0)
! 	    {
! 	      output_asm_insn (info.shift1, operands);
! 	      n -= 1;
! 	    }
  
  	  /* Keep track of CC.  */
  	  if (info.cc_valid_p)
--- 2651,2677 ----
        else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
  	n = GET_MODE_BITSIZE (mode);
  
!       get_shift_alg (shift_type, shift_mode, n, &info);
  
!       switch (info.alg)
  	{
+ 	case SHIFT_SPECIAL:
+ 	  output_asm_insn (info.special, operands);
+ 	  /* Fall through.  */
+ 
  	case SHIFT_INLINE:
+ 	  n = info.remainder;
+ 
  	  /* Emit two bit shifts first.  */
! 	  if (info.shift2 != NULL)
  	    {
! 	      for (; n >= 2; n -= 2)
! 		output_asm_insn (info.shift2, operands);
  	    }
  
  	  /* Now emit one bit shifts for any residual.  */
! 	  for (; n >= 1; n--)
! 	    output_asm_insn (info.shift1, operands);
  
  	  /* Keep track of CC.  */
  	  if (info.cc_valid_p)
***************
*** 2599,2622 ****
  			: (1 << (GET_MODE_BITSIZE (mode) - n)) - 1);
  	    char insn_buf[200];
  
! 	    /* Not all possibilities of rotate are supported.  They shouldn't
! 	       be generated, but let's watch for 'em.  */
  	    if (info.shift1 == 0)
  	      abort ();
  
! 	    /* Emit two bit rotates first.  */
! 	    while (m > 1 && info.shift2 != NULL)
  	      {
! 		output_asm_insn (info.shift2, operands);
! 		m -= 2;
  	      }
  
! 	    /* Now single bit rotates for any residual.  */
! 	    while (m > 0)
! 	      {
! 		output_asm_insn (info.shift1, operands);
! 		m -= 1;
! 	      }
  
  	    /* Now mask off the high bits.  */
  	    if (TARGET_H8300)
--- 2689,2709 ----
  			: (1 << (GET_MODE_BITSIZE (mode) - n)) - 1);
  	    char insn_buf[200];
  
! 	    /* Not all possibilities of rotate are supported.  They
! 	       shouldn't be generated, but let's watch for them.  */
  	    if (info.shift1 == 0)
  	      abort ();
  
! 	    /* Emit two-bit rotates if available.  */
! 	    if (info.shift2 != NULL)
  	      {
! 		for (; m >= 2; m -= 2)
! 		  output_asm_insn (info.shift2, operands);
  	      }
  
! 	    /* Now emit one-bit rotates for any residue.  */
! 	    for (; m >= 1; m--)
! 	      output_asm_insn (info.shift1, operands);
  
  	    /* Now mask off the high bits.  */
  	    if (TARGET_H8300)
***************
*** 2650,2659 ****
  	    return "";
  	  }
  
- 	case SHIFT_SPECIAL:
- 	  output_asm_insn (info.special, operands);
- 	  return "";
- 
  	case SHIFT_LOOP:
  	  /* A loop to shift by a "large" constant value.
  	     If we have shift-by-2 insns, use them.  */
--- 2737,2742 ----
***************
*** 3042,3052 ****
    if (is_attribute_p ("eightbit_data", attr)
        && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
      {
-       if (DECL_INITIAL (decl) == NULL_TREE)
- 	{
- 	  warning ("Only initialized variables can be placed into the 8-bit area.");
- 	  return 0;
- 	}
        DECL_SECTION_NAME (decl) = build_string (7, ".eight");
        return 1;
      }
--- 3125,3130 ----
***************
*** 3054,3064 ****
    if (is_attribute_p ("tiny_data", attr)
        && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
      {
-       if (DECL_INITIAL (decl) == NULL_TREE)
- 	{
- 	  warning ("Only initialized variables can be placed into the 8-bit area.");
- 	  return 0;
- 	}
        DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
        return 1;
      }
--- 3132,3137 ----
***************
*** 3072,3084 ****
  {
    const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
    int len = strlen (str);
!   char *newstr;
  
!   newstr = ggc_alloc_string (NULL, len + 1);
  
!   strcpy (newstr + 1, str);
!   *newstr = '&';
!   XSTR (XEXP (DECL_RTL (decl), 0), 0) = newstr;
  }
  
  const char *
--- 3145,3157 ----
  {
    const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
    int len = strlen (str);
!   char *newstr = alloca (len + 2);
  
!   newstr[0] = '&';
!   strcpy (&newstr[1], str);
  
!   XSTR (XEXP (DECL_RTL (decl), 0), 0) =
!     ggc_alloc_string (newstr, len + 1);
  }
  
  const char *
diff -rcN gcc-3.0.2-original/gcc/config/h8300/h8300.md gcc-3.0.2/gcc/config/h8300/h8300.md
*** gcc-3.0.2-original/gcc/config/h8300/h8300.md	Wed Aug 29 12:22:51 2001
--- gcc-3.0.2/gcc/config/h8300/h8300.md	Mon Oct 29 20:31:47 2001
***************
*** 445,456 ****
  	      return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\";
  	    }
  
! 	  /* Now look for small negative numbers.  We can subtract them
! 	     from zero to get the desired constant.  */
! 	  if (val == -4 || val == -2 || val == -1)
  	    {
! 	      operands[1] = GEN_INT (-INTVAL (operands[1]));
! 	      return \"sub.l\\t%S0,%S0\;subs\\t%1,%S0\";
  	    }
  	}
      }
--- 445,475 ----
  	      return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\";
  	    }
  
! 	  /* Look for constants that can be obtained by subs, inc, and
!              dec to 0.  */
! 	  switch (val & 0xffffffff)
  	    {
! 	    case 0xffffffff:
! 	      return \"sub.l\\t%S0,%S0\;subs\\t#1,%S0\";
! 	    case 0xfffffffe:
! 	      return \"sub.l\\t%S0,%S0\;subs\\t#2,%S0\";
! 	    case 0xfffffffc:
! 	      return \"sub.l\\t%S0,%S0\;subs\\t#4,%S0\";
! 
! 	    case 0x0000ffff:
! 	      return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%f0\";
! 	    case 0x0000fffe:
! 	      return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%f0\";
! 
! 	    case 0xffff0000:
! 	      return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%e0\";
! 	    case 0xfffe0000:
! 	      return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%e0\";
! 
! 	    case 0x00010000:
! 	      return \"sub.l\\t%S0,%S0\;inc.w\\t#1,%e0\";
! 	    case 0x00020000:
! 	      return \"sub.l\\t%S0,%S0\;inc.w\\t#2,%e0\";
  	    }
  	}
      }
***************
*** 480,510 ****
  ;; ----------------------------------------------------------------------
  
  (define_insn ""
!   [(set (cc0) (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "rU")
  			       (const_int 1)
! 			       (match_operand:QI 1 "const_int_operand" "n")))]
    ""
    "btst	%Z1,%R0"
!   [(set_attr "length" "2")
!    (set_attr "cc" "set_zn")])
  
  (define_insn ""
!   [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "rU")
  			       (const_int 1)
! 			       (match_operand:QI 1 "const_int_operand" "n")))]
    ""
    "btst	%Z1,%Y0"
!   [(set_attr "length" "2")
!    (set_attr "cc" "set_zn")])
  
  (define_insn ""
!   [(set (cc0) (zero_extract:SI (match_operand:QI 0 "bit_memory_operand" "rU")
  			       (const_int 1)
! 			       (match_operand:QI 1 "const_int_operand" "n")))]
    ""
    "btst	%Z1,%Y0"
!   [(set_attr "length" "2")
!    (set_attr "cc" "set_zn")])
  
  (define_insn ""
    [(set (cc0) (zero_extract:QI (match_operand:HI 0 "register_operand" "r")
--- 499,529 ----
  ;; ----------------------------------------------------------------------
  
  (define_insn ""
!   [(set (cc0) (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "r,U")
  			       (const_int 1)
! 			       (match_operand:QI 1 "const_int_operand" "n,n")))]
    ""
    "btst	%Z1,%R0"
!   [(set_attr "length" "2,8")
!    (set_attr "cc" "set_zn,set_zn")])
  
  (define_insn ""
!   [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "r,U")
  			       (const_int 1)
! 			       (match_operand:QI 1 "const_int_operand" "n,n")))]
    ""
    "btst	%Z1,%Y0"
!   [(set_attr "length" "2,8")
!    (set_attr "cc" "set_zn,set_zn")])
  
  (define_insn ""
!   [(set (cc0) (zero_extract:SI (match_operand:QI 0 "bit_memory_operand" "r,U")
  			       (const_int 1)
! 			       (match_operand:QI 1 "const_int_operand" "n,n")))]
    ""
    "btst	%Z1,%Y0"
!   [(set_attr "length" "2,8")
!    (set_attr "cc" "set_zn,set_zn")])
  
  (define_insn ""
    [(set (cc0) (zero_extract:QI (match_operand:HI 0 "register_operand" "r")
***************
*** 953,959 ****
    "@
     and	%X2,%X0
     bclr	%W2,%R0"
!   [(set_attr "length" "2,4")
     (set_attr "adjust_length" "no")
     (set_attr "cc" "set_znv,none_0hit")])
  
--- 972,978 ----
    "@
     and	%X2,%X0
     bclr	%W2,%R0"
!   [(set_attr "length" "2,8")
     (set_attr "adjust_length" "no")
     (set_attr "cc" "set_znv,none_0hit")])
  
***************
*** 968,1050 ****
      DONE;
  }")
  
! (define_insn "andhi3"
    [(set (match_operand:HI 0 "register_operand" "=r")
  	(and:HI (match_operand:HI 1 "register_operand" "%0")
  		(match_operand:HI 2 "nonmemory_operand" "rn")))]
    ""
    "*
  {
!   if (GET_CODE (operands[2]) == CONST_INT)
      {
!       int i = INTVAL (operands[2]);
! 
!       if ((i & 0x00ff) != 0x00ff)
! 	output_asm_insn (\"and	%s2,%s0\", operands);
!       if ((i & 0xff00) != 0xff00)
! 	output_asm_insn (\"and	%t2,%t0\", operands);
!       return \"\";
      }
!   if (TARGET_H8300H || TARGET_H8300S)
!     return \"and.w	%T2,%T0\";
!   return \"and	%s2,%s0\;and	%t2,%t0;\";
  }"
    [(set_attr "length" "4")
     (set_attr "cc" "clobber")])
  
! (define_insn "andsi3"
    [(set (match_operand:SI 0 "register_operand" "=r")
  	(and:SI (match_operand:SI 1 "register_operand" "%0")
  		(match_operand:SI 2 "nonmemory_operand" "rn")))]
!   ""
!   "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       int i = INTVAL (operands[2]);
!       int upper_cleared, lower_cleared;
! 
!       /* The h8300h can't do byte-wise operations on the
! 	 upper 16bits of 32bit registers.  However, if
! 	 those bits aren't going to change, or they're
! 	 going to be zero'd out, then we can work on the
! 	 low-order bits.  */
!       if ((TARGET_H8300H || TARGET_H8300S)
! 	  && ((i & 0xffff0000) != 0xffff0000
! 	      || (i & 0xffff0000) == 0x00000000))
!         return \"and.l	%S2,%S0\";
! 
!       lower_cleared = 0;
!       if ((i & 0x0000ffff) == 0x00000000)
! 	{
! 	  output_asm_insn (\"sub.w	%f0,%f0\", operands);
! 	  lower_cleared = 1;
! 	}
! 
!       upper_cleared = 0;
!       if ((i & 0xffff0000) == 0x00000000)
! 	{
! 	  output_asm_insn (\"sub.w	%e0,%e0\", operands);
! 	  upper_cleared = 1;
! 	}
! 
!       if ((i & 0x000000ff) != 0x000000ff && !lower_cleared)
! 	output_asm_insn (\"and	%w2,%w0\", operands);
!       if ((i & 0x0000ff00) != 0x0000ff00 && !lower_cleared)
! 	output_asm_insn (\"and	%x2,%x0\", operands);
!       if ((i & 0x00ff0000) != 0x00ff0000 && !upper_cleared)
! 	output_asm_insn (\"and	%y2,%y0\", operands);
!       if ((i & 0xff000000) != 0xff000000 && !upper_cleared)
! 	output_asm_insn (\"and	%z2,%z0\", operands);
!       return \"\";
!     }
!   if (TARGET_H8300H || TARGET_H8300S)
!     return \"and.l	%S2,%S0\";
!   return \"and	%w2,%w0\;and	%x2,%x0\;and	%y2,%y0\;and	%z2,%z0\";
! }"
    [(set_attr "length" "8")
     (set_attr "cc" "clobber")])
  
  
  ;; ----------------------------------------------------------------------
  ;; OR INSTRUCTIONS
--- 987,1059 ----
      DONE;
  }")
  
! (define_expand "andhi3"
!   [(set (match_operand:HI 0 "register_operand" "")
! 	(and:HI (match_operand:HI 1 "register_operand" "")
! 		(match_operand:HI 2 "nonmemory_operand" "")))]
!   ""
!   "")
! 
! (define_insn ""
    [(set (match_operand:HI 0 "register_operand" "=r")
  	(and:HI (match_operand:HI 1 "register_operand" "%0")
  		(match_operand:HI 2 "nonmemory_operand" "rn")))]
+   "TARGET_H8300"
+   "* return output_logical_op (HImode, AND, operands);"
+   [(set_attr "length" "4")
+    (set_attr "cc" "clobber")])
+ 
+ (define_insn ""
+   [(set (match_operand:HI 0 "register_operand" "=r,r")
+ 	(and:HI (match_operand:HI 1 "register_operand" "%0,0")
+ 		(match_operand:HI 2 "nonmemory_operand" "r,n")))]
+   "TARGET_H8300H || TARGET_H8300S"
+   "* return output_logical_op (HImode, AND, operands);"
+   [(set_attr "length" "2,4")
+    (set_attr "cc" "set_znv,clobber")])
+ 
+ (define_insn "*andorhi3"
+   [(set (match_operand:HI 0 "register_operand" "=r")
+ 	(ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
+ 			(match_operand:HI 3 "p_operand" "P"))
+ 	(match_operand:HI 1 "register_operand" "0")))]
    ""
    "*
  {
!   if (INTVAL (operands[3]) > 128)
      {
!       operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
!       return \"bld\\t%V3,%t2\;bst\\t%V3,%t0\";
      }
!   return \"bld\\t%V3,%s2\;bst\\t%V3,%s0\";
  }"
    [(set_attr "length" "4")
     (set_attr "cc" "clobber")])
  
! (define_expand "andsi3"
!   [(set (match_operand:SI 0 "register_operand" "")
! 	(and:SI (match_operand:SI 1 "register_operand" "")
! 		(match_operand:SI 2 "nonmemory_operand" "")))]
!   ""
!   "")
! 
! (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=r")
  	(and:SI (match_operand:SI 1 "register_operand" "%0")
  		(match_operand:SI 2 "nonmemory_operand" "rn")))]
!   "TARGET_H8300"
!   "* return output_logical_op (SImode, AND, operands);"
    [(set_attr "length" "8")
     (set_attr "cc" "clobber")])
  
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r,r")
+ 	(and:SI (match_operand:SI 1 "register_operand" "%0,0")
+ 		(match_operand:SI 2 "nonmemory_operand" "r,n")))]
+   "TARGET_H8300H || TARGET_H8300S"
+   "* return output_logical_op (SImode, AND, operands);"
+   [(set_attr "length" "4,6")
+    (set_attr "cc" "set_znv,clobber")])
  
  ;; ----------------------------------------------------------------------
  ;; OR INSTRUCTIONS
***************
*** 1058,1064 ****
    "@
     or	%X2,%X0
     bset	%V2,%R0"
!   [(set_attr "length" "2,4")
     (set_attr "adjust_length" "no")
     (set_attr "cc" "set_znv,none_0hit")])
  
--- 1067,1073 ----
    "@
     or	%X2,%X0
     bset	%V2,%R0"
!   [(set_attr "length" "2,8")
     (set_attr "adjust_length" "no")
     (set_attr "cc" "set_znv,none_0hit")])
  
***************
*** 1073,1138 ****
      DONE;
  }")
  
! (define_insn "iorhi3"
    [(set (match_operand:HI 0 "general_operand" "=r,r")
  	(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
  		(match_operand:HI 2 "general_operand" "J,rn")))]
    ""
!   "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       int i = INTVAL (operands[2]);
  
!       if ((i & 0x00ff) != 0)
! 	output_asm_insn (\"or	%s2,%s0\", operands);
!       if ((i & 0xff00) != 0)
! 	output_asm_insn (\"or	%t2,%t0\", operands);
!       return \"\";
!     }
!   if (TARGET_H8300H || TARGET_H8300S)
!     return \"or.w	%T2,%T0\";
!   return \"or	%s2,%s0\;or	%t2,%t0; %2 or2\";
! }"
    [(set_attr "length" "2,4")
     (set_attr "cc" "clobber,clobber")])
  
! (define_insn "iorsi3"
    [(set (match_operand:SI 0 "register_operand" "=r,r")
  	(ior:SI (match_operand:SI 1 "register_operand" "%0,0")
  		(match_operand:SI 2 "nonmemory_operand" "J,rn")))]
!   ""
!   "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       int i = INTVAL (operands[2]);
! 
!       /* The h8300h can't do byte-wise operations on the
! 	 upper 16bits of 32bit registers.  However, if
! 	 those bits aren't going to change, then we can
! 	 work on the low-order bits.  */
!       if ((TARGET_H8300H || TARGET_H8300S)
! 	  && (i & 0xffff0000) != 0x00000000)
!         return \"or.l	%S2,%S0\";
! 
!       if ((i & 0x000000ff) != 0)
! 	output_asm_insn (\"or	%w2,%w0\", operands);
!       if ((i & 0x0000ff00) != 0)
! 	output_asm_insn (\"or	%x2,%x0\", operands);
!       if ((i & 0x00ff0000) != 0)
! 	output_asm_insn (\"or	%y2,%y0\", operands);
!       if ((i & 0xff000000) != 0)
! 	output_asm_insn (\"or	%z2,%z0\", operands);
!       return \"\";
!     }
!   if (TARGET_H8300H || TARGET_H8300S)
!     return \"or.l	%S2,%S0\";
!   return \"or	%w2,%w0\;or	%x2,%x0\;or	%y2,%y0\;or	%z2,%z0\";
! }"
    [(set_attr "length" "2,8")
     (set_attr "cc" "clobber,clobber")])
  
  ;; ----------------------------------------------------------------------
  ;; XOR INSTRUCTIONS
  ;; ----------------------------------------------------------------------
--- 1082,1137 ----
      DONE;
  }")
  
! (define_expand "iorhi3"
    [(set (match_operand:HI 0 "general_operand" "=r,r")
  	(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
  		(match_operand:HI 2 "general_operand" "J,rn")))]
    ""
!   "")
  
! (define_insn ""
!   [(set (match_operand:HI 0 "general_operand" "=r,r")
! 	(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
! 		(match_operand:HI 2 "general_operand" "J,rn")))]
!   "TARGET_H8300"
!   "* return output_logical_op (HImode, IOR, operands);"
    [(set_attr "length" "2,4")
     (set_attr "cc" "clobber,clobber")])
  
! (define_insn ""
!   [(set (match_operand:HI 0 "general_operand" "=r,r,r")
! 	(ior:HI (match_operand:HI 1 "general_operand" "%0,0,0")
! 		(match_operand:HI 2 "general_operand" "J,r,n")))]
!   "TARGET_H8300H || TARGET_H8300S"
!   "* return output_logical_op (HImode, IOR, operands);"
!   [(set_attr "length" "2,2,4")
!    (set_attr "cc" "clobber,set_znv,clobber")])
! 
! (define_expand "iorsi3"
!   [(set (match_operand:SI 0 "register_operand" "")
! 	(ior:SI (match_operand:SI 1 "register_operand" "")
! 		(match_operand:SI 2 "nonmemory_operand" "")))]
!   ""
!   "")
! 
! (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=r,r")
  	(ior:SI (match_operand:SI 1 "register_operand" "%0,0")
  		(match_operand:SI 2 "nonmemory_operand" "J,rn")))]
!   "TARGET_H8300"
!   "* return output_logical_op (SImode, IOR, operands);"
    [(set_attr "length" "2,8")
     (set_attr "cc" "clobber,clobber")])
  
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ 	(ior:SI (match_operand:SI 1 "register_operand" "%0,0,0")
+ 		(match_operand:SI 2 "nonmemory_operand" "J,r,n")))]
+   "TARGET_H8300H || TARGET_H8300S"
+   "* return output_logical_op (SImode, IOR, operands);"
+   [(set_attr "length" "2,4,6")
+    (set_attr "cc" "clobber,set_znv,clobber")])
+ 
  ;; ----------------------------------------------------------------------
  ;; XOR INSTRUCTIONS
  ;; ----------------------------------------------------------------------
***************
*** 1145,1151 ****
    "@
     xor	%X2,%X0
     bnot	%V2,%R0"
!   [(set_attr "length" "2,4")
     (set_attr "adjust_length" "no")
     (set_attr "cc" "set_znv,none_0hit")])
  
--- 1144,1150 ----
    "@
     xor	%X2,%X0
     bnot	%V2,%R0"
!   [(set_attr "length" "2,8")
     (set_attr "adjust_length" "no")
     (set_attr "cc" "set_znv,none_0hit")])
  
***************
*** 1160,1224 ****
      DONE;
  }")
  
! (define_insn "xorhi3"
    [(set (match_operand:HI 0 "register_operand" "=r,r")
  	(xor:HI (match_operand:HI 1 "general_operand" "%0,0")
  		(match_operand:HI 2 "nonmemory_operand" "J,rn")))]
!   ""
!   "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       int i = INTVAL (operands[2]);
! 
!       if ((i & 0x00ff) != 0)
! 	output_asm_insn (\"xor	%s2,%s0\", operands);
!       if ((i & 0xff00) != 0)
! 	output_asm_insn (\"xor	%t2,%t0\", operands);
!       return \"\";
!     }
!   if (TARGET_H8300H || TARGET_H8300S)
!     return \"xor.w	%T2,%T0\";
!   return \"xor	%s2,%s0\;xor	%t2,%t0\";
! }"
    [(set_attr "length" "2,4")
     (set_attr "cc" "clobber,clobber")])
  
! (define_insn "xorsi3"
    [(set (match_operand:SI 0 "register_operand" "=r,r")
  	(xor:SI (match_operand:SI 1 "register_operand" "%0,0")
  		(match_operand:SI 2 "nonmemory_operand" "J,rn")))]
!   ""
!   "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       int i = INTVAL (operands[2]);
! 
!       /* The h8300h can't do byte-wise operations on the
! 	 upper 16bits of 32bit registers.  However, if
! 	 those bits aren't going to change, then we can
! 	 work on the low-order bits.  */
!       if ((TARGET_H8300H || TARGET_H8300S)
! 	  && (i & 0xffff0000) != 0x00000000)
!         return \"xor.l	%S2,%S0\";
! 
!       if ((i & 0x000000ff) != 0)
! 	output_asm_insn (\"xor	%w2,%w0\", operands);
!       if ((i & 0x0000ff00) != 0)
! 	output_asm_insn (\"xor	%x2,%x0\", operands);
!       if ((i & 0x00ff0000) != 0)
! 	output_asm_insn (\"xor	%y2,%y0\", operands);
!       if ((i & 0xff000000) != 0)
! 	output_asm_insn (\"xor	%z2,%z0\", operands);
!       return \"\";
!     }
!   if (TARGET_H8300H || TARGET_H8300S)
!     return \"xor.l	%S2,%S0\";
!   return \"xor	%w2,%w0\;xor	%x2,%x0\;xor	%y2,%y0\;xor	%z2,%z0\";
! }"
    [(set_attr "length" "2,8")
     (set_attr "cc" "clobber,clobber")])
  
  ;; ----------------------------------------------------------------------
  ;; NEGATION INSTRUCTIONS
--- 1159,1213 ----
      DONE;
  }")
  
! (define_expand "xorhi3"
!   [(set (match_operand:HI 0 "register_operand" "")
! 	(xor:HI (match_operand:HI 1 "general_operand" "")
! 		(match_operand:HI 2 "nonmemory_operand" "")))]
!   ""
!   "")
! 
! (define_insn ""
    [(set (match_operand:HI 0 "register_operand" "=r,r")
  	(xor:HI (match_operand:HI 1 "general_operand" "%0,0")
  		(match_operand:HI 2 "nonmemory_operand" "J,rn")))]
!   "TARGET_H8300"
!   "* return output_logical_op (HImode, XOR, operands);"
    [(set_attr "length" "2,4")
     (set_attr "cc" "clobber,clobber")])
  
! (define_insn ""
!   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
! 	(xor:HI (match_operand:HI 1 "general_operand" "%0,0,0")
! 		(match_operand:HI 2 "nonmemory_operand" "J,r,n")))]
!   "TARGET_H8300H || TARGET_H8300S"
!   "* return output_logical_op (HImode, XOR, operands);"
!   [(set_attr "length" "2,2,4")
!    (set_attr "cc" "clobber,set_znv,clobber")])
! 
! (define_expand "xorsi3"
!   [(set (match_operand:SI 0 "register_operand" "")
! 	(xor:SI (match_operand:SI 1 "register_operand" "")
! 		(match_operand:SI 2 "nonmemory_operand" "")))]
!   ""
!   "")
! 
! (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=r,r")
  	(xor:SI (match_operand:SI 1 "register_operand" "%0,0")
  		(match_operand:SI 2 "nonmemory_operand" "J,rn")))]
!   "TARGET_H8300"
!   "* return output_logical_op (SImode, XOR, operands);"
    [(set_attr "length" "2,8")
     (set_attr "cc" "clobber,clobber")])
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ 	(xor:SI (match_operand:SI 1 "register_operand" "%0,0,0")
+ 		(match_operand:SI 2 "nonmemory_operand" "J,r,n")))]
+   "TARGET_H8300H || TARGET_H8300S"
+   "* return output_logical_op (SImode, XOR, operands);"
+   [(set_attr "length" "2,4,6")
+    (set_attr "cc" "clobber,set_znv,clobber")])
  
  ;; ----------------------------------------------------------------------
  ;; NEGATION INSTRUCTIONS
***************
*** 1614,1629 ****
  ;; EXTEND INSTRUCTIONS
  ;; ----------------------------------------------------------------------
  
! (define_insn "zero_extendqihi2"
    [(set (match_operand:HI 0 "register_operand" "=r,r")
  	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
!   ""
    "@
    mov.b	#0,%t0
    mov.b	%R1,%s0\;mov.b	#0,%t0"
    [(set_attr "length" "2,10")
     (set_attr "cc" "clobber,clobber")])
  
  ;; The compiler can synthesize a 300H variant of this which is
  ;; just as efficient as one that we'd create
  (define_insn "zero_extendqisi2"
--- 1603,1634 ----
  ;; EXTEND INSTRUCTIONS
  ;; ----------------------------------------------------------------------
  
! (define_expand "zero_extendqihi2"
!   [(set (match_operand:HI 0 "register_operand" "")
! 	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
!   ""
!   "")
! 
! (define_insn ""
    [(set (match_operand:HI 0 "register_operand" "=r,r")
  	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
!   "TARGET_H8300"
    "@
    mov.b	#0,%t0
    mov.b	%R1,%s0\;mov.b	#0,%t0"
    [(set_attr "length" "2,10")
     (set_attr "cc" "clobber,clobber")])
  
+ (define_insn ""
+   [(set (match_operand:HI 0 "register_operand" "=r,r")
+ 	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
+   "TARGET_H8300H || TARGET_H8300S"
+   "@
+   extu.w	%T0
+   mov.b	%R1,%s0\;extu.w	%T0"
+   [(set_attr "length" "2,10")
+    (set_attr "cc" "set_znv,set_znv")])
+ 
  ;; The compiler can synthesize a 300H variant of this which is
  ;; just as efficient as one that we'd create
  (define_insn "zero_extendqisi2"
***************
*** 2226,2228 ****
--- 2231,2322 ----
    [(set_attr "cc" "clobber")
     (set_attr "length" "6")
     (set_attr "adjust_length" "no")])
+ 
+ ;; -----------------------------------------------------------------
+ ;; COMBINE PATTERNS
+ ;; -----------------------------------------------------------------
+ 
+ (define_insn ""
+   [(set (match_operand:HI 0 "register_operand" "=r")
+         (ior:HI
+            (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
+            (match_operand:HI 2 "register_operand" "0")))]
+   "REGNO (operands[0]) != REGNO (operands[1])"
+   "or\\t%X1,%s0"
+   [(set_attr "cc" "clobber")
+    (set_attr "length" "2")])
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+         (ior:SI
+            (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
+            (match_operand:SI 2 "register_operand" "0")))]
+   "(TARGET_H8300H || TARGET_H8300S)
+     && (REGNO (operands[0]) != REGNO (operands[1]))"
+   "or.w\\t%T1,%f0"
+   [(set_attr "cc" "clobber")
+    (set_attr "length" "2")])
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+         (ior:SI
+            (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
+            (match_operand:SI 2 "register_operand" "0")))]
+   "REGNO (operands[0]) != REGNO (operands[1])"
+   "or\\t%X1,%s0"
+   [(set_attr "cc" "clobber")
+    (set_attr "length" "2")])
+ 
+ (define_insn ""
+   [(set (match_operand:HI 0 "register_operand" "=r")
+         (xor:HI
+            (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
+            (match_operand:HI 2 "register_operand" "0")))]
+   "REGNO (operands[0]) != REGNO (operands[1])"
+   "xor\\t%X1,%s0"
+   [(set_attr "cc" "clobber")
+    (set_attr "length" "2")])
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+         (xor:SI
+            (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
+            (match_operand:SI 2 "register_operand" "0")))]
+   "(TARGET_H8300H || TARGET_H8300S)
+     && (REGNO (operands[0]) != REGNO (operands[1]))"
+   "xor.w\\t%T1,%f0"
+   [(set_attr "cc" "clobber")
+    (set_attr "length" "2")])
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+         (xor:SI
+            (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
+            (match_operand:SI 2 "register_operand" "0")))]
+   "REGNO (operands[0]) != REGNO (operands[1])"
+   "xor\\t%X1,%s0"
+   [(set_attr "cc" "clobber")
+    (set_attr "length" "2")])
+ 
+ (define_insn ""
+   [(set (match_operand:HI 0 "register_operand" "=r")
+         (ior:HI
+            (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
+            (ashift:HI (match_operand:HI 2 "register_operand" "r")
+                       (const_int 8))))]
+   "REGNO (operands[0]) != REGNO (operands[2])"
+   "mov.b\\t%s2,%t0"
+   [(set_attr "cc" "clobber")
+    (set_attr "length" "2")])
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+         (ior:SI
+            (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
+            (ashift:SI (match_operand:SI 2 "register_operand" "r")
+                       (const_int 16))))]
+   "(TARGET_H8300H || TARGET_H8300S)
+     && (REGNO (operands[0]) != REGNO (operands[2]))"
+   "mov.w\\t%f2,%e0"
+   [(set_attr "cc" "clobber")
+    (set_attr "length" "2")])
diff -rcN gcc-3.0.2-original/gcc/expr.c gcc-3.0.2/gcc/expr.c
*** gcc-3.0.2-original/gcc/expr.c	Fri Sep 21 21:33:19 2001
--- gcc-3.0.2/gcc/expr.c	Mon Oct 29 20:31:12 2001
***************
*** 2900,2906 ****
  	 X with a reference to the stack pointer.  */
        if (push_operand (x, GET_MODE (x)))
  	{
! 	  anti_adjust_stack (GEN_INT (GET_MODE_SIZE (GET_MODE (x))));
  	  x = change_address (x, VOIDmode, stack_pointer_rtx);
  	}
  #endif
--- 2900,2923 ----
  	 X with a reference to the stack pointer.  */
        if (push_operand (x, GET_MODE (x)))
  	{
!           /* Do not use anti_adjust_stack, since we don't want to update
!              stack_pointer_delta.  */
! 	  rtx temp = expand_binop (Pmode,
! #ifdef STACK_GROWS_DOWNWARD
! 				   sub_optab,
! #else
! 				   add_optab,
! #endif
! 				   stack_pointer_rtx,
! 				   GEN_INT
! 				   (PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)))),
! 				   stack_pointer_rtx,
! 				   0,
! 				   OPTAB_LIB_WIDEN);
! 
! 	  if (temp != stack_pointer_rtx)
! 	    emit_move_insn (stack_pointer_rtx, temp);
! 
  	  x = change_address (x, VOIDmode, stack_pointer_rtx);
  	}
  #endif
diff -rcN gcc-3.0.2-original/gcc/flow.c gcc-3.0.2/gcc/flow.c
*** gcc-3.0.2-original/gcc/flow.c	Fri Sep  7 19:28:52 2001
--- gcc-3.0.2/gcc/flow.c	Mon Oct 29 20:31:16 2001
***************
*** 5961,5969 ****
    if (y != 0
        && SET_DEST (x) != stack_pointer_rtx
        && BLOCK_NUM (y) == BLOCK_NUM (insn)
!       /* Don't do this if the reg dies, or gets set in y; a standard addressing
! 	 mode would be better.  */
!       && ! dead_or_set_p (y, SET_DEST (x))
        && try_pre_increment (y, SET_DEST (x), amount))
      {
        /* We have found a suitable auto-increment and already changed
--- 5961,5970 ----
    if (y != 0
        && SET_DEST (x) != stack_pointer_rtx
        && BLOCK_NUM (y) == BLOCK_NUM (insn)
!       /* We cannot use pre-increment if y clobbers the register REGNO.
!          We can still consider a register that is not used after y,
!          hoping pre-increment is faster than indexed addressing.  */
!       && ! reg_set_p (SET_DEST (x), y)
        && try_pre_increment (y, SET_DEST (x), amount))
      {
        /* We have found a suitable auto-increment and already changed
