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]

avr port: various changes



Marek !
I added your patches inside my changes.

Tue May  9 20:52:43 2000  Denis Chertykov  <denisc@overta.ru>

 	* config/avr/avr-protos.h (extra_constraint): change a type of
	second argument from char to int to avoid warnings.
	(asm_output_byte): Likewise.
	
	* config/avr/avr.c (MAX_LD_OFFSET) New macro.
	(initial_elimination_offset): Handle elimination from
	FRAME_POINTER_REGNUM to STACK_POINTER_REGNUM.
	(legitimate_address_p): Use MAX_LD_OFFSET.
	(legitimize_address): Likewise.
	(out_movqi_r_mr): Likewise.
	(out_movhi_r_mr): Likewise, use `fatal_insn' instead of `fatal'.
	(out_movsi_r_mr): Use MAX_LD_OFFSET.
	(out_movsi_mr_r): Likewise.
	(out_movqi_mr_r): Likewise.
	(out_movhi_mr_r): Likewise.
	(notice_update_cc): Correct CC for the ashrqi3 with the shift
	count as CONST_INT != 6.
	(ashlqi3_out): Coding style modifications. Run `fatal_insn' if
	shift count is a CONSTANT_P, but not a CONST_INT.
	(ashlhi3_out): Coding style modifications.
	(ashlsi3_out): Likewise.
	(ashrhi3_out): Likewise.
	(ashrsi3_out): Likewise.
	(lshrhi3_out): Likewise.
	(lshrsi3_out): Likewise.
	(ashrqi3_out): Generate shift for any known constant count without
	scratch register. Run `fatal_insn' if shift count is a CONSTANT_P,
	but not a CONST_INT.
	(lshrqi3_out): Coding style modifications. Run `fatal_insn' if
	shift count is a CONSTANT_P, but not a CONST_INT. 
	(extra_constraint): change a type of
	second argument from char to int to avoid warnings.
	(asm_output_byte): Likewise.
	(asm_file_end): Output size generated commands count as a hex
	number too.

	* config/avr/avr.h (RETURN_ADDR_RTX): New macro.

	* config/avr/avr.md (addhi3): Fragment commented by &&0 is
	removed.
	(ashlqi3): Values of "length" attribute changed. Shift count
	uses constraints 'n' instead of 'i'.
	(ashrqi3): Likewise. Values of "cc" attribute changed. Generate
	shifts without clobber register.
	(lshrqi3): Shift count uses constraints 'n' instead of 'i'.
	(call_insn): Correct test for which_alternative == 1 (was 0).
	(call_value_insn): Likewise.
	
	* config/avr/t-avr: Remove definition of FLOAT while generates
	fp-bit.c
	

Index: gcc/config/avr/avr-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/avr/avr-protos.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 avr-protos.h
*** avr-protos.h	2000/05/03 19:20:09	1.2
--- avr-protos.h	2000/05/09 16:52:27
*************** extern char * lshrsi3_out     PARAMS ((r
*** 110,116 ****
  extern enum reg_class preferred_reload_class PARAMS ((rtx x,
  						     enum reg_class class));
  extern int    avr_address_cost       PARAMS ((rtx x));
! extern int    extra_constraint       PARAMS ((rtx x, char c));
  extern rtx    legitimize_address     PARAMS ((rtx x, rtx oldx,
  					     enum machine_mode mode));
  extern int    adjust_insn_length     PARAMS ((rtx insn, int len));
--- 110,116 ----
  extern enum reg_class preferred_reload_class PARAMS ((rtx x,
  						     enum reg_class class));
  extern int    avr_address_cost       PARAMS ((rtx x));
! extern int    extra_constraint       PARAMS ((rtx x, int c));
  extern rtx    legitimize_address     PARAMS ((rtx x, rtx oldx,
  					     enum machine_mode mode));
  extern int    adjust_insn_length     PARAMS ((rtx insn, int len));
*************** extern int    default_rtx_costs      PAR
*** 123,129 ****
  					     RTX_CODE outer_code));
  extern void   asm_output_char        PARAMS ((FILE *file, rtx value));
  extern void   asm_output_short       PARAMS ((FILE *file, rtx value));
! extern void   asm_output_byte        PARAMS ((FILE *file, char value));
  extern enum reg_class secondary_input_reload_class PARAMS ((enum reg_class,
  							   enum machine_mode,
  							   rtx));
--- 123,129 ----
  					     RTX_CODE outer_code));
  extern void   asm_output_char        PARAMS ((FILE *file, rtx value));
  extern void   asm_output_short       PARAMS ((FILE *file, rtx value));
! extern void   asm_output_byte        PARAMS ((FILE *file, int value));
  extern enum reg_class secondary_input_reload_class PARAMS ((enum reg_class,
  							   enum machine_mode,
  							   rtx));
Index: gcc/config/avr/avr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/avr/avr.c,v
retrieving revision 1.9
diff -c -3 -p -r1.9 avr.c
*** avr.c	2000/05/06 03:06:46	1.9
--- avr.c	2000/05/09 16:52:39
***************
*** 40,45 ****
--- 40,47 ----
  #include "recog.h"
  #include "tm_p.h"
  
+ /* Maximal allowed offset for an address in the LD command */
+ #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
  
  static int    avr_naked_function_p PARAMS ((tree));
  static int    interrupt_function_p PARAMS ((tree));
*************** interrupt_function_p (func)
*** 230,236 ****
    return a != NULL_TREE;
  }
  
! /* Return nonzero if FUNC is an signal function as specified
     by the "signal" attribute.  */
  
  static int
--- 232,238 ----
    return a != NULL_TREE;
  }
  
! /* Return nonzero if FUNC is a signal function as specified
     by the "signal" attribute.  */
  
  static int
*************** initial_elimination_offset (from,to)
*** 254,277 ****
       int to ATTRIBUTE_UNUSED;
  {
    int reg;
!   int interrupt_func_p = interrupt_function_p (current_function_decl);
!   int signal_func_p = signal_function_p (current_function_decl);
!   int leaf_func_p = leaf_function_p ();
!   int offset= frame_pointer_needed ? 2 : 0;
! 
!   for (reg = 0; reg < 32; ++reg)
      {
!       if ((!leaf_func_p && (call_used_regs[reg]
! 			    && (interrupt_func_p || signal_func_p)))
! 	  || (regs_ever_live[reg]
! 	      && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
! 	      && ! (frame_pointer_needed
! 		    && (reg == REG_Y || reg == (REG_Y+1)))))
  	{
! 	  ++offset;
  	}
      }
!   return get_frame_size () + 2 + 1 + offset;
  }
  
  /* This function checks sequence of live registers */
--- 256,285 ----
       int to ATTRIBUTE_UNUSED;
  {
    int reg;
!   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
!     return 0;
!   else
      {
!       int interrupt_func_p = interrupt_function_p (current_function_decl);
!       int signal_func_p = signal_function_p (current_function_decl);
!       int leaf_func_p = leaf_function_p ();
!       int offset= frame_pointer_needed ? 2 : 0;
! 
!       for (reg = 0; reg < 32; ++reg)
  	{
! 	  if ((!leaf_func_p && (call_used_regs[reg]
! 				&& (interrupt_func_p || signal_func_p)))
! 	      || (regs_ever_live[reg]
! 		  && (!call_used_regs[reg] || interrupt_func_p || signal_func_p)
! 		  && ! (frame_pointer_needed
! 			&& (reg == REG_Y || reg == (REG_Y+1)))))
! 	    {
! 	      ++offset;
! 	    }
  	}
+       return get_frame_size () + 2 + 1 + offset;
      }
!   return 0;
  }
  
  /* This function checks sequence of live registers */
*************** legitimate_address_p (mode, x, strict)
*** 672,678 ****
  	  && REG_P (XEXP (x, 0))
  	  && GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && INTVAL (XEXP (x, 1)) >= 0
! 	  && INTVAL (XEXP (x, 1)) <= (64 - GET_MODE_SIZE (mode))
  	  && reg_renumber
  	  )
  	fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
--- 680,686 ----
  	  && REG_P (XEXP (x, 0))
  	  && GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && INTVAL (XEXP (x, 1)) >= 0
! 	  && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
  	  && reg_renumber
  	  )
  	fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
*************** legitimate_address_p (mode, x, strict)
*** 689,695 ****
  	   && GET_CODE (XEXP (x, 1)) == CONST_INT
  	   && INTVAL (XEXP (x, 1)) >= 0)
      {
!       int fit = INTVAL (XEXP (x, 1)) <= (64 - GET_MODE_SIZE (mode));
        if (fit)
  	{
  	  if (! strict
--- 697,703 ----
  	   && GET_CODE (XEXP (x, 1)) == CONST_INT
  	   && INTVAL (XEXP (x, 1)) >= 0)
      {
!       int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
        if (fit)
  	{
  	  if (! strict
*************** legitimize_address (x, oldx, mode)
*** 741,747 ****
  	{
  	  int offs = INTVAL (XEXP (oldx,1));
  	  if (frame_pointer_rtx != XEXP (oldx,0))
! 	    if (offs > 64 - GET_MODE_SIZE (mode))
  	      {
  		if (TARGET_ALL_DEBUG)
  		  fprintf (stderr, "force_reg (big offset)\n");
--- 749,755 ----
  	{
  	  int offs = INTVAL (XEXP (oldx,1));
  	  if (frame_pointer_rtx != XEXP (oldx,0))
! 	    if (offs > MAX_LD_OFFSET (mode))
  	      {
  		if (TARGET_ALL_DEBUG)
  		  fprintf (stderr, "force_reg (big offset)\n");
*************** notice_update_cc (body, insn)
*** 938,943 ****
--- 946,953 ----
       rtx body ATTRIBUTE_UNUSED;
       rtx insn;
  {
+   rtx set;
+   
    switch (get_attr_cc (insn))
      {
      case CC_NONE:
*************** notice_update_cc (body, insn)
*** 949,992 ****
        break;
  
      case CC_SET_ZN:
!       {
! 	rtx set = single_set (insn);
! 	CC_STATUS_INIT;
! 	if (set)
! 	  {
! 	    cc_status.flags |= CC_NO_OVERFLOW;
! 	    cc_status.value1 = SET_DEST (set);
! 	  }
!       }
        break;
  
      case CC_SET_CZN:
        /* Insn sets the Z,N,C flags of CC to recog_operand[0].
           The V flag may or may not be known but that's ok because
           alter_cond will change tests to use EQ/NE.  */
!       {
! 	rtx set = single_set (insn);
! 	CC_STATUS_INIT;
! 	if (set)
! 	  {
! 	    cc_status.value1 = SET_DEST (set);
! 	    cc_status.flags |= CC_OVERFLOW_UNUSABLE;
! 	  }
!       }
        break;
  
      case CC_COMPARE:
!       {
! 	rtx set = single_set (insn);
! 	CC_STATUS_INIT;
! 	if (set)
! 	  cc_status.value1 = SET_SRC (set);
!       }
        break;
! 
      case CC_CLOBBER:
        /* Insn doesn't leave CC in a usable state.  */
        CC_STATUS_INIT;
        break;
      }
  }
--- 959,1016 ----
        break;
  
      case CC_SET_ZN:
!       set = single_set (insn);
!       CC_STATUS_INIT;
!       if (set)
! 	{
! 	  cc_status.flags |= CC_NO_OVERFLOW;
! 	  cc_status.value1 = SET_DEST (set);
! 	}
        break;
  
      case CC_SET_CZN:
        /* Insn sets the Z,N,C flags of CC to recog_operand[0].
           The V flag may or may not be known but that's ok because
           alter_cond will change tests to use EQ/NE.  */
!       set = single_set (insn);
!       CC_STATUS_INIT;
!       if (set)
! 	{
! 	  cc_status.value1 = SET_DEST (set);
! 	  cc_status.flags |= CC_OVERFLOW_UNUSABLE;
! 	}
        break;
  
      case CC_COMPARE:
!       set = single_set (insn);
!       CC_STATUS_INIT;
!       if (set)
! 	cc_status.value1 = SET_SRC (set);
        break;
!       
      case CC_CLOBBER:
        /* Insn doesn't leave CC in a usable state.  */
        CC_STATUS_INIT;
+ 
+       /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
+       set = single_set (insn);
+       if (set)
+ 	{
+ 	  rtx src = SET_SRC (set);
+ 	  
+ 	  if (GET_CODE (src) == ASHIFTRT
+ 	      && GET_MODE (src) == QImode)
+ 	    {
+ 	      rtx x = XEXP (src, 1);
+ 
+ 	      if (GET_CODE (x) == CONST_INT
+ 		  && INTVAL (x) != 6)
+ 		{
+ 		  cc_status.value1 = SET_DEST (set);
+ 		  cc_status.flags |= CC_OVERFLOW_UNUSABLE;
+ 		}
+ 	    }
+ 	}
        break;
      }
  }
*************** out_movqi_r_mr (insn, op, l)
*** 1273,1279 ****
  	      int disp = INTVAL (XEXP (x,1));
  	      if (REGNO (XEXP (x,0)) != REG_Y)
  		fatal_insn ("Incorrect insn:",insn);
! 	      if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
  		{
  		  if (l)
  		    *l = 3;
--- 1297,1303 ----
  	      int disp = INTVAL (XEXP (x,1));
  	      if (REGNO (XEXP (x,0)) != REG_Y)
  		fatal_insn ("Incorrect insn:",insn);
! 	      if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
  		{
  		  if (l)
  		    *l = 3;
*************** out_movhi_r_mr (insn, op, l)
*** 1358,1369 ****
        int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
        int reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
        
!       if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[1])))
  	{
  	  rtx x = XEXP (op[1],0);
  	  if (REGNO (XEXP (x,0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
  	    {
  	      op[4] = GEN_INT (disp - 62);
  	      return *l=4, (AS2 (adiw, r28, %4) CR_TAB
--- 1382,1393 ----
        int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
        int reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
        
!       if (disp > MAX_LD_OFFSET (GET_MODE (op[1])))
  	{
  	  rtx x = XEXP (op[1],0);
  	  if (REGNO (XEXP (x,0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
  	    {
  	      op[4] = GEN_INT (disp - 62);
  	      return *l=4, (AS2 (adiw, r28, %4) CR_TAB
*************** out_movhi_r_mr (insn, op, l)
*** 1425,1444 ****
    else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
      {
        if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
! 	{
! 	  debug_rtx (insn);
! 	  fatal ("Internal error. Incorrect insn.");
! 	}
        return *l=2, (AS2 (ld,%B0,%1) CR_TAB
  		    AS2 (ld,%A0,%1));
      }
    else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
      {
        if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
! 	{
! 	  debug_rtx (insn);
! 	  fatal ("Internal error. Incorrect insn.");
! 	}
        return *l=2, (AS2 (ld,%A0,%1)  CR_TAB
  		    AS2 (ld,%B0,%1));
      }
--- 1449,1464 ----
    else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
      {
        if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
! 	fatal_insn ("Incorrect insn:", insn);
!       
        return *l=2, (AS2 (ld,%B0,%1) CR_TAB
  		    AS2 (ld,%A0,%1));
      }
    else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
      {
        if (reg_overlap_mentioned_p (op[0], XEXP (XEXP (op[1],0),0)))
! 	fatal_insn ("Incorrect insn:", insn);
!       
        return *l=2, (AS2 (ld,%A0,%1)  CR_TAB
  		    AS2 (ld,%B0,%1));
      }
*************** out_movsi_r_mr (insn,op,l)
*** 1514,1525 ****
      {
        int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
        
!       if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[1])))
  	{
  	  rtx x = XEXP (op[1],0);
  	  if (REGNO (XEXP (x,0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[1])))
  	    {
  	      op[4] = GEN_INT (disp - 60);
  	      return *l=6,(AS2 (adiw, r28, %4) CR_TAB
--- 1534,1545 ----
      {
        int disp = INTVAL(XEXP (XEXP (op[1],0), 1));
        
!       if (disp > MAX_LD_OFFSET (GET_MODE (op[1])))
  	{
  	  rtx x = XEXP (op[1],0);
  	  if (REGNO (XEXP (x,0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[1])))
  	    {
  	      op[4] = GEN_INT (disp - 60);
  	      return *l=6,(AS2 (adiw, r28, %4) CR_TAB
*************** out_movsi_mr_r (insn,op,l)
*** 1652,1663 ****
    else if (GET_CODE (XEXP (op[0],0)) == PLUS) /* (R + i) */
      {
        int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
!       if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[0])))
  	{
  	  rtx x = XEXP (op[0],0);
  	  if (REGNO (XEXP (x,0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
  	    {
  	      op[4] = GEN_INT (disp - 60);
  	      return *l=6,(AS2 (adiw, r28, %4) CR_TAB
--- 1672,1683 ----
    else if (GET_CODE (XEXP (op[0],0)) == PLUS) /* (R + i) */
      {
        int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
!       if (disp > MAX_LD_OFFSET (GET_MODE (op[0])))
  	{
  	  rtx x = XEXP (op[0],0);
  	  if (REGNO (XEXP (x,0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
  	    {
  	      op[4] = GEN_INT (disp - 60);
  	      return *l=6,(AS2 (adiw, r28, %4) CR_TAB
*************** out_movqi_mr_r (insn, op, l)
*** 1781,1787 ****
  	      int disp = INTVAL (XEXP (x,1));
  	      if (REGNO (XEXP (x,0)) != REG_Y)
  		fatal_insn ("Incorrect insn:",insn);
! 	      if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
  		{
  		  if (l)
  		    *l = 3;
--- 1801,1807 ----
  	      int disp = INTVAL (XEXP (x,1));
  	      if (REGNO (XEXP (x,0)) != REG_Y)
  		fatal_insn ("Incorrect insn:",insn);
! 	      if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
  		{
  		  if (l)
  		    *l = 3;
*************** out_movhi_mr_r (insn,op,l)
*** 1877,1888 ****
    else if (GET_CODE (XEXP (op[0],0)) == PLUS)
      {
        int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
!       if (disp > 64 - GET_MODE_SIZE (GET_MODE (op[0])))
  	{
  	  rtx x = XEXP (op[0],0);
  	  if (REGNO (XEXP (x,0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + 64 - GET_MODE_SIZE (GET_MODE (op[0])))
  	    {
  	      op[4] = GEN_INT (disp - 62);
  	      return *l=4,(AS2 (adiw, r28, %4) CR_TAB
--- 1897,1908 ----
    else if (GET_CODE (XEXP (op[0],0)) == PLUS)
      {
        int disp = INTVAL(XEXP (XEXP (op[0],0), 1));
!       if (disp > MAX_LD_OFFSET (GET_MODE (op[0])))
  	{
  	  rtx x = XEXP (op[0],0);
  	  if (REGNO (XEXP (x,0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (op[0])))
  	    {
  	      op[4] = GEN_INT (disp - 62);
  	      return *l=4,(AS2 (adiw, r28, %4) CR_TAB
*************** ashlqi3_out (insn,operands,len)
*** 2107,2179 ****
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
!       int *t=len;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
! 	default: len = t; break;
  	case 1:
! 	  *len=1;
  	  return AS1 (lsl,%0);
  	case 2:
! 	  *len=2;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
  	case 3:
! 	  *len=3;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
  	case 4:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len=2;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS2 (andi,%0,0xf0));
  	    }
! 	  *len=4;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
  	case 5:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len=3;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS1 (lsl,%0)  CR_TAB
  		      AS2 (andi,%0,0xe0));
  	    }
! 	  *len=5;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
  	case 6:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len=4;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS1 (lsl,%0)  CR_TAB
  		      AS1 (lsl,%0)  CR_TAB
  		      AS2 (andi,%0,0xc0));
  	    }
! 	  *len=6;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
  	case 7:
! 	  *len=3;
  	  return (AS1 (ror,%0) CR_TAB
  		  AS1 (clr,%0) CR_TAB
  		  AS1 (ror,%0));
  	}
      }
    if (len)
      *len = 3;
    out_shift_with_cnt (AS1 (lsl,%0),
--- 2127,2212 ----
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
! 
        if (!len)
  	len = &k;
+ 
        switch (INTVAL (operands[2]))
  	{
! 	default:
! 	  *len = 1;
! 	  return AS1 (clr,%0);
! 	  
  	case 1:
! 	  *len = 1;
  	  return AS1 (lsl,%0);
+ 	  
  	case 2:
! 	  *len = 2;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
+ 
  	case 3:
! 	  *len = 3;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
+ 
  	case 4:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len = 2;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS2 (andi,%0,0xf0));
  	    }
! 	  *len = 4;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
+ 
  	case 5:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len = 3;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS1 (lsl,%0)  CR_TAB
  		      AS2 (andi,%0,0xe0));
  	    }
! 	  *len = 5;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
+ 
  	case 6:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len = 4;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS1 (lsl,%0)  CR_TAB
  		      AS1 (lsl,%0)  CR_TAB
  		      AS2 (andi,%0,0xc0));
  	    }
! 	  *len = 6;
  	  return (AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0) CR_TAB
  		  AS1 (lsl,%0));
+ 
  	case 7:
! 	  *len = 3;
  	  return (AS1 (ror,%0) CR_TAB
  		  AS1 (clr,%0) CR_TAB
  		  AS1 (ror,%0));
  	}
      }
+   else if (CONSTANT_P (operands[2]))
+     fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
+ 
    if (len)
      *len = 3;
    out_shift_with_cnt (AS1 (lsl,%0),
*************** ashlhi3_out (insn,operands,len)
*** 2194,2214 ****
      {
        int k;
        int *t=len;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
  	case 1:
! 	  *len=2;
  	  return (AS1 (lsl,%A0) CR_TAB
  		  AS1 (rol,%B0));
  	case 2:
! 	  *len=4;
  	  return (AS1 (lsl,%A0) CR_TAB
  		  AS1 (rol,%B0) CR_TAB
  		  AS1 (lsl,%0)  CR_TAB
  		  AS1 (rol,%B0));
  	case 8:
  	  if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
  	    return *len = 1, AS1 (clr,%A0);
--- 2227,2252 ----
      {
        int k;
        int *t=len;
+ 
        if (!len)
  	len = &k;
+       
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
+ 	  
  	case 1:
! 	  *len = 2;
  	  return (AS1 (lsl,%A0) CR_TAB
  		  AS1 (rol,%B0));
+ 
  	case 2:
! 	  *len = 4;
  	  return (AS1 (lsl,%A0) CR_TAB
  		  AS1 (rol,%B0) CR_TAB
  		  AS1 (lsl,%0)  CR_TAB
  		  AS1 (rol,%B0));
+ 
  	case 8:
  	  if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
  	    return *len = 1, AS1 (clr,%A0);
*************** ashlsi3_out (insn,operands,len)
*** 2238,2302 ****
      {
        int k;
        int *t=len;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
  	case 1:
! 	  *len=4;
  	  return (AS1 (lsl,%A0) CR_TAB
  		  AS1 (rol,%B0) CR_TAB
  		  AS1 (rol,%C0) CR_TAB
  		  AS1 (rol,%D0));
  	case 8:
  	  {
  	    int reg0 = true_regnum (operands[0]);
  	    int reg1 = true_regnum (operands[1]);
! 	    *len=4;
  	    if (reg0 >= reg1)
  	      return (AS2 (mov,%D0,%C1)  CR_TAB
  		      AS2 (mov,%C0,%B1)  CR_TAB
  		      AS2 (mov,%B0,%A1)  CR_TAB
  		      AS1 (clr,%A0));
  	    else if (reg0 + 1 == reg1)
! 	      return *len = 1, AS1 (clr,%A0);
  	    else
  	      return (AS1 (clr,%A0)      CR_TAB
  		      AS2 (mov,%B0,%A1)  CR_TAB
  		      AS2 (mov,%C0,%B1)  CR_TAB
  		      AS2 (mov,%D0,%C1));
  	  }
  	case 16:
  	  {
  	    int reg0 = true_regnum (operands[0]);
  	    int reg1 = true_regnum (operands[1]);
! 	    *len=4;
  	    if (reg0 + 1 >= reg1)
  	      return (AS2 (mov,%D0,%B1)  CR_TAB
  		      AS2 (mov,%C0,%A1)  CR_TAB
  		      AS1 (clr,%B0)      CR_TAB
  		      AS1 (clr,%A0));
  	    if (reg0 + 2 == reg1)
! 	      return *len = 2, (AS1 (clr,%B0)      CR_TAB
! 				AS1 (clr,%A0));
  	    else
  	      return (AS2 (mov,%C0,%A1)  CR_TAB
  		      AS2 (mov,%D0,%B1)  CR_TAB
  		      AS1 (clr,%B0)      CR_TAB
  		      AS1 (clr,%A0));
  	  }
  	case 24:
! 	  *len=4;
  	  if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
  	    return (AS2 (mov,%D0,%A1)  CR_TAB
  		    AS1 (clr,%C0)      CR_TAB
  		    AS1 (clr,%B0)      CR_TAB
  		    AS1 (clr,%A0));
  	  else
! 	    return *len = 3, (AS1 (clr,%C0)      CR_TAB
! 			      AS1 (clr,%B0)      CR_TAB
! 			      AS1 (clr,%A0));
  	}
      }
    if (len)
--- 2276,2355 ----
      {
        int k;
        int *t=len;
+       
        if (!len)
  	len = &k;
+       
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
+ 	  
  	case 1:
! 	  *len = 4;
  	  return (AS1 (lsl,%A0) CR_TAB
  		  AS1 (rol,%B0) CR_TAB
  		  AS1 (rol,%C0) CR_TAB
  		  AS1 (rol,%D0));
+ 
  	case 8:
  	  {
  	    int reg0 = true_regnum (operands[0]);
  	    int reg1 = true_regnum (operands[1]);
! 	    *len = 4;
  	    if (reg0 >= reg1)
  	      return (AS2 (mov,%D0,%C1)  CR_TAB
  		      AS2 (mov,%C0,%B1)  CR_TAB
  		      AS2 (mov,%B0,%A1)  CR_TAB
  		      AS1 (clr,%A0));
  	    else if (reg0 + 1 == reg1)
! 	      {
! 		*len = 1;
! 		return AS1 (clr,%A0);
! 	      }
  	    else
  	      return (AS1 (clr,%A0)      CR_TAB
  		      AS2 (mov,%B0,%A1)  CR_TAB
  		      AS2 (mov,%C0,%B1)  CR_TAB
  		      AS2 (mov,%D0,%C1));
  	  }
+ 
  	case 16:
  	  {
  	    int reg0 = true_regnum (operands[0]);
  	    int reg1 = true_regnum (operands[1]);
! 	    *len = 4;
  	    if (reg0 + 1 >= reg1)
  	      return (AS2 (mov,%D0,%B1)  CR_TAB
  		      AS2 (mov,%C0,%A1)  CR_TAB
  		      AS1 (clr,%B0)      CR_TAB
  		      AS1 (clr,%A0));
  	    if (reg0 + 2 == reg1)
! 	      {
! 		*len = 2;
! 		return (AS1 (clr,%B0)      CR_TAB
! 			AS1 (clr,%A0));
! 	      }
  	    else
  	      return (AS2 (mov,%C0,%A1)  CR_TAB
  		      AS2 (mov,%D0,%B1)  CR_TAB
  		      AS1 (clr,%B0)      CR_TAB
  		      AS1 (clr,%A0));
  	  }
+ 
  	case 24:
! 	  *len = 4;
  	  if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
  	    return (AS2 (mov,%D0,%A1)  CR_TAB
  		    AS1 (clr,%C0)      CR_TAB
  		    AS1 (clr,%B0)      CR_TAB
  		    AS1 (clr,%A0));
  	  else
! 	    {
! 	      *len = 3;
! 	      return (AS1 (clr,%C0)      CR_TAB
! 		      AS1 (clr,%B0)      CR_TAB
! 		      AS1 (clr,%A0));
! 	    }
  	}
      }
    if (len)
*************** ashrqi3_out (insn,operands,len)
*** 2319,2351 ****
  {
    if (GET_CODE (operands[2]) == CONST_INT)
      {
-       int *t=len;
        int k;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
- 	default: len = t; break;
  	case 1:
! 	  *len=1;
  	  return AS1 (asr,%0);
  	case 2:
! 	  *len=2;
  	  return (AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0));
  	case 3:
! 	  *len=3;
  	  return (AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0));
  	case 4:
! 	  *len=4;
  	  return (AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0));
  	}
      }
    if (len)
      *len = 3;
    out_shift_with_cnt (AS1 (asr,%0),
--- 2372,2431 ----
  {
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
+ 
        if (!len)
  	len = &k;
+ 
        switch (INTVAL (operands[2]))
  	{
  	case 1:
! 	  *len = 1;
  	  return AS1 (asr,%0);
+ 
  	case 2:
! 	  *len = 2;
  	  return (AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0));
+ 
  	case 3:
! 	  *len = 3;
  	  return (AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0));
+ 
  	case 4:
! 	  *len = 4;
! 	  return (AS1 (asr,%0) CR_TAB
! 		  AS1 (asr,%0) CR_TAB
! 		  AS1 (asr,%0) CR_TAB
! 		  AS1 (asr,%0));
! 
! 	case 5:
! 	  *len = 5;
  	  return (AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0) CR_TAB
+ 		  AS1 (asr,%0) CR_TAB
  		  AS1 (asr,%0));
+ 
+ 	case 6:
+ 	  *len = 4;
+ 	  return (AS2 (bst,%0,6)  CR_TAB
+ 		  AS1 (lsl,%0)    CR_TAB
+ 		  AS2 (sbc,%0,%0) CR_TAB
+ 		  AS2 (bld,%0,0));
+ 
+ 	default:
+ 	case 7:
+ 	  *len = 2;
+ 	  return (AS1 (lsl,%0) CR_TAB
+ 		  AS2 (sbc,%0,%0));
  	}
      }
+   else if (CONSTANT_P (operands[2]))
+     fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
+ 
    if (len)
      *len = 3;
    out_shift_with_cnt (AS1 (asr,%0),
*************** ashrhi3_out (insn,operands,len)
*** 2365,2386 ****
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
!       int *t=len;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
  	case 1:
  	  *len=2;
  	  return (AS1 (asr,%B0) CR_TAB
  		  AS1 (ror,%A0));
  	case 2:
  	  *len=4;
  	  return (AS1 (asr,%B0)  CR_TAB
  		  AS1 (ror,%A0) CR_TAB
  		  AS1 (asr,%B0)  CR_TAB
  		  AS1 (ror,%A0));
  	case 8:
  	  if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
  	    return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
--- 2445,2471 ----
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
!       int *t = len;
!       
        if (!len)
  	len = &k;
+ 
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
+ 	  
  	case 1:
  	  *len=2;
  	  return (AS1 (asr,%B0) CR_TAB
  		  AS1 (ror,%A0));
+ 
  	case 2:
  	  *len=4;
  	  return (AS1 (asr,%B0)  CR_TAB
  		  AS1 (ror,%A0) CR_TAB
  		  AS1 (asr,%B0)  CR_TAB
  		  AS1 (ror,%A0));
+ 
  	case 8:
  	  if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
  	    return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
*************** ashrhi3_out (insn,operands,len)
*** 2391,2396 ****
--- 2476,2482 ----
  	    return *len = 3, (AS1 (clr,%B0)     CR_TAB
  			      AS2 (sbrc,%A0,7)  CR_TAB
  			      AS1 (dec,%B0));
+ 
  	case 15:
  	  return *len = 3, (AS1 (lsl,%B0)     CR_TAB
  			    AS2 (sbc,%A0,%A0) CR_TAB
*************** ashrsi3_out (insn,operands,len)
*** 2418,2434 ****
      {
        int k;
        int *t = len;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
  	case 1:
  	  *len=4;
  	  return (AS1 (asr,%D0)  CR_TAB
! 		  AS1 (ror,%C0) CR_TAB
! 		  AS1 (ror,%B0) CR_TAB
  		  AS1 (ror,%A0));
  	case 8:
  	  {
  	    int reg0 = true_regnum (operands[0]);
--- 2504,2524 ----
      {
        int k;
        int *t = len;
+       
        if (!len)
  	len = &k;
+       
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
+ 
  	case 1:
  	  *len=4;
  	  return (AS1 (asr,%D0)  CR_TAB
! 		  AS1 (ror,%C0)  CR_TAB
! 		  AS1 (ror,%B0)  CR_TAB
  		  AS1 (ror,%A0));
+ 
  	case 8:
  	  {
  	    int reg0 = true_regnum (operands[0]);
*************** ashrsi3_out (insn,operands,len)
*** 2442,2450 ****
  		      AS2 (sbrc,%C0,7)  CR_TAB
  		      AS1 (dec,%D0));
  	    else if (reg0 == reg1 + 1)
! 	      return *len = 3, (AS1 (clr,%D0)     CR_TAB
! 				AS2 (sbrc,%C0,7)  CR_TAB
! 				AS1 (dec,%D0));
  	    else
  	      return (AS1 (clr,%D0)     CR_TAB
  		      AS2 (sbrc,%D1,7)  CR_TAB
--- 2532,2543 ----
  		      AS2 (sbrc,%C0,7)  CR_TAB
  		      AS1 (dec,%D0));
  	    else if (reg0 == reg1 + 1)
! 	      {
! 		*len = 3;
! 		return (AS1 (clr,%D0)     CR_TAB
! 			AS2 (sbrc,%C0,7)  CR_TAB
! 			AS1 (dec,%D0));
! 	      }
  	    else
  	      return (AS1 (clr,%D0)     CR_TAB
  		      AS2 (sbrc,%D1,7)  CR_TAB
*************** ashrsi3_out (insn,operands,len)
*** 2453,2458 ****
--- 2546,2552 ----
  		      AS2 (mov,%B0,%C1) CR_TAB
  		      AS2 (mov,%A0,%B1));
  	  }
+ 	  
  	case 16:
  	  {
  	    int reg0 = true_regnum (operands[0]);
*************** ashrsi3_out (insn,operands,len)
*** 2478,2483 ****
--- 2572,2578 ----
  		      AS1 (com,%D0)     CR_TAB
  		      AS2 (mov,%C0,%D0));
  	  }
+ 
  	case 24:
  	  if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
  	    return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
*************** lshrqi3_out (insn,operands,len)
*** 2515,2538 ****
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
!       int *t=len;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
! 	default: len = t; break;
  	case 1:
! 	  *len=1;
  	  return AS1 (lsr,%0);
  	case 2:
! 	  *len=2;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
  	case 3:
! 	  *len=3;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
  	case 4:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
--- 2610,2639 ----
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
! 
        if (!len)
  	len = &k;
+       
        switch (INTVAL (operands[2]))
  	{
! 	default:
! 	  *len = 1;
! 	  return AS1 (clr,%0);
! 
  	case 1:
! 	  *len = 1;
  	  return AS1 (lsr,%0);
+ 
  	case 2:
! 	  *len = 2;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
  	case 3:
! 	  *len = 3;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
+ 	  
  	case 4:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
*************** lshrqi3_out (insn,operands,len)
*** 2540,2587 ****
  	      return (AS1 (swap,%0) CR_TAB
  		      AS2 (andi,%0,0x0f));
  	    }
! 	  *len=4;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
  	case 5:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len=3;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS1 (lsr,%0)  CR_TAB
  		      AS2 (andi,%0,0x7));
  	    }
! 	  *len=5;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
  	case 6:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len=4;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS1 (lsr,%0)  CR_TAB
  		      AS1 (lsr,%0)  CR_TAB
  		      AS2 (andi,%0,0x3));
  	    }
! 	  *len=6;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
  	case 7:
! 	  *len=3;
  	  return (AS1 (rol,%0) CR_TAB
  		  AS1 (clr,%0) CR_TAB
  		  AS1 (rol,%0));
  	}
      }
    if (len)
      *len = 3;
    out_shift_with_cnt (AS1 (lsr,%0),
--- 2641,2694 ----
  	      return (AS1 (swap,%0) CR_TAB
  		      AS2 (andi,%0,0x0f));
  	    }
! 	  *len = 4;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
+ 	  
  	case 5:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len = 3;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS1 (lsr,%0)  CR_TAB
  		      AS2 (andi,%0,0x7));
  	    }
! 	  *len = 5;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
+ 	  
  	case 6:
  	  if (TEST_HARD_REG_CLASS (LD_REGS, true_regnum (operands[0])))
  	    {
! 	      *len = 4;
  	      return (AS1 (swap,%0) CR_TAB
  		      AS1 (lsr,%0)  CR_TAB
  		      AS1 (lsr,%0)  CR_TAB
  		      AS2 (andi,%0,0x3));
  	    }
! 	  *len = 6;
  	  return (AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0) CR_TAB
  		  AS1 (lsr,%0));
+ 	  
  	case 7:
! 	  *len = 3;
  	  return (AS1 (rol,%0) CR_TAB
  		  AS1 (clr,%0) CR_TAB
  		  AS1 (rol,%0));
  	}
      }
+   else if (CONSTANT_P (operands[2]))
+     fatal_insn ("Internal compiler bug.\nIncorrect shift:", insn);
+   
    if (len)
      *len = 3;
    out_shift_with_cnt (AS1 (lsr,%0),
*************** lshrhi3_out (insn,operands,len)
*** 2600,2621 ****
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
!       int *t=len;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
  	case 1:
! 	  *len=2;
  	  return (AS1 (lsr,%B0) CR_TAB
  		  AS1 (ror,%A0));
  	case 2:
! 	  *len=4;
  	  return (AS1 (lsr,%B0)  CR_TAB
  		  AS1 (ror,%A0)  CR_TAB
  		  AS1 (lsr,%B0)  CR_TAB
  		  AS1 (ror,%A0));
  	case 8:
  	  if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
  	    return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
--- 2707,2733 ----
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
!       int *t = len;
!       
        if (!len)
  	len = &k;
+       
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
+ 	  
  	case 1:
! 	  *len = 2;
  	  return (AS1 (lsr,%B0) CR_TAB
  		  AS1 (ror,%A0));
+ 	  
  	case 2:
! 	  *len = 4;
  	  return (AS1 (lsr,%B0)  CR_TAB
  		  AS1 (ror,%A0)  CR_TAB
  		  AS1 (lsr,%B0)  CR_TAB
  		  AS1 (ror,%A0));
+ 	  
  	case 8:
  	  if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
  	    return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
*************** lshrhi3_out (insn,operands,len)
*** 2624,2633 ****
  	    return *len = 1, AS1 (clr,%B0);
  	  
  	case 15:
! 	  return *len = 4, (AS1 (lsl,%B0)     CR_TAB
! 			    AS2 (sbc,%A0,%A0) CR_TAB
! 			    AS1 (neg,%A0)     CR_TAB
! 			    AS1 (clr,%B0));
  	}
      }
    if (len)
--- 2736,2746 ----
  	    return *len = 1, AS1 (clr,%B0);
  	  
  	case 15:
! 	  *len = 4;
! 	  return (AS1 (lsl,%B0)     CR_TAB
! 		  AS2 (sbc,%A0,%A0) CR_TAB
! 		  AS1 (neg,%A0)     CR_TAB
! 		  AS1 (clr,%B0));
  	}
      }
    if (len)
*************** lshrsi3_out (insn,operands,len)
*** 2649,2671 ****
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
!       int *t=len;
        if (!len)
  	len = &k;
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
  	case 1:
! 	  *len=4;
  	  return (AS1 (lsr,%D0)  CR_TAB
  		  AS1 (ror,%C0) CR_TAB
  		  AS1 (ror,%B0) CR_TAB
  		  AS1 (ror,%A0));
  	case 8:
  	  {
  	    int reg0 = true_regnum (operands[0]);
  	    int reg1 = true_regnum (operands[1]);
! 	    *len=4;
  	    if (reg0 <= reg1)
  	      return (AS2 (mov,%A0,%B1) CR_TAB
  		      AS2 (mov,%B0,%C1) CR_TAB
--- 2762,2788 ----
    if (GET_CODE (operands[2]) == CONST_INT)
      {
        int k;
!       int *t = len;
!       
        if (!len)
  	len = &k;
+       
        switch (INTVAL (operands[2]))
  	{
  	default: len = t; break;
+ 	  
  	case 1:
! 	  *len = 4;
  	  return (AS1 (lsr,%D0)  CR_TAB
  		  AS1 (ror,%C0) CR_TAB
  		  AS1 (ror,%B0) CR_TAB
  		  AS1 (ror,%A0));
+ 	  
  	case 8:
  	  {
  	    int reg0 = true_regnum (operands[0]);
  	    int reg1 = true_regnum (operands[1]);
! 	    *len = 4;
  	    if (reg0 <= reg1)
  	      return (AS2 (mov,%A0,%B1) CR_TAB
  		      AS2 (mov,%B0,%C1) CR_TAB
*************** lshrsi3_out (insn,operands,len)
*** 2679,2689 ****
  		      AS2 (mov,%B0,%C1) CR_TAB
  		      AS2 (mov,%A0,%B1)); 
  	  }
  	case 16:
  	  {
  	    int reg0 = true_regnum (operands[0]);
  	    int reg1 = true_regnum (operands[1]);
! 	    *len=4;
  	    if (reg0 <= reg1 + 1)
  	      return (AS2 (mov,%A0,%C1) CR_TAB
  		      AS2 (mov,%B0,%D1) CR_TAB
--- 2796,2807 ----
  		      AS2 (mov,%B0,%C1) CR_TAB
  		      AS2 (mov,%A0,%B1)); 
  	  }
+ 	  
  	case 16:
  	  {
  	    int reg0 = true_regnum (operands[0]);
  	    int reg1 = true_regnum (operands[1]);
! 	    *len = 4;
  	    if (reg0 <= reg1 + 1)
  	      return (AS2 (mov,%A0,%C1) CR_TAB
  		      AS2 (mov,%B0,%D1) CR_TAB
*************** lshrsi3_out (insn,operands,len)
*** 2698,2703 ****
--- 2816,2822 ----
  		      AS1 (clr,%C0)     CR_TAB
  		      AS1 (clr,%D0));
  	  }
+ 	  
  	case 24:
  	  if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
  	    return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
*************** asm_output_char(file,value)
*** 3010,3016 ****
  void
  asm_output_byte (file,value)
       FILE *file;
!      char value;
  {
    fprintf (file, "\t.byte 0x%x\n",value & 0xff);
  }
--- 3129,3135 ----
  void
  asm_output_byte (file,value)
       FILE *file;
!      int value;
  {
    fprintf (file, "\t.byte 0x%x\n",value & 0xff);
  }
*************** asm_file_end (file)
*** 3342,3350 ****
       FILE *file;
  {
    fprintf (file,
! 	   "/* File %s: code %4d (%4d), prologues %3d, epilogues %3d */\n",
  	   main_input_filename,
  	   commands_in_file,
  	   commands_in_file - commands_in_prologues - commands_in_epilogues,
  	   commands_in_prologues, commands_in_epilogues);
  }
--- 3461,3470 ----
       FILE *file;
  {
    fprintf (file,
! 	   "/* File %s: code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
  	   main_input_filename,
  	   commands_in_file,
+ 	   commands_in_file,
  	   commands_in_file - commands_in_prologues - commands_in_epilogues,
  	   commands_in_prologues, commands_in_epilogues);
  }
*************** avr_address_cost (rtx x)
*** 3487,3493 ****
  int
  extra_constraint (x,c)
       rtx x;
!      char c;
  {
    if (c == 'Q'
        && GET_CODE (x) == MEM
--- 3607,3613 ----
  int
  extra_constraint (x,c)
       rtx x;
!      int c;
  {
    if (c == 'Q'
        && GET_CODE (x) == MEM
*************** extra_constraint (x,c)
*** 3506,3512 ****
  	  && REG_P (XEXP (XEXP (x,0), 0))
  	  && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
  	  && (INTVAL (XEXP (XEXP (x,0), 1))
! 	      <= (64 - GET_MODE_SIZE (GET_MODE (x)))))
  	{
  	  rtx xx = XEXP (XEXP (x,0), 0);
  	  int regno = REGNO (xx);
--- 3626,3632 ----
  	  && REG_P (XEXP (XEXP (x,0), 0))
  	  && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
  	  && (INTVAL (XEXP (XEXP (x,0), 1))
! 	      <= MAX_LD_OFFSET (GET_MODE (x))))
  	{
  	  rtx xx = XEXP (XEXP (x,0), 0);
  	  int regno = REGNO (xx);
*************** avr_function_value (type,func)
*** 3667,3673 ****
       tree type;
       tree func ATTRIBUTE_UNUSED;
  {
!   int offs;
    if (TYPE_MODE (type) != BLKmode)
      return avr_libcall_value (TYPE_MODE (type));
    
--- 3787,3793 ----
       tree type;
       tree func ATTRIBUTE_UNUSED;
  {
!   unsigned int offs;
    if (TYPE_MODE (type) != BLKmode)
      return avr_libcall_value (TYPE_MODE (type));
    
Index: gcc/config/avr/avr.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/avr/avr.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 avr.h
*** avr.h	2000/05/01 14:37:11	1.3
--- avr.h	2000/05/09 16:53:09
*************** enum reg_class {
*** 1079,1084 ****
--- 1079,1087 ----
     registers.  This macro must be defined if `ELIMINABLE_REGS' is
     defined.  */
  
+ #define RETURN_ADDR_RTX(count, x) \
+   gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (tem, 1)))
+ 
  #define PUSH_ROUNDING(NPUSHED) (NPUSHED)
  /* A C expression that is the number of bytes actually pushed onto the
     stack when an instruction attempts to push NPUSHED bytes.
Index: gcc/config/avr/avr.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/avr/avr.md,v
retrieving revision 1.2
diff -c -3 -p -r1.2 avr.md
*** avr.md	2000/05/03 19:20:09	1.2
--- avr.md	2000/05/09 16:53:15
***************
*** 254,260 ****
      case 1:  /* mov r,L */
        return (AS1 (clr,%A0) CR_TAB
  	      AS1 (clr,%B0));
!     case 2: /* mov r,d */
        if (operands[1] == const1_rtx
            && (link = find_reg_note (insn, REG_WAS_0, 0))
  	  /* Make sure the insn that stored the 0 is still present.  */
--- 254,260 ----
      case 1:  /* mov r,L */
        return (AS1 (clr,%A0) CR_TAB
  	      AS1 (clr,%B0));
!     case 2: /* ld d,i */
        if (operands[1] == const1_rtx
            && (link = find_reg_note (insn, REG_WAS_0, 0))
  	  /* Make sure the insn that stored the 0 is still present.  */
***************
*** 272,278 ****
        return out_movhi_r_mr (insn, operands, NULL);
      case 4: /* mov m,r*/
          {
!           rtx save1=NULL;
            if (operands[1] == const0_rtx)
              {
                save1 = operands[1];
--- 272,278 ----
        return out_movhi_r_mr (insn, operands, NULL);
      case 4: /* mov m,r*/
          {
!           rtx save1 = NULL;
            if (operands[1] == const0_rtx)
              {
                save1 = operands[1];
***************
*** 543,557 ****
        short tmp = INTVAL (operands[2]);
        operands[2] = GEN_INT(tmp);
      }
-  if (! (reload_completed | reload_in_progress))
-    {
-      if (REGNO (operands[0]) != REGNO (operands[1])
- 	 && REGNO (operands[0]) != REGNO (operands[2])&&0)
-        {
- 	 emit_move_insn (operands[0], operands[1]);
- 	 operands[1] = operands[0];
-        }
-    }
  }")
  
  
--- 543,548 ----
***************
*** 871,880 ****
  (define_insn "ashlqi3"
    [(set (match_operand:QI 0 "register_operand" "=r,!d,r,r")
  	(ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0")
! 		   (match_operand:QI 2 "general_operand" "r,i,i,Qm")))]
    ""
    "* return ashlqi3_out (insn, operands, NULL);"
!   [(set_attr "length" "6,4,6,7")
     (set_attr "cc" "clobber,set_czn,set_czn,clobber")])
  
  (define_insn "ashlhi3"
--- 862,871 ----
  (define_insn "ashlqi3"
    [(set (match_operand:QI 0 "register_operand" "=r,!d,r,r")
  	(ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0")
! 		   (match_operand:QI 2 "general_operand" "r,n,n,Qm")))]
    ""
    "* return ashlqi3_out (insn, operands, NULL);"
!   [(set_attr "length" "5,4,6,7")
     (set_attr "cc" "clobber,set_czn,set_czn,clobber")])
  
  (define_insn "ashlhi3"
***************
*** 903,914 ****
  (define_insn "ashrqi3"
    [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
  	(ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0")
! 		     (match_operand:QI 2 "general_operand" "r,P,K,i,Qm")))
!    (clobber (match_scratch:QI 3 "=X,X,X,&d,X"))]
    ""
!   "* return ashrqi3_out (insn,operands, NULL);"
!   [(set_attr "length" "6,1,2,4,7")
!    (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")])
  
  (define_insn "ashrhi3"
    [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r")
--- 894,904 ----
  (define_insn "ashrqi3"
    [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
  	(ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0")
! 		     (match_operand:QI 2 "general_operand" "r,P,K,n,Qm")))]
    ""
!   "* return ashrqi3_out (insn, operands, NULL);"
!   [(set_attr "length" "5,1,2,5,7")
!    (set_attr "cc" "clobber,set_zn,set_zn,clobber,clobber")])
  
  (define_insn "ashrhi3"
    [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r")
***************
*** 936,942 ****
  (define_insn "lshrqi3"
    [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
  	(lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0")
! 		     (match_operand:QI 2 "general_operand" "r,i,i,Qm")))]
    ""
    "* return lshrqi3_out (insn,operands, NULL);"
    [(set_attr "length" "6,4,6,7")
--- 926,932 ----
  (define_insn "lshrqi3"
    [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
  	(lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0")
! 		     (match_operand:QI 2 "general_operand" "r,n,n,Qm")))]
    ""
    "* return lshrqi3_out (insn,operands, NULL);"
    [(set_attr "length" "6,4,6,7")
***************
*** 1621,1627 ****
     (set (attr "length")
  	(cond [(eq (symbol_ref "which_alternative") (const_int 0))
  	       (const_int 1)
! 	       (eq (symbol_ref "which_alternative") (const_int 0))
  	       (const_int 3)
  	       (eq (symbol_ref "!AVR_MEGA")
  		   (const_int 0))
--- 1611,1617 ----
     (set (attr "length")
  	(cond [(eq (symbol_ref "which_alternative") (const_int 0))
  	       (const_int 1)
! 	       (eq (symbol_ref "which_alternative") (const_int 1))
  	       (const_int 3)
  	       (eq (symbol_ref "!AVR_MEGA")
  		   (const_int 0))
***************
*** 1651,1657 ****
     (set (attr "length")
  	(cond [(eq (symbol_ref "which_alternative") (const_int 0))
  	       (const_int 1)
! 	       (eq (symbol_ref "which_alternative") (const_int 0))
  	       (const_int 3)
  	       (eq (symbol_ref "!AVR_MEGA")
  		   (const_int 0))
--- 1641,1647 ----
     (set (attr "length")
  	(cond [(eq (symbol_ref "which_alternative") (const_int 0))
  	       (const_int 1)
! 	       (eq (symbol_ref "which_alternative") (const_int 1))
  	       (const_int 3)
  	       (eq (symbol_ref "!AVR_MEGA")
  		   (const_int 0))
Index: gcc/config/avr/t-avr
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/avr/t-avr,v
retrieving revision 1.1
diff -c -3 -p -r1.1 t-avr
*** t-avr	2000/02/11 22:31:46	1.1
--- t-avr	2000/05/09 16:53:15
*************** TARGET_LIBGCC2_CFLAGS = -DDF=SF -Dinhibi
*** 32,38 ****
  #LIBGCC2 = $(LIBGCC1)
  
  fp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/avr/t-avr
- 	echo '#define FLOAT' > fp-bit.c
  	echo '#define FLOAT_ONLY' >> fp-bit.c
  	echo '#define CMPtype QItype' >> fp-bit.c
  	echo '#define DF SF' >> fp-bit.c
--- 32,37 ----



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