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 patch: various random fixes and cleanups



Already applied patch.

2000-09-02  Marek Michalkiewicz  <marekm@linux.org.pl>

	* config/avr/avr-protos.h, config/avr/avr.c (unique_section,
	gas_output_limited_string, gas_output_ascii, output_movqi,
	output_movhi, out_movqi_r_mr, out_movqi_mr_r, out_movhi_r_mr,
	out_movhi_mr_r, out_movsi_r_mr, out_movsi_mr_r, output_movsisf,
	out_tstsi, out_tsthi, ret_cond_branch, ashlqi3_out, ashlhi3_out,
	ashlsi3_out, ashrqi3_out, ashrhi3_out, ashrsi3_out, lshrqi3_out,
	lshrhi3_out, lshrsi3_out, output_reload_inhi, output_reload_insisf,
	out_shift_with_cnt, ptrreg_to_str, cond_string, encode_section_info):
	Add "const" as needed to remove warnings.

	* config/avr/avr.c (avr_override_options, avr_init_once,
	function_prologue, function_epilogue, frame_pointer_required_p,
	class_likely_spilled_p, order_regs_for_local_alloc,
	avr_address_cost, avr_ret_register): Use K&R style arguments.
	(initial_elimination_offset, gas_output_limited_string):
	Remove ATTRIBUTE_UNUSED from the used arguments.
	(output_mov*, out_mov*_r_mr, out_mov*_mr_r, output_reload_insisf):
	Use local variables src, dest, base to access operands[].
	Rename reg_dest to reg_src if that's what it is.
	(output_movhi, output_movsisf): Optimize loading 8-bit immediate
	constants to LD_REGS if reg_was_0.
	(output_reload_insisf): Change arg 3 to insn length and set it.
	(out_movhi_r_mr, out_movhi_mr_r): Use in/out for more efficient
	access to 16-bit I/O register pairs.
	(avr_address_cost): Lower cost for the above case.
	(out_tsthi): Use "or" (faster) instead of "sbiw" if the operand
	may be clobbered, also for LD_REGS.
	(adjust_insn_length): Correct insn length for iorhi3 and iorsi3
	with a CONST_INT.

	* config/avr/avr.h (PTRDIFF_TYPE): Make signed.

	* config/avr/avr.md: Change all uses of the TEST_HARD_REG_CLASS
	macro to test_hard_reg_class function.
	(*movsi, *movsf): Change "cc" attribute from "clobber" to "none"
	for loading immediate constants to LD_REGS.
	(andsi3, cmphi, cmpsi): Add return statements to avoid warnings.


diff -rc3p orig/egcs/gcc/config/avr/avr-protos.h egcs/gcc/config/avr/avr-protos.h
*** orig/egcs/gcc/config/avr/avr-protos.h	Wed Aug 30 18:04:50 2000
--- egcs/gcc/config/avr/avr-protos.h	Sat Sep  2 14:16:26 2000
*************** extern void   asm_file_end              
*** 27,33 ****
  extern void   avr_init_once                     PARAMS ((void));
  extern void   avr_override_options              PARAMS ((void));
  extern char * avr_change_section                PARAMS ((char *sect_name));
! extern int    avr_ret_register                  PARAMS((void));
  extern enum reg_class class_likely_spilled_p    PARAMS ((int c));
  extern enum reg_class avr_regno_reg_class       PARAMS ((int r));
  extern enum reg_class avr_reg_class_from_letter PARAMS ((int c));
--- 27,33 ----
  extern void   avr_init_once                     PARAMS ((void));
  extern void   avr_override_options              PARAMS ((void));
  extern char * avr_change_section                PARAMS ((char *sect_name));
! extern int    avr_ret_register                  PARAMS ((void));
  extern enum reg_class class_likely_spilled_p    PARAMS ((int c));
  extern enum reg_class avr_regno_reg_class       PARAMS ((int r));
  extern enum reg_class avr_reg_class_from_letter PARAMS ((int c));
*************** extern void   function_prologue         
*** 39,46 ****
  extern void   function_epilogue           PARAMS ((FILE *file, int size));
  extern void   progmem_section             PARAMS ((void));
  extern int    mask_one_bit_p              PARAMS ((HOST_WIDE_INT mask));
! extern void   gas_output_limited_string   PARAMS ((FILE *file, char *str));
! extern void   gas_output_ascii            PARAMS ((FILE *file, char * str,
  							 size_t length));
  
  
--- 39,46 ----
  extern void   function_epilogue           PARAMS ((FILE *file, int size));
  extern void   progmem_section             PARAMS ((void));
  extern int    mask_one_bit_p              PARAMS ((HOST_WIDE_INT mask));
! extern void   gas_output_limited_string PARAMS ((FILE *file, const char *str));
! extern void   gas_output_ascii          PARAMS ((FILE *file, const char *str,
  							 size_t length));
  
  
*************** extern int    legitimate_address_p    PA
*** 86,115 ****
  					int strict));
  extern void   machine_dependent_reorg PARAMS ((rtx first_insn));
  extern int    compare_diff_p  PARAMS ((rtx insn));
! extern char * output_movqi    PARAMS ((rtx insn, rtx operands[], int *l));
! extern char * output_movhi    PARAMS ((rtx insn, rtx operands[], int *l));
! extern char * out_movqi_r_mr  PARAMS ((rtx insn, rtx op[], int *l));
! extern char * out_movqi_mr_r  PARAMS ((rtx insn, rtx op[], int *l));
! extern char * out_movhi_r_mr  PARAMS ((rtx insn, rtx op[], int *l));
! extern char * out_movhi_mr_r  PARAMS ((rtx insn, rtx op[], int *l));
! extern char * out_movsi_r_mr  PARAMS ((rtx insn, rtx op[], int *l));
! extern char * out_movsi_mr_r  PARAMS ((rtx insn, rtx op[], int *l));
! extern char * output_movsisf  PARAMS ((rtx insn, rtx operands[], int *l));
! extern char * out_tstsi       PARAMS ((rtx insn, int *l));
! extern char * out_tsthi       PARAMS ((rtx insn, int *l));
! extern char * ret_cond_branch PARAMS ((RTX_CODE cond, int len));
! 
! extern char * ashlqi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
! extern char * ashlhi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
! extern char * ashlsi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
! 
! extern char * ashrqi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
! extern char * ashrhi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
! extern char * ashrsi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
! 
! extern char * lshrqi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
! extern char * lshrhi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
! extern char * lshrsi3_out     PARAMS ((rtx insn, rtx operands[], int *len));
  
  extern enum reg_class preferred_reload_class PARAMS ((rtx x,
  						     enum reg_class class));
--- 86,115 ----
  					int strict));
  extern void   machine_dependent_reorg PARAMS ((rtx first_insn));
  extern int    compare_diff_p  PARAMS ((rtx insn));
! extern const char * output_movqi    PARAMS ((rtx insn, rtx operands[], int *l));
! extern const char * output_movhi    PARAMS ((rtx insn, rtx operands[], int *l));
! extern const char * out_movqi_r_mr  PARAMS ((rtx insn, rtx op[], int *l));
! extern const char * out_movqi_mr_r  PARAMS ((rtx insn, rtx op[], int *l));
! extern const char * out_movhi_r_mr  PARAMS ((rtx insn, rtx op[], int *l));
! extern const char * out_movhi_mr_r  PARAMS ((rtx insn, rtx op[], int *l));
! extern const char * out_movsi_r_mr  PARAMS ((rtx insn, rtx op[], int *l));
! extern const char * out_movsi_mr_r  PARAMS ((rtx insn, rtx op[], int *l));
! extern const char * output_movsisf  PARAMS ((rtx insn, rtx operands[], int *l));
! extern const char * out_tstsi       PARAMS ((rtx insn, int *l));
! extern const char * out_tsthi       PARAMS ((rtx insn, int *l));
! extern const char * ret_cond_branch PARAMS ((RTX_CODE cond, int len));
! 
! extern const char * ashlqi3_out PARAMS ((rtx insn, rtx operands[], int *len));
! extern const char * ashlhi3_out PARAMS ((rtx insn, rtx operands[], int *len));
! extern const char * ashlsi3_out PARAMS ((rtx insn, rtx operands[], int *len));
! 
! extern const char * ashrqi3_out PARAMS ((rtx insn, rtx operands[], int *len));
! extern const char * ashrhi3_out PARAMS ((rtx insn, rtx operands[], int *len));
! extern const char * ashrsi3_out PARAMS ((rtx insn, rtx operands[], int *len));
! 
! extern const char * lshrqi3_out PARAMS ((rtx insn, rtx operands[], int *len));
! extern const char * lshrhi3_out PARAMS ((rtx insn, rtx operands[], int *len));
! extern const char * lshrsi3_out PARAMS ((rtx insn, rtx operands[], int *len));
  
  extern enum reg_class preferred_reload_class PARAMS ((rtx x,
  						     enum reg_class class));
*************** extern rtx    legitimize_address     PAR
*** 119,128 ****
  					     enum machine_mode mode));
  extern int    adjust_insn_length     PARAMS ((rtx insn, int len));
  extern rtx    avr_libcall_value      PARAMS ((enum machine_mode mode));
! extern char * output_reload_inhi     PARAMS ((rtx insn, rtx *operands,
! 					     int *len));
! extern char * output_reload_insisf   PARAMS ((rtx insn, rtx *operands,
! 					     int which_alternative));
  extern int    default_rtx_costs      PARAMS ((rtx X, RTX_CODE code,
  					     RTX_CODE outer_code));
  extern void   asm_output_char        PARAMS ((FILE *file, rtx value));
--- 119,128 ----
  					     enum machine_mode mode));
  extern int    adjust_insn_length     PARAMS ((rtx insn, int len));
  extern rtx    avr_libcall_value      PARAMS ((enum machine_mode mode));
! extern const char * output_reload_inhi PARAMS ((rtx insn, rtx *operands,
! 						int *len));
! extern const char * output_reload_insisf PARAMS ((rtx insn, rtx *operands,
! 						int *len));
  extern int    default_rtx_costs      PARAMS ((rtx X, RTX_CODE code,
  					     RTX_CODE outer_code));
  extern void   asm_output_char        PARAMS ((FILE *file, rtx value));
*************** extern int    avr_simplify_comparision_p
*** 151,157 ****
  					      RTX_CODE operator, rtx x));
  extern RTX_CODE avr_normalize_condition  PARAMS ((RTX_CODE condition));
  extern int    compare_eq_p           PARAMS ((rtx insn));
! extern void   out_shift_with_cnt     PARAMS ((char * template, rtx insn,
  					      rtx operands[], int *len));
  extern int    const_int_pow2_p       PARAMS ((rtx x));
  #endif /* RTX_CODE */
--- 151,157 ----
  					      RTX_CODE operator, rtx x));
  extern RTX_CODE avr_normalize_condition  PARAMS ((RTX_CODE condition));
  extern int    compare_eq_p           PARAMS ((rtx insn));
! extern void   out_shift_with_cnt     PARAMS ((const char *template, rtx insn,
  					      rtx operands[], int *len));
  extern int    const_int_pow2_p       PARAMS ((rtx x));
  #endif /* RTX_CODE */
diff -rc3p orig/egcs/gcc/config/avr/avr.c egcs/gcc/config/avr/avr.c
*** orig/egcs/gcc/config/avr/avr.c	Wed Aug 30 18:04:50 2000
--- egcs/gcc/config/avr/avr.c	Sat Sep  2 14:40:15 2000
*************** static int    avr_naked_function_p PARAM
*** 47,54 ****
  static int    interrupt_function_p PARAMS ((tree));
  static int    signal_function_p    PARAMS ((tree));
  static int    sequent_regs_live    PARAMS ((void));
! static char * ptrreg_to_str        PARAMS ((int));
! static char * cond_string          PARAMS ((enum rtx_code));
  static int    avr_num_arg_regs     PARAMS ((enum machine_mode, tree));
  static int    out_adj_frame_ptr    PARAMS ((FILE *, int));
  static int    out_set_stack_ptr    PARAMS ((FILE *, int, int));
--- 47,54 ----
  static int    interrupt_function_p PARAMS ((tree));
  static int    signal_function_p    PARAMS ((tree));
  static int    sequent_regs_live    PARAMS ((void));
! static const char * ptrreg_to_str  PARAMS ((int));
! static const char * cond_string    PARAMS ((enum rtx_code));
  static int    avr_num_arg_regs     PARAMS ((enum machine_mode, tree));
  static int    out_adj_frame_ptr    PARAMS ((FILE *, int));
  static int    out_set_stack_ptr    PARAMS ((FILE *, int, int));
*************** static const struct mcu_type_s avr_mcu_t
*** 161,167 ****
  };
  
  void
! avr_override_options (void)
  {
    const struct mcu_type_s *t;
  
--- 161,167 ----
  };
  
  void
! avr_override_options ()
  {
    const struct mcu_type_s *t;
  
*************** avr_override_options (void)
*** 182,188 ****
      {
        case AVR1:
        default:
!       fatal ("MCU `%s' not supported", avr_mcu_name);
        case AVR2: avr_enhanced_p = 0; avr_mega_p = 0; break;
        case AVR3: avr_enhanced_p = 0; avr_mega_p = 1; break;
        case AVR4: avr_enhanced_p = 1; avr_mega_p = 0; break;
--- 182,188 ----
      {
        case AVR1:
        default:
! 	fatal ("MCU `%s' not supported", avr_mcu_name);
        case AVR2: avr_enhanced_p = 0; avr_mega_p = 0; break;
        case AVR3: avr_enhanced_p = 0; avr_mega_p = 1; break;
        case AVR4: avr_enhanced_p = 1; avr_mega_p = 0; break;
*************** avr_override_options (void)
*** 193,199 ****
  
  /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
  void
! avr_init_once (void)
  {
    tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
    memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
--- 193,199 ----
  
  /* Initialize TMP_REG_RTX and ZERO_REG_RTX */
  void
! avr_init_once ()
  {
    tmp_reg_rtx = xmalloc (sizeof (struct rtx_def) + 1 * sizeof (rtunion));
    memset (tmp_reg_rtx, 0, sizeof (struct rtx_def) + 1 * sizeof (rtunion));
*************** signal_function_p (func)
*** 321,329 ****
  /* Compute offset between arg_pointer and frame_pointer */
  
  int
! initial_elimination_offset (from,to)
!      int from ATTRIBUTE_UNUSED;
!      int to ATTRIBUTE_UNUSED;
  {
    int reg;
    if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
--- 321,329 ----
  /* Compute offset between arg_pointer and frame_pointer */
  
  int
! initial_elimination_offset (from, to)
!      int from;
!      int to;
  {
    int reg;
    if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
*************** out_set_stack_ptr (file, before, after)
*** 517,523 ****
  /* Output function prologue */
  
  void
! function_prologue (FILE *file, int size)
  {
    int reg;
    int interrupt_func_p;
--- 517,525 ----
  /* Output function prologue */
  
  void
! function_prologue (file, size)
!      FILE *file;
!      int size;
  {
    int reg;
    int interrupt_func_p;
*************** function_prologue (FILE *file, int size)
*** 651,657 ****
  /* Output function epilogue */
  
  void
! function_epilogue (FILE *file, int size)
  {
    int reg;
    int interrupt_func_p;
--- 653,661 ----
  /* Output function epilogue */
  
  void
! function_epilogue (file, size)
!      FILE *file;
!      int size;
  {
    int reg;
    int interrupt_func_p;
*************** legitimize_address (x, oldx, mode)
*** 884,890 ****
  
  /* Return a pointer register name as a string */
  
! static char *
  ptrreg_to_str (regno)
       int regno;
  {
--- 888,894 ----
  
  /* Return a pointer register name as a string */
  
! static const char *
  ptrreg_to_str (regno)
       int regno;
  {
*************** ptrreg_to_str (regno)
*** 902,908 ****
  /* Return the condition name as a string.
     Used in conditional jump constructing  */
  
! static char *
  cond_string (code)
       enum rtx_code code;
  {
--- 906,912 ----
  /* Return the condition name as a string.
     Used in conditional jump constructing  */
  
! static const char *
  cond_string (code)
       enum rtx_code code;
  {
*************** class_max_nregs (class, mode)
*** 1147,1153 ****
     3 - absolute jump (only for ATmega[16]03).  */
  
  int
! avr_jump_mode (x,insn)
       rtx x;                     /* jump operand */
       rtx insn;                  /* jump insn */
  {
--- 1151,1157 ----
     3 - absolute jump (only for ATmega[16]03).  */
  
  int
! avr_jump_mode (x, insn)
       rtx x;                     /* jump operand */
       rtx insn;                  /* jump insn */
  {
*************** avr_jump_mode (x,insn)
*** 1169,1176 ****
  /* return a AVR condition jump commands.
   LEN is a number returned by avr_jump_mode function.  */
  
! char *
! ret_cond_branch (cond,len)
       RTX_CODE cond;
       int len;
  {
--- 1173,1180 ----
  /* return a AVR condition jump commands.
   LEN is a number returned by avr_jump_mode function.  */
  
! const char *
! ret_cond_branch (cond, len)
       RTX_CODE cond;
       int len;
  {
*************** final_prescan_insn (insn, operand, num_o
*** 1289,1296 ****
      }
  }
  
! /* return 1 if undefined,
!    1 if always true or always false  */
  
  int
  avr_simplify_comparision_p (mode, operator, x)
--- 1293,1299 ----
      }
  }
  
! /* Return 0 if undefined, 1 if always true or always false.  */
  
  int
  avr_simplify_comparision_p (mode, operator, x)
*************** function_arg_advance (cum, mode, type, n
*** 1416,1422 ****
  /***********************************************************************
    Functions for outputting various mov's for a various modes
  ************************************************************************/
! char *
  output_movqi (insn, operands, l)
       rtx insn;
       rtx operands[];
--- 1419,1425 ----
  /***********************************************************************
    Functions for outputting various mov's for a various modes
  ************************************************************************/
! const char *
  output_movqi (insn, operands, l)
       rtx insn;
       rtx operands[];
*************** output_movqi (insn, operands, l)
*** 1454,1460 ****
  		return AS1 (clr,%0);
  	      else if (src == const1_rtx)
  		{
! 		  if (reg_was_0 (insn, operands[0]))
  		    return AS1 (inc,%0 ; reg_was_0);
  
  		  *l = 2;
--- 1457,1463 ----
  		return AS1 (clr,%0);
  	      else if (src == const1_rtx)
  		{
! 		  if (reg_was_0 (insn, dest))
  		    return AS1 (inc,%0 ; reg_was_0);
  
  		  *l = 2;
*************** output_movqi (insn, operands, l)
*** 1463,1469 ****
  		}
  	      else if (src == const2_rtx)
  		{
! 		  if (reg_was_0 (insn, operands[0]))
  		    {
  		      *l = 2;
  		      return (AS1 (inc,%0 ; reg_was_0) CR_TAB
--- 1466,1472 ----
  		}
  	      else if (src == const2_rtx)
  		{
! 		  if (reg_was_0 (insn, dest))
  		    {
  		      *l = 2;
  		      return (AS1 (inc,%0 ; reg_was_0) CR_TAB
*************** output_movqi (insn, operands, l)
*** 1478,1484 ****
  	      else if (src == constm1_rtx)
  		{
  		  /* Immediate constants -1 to any register */
! 		  if (reg_was_0 (insn, operands[0]))
  		    return AS1 (dec,%0 ; reg_was_0);
  
  		  *l = 2;
--- 1481,1487 ----
  	      else if (src == constm1_rtx)
  		{
  		  /* Immediate constants -1 to any register */
! 		  if (reg_was_0 (insn, dest))
  		    return AS1 (dec,%0 ; reg_was_0);
  
  		  *l = 2;
*************** output_movqi (insn, operands, l)
*** 1500,1527 ****
      }
    else if (GET_CODE (dest) == MEM)
      {
!       int save = 0;
!       char *template;
!       
!       if (operands[1] == const0_rtx)
! 	{
! 	  operands[1] = zero_reg_rtx;
! 	  save = 1;
! 	}
!       
        template = out_movqi_mr_r (insn, operands, real_l);
  
        if (!real_l)
  	output_asm_insn (template, operands);
!       
!       if (save)
! 	operands[1] = const0_rtx;
      }
    return "";
  }
  
  
! char *
  output_movhi (insn, operands, l)
       rtx insn;
       rtx operands[];
--- 1503,1525 ----
      }
    else if (GET_CODE (dest) == MEM)
      {
!       const char *template;
! 
!       if (src == const0_rtx)
! 	operands[1] = zero_reg_rtx;
! 
        template = out_movqi_mr_r (insn, operands, real_l);
  
        if (!real_l)
  	output_asm_insn (template, operands);
! 
!       operands[1] = src;
      }
    return "";
  }
  
  
! const char *
  output_movhi (insn, operands, l)
       rtx insn;
       rtx operands[];
*************** output_movhi (insn, operands, l)
*** 1573,1579 ****
  	      return (AS2 (movw,%0,%1));
  	    }
  
! 	  if (true_regnum (operands[0]) > true_regnum (operands[1]))
  	    {
  	      *l = 2;
  	      return (AS2 (mov,%B0,%B1) CR_TAB
--- 1571,1577 ----
  	      return (AS2 (movw,%0,%1));
  	    }
  
! 	  if (true_regnum (dest) > true_regnum (src))
  	    {
  	      *l = 2;
  	      return (AS2 (mov,%B0,%B1) CR_TAB
*************** output_movhi (insn, operands, l)
*** 1590,1595 ****
--- 1588,1600 ----
  	{
  	  if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
  	    {
+ 	      if (byte_immediate_operand (src, HImode)
+ 		  && reg_was_0 (insn, dest))
+ 		{
+ 		  *l = 1;
+ 		  return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
+ 		}
+ 
  	      *l = 2;
  	      return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
  		      AS2 (ldi,%B0,hi8(%1)));
*************** output_movhi (insn, operands, l)
*** 1605,1611 ****
  		}
  	      else if (src == const1_rtx)
  		{
! 		  if (reg_was_0 (insn, operands[0]))
  		    {
  		      *l = 1;
  		      return AS1 (inc,%0 ; reg_was_0);
--- 1610,1616 ----
  		}
  	      else if (src == const1_rtx)
  		{
! 		  if (reg_was_0 (insn, dest))
  		    {
  		      *l = 1;
  		      return AS1 (inc,%0 ; reg_was_0);
*************** output_movhi (insn, operands, l)
*** 1617,1623 ****
  		}
  	      else if (src == const2_rtx)
  		{
! 		  if (reg_was_0 (insn, operands[0]))
  		    {
  		      *l = 2;
  		      return (AS1 (inc,%0 ; reg_was_0) CR_TAB
--- 1622,1628 ----
  		}
  	      else if (src == const2_rtx)
  		{
! 		  if (reg_was_0 (insn, dest))
  		    {
  		      *l = 2;
  		      return (AS1 (inc,%0 ; reg_was_0) CR_TAB
*************** output_movhi (insn, operands, l)
*** 1632,1638 ****
  	      else if (src == constm1_rtx)
  		{
  		  /* Immediate constants -1 to any register */
! 		  if (reg_was_0 (insn, operands[0]))
  		    {
  		      *l = 2;
  		      return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
--- 1637,1643 ----
  	      else if (src == constm1_rtx)
  		{
  		  /* Immediate constants -1 to any register */
! 		  if (reg_was_0 (insn, dest))
  		    {
  		      *l = 2;
  		      return (AS1 (dec,%A0 ; reg_was_0) CR_TAB
*************** output_movhi (insn, operands, l)
*** 1678,1717 ****
      }
    else if (GET_CODE (dest) == MEM)
      {
!       int save = 0;
!       char *template;
!       
!       if (operands[1] == const0_rtx)
! 	{
! 	  operands[1] = zero_reg_rtx;
! 	  save = 1;
! 	}
!       
        template = out_movhi_mr_r (insn, operands, real_l);
  
        if (!real_l)
  	output_asm_insn (template, operands);
!       
!       if (save)
! 	operands[1] = const0_rtx;
        return "";
      }
    fatal_insn ("Invalid insn:", insn);
    return "";
  }
  
! char *
  out_movqi_r_mr (insn, op, l)
       rtx insn;
       rtx op[];
       int *l; /* instruction length */
  {
!   rtx x;
    int dummy;
    
    if (!l)
      l = &dummy;
-   x = XEXP (op[1],0);
    
    if (CONSTANT_ADDRESS_P (x))
      {
--- 1683,1718 ----
      }
    else if (GET_CODE (dest) == MEM)
      {
!       const char *template;
! 
!       if (src == const0_rtx)
! 	operands[1] = zero_reg_rtx;
! 
        template = out_movhi_mr_r (insn, operands, real_l);
  
        if (!real_l)
  	output_asm_insn (template, operands);
! 
!       operands[1] = src;
        return "";
      }
    fatal_insn ("Invalid insn:", insn);
    return "";
  }
  
! const char *
  out_movqi_r_mr (insn, op, l)
       rtx insn;
       rtx op[];
       int *l; /* instruction length */
  {
!   rtx dest = op[0];
!   rtx src = op[1];
!   rtx x = XEXP (src, 0);
    int dummy;
    
    if (!l)
      l = &dummy;
    
    if (CONSTANT_ADDRESS_P (x))
      {
*************** out_movqi_r_mr (insn, op, l)
*** 1728,1739 ****
        && REG_P (XEXP (x,0))
        && GET_CODE (XEXP (x,1)) == CONST_INT)
      {
!       if((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (op[1]))) >= 63)
  	{
  	  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])))
  	    {
  	      *l = 3;
  	      op[4] = XEXP (x, 1);
--- 1729,1740 ----
        && REG_P (XEXP (x,0))
        && GET_CODE (XEXP (x,1)) == CONST_INT)
      {
!       if((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
  	{
  	  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 (src)))
  	    {
  	      *l = 3;
  	      op[4] = XEXP (x, 1);
*************** out_movqi_r_mr (insn, op, l)
*** 1757,1763 ****
  	  op[4] = XEXP (x, 1);
  	  /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
  	     it but I have this situation with extremal optimizing options.  */
! 	  if (reg_overlap_mentioned_p (op[0],XEXP (x,0))
  	      || reg_unused_after (insn, XEXP (x,0)))
  	    {
  	      *l = 2;
--- 1758,1764 ----
  	  op[4] = XEXP (x, 1);
  	  /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
  	     it but I have this situation with extremal optimizing options.  */
! 	  if (reg_overlap_mentioned_p (dest, XEXP (x,0))
  	      || reg_unused_after (insn, XEXP (x,0)))
  	    {
  	      *l = 2;
*************** out_movqi_r_mr (insn, op, l)
*** 1776,1789 ****
    return AS2 (ld,%0,%1);
  }
  
! char *
  out_movhi_r_mr (insn, op, l)
       rtx insn;
       rtx op[];
       int *l; /* instruction length */
  {
!   int reg_dest = true_regnum (op[0]);
!   int reg_base = true_regnum (XEXP (op[1], 0));
    int tmp;
  
    if (!l)
--- 1777,1793 ----
    return AS2 (ld,%0,%1);
  }
  
! const char *
  out_movhi_r_mr (insn, op, l)
       rtx insn;
       rtx op[];
       int *l; /* instruction length */
  {
!   rtx dest = op[0];
!   rtx src = op[1];
!   rtx base = XEXP (src, 0);
!   int reg_dest = true_regnum (dest);
!   int reg_base = true_regnum (base);
    int tmp;
  
    if (!l)
*************** out_movhi_r_mr (insn, op, l)
*** 1800,1806 ****
  	}
        else if (reg_base == REG_X)        /* (R26) */
          {
!           if (reg_unused_after (insn, XEXP (op[1],0)))
  	    {
  	      *l = 2;
  	      return (AS2 (ld,%A0,X+) CR_TAB
--- 1804,1810 ----
  	}
        else if (reg_base == REG_X)        /* (R26) */
          {
!           if (reg_unused_after (insn, base))
  	    {
  	      *l = 2;
  	      return (AS2 (ld,%A0,X+) CR_TAB
*************** out_movhi_r_mr (insn, op, l)
*** 1818,1837 ****
  		  AS2 (ldd,%B0,%1+1));
  	}
      }
!   else if (GET_CODE (XEXP (op[1],0)) == PLUS) /* (R + i) */
      {
!       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);
! 	  op[4] = 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])))
  	    {
  	      *l = 4;
  	      return (AS2 (adiw,r28,%4-62) CR_TAB
--- 1822,1840 ----
  		  AS2 (ldd,%B0,%1+1));
  	}
      }
!   else if (GET_CODE (base) == PLUS) /* (R + i) */
      {
!       int disp = INTVAL (XEXP (base, 1));
!       int reg_base = true_regnum (XEXP (base, 0));
        
!       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
  	{
! 	  op[4] = XEXP (base, 1);
  
! 	  if (REGNO (XEXP (base, 0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
  	  
! 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
  	    {
  	      *l = 4;
  	      return (AS2 (adiw,r28,%4-62) CR_TAB
*************** out_movhi_r_mr (insn, op, l)
*** 1856,1862 ****
  	     it but I have this situation with extremal
  	     optimization options.  */
  	  
! 	  op[4] = XEXP (XEXP (op[1],0), 1);
  	  
  	  if (reg_base == reg_dest)
  	    {
--- 1859,1865 ----
  	     it but I have this situation with extremal
  	     optimization options.  */
  	  
! 	  op[4] = XEXP (base, 1);
  	  
  	  if (reg_base == reg_dest)
  	    {
*************** out_movhi_r_mr (insn, op, l)
*** 1895,1920 ****
        return (AS2 (ldd,%A0,%A1) CR_TAB
  	      AS2 (ldd,%B0,%B1));
      }
!   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);
  
        *l = 2;
        return (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);
  
        *l = 2;
        return (AS2 (ld,%A0,%1)  CR_TAB
  	      AS2 (ld,%B0,%1));
      }
!   else if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
      {
        *l = 4;
        return (AS2 (lds,%A0,%A1) CR_TAB
  	      AS2 (lds,%B0,%B1));
--- 1898,1929 ----
        return (AS2 (ldd,%A0,%A1) CR_TAB
  	      AS2 (ldd,%B0,%B1));
      }
!   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
      {
!       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
  	fatal_insn ("Incorrect insn:", insn);
  
        *l = 2;
        return (AS2 (ld,%B0,%1) CR_TAB
  	      AS2 (ld,%A0,%1));
      }
!   else if (GET_CODE (base) == POST_INC) /* (R++) */
      {
!       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
  	fatal_insn ("Incorrect insn:", insn);
  
        *l = 2;
        return (AS2 (ld,%A0,%1)  CR_TAB
  	      AS2 (ld,%B0,%1));
      }
!   else if (CONSTANT_ADDRESS_P (base))
      {
+       if (io_address_p (base, 2))
+ 	{
+ 	  *l = 2;
+ 	  return (AS2 (in,%A0,%A1-0x20) CR_TAB
+ 		  AS2 (in,%B0,%B1-0x20));
+ 	}
        *l = 4;
        return (AS2 (lds,%A0,%A1) CR_TAB
  	      AS2 (lds,%B0,%B1));
*************** out_movhi_r_mr (insn, op, l)
*** 1924,1937 ****
    return "";
  }
  
! char *
! out_movsi_r_mr (insn,op,l)
       rtx insn;
       rtx op[];
       int *l; /* instruction length */
  {
!   int reg_dest=true_regnum (op[0]);
!   int reg_base=true_regnum (XEXP (op[1],0));
    int tmp;
  
    if (!l)
--- 1933,1949 ----
    return "";
  }
  
! const char *
! out_movsi_r_mr (insn, op, l)
       rtx insn;
       rtx op[];
       int *l; /* instruction length */
  {
!   rtx dest = op[0];
!   rtx src = op[1];
!   rtx base = XEXP (src, 0);
!   int reg_dest = true_regnum (dest);
!   int reg_base = true_regnum (base);
    int tmp;
  
    if (!l)
*************** out_movsi_r_mr (insn,op,l)
*** 1954,1960 ****
                            AS2 (ld,__tmp_reg__,X+)  CR_TAB
                            AS2 (ld,%D0,X)  CR_TAB
                            AS2 (mov,%C0,__tmp_reg__));
!           else if (reg_unused_after (insn,XEXP (op[1],0)))
              return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
                             AS2 (ld,%B0,X+) CR_TAB
                             AS2 (ld,%C0,X+) CR_TAB
--- 1966,1972 ----
                            AS2 (ld,__tmp_reg__,X+)  CR_TAB
                            AS2 (ld,%D0,X)  CR_TAB
                            AS2 (mov,%C0,__tmp_reg__));
!           else if (reg_unused_after (insn, base))
              return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
                             AS2 (ld,%B0,X+) CR_TAB
                             AS2 (ld,%C0,X+) CR_TAB
*************** out_movsi_r_mr (insn,op,l)
*** 1987,2002 ****
                            AS2 (ldd,%D0,%1+3));
          }
      }
!   else if (GET_CODE (XEXP (op[1],0)) == PLUS) /* (R + i) */
      {
!       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
--- 1999,2013 ----
                            AS2 (ldd,%D0,%1+3));
          }
      }
!   else if (GET_CODE (base) == PLUS) /* (R + i) */
      {
!       int disp = INTVAL (XEXP (base, 1));
        
!       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
  	{
! 	  if (REGNO (XEXP (base, 0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
  	    {
  	      op[4] = GEN_INT (disp - 60);
  	      return *l=6,(AS2 (adiw, r28, %4) CR_TAB
*************** out_movsi_r_mr (insn,op,l)
*** 2008,2014 ****
  	    }
  	  else
  	    {
! 	      op[4] = XEXP (x,1);
  	      return *l=8,(AS2 (subi, r28, lo8(-%4))  CR_TAB
  			   AS2 (sbci, r29, hi8(-%4)) CR_TAB
  			   AS2 (ld, %A0,Y)             CR_TAB
--- 2019,2025 ----
  	    }
  	  else
  	    {
! 	      op[4] = XEXP (base, 1);
  	      return *l=8,(AS2 (subi, r28, lo8(-%4))  CR_TAB
  			   AS2 (sbci, r29, hi8(-%4)) CR_TAB
  			   AS2 (ld, %A0,Y)             CR_TAB
*************** out_movsi_r_mr (insn,op,l)
*** 2020,2026 ****
  	    }
  	}
  
!       reg_base = true_regnum (XEXP (XEXP (op[1],0), 0));
        if (reg_dest == reg_base)
          return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
                        AS2 (ldd,%C0,%C1) CR_TAB
--- 2031,2037 ----
  	    }
  	}
  
!       reg_base = true_regnum (XEXP (base, 0));
        if (reg_dest == reg_base)
          return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
                        AS2 (ldd,%C0,%C1) CR_TAB
*************** out_movsi_r_mr (insn,op,l)
*** 2038,2054 ****
                      AS2 (ldd,%C0,%C1) CR_TAB
                      AS2 (ldd,%D0,%D1));
      }
!   else if (GET_CODE (XEXP (op[1],0)) == PRE_DEC) /* (--R) */
      return *l=4, (AS2 (ld,%D0,%1) CR_TAB
  		  AS2 (ld,%C0,%1) CR_TAB
  		  AS2 (ld,%B0,%1) CR_TAB
  		  AS2 (ld,%A0,%1));
!   else if (GET_CODE (XEXP (op[1],0)) == POST_INC) /* (R++) */
      return *l=4, (AS2 (ld,%A0,%1) CR_TAB
  		  AS2 (ld,%B0,%1) CR_TAB
  		  AS2 (ld,%C0,%1) CR_TAB
  		  AS2 (ld,%D0,%1));
!   else if (CONSTANT_ADDRESS_P (XEXP (op[1],0)))
        return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
  		    AS2 (lds,%B0,%B1) CR_TAB
  		    AS2 (lds,%C0,%C1) CR_TAB
--- 2049,2065 ----
                      AS2 (ldd,%C0,%C1) CR_TAB
                      AS2 (ldd,%D0,%D1));
      }
!   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
      return *l=4, (AS2 (ld,%D0,%1) CR_TAB
  		  AS2 (ld,%C0,%1) CR_TAB
  		  AS2 (ld,%B0,%1) CR_TAB
  		  AS2 (ld,%A0,%1));
!   else if (GET_CODE (base) == POST_INC) /* (R++) */
      return *l=4, (AS2 (ld,%A0,%1) CR_TAB
  		  AS2 (ld,%B0,%1) CR_TAB
  		  AS2 (ld,%C0,%1) CR_TAB
  		  AS2 (ld,%D0,%1));
!   else if (CONSTANT_ADDRESS_P (base))
        return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
  		    AS2 (lds,%B0,%B1) CR_TAB
  		    AS2 (lds,%C0,%C1) CR_TAB
*************** out_movsi_r_mr (insn,op,l)
*** 2058,2077 ****
    return "";
  }
  
! char *
! out_movsi_mr_r (insn,op,l)
       rtx insn;
       rtx op[];
       int *l;
  {
!   int reg_base = true_regnum (XEXP (op[0],0));
!   int reg_dest = true_regnum (op[1]);
    int tmp;
    
    if (!l)
      l = &tmp;
    
!   if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
      return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
  		 AS2 (sts,%B0,%B1) CR_TAB
  		 AS2 (sts,%C0,%C1) CR_TAB
--- 2069,2091 ----
    return "";
  }
  
! const char *
! out_movsi_mr_r (insn, op, l)
       rtx insn;
       rtx op[];
       int *l;
  {
!   rtx dest = op[0];
!   rtx src = op[1];
!   rtx base = XEXP (dest, 0);
!   int reg_base = true_regnum (base);
!   int reg_src = true_regnum (src);
    int tmp;
    
    if (!l)
      l = &tmp;
    
!   if (CONSTANT_ADDRESS_P (base))
      return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
  		 AS2 (sts,%B0,%B1) CR_TAB
  		 AS2 (sts,%C0,%C1) CR_TAB
*************** out_movsi_mr_r (insn,op,l)
*** 2080,2088 ****
      {
        if (reg_base == REG_X)                /* (R26) */
          {
!           if (reg_dest == REG_X)
              {
!               if (reg_unused_after (insn,XEXP (op[0],0)))
                  return *l=5, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
                                AS2 (st,%0+,%A1) CR_TAB
                                AS2 (st,%0+,__tmp_reg__)  CR_TAB
--- 2094,2102 ----
      {
        if (reg_base == REG_X)                /* (R26) */
          {
!           if (reg_src == REG_X)
              {
!               if (reg_unused_after (insn, base))
                  return *l=5, (AS2 (mov,__tmp_reg__,%B1) CR_TAB
                                AS2 (st,%0+,%A1) CR_TAB
                                AS2 (st,%0+,__tmp_reg__)  CR_TAB
*************** out_movsi_mr_r (insn,op,l)
*** 2096,2104 ****
                                AS2 (st,%0,%D1)  CR_TAB
                                AS2 (sbiw,r26,3));
              }
!           else if (reg_base == reg_dest+2)
              {
!               if (reg_unused_after (insn,XEXP (op[0],0)))
                  return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
                                AS2 (mov,__tmp_reg__,%D1) CR_TAB
                                AS2 (st,%0+,%A1) CR_TAB
--- 2110,2118 ----
                                AS2 (st,%0,%D1)  CR_TAB
                                AS2 (sbiw,r26,3));
              }
!           else if (reg_base == reg_src + 2)
              {
!               if (reg_unused_after (insn, base))
                  return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
                                AS2 (mov,__tmp_reg__,%D1) CR_TAB
                                AS2 (st,%0+,%A1) CR_TAB
*************** out_movsi_mr_r (insn,op,l)
*** 2128,2142 ****
  		      AS2 (std,%0+2,%C1) CR_TAB
  		      AS2 (std,%0+3,%D1));
      }
!   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
--- 2142,2155 ----
  		      AS2 (std,%0+2,%C1) CR_TAB
  		      AS2 (std,%0+3,%D1));
      }
!   else if (GET_CODE (base) == PLUS) /* (R + i) */
      {
!       int disp = INTVAL (XEXP (base, 1));
!       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
  	{
! 	  if (REGNO (XEXP (base, 0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
  	    {
  	      op[4] = GEN_INT (disp - 60);
  	      return *l=6,(AS2 (adiw, r28, %4) CR_TAB
*************** out_movsi_mr_r (insn,op,l)
*** 2148,2154 ****
  	    }
  	  else
  	    {
! 	      op[4] = XEXP (x,1);
  	      return *l=8,(AS2 (subi, r28, lo8(-%4))  CR_TAB
  			   AS2 (sbci, r29, hi8(-%4)) CR_TAB
  			   AS2 (st, Y,%A1)             CR_TAB
--- 2161,2167 ----
  	    }
  	  else
  	    {
! 	      op[4] = XEXP (base, 1);
  	      return *l=8,(AS2 (subi, r28, lo8(-%4))  CR_TAB
  			   AS2 (sbci, r29, hi8(-%4)) CR_TAB
  			   AS2 (st, Y,%A1)             CR_TAB
*************** out_movsi_mr_r (insn,op,l)
*** 2164,2175 ****
  		    AS2 (std,%C0,%C1) CR_TAB
  		    AS2 (std,%D0,%D1));
      }
!   else if (GET_CODE (XEXP (op[0],0)) == PRE_DEC) /* (--R) */
      return *l=4, (AS2 (st,%0,%D1) CR_TAB
  		  AS2 (st,%0,%C1) CR_TAB
  		  AS2 (st,%0,%B1) CR_TAB
  		  AS2 (st,%0,%A1));
!   else if (GET_CODE (XEXP (op[0],0)) == POST_INC) /* (R++) */
      return *l=4, (AS2 (st,%0,%A1)  CR_TAB
  		  AS2 (st,%0,%B1) CR_TAB
  		  AS2 (st,%0,%C1) CR_TAB
--- 2177,2188 ----
  		    AS2 (std,%C0,%C1) CR_TAB
  		    AS2 (std,%D0,%D1));
      }
!   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
      return *l=4, (AS2 (st,%0,%D1) CR_TAB
  		  AS2 (st,%0,%C1) CR_TAB
  		  AS2 (st,%0,%B1) CR_TAB
  		  AS2 (st,%0,%A1));
!   else if (GET_CODE (base) == POST_INC) /* (R++) */
      return *l=4, (AS2 (st,%0,%A1)  CR_TAB
  		  AS2 (st,%0,%B1) CR_TAB
  		  AS2 (st,%0,%C1) CR_TAB
*************** out_movsi_mr_r (insn,op,l)
*** 2178,2184 ****
    return "";
  }
  
! char *
  output_movsisf(insn, operands, l)
       rtx insn;
       rtx operands[];
--- 2191,2197 ----
    return "";
  }
  
! const char *
  output_movsisf(insn, operands, l)
       rtx insn;
       rtx operands[];
*************** output_movsisf(insn, operands, l)
*** 2229,2234 ****
--- 2242,2254 ----
  	{
  	  if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
  	    {
+ 	      if (byte_immediate_operand (src, SImode)
+ 		  && reg_was_0 (insn, dest))
+ 		{
+ 		  *l = 1;
+ 		  return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0));
+ 		}
+ 
  	      *l = 4;
  	      return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
  		      AS2 (ldi,%B0,hi8(%1))  CR_TAB
*************** output_movsisf(insn, operands, l)
*** 2255,2261 ****
  		}
  	      else if (src == const1_rtx)
  		{
! 		  if (reg_was_0 (insn, operands[0]))
  		    {
  		      *l = 1;
  		      return AS1 (inc,%A0 ; reg_was_0);
--- 2275,2281 ----
  		}
  	      else if (src == const1_rtx)
  		{
! 		  if (reg_was_0 (insn, dest))
  		    {
  		      *l = 1;
  		      return AS1 (inc,%A0 ; reg_was_0);
*************** output_movsisf(insn, operands, l)
*** 2269,2275 ****
  		}
  	      else if (src == const2_rtx)
  		{
! 		  if (reg_was_0 (insn, operands[0]))
  		    {
  		      *l = 2;
  		      return (AS1 (inc,%A0 ; reg_was_0) CR_TAB
--- 2289,2295 ----
  		}
  	      else if (src == const2_rtx)
  		{
! 		  if (reg_was_0 (insn, dest))
  		    {
  		      *l = 2;
  		      return (AS1 (inc,%A0 ; reg_was_0) CR_TAB
*************** output_movsisf(insn, operands, l)
*** 2296,2302 ****
  	      else if (src == constm1_rtx)
  		{
  		  /* Immediate constants -1 to any register */
! 		  if (reg_was_0 (insn, operands[0]))
  		    {
  		      if (AVR_ENHANCED)
  			{
--- 2316,2322 ----
  	      else if (src == constm1_rtx)
  		{
  		  /* Immediate constants -1 to any register */
! 		  if (reg_was_0 (insn, dest))
  		    {
  		      if (AVR_ENHANCED)
  			{
*************** output_movsisf(insn, operands, l)
*** 2346,2386 ****
      }
    else if (GET_CODE (dest) == MEM)
      {
!       int save = 0;
!       char *template;
!       
!       if (operands[1] == const0_rtx)
! 	{
  	  operands[1] = zero_reg_rtx;
! 	  save = 1;
! 	}
!       
        template = out_movsi_mr_r (insn, operands, real_l);
  
        if (!real_l)
  	output_asm_insn (template, operands);
!       
!       if (save)
! 	operands[1] = const0_rtx;
        return "";
      }
    fatal_insn ("Invalid insn:", insn);
    return "";
  }
  
! char *
  out_movqi_mr_r (insn, op, l)
       rtx insn;
       rtx op[];
       int *l; /* instruction length */
  {
!   rtx x;
    int dummy;
  
    if (!l)
      l = &dummy;
-     
-   x = XEXP (op[0],0);
    
    if (CONSTANT_ADDRESS_P (x))
      {
--- 2366,2401 ----
      }
    else if (GET_CODE (dest) == MEM)
      {
!       const char *template;
! 
!       if (src == const0_rtx)
  	  operands[1] = zero_reg_rtx;
! 
        template = out_movsi_mr_r (insn, operands, real_l);
  
        if (!real_l)
  	output_asm_insn (template, operands);
! 
!       operands[1] = src;
        return "";
      }
    fatal_insn ("Invalid insn:", insn);
    return "";
  }
  
! const char *
  out_movqi_mr_r (insn, op, l)
       rtx insn;
       rtx op[];
       int *l; /* instruction length */
  {
!   rtx dest = op[0];
!   rtx src = op[1];
!   rtx x = XEXP (dest, 0);
    int dummy;
  
    if (!l)
      l = &dummy;
    
    if (CONSTANT_ADDRESS_P (x))
      {
*************** out_movqi_mr_r (insn, op, l)
*** 2397,2408 ****
        && REG_P (XEXP (x,0))
        && GET_CODE (XEXP (x,1)) == CONST_INT)
      {
!       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (op[0]))) >= 63)
  	{
  	  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])))
  	    {
  	      *l = 3;
  	      op[4] = XEXP (x, 1);
--- 2412,2423 ----
        && REG_P (XEXP (x,0))
        && GET_CODE (XEXP (x,1)) == CONST_INT)
      {
!       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
  	{
  	  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 (dest)))
  	    {
  	      *l = 3;
  	      op[4] = XEXP (x, 1);
*************** out_movqi_mr_r (insn, op, l)
*** 2424,2430 ****
        else if (REGNO (XEXP (x,0)) == REG_X)
  	{
  	  op[4] = XEXP (x,1);
! 	  if (reg_overlap_mentioned_p (op[1],XEXP (x,0)))
  	    {
  	      if (reg_unused_after (insn, XEXP (x,0)))
  		{
--- 2439,2445 ----
        else if (REGNO (XEXP (x,0)) == REG_X)
  	{
  	  op[4] = XEXP (x,1);
! 	  if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
  	    {
  	      if (reg_unused_after (insn, XEXP (x,0)))
  		{
*************** out_movqi_mr_r (insn, op, l)
*** 2460,2486 ****
    return AS2 (st,%0,%1);
  }
  
! char *
! out_movhi_mr_r (insn,op,l)
       rtx insn;
       rtx op[];
       int *l;
  {
!   int reg_base = true_regnum (XEXP (op[0],0));
!   int reg_dest = true_regnum (op[1]);
    int tmp;
    if (!l)
      l = &tmp;
!   if (CONSTANT_ADDRESS_P (XEXP (op[0],0)))
!     return *l=4,(AS2 (sts,%A0,%A1) CR_TAB
! 		 AS2 (sts,%B0,%B1));
    if (reg_base > 0)
      {
        if (reg_base == REG_X)
          {
!           if (reg_dest == REG_X)
              {
!               if (reg_unused_after (insn, op[1]))
                  return *l=3, (AS2 (mov,__tmp_reg__,r27) CR_TAB
                                AS2 (st ,X+,r26) CR_TAB
                                AS2 (st ,X,__tmp_reg__));
--- 2475,2512 ----
    return AS2 (st,%0,%1);
  }
  
! const char *
! out_movhi_mr_r (insn, op, l)
       rtx insn;
       rtx op[];
       int *l;
  {
!   rtx dest = op[0];
!   rtx src = op[1];
!   rtx base = XEXP (dest, 0);
!   int reg_base = true_regnum (base);
!   int reg_src = true_regnum (src);
    int tmp;
    if (!l)
      l = &tmp;
!   if (CONSTANT_ADDRESS_P (base))
!     {
!       if (io_address_p (base, 2))
! 	{
! 	  *l = 2;
! 	  return (AS2 (out,%B0-0x20,%B1) CR_TAB
! 		  AS2 (out,%A0-0x20,%A1));
! 	}
!       return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
! 		      AS2 (sts,%A0,%A1));
!     }
    if (reg_base > 0)
      {
        if (reg_base == REG_X)
          {
!           if (reg_src == REG_X)
              {
!               if (reg_unused_after (insn, src))
                  return *l=3, (AS2 (mov,__tmp_reg__,r27) CR_TAB
                                AS2 (st ,X+,r26) CR_TAB
                                AS2 (st ,X,__tmp_reg__));
*************** out_movhi_mr_r (insn,op,l)
*** 2492,2498 ****
              }
            else
              {
!               if (reg_unused_after (insn, XEXP (op[0],0)))
                  return *l=2, (AS2 (st,X+,%A1) CR_TAB
                                AS2 (st,X,%B1));
                else
--- 2518,2524 ----
              }
            else
              {
!               if (reg_unused_after (insn, base))
                  return *l=2, (AS2 (st,X+,%A1) CR_TAB
                                AS2 (st,X,%B1));
                else
*************** out_movhi_mr_r (insn,op,l)
*** 2505,2519 ****
          return  *l=2, (AS2 (st ,%0,%A1)    CR_TAB
                         AS2 (std,%0+1,%B1));
      }
!   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
--- 2531,2544 ----
          return  *l=2, (AS2 (st ,%0,%A1)    CR_TAB
                         AS2 (std,%0+1,%B1));
      }
!   else if (GET_CODE (base) == PLUS)
      {
!       int disp = INTVAL (XEXP (base, 1));
!       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
  	{
! 	  if (REGNO (XEXP (base, 0)) != REG_Y)
  	    fatal_insn ("Incorrect insn:",insn);
! 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
  	    {
  	      op[4] = GEN_INT (disp - 62);
  	      return *l=4,(AS2 (adiw, r28, %4) CR_TAB
*************** out_movhi_mr_r (insn,op,l)
*** 2523,2529 ****
  	    }
  	  else
  	    {
! 	      op[4] = XEXP (x,1);
  	      return *l=6,(AS2 (subi, r28, lo8(-%4))  CR_TAB
  			   AS2 (sbci, r29, hi8(-%4)) CR_TAB
  			   AS2 (st, Y,%A1)           CR_TAB
--- 2548,2554 ----
  	    }
  	  else
  	    {
! 	      op[4] = XEXP (base, 1);
  	      return *l=6,(AS2 (subi, r28, lo8(-%4))  CR_TAB
  			   AS2 (sbci, r29, hi8(-%4)) CR_TAB
  			   AS2 (st, Y,%A1)           CR_TAB
*************** out_movhi_mr_r (insn,op,l)
*** 2535,2544 ****
        return *l=2, (AS2 (std,%A0,%A1)    CR_TAB
  		    AS2 (std,%B0,%B1));
      }
!   else if (GET_CODE (XEXP (op[0],0)) == PRE_DEC) /* (--R) */
      return *l=2, (AS2 (st,%0,%B1) CR_TAB
  		  AS2 (st,%0,%A1));
!   else if (GET_CODE (XEXP (op[0],0)) == POST_INC) /* (R++) */
      return *l=2, (AS2 (st,%0,%A1)  CR_TAB
  		  AS2 (st,%0,%B1));
    fatal_insn ("Unknown move insn:",insn);
--- 2560,2569 ----
        return *l=2, (AS2 (std,%A0,%A1)    CR_TAB
  		    AS2 (std,%B0,%B1));
      }
!   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
      return *l=2, (AS2 (st,%0,%B1) CR_TAB
  		  AS2 (st,%0,%A1));
!   else if (GET_CODE (base) == POST_INC) /* (R++) */
      return *l=2, (AS2 (st,%0,%A1)  CR_TAB
  		  AS2 (st,%0,%B1));
    fatal_insn ("Unknown move insn:",insn);
*************** out_movhi_mr_r (insn,op,l)
*** 2548,2554 ****
  /* Return 1 if frame pointer for current function required */
  
  int
! frame_pointer_required_p(void)
  {
    return (current_function_calls_alloca
  	  || current_function_args_info.nregs == 0
--- 2573,2579 ----
  /* Return 1 if frame pointer for current function required */
  
  int
! frame_pointer_required_p ()
  {
    return (current_function_calls_alloca
  	  || current_function_args_info.nregs == 0
*************** compare_eq_p (insn)
*** 2595,2602 ****
  
  /* Output test instruction for HImode */
  
! char *
! out_tsthi (insn,l)
       rtx insn;
       int *l;
  {
--- 2620,2627 ----
  
  /* Output test instruction for HImode */
  
! const char *
! out_tsthi (insn, l)
       rtx insn;
       int *l;
  {
*************** out_tsthi (insn,l)
*** 2605,2619 ****
        if (l) *l = 1;
        return AS1 (tst,%B0);
      }
!   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
      {
        if (l) *l = 1;
!       return AS2 (sbiw,%0,0);
      }
!   if (compare_eq_p (insn) && reg_unused_after (insn, SET_SRC (PATTERN (insn))))
      {
        if (l) *l = 1;
!       return AS2 (or,%A0,%B0);
      }
    if (l) *l = 2;
    return (AS2 (cp,%A0,__zero_reg__) CR_TAB
--- 2630,2645 ----
        if (l) *l = 1;
        return AS1 (tst,%B0);
      }
!   if (reg_unused_after (insn, SET_SRC (PATTERN (insn))))
      {
+       /* faster than sbiw if we can clobber the operand */
        if (l) *l = 1;
!       return AS2 (or,%A0,%B0);
      }
!   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
      {
        if (l) *l = 1;
!       return AS2 (sbiw,%0,0);
      }
    if (l) *l = 2;
    return (AS2 (cp,%A0,__zero_reg__) CR_TAB
*************** out_tsthi (insn,l)
*** 2623,2630 ****
  
  /* Output test instruction for SImode */
  
! char *
! out_tstsi (insn,l)
       rtx insn;
       int *l;
  {
--- 2649,2656 ----
  
  /* Output test instruction for SImode */
  
! const char *
! out_tstsi (insn, l)
       rtx insn;
       int *l;
  {
*************** out_tstsi (insn,l)
*** 2652,2659 ****
     Shift count are CONST_INT or REG.  */
  
  void
! out_shift_with_cnt (template,insn,operands,len)
!      char * template;
       rtx insn;
       rtx operands[];
       int *len;
--- 2678,2685 ----
     Shift count are CONST_INT or REG.  */
  
  void
! out_shift_with_cnt (template, insn, operands, len)
!      const char *template;
       rtx insn;
       rtx operands[];
       int *len;
*************** out_shift_with_cnt (template,insn,operan
*** 2729,2736 ****
  
  /* 8bit shift left ((char)x << i)   */
  
! char *
! ashlqi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len;			/* insn length (may be NULL) */
--- 2755,2762 ----
  
  /* 8bit shift left ((char)x << i)   */
  
! const char *
! ashlqi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len;			/* insn length (may be NULL) */
*************** ashlqi3_out (insn,operands,len)
*** 2828,2835 ****
  
  /* 16bit shift left ((short)x << i)   */
  
! char *
! ashlhi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len;
--- 2854,2861 ----
  
  /* 16bit shift left ((short)x << i)   */
  
! const char *
! ashlhi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len;
*************** ashlhi3_out (insn,operands,len)
*** 2877,2884 ****
  
  /* 32bit shift left ((long)x << i)   */
  
! char *
! ashlsi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len;
--- 2903,2910 ----
  
  /* 32bit shift left ((long)x << i)   */
  
! const char *
! ashlsi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len;
*************** ashlsi3_out (insn,operands,len)
*** 2982,2989 ****
  
  /* 8bit arithmetic shift right  ((signed char)x >> i) */
  
! char *
! ashrqi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len; /* insn length */
--- 3008,3015 ----
  
  /* 8bit arithmetic shift right  ((signed char)x >> i) */
  
! const char *
! ashrqi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len; /* insn length */
*************** ashrqi3_out (insn,operands,len)
*** 3054,3061 ****
  
  /* 16bit arithmetic shift right  ((signed short)x >> i) */
  
! char *
! ashrhi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len;
--- 3080,3087 ----
  
  /* 16bit arithmetic shift right  ((signed short)x >> i) */
  
! const char *
! ashrhi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len;
*************** ashrhi3_out (insn,operands,len)
*** 3112,3119 ****
  
  /* 32bit arithmetic shift right  ((signed long)x >> i) */
  
! char *
! ashrsi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len;
--- 3138,3145 ----
  
  /* 32bit arithmetic shift right  ((signed long)x >> i) */
  
! const char *
! ashrsi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len;
*************** ashrsi3_out (insn,operands,len)
*** 3228,3235 ****
  
  /* 8bit logic shift right ((unsigned char)x >> i) */
  
! char *
! lshrqi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len;
--- 3254,3261 ----
  
  /* 8bit logic shift right ((unsigned char)x >> i) */
  
! const char *
! lshrqi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len;
*************** lshrqi3_out (insn,operands,len)
*** 3325,3332 ****
  
  /* 16bit logic shift right ((unsigned short)x >> i) */
  
! char *
! lshrhi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len;
--- 3351,3358 ----
  
  /* 16bit logic shift right ((unsigned short)x >> i) */
  
! const char *
! lshrhi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len;
*************** lshrhi3_out (insn,operands,len)
*** 3380,3387 ****
  
  /* 32bit logic shift right ((unsigned int)x >> i) */
  
! char *
! lshrsi3_out (insn,operands,len)
       rtx insn;
       rtx operands[];
       int *len;
--- 3406,3413 ----
  
  /* 32bit logic shift right ((unsigned int)x >> i) */
  
! const char *
! lshrsi3_out (insn, operands, len)
       rtx insn;
       rtx operands[];
       int *len;
*************** lshrsi3_out (insn,operands,len)
*** 3477,3483 ****
   LEN is the initially computed length of the insn.  */
  
  int
! adjust_insn_length (insn,len)
       rtx insn;
       int len;
  {
--- 3503,3509 ----
   LEN is the initially computed length of the insn.  */
  
  int
! adjust_insn_length (insn, len)
       rtx insn;
       int len;
  {
*************** adjust_insn_length (insn,len)
*** 3537,3549 ****
  	    {
  	      HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
  	      if (GET_MODE (op[1]) == SImode)
! 		len = (((mask & 0xff) == 0)
! 		       + ((mask & 0xff00) == 0)
! 		       + ((mask & 0xff0000UL) == 0)
! 		       + ((mask & 0xff000000UL) ==0));
  	      else if (GET_MODE (op[1]) == HImode)
! 		len = (((mask & 0xff) == 0)
! 		       + ((mask & 0xff00) == 0));
  	    }
  	}
      }
--- 3563,3575 ----
  	    {
  	      HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
  	      if (GET_MODE (op[1]) == SImode)
! 		len = (((mask & 0xff) != 0)
! 		       + ((mask & 0xff00) != 0)
! 		       + ((mask & 0xff0000UL) != 0)
! 		       + ((mask & 0xff000000UL) != 0));
  	      else if (GET_MODE (op[1]) == HImode)
! 		len = (((mask & 0xff) != 0)
! 		       + ((mask & 0xff00) != 0));
  	    }
  	}
      }
*************** _reg_unused_after (insn, reg)
*** 3718,3724 ****
  /* Output rtx VALUE as .byte to file FILE */
  
  void
! asm_output_char(file,value)
       FILE *file;
       rtx value;
  {
--- 3744,3750 ----
  /* Output rtx VALUE as .byte to file FILE */
  
  void
! asm_output_char (file, value)
       FILE *file;
       rtx value;
  {
*************** asm_output_char(file,value)
*** 3731,3741 ****
  /* Output VALUE as .byte to file FILE */
  
  void
! asm_output_byte (file,value)
       FILE *file;
       int value;
  {
!   fprintf (file, "\t.byte 0x%x\n",value & 0xff);
  }
  
  
--- 3757,3767 ----
  /* Output VALUE as .byte to file FILE */
  
  void
! asm_output_byte (file, value)
       FILE *file;
       int value;
  {
!   fprintf (file, "\t.byte 0x%x\n", value & 0xff);
  }
  
  
*************** asm_output_float (file, n)
*** 3773,3779 ****
    
    REAL_VALUE_TO_TARGET_SINGLE (n, val);
    REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
!   fprintf (file, "\t.long 0x%08lx\t/* %s */\n",val, dstr);
  }
  
  /* Sets section name for declaration DECL */
--- 3799,3805 ----
    
    REAL_VALUE_TO_TARGET_SINGLE (n, val);
    REAL_VALUE_TO_DECIMAL (n, "%g", dstr);
!   fprintf (file, "\t.long 0x%08lx\t/* %s */\n", val, dstr);
  }
  
  /* Sets section name for declaration DECL */
*************** unique_section (decl, reloc)
*** 3784,3791 ****
       int reloc ATTRIBUTE_UNUSED;
  {
    int len;
!   char *name,*string;
!   char *prefix;
    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    /* Strip off any encoding in name.  */
    STRIP_NAME_ENCODING (name, name);
--- 3810,3817 ----
       int reloc ATTRIBUTE_UNUSED;
  {
    int len;
!   const char *name, *prefix;
!   char *string;
    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    /* Strip off any encoding in name.  */
    STRIP_NAME_ENCODING (name, name);
*************** asm_output_section_name(file, decl, name
*** 3836,3845 ****
  
  void
  gas_output_limited_string(file, str)
!      FILE * file ATTRIBUTE_UNUSED;
!      char * str;
  {
!   unsigned char *_limited_str = (unsigned char *) str;
    unsigned ch;
    fprintf (file, "\t%s\t\"", STRING_ASM_OP);
    for (; (ch = *_limited_str); _limited_str++)
--- 3862,3871 ----
  
  void
  gas_output_limited_string(file, str)
!      FILE *file;
!      const char * str;
  {
!   const unsigned char *_limited_str = (unsigned char *) str;
    unsigned ch;
    fprintf (file, "\t%s\t\"", STRING_ASM_OP);
    for (; (ch = *_limited_str); _limited_str++)
*************** gas_output_limited_string(file, str)
*** 3872,3886 ****
  void
  gas_output_ascii(file, str, length)
       FILE * file;
!      char * str;
       size_t length;
  {
!   unsigned char *_ascii_bytes = (unsigned char *) str;
!   unsigned char *limit = _ascii_bytes + length;
    unsigned bytes_in_chunk = 0;
    for (; _ascii_bytes < limit; _ascii_bytes++)
      {
!       register unsigned char *p;
        if (bytes_in_chunk >= 60)
  	{
  	  fprintf (file, "\"\n");
--- 3898,3912 ----
  void
  gas_output_ascii(file, str, length)
       FILE * file;
!      const char * str;
       size_t length;
  {
!   const unsigned char *_ascii_bytes = (const unsigned char *) str;
!   const unsigned char *limit = _ascii_bytes + length;
    unsigned bytes_in_chunk = 0;
    for (; _ascii_bytes < limit; _ascii_bytes++)
      {
!       const unsigned char *p;
        if (bytes_in_chunk >= 60)
  	{
  	  fprintf (file, "\"\n");
*************** gas_output_ascii(file, str, length)
*** 3931,3937 ****
     because registers of CLASS are needed for spill registers.  */
  
  enum reg_class
! class_likely_spilled_p(int c)
  {
    return (c != ALL_REGS && c != ADDW_REGS);
  }
--- 3957,3964 ----
     because registers of CLASS are needed for spill registers.  */
  
  enum reg_class
! class_likely_spilled_p (c)
!      int c;
  {
    return (c != ALL_REGS && c != ADDW_REGS);
  }
*************** encode_section_info (decl)
*** 4025,4031 ****
        && TREE_CODE (decl) == VAR_DECL
        && avr_progmem_p (decl))
      {
!       char * dsec = ".progmem.data";
        DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
        TREE_READONLY (decl) = 1;
      }
--- 4052,4058 ----
        && TREE_CODE (decl) == VAR_DECL
        && avr_progmem_p (decl))
      {
!       const char *dsec = ".progmem.data";
        DECL_SECTION_NAME (decl) = build_string (strlen (dsec), dsec);
        TREE_READONLY (decl) = 1;
      }
*************** asm_file_end (file)
*** 4077,4083 ****
     next register; and so on.  */
  
  void
! order_regs_for_local_alloc (void)
  {
    unsigned int i;
    int order_0[] = {
--- 4104,4110 ----
     next register; and so on.  */
  
  void
! order_regs_for_local_alloc ()
  {
    unsigned int i;
    int order_0[] = {
*************** default_rtx_costs (X, code, outer_code)
*** 4190,4196 ****
  /* Calculate the cost of a memory address */
  
  int
! avr_address_cost (rtx x)
  {
    if (GET_CODE (x) == PLUS
        && GET_CODE (XEXP (x,1)) == CONST_INT
--- 4217,4224 ----
  /* Calculate the cost of a memory address */
  
  int
! avr_address_cost (x)
!      rtx x;
  {
    if (GET_CODE (x) == PLUS
        && GET_CODE (XEXP (x,1)) == CONST_INT
*************** avr_address_cost (rtx x)
*** 4198,4211 ****
        && INTVAL (XEXP (x,1)) >= 61)
      return 18;
    if (CONSTANT_ADDRESS_P (x))
!     return 4;
    return 4;
  }
  
  /*  EXTRA_CONSTRAINT helper */
  
  int
! extra_constraint (x,c)
       rtx x;
       int c;
  {
--- 4226,4243 ----
        && INTVAL (XEXP (x,1)) >= 61)
      return 18;
    if (CONSTANT_ADDRESS_P (x))
!     {
!       if (io_address_p (x, 1))
! 	return 2;
!       return 4;
!     }
    return 4;
  }
  
  /*  EXTRA_CONSTRAINT helper */
  
  int
! extra_constraint (x, c)
       rtx x;
       int c;
  {
*************** machine_dependent_reorg (first_insn)
*** 4361,4367 ****
  /* Returns register number for function return value.*/
  
  int
! avr_ret_register (void)
  {
    return 24;
  }
--- 4393,4399 ----
  /* Returns register number for function return value.*/
  
  int
! avr_ret_register ()
  {
    return 24;
  }
*************** avr_libcall_value (mode)
*** 4383,4389 ****
     function returns a value of data type VALTYPE.  */
  
  rtx
! avr_function_value (type,func)
       tree type;
       tree func ATTRIBUTE_UNUSED;
  {
--- 4415,4421 ----
     function returns a value of data type VALTYPE.  */
  
  rtx
! avr_function_value (type, func)
       tree type;
       tree func ATTRIBUTE_UNUSED;
  {
*************** const_int_pow2_p (x)
*** 4539,4545 ****
    return 0;
  }
  
! char *
  output_reload_inhi (insn, operands, len)
       rtx insn ATTRIBUTE_UNUSED;
       rtx *operands;
--- 4571,4577 ----
    return 0;
  }
  
! const char *
  output_reload_inhi (insn, operands, len)
       rtx insn ATTRIBUTE_UNUSED;
       rtx *operands;
*************** output_reload_inhi (insn, operands, len)
*** 4582,4617 ****
  }
  
  
! char *
! output_reload_insisf (insn, operands, which_alternative)
       rtx insn ATTRIBUTE_UNUSED;
       rtx *operands;
!      int which_alternative ATTRIBUTE_UNUSED;
  {
!   int cnst = (GET_CODE (operands[1]) == CONST_INT);
  
!   if (cnst && ((INTVAL (operands[1]) & 0xff) == 0))
      output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
    else
      {
        output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
        output_asm_insn (AS2 (mov, %A0, %2), operands);
      }
!   if (cnst && ((INTVAL (operands[1]) & 0xff00) == 0))
      output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
    else
      {
        output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
        output_asm_insn (AS2 (mov, %B0, %2), operands);
      }
!   if (cnst && ((INTVAL (operands[1]) & 0xff0000) == 0))
      output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
    else
      {
        output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
        output_asm_insn (AS2 (mov, %C0, %2), operands);
      }
!   if (cnst && ((INTVAL (operands[1]) & 0xff000000U) == 0))
      output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
    else
      {
--- 4614,4663 ----
  }
  
  
! const char *
! output_reload_insisf (insn, operands, len)
       rtx insn ATTRIBUTE_UNUSED;
       rtx *operands;
!      int *len;
  {
!   rtx src = operands[1];
!   int cnst = (GET_CODE (src) == CONST_INT);
! 
!   if (len)
!     {
!       if (cnst)
! 	*len = 4 + ((INTVAL (src) & 0xff) != 0)
! 		+ ((INTVAL (src) & 0xff00) != 0)
! 		+ ((INTVAL (src) & 0xff0000) != 0)
! 		+ ((INTVAL (src) & 0xff000000U) != 0);
!       else
! 	*len = 8;
! 
!       return "";
!     }
  
!   if (cnst && ((INTVAL (src) & 0xff) == 0))
      output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
    else
      {
        output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
        output_asm_insn (AS2 (mov, %A0, %2), operands);
      }
!   if (cnst && ((INTVAL (src) & 0xff00) == 0))
      output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
    else
      {
        output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
        output_asm_insn (AS2 (mov, %B0, %2), operands);
      }
!   if (cnst && ((INTVAL (src) & 0xff0000) == 0))
      output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
    else
      {
        output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
        output_asm_insn (AS2 (mov, %C0, %2), operands);
      }
!   if (cnst && ((INTVAL (src) & 0xff000000U) == 0))
      output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
    else
      {
diff -rc3p orig/egcs/gcc/config/avr/avr.h egcs/gcc/config/avr/avr.h
*** orig/egcs/gcc/config/avr/avr.h	Wed Aug 30 18:04:51 2000
--- egcs/gcc/config/avr/avr.h	Sat Sep  2 10:32:09 2000
*************** extern int avr_enhanced_p;
*** 323,329 ****
     If you don't define this macro, the default is `"long unsigned
     int"'.  */
  
! #define PTRDIFF_TYPE (INT_TYPE_SIZE == 8 ? "long unsigned int" :"unsigned int")
  /* A C expression for a string describing the name of the data type
     to use for the result of subtracting two pointers.  The typedef
     name `ptrdiff_t' is defined using the contents of the string.  See
--- 323,329 ----
     If you don't define this macro, the default is `"long unsigned
     int"'.  */
  
! #define PTRDIFF_TYPE (INT_TYPE_SIZE == 8 ? "long int" :"int")
  /* A C expression for a string describing the name of the data type
     to use for the result of subtracting two pointers.  The typedef
     name `ptrdiff_t' is defined using the contents of the string.  See
diff -rc3p orig/egcs/gcc/config/avr/avr.md egcs/gcc/config/avr/avr.md
*** orig/egcs/gcc/config/avr/avr.md	Sat Sep  2 12:48:43 2000
--- egcs/gcc/config/avr/avr.md	Sat Sep  2 14:52:42 2000
***************
*** 271,277 ****
      || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
    "* return output_movsisf (insn, operands, NULL);"
    [(set_attr "length" "4,4,8,8,4,10")
!    (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
  
  ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  ;; move floating point numbers (32 bit)
--- 271,277 ----
      || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
    "* return output_movsisf (insn, operands, NULL);"
    [(set_attr "length" "4,4,8,8,4,10")
!    (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
  
  ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  ;; move floating point numbers (32 bit)
***************
*** 297,303 ****
     || register_operand (operands[1], SFmode)"
    "* return output_movsisf (insn, operands, NULL);"
    [(set_attr "length" "4,4,8,8,4,10")
!    (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
  
  ;;=========================================================================
  ;; move string (like memcpy)
--- 297,303 ----
     || register_operand (operands[1], SFmode)"
    "* return output_movsisf (insn, operands, NULL);"
    [(set_attr "length" "4,4,8,8,4,10")
!    (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
  
  ;;=========================================================================
  ;; move string (like memcpy)
***************
*** 555,560 ****
--- 555,561 ----
    [(set_attr "length" "2,1,1,2,3,3")
     (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
  
+ ;; TODO: use "movw" if available
  (define_insn "addsi3"
    [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r,&*!w,&*!w")
  	  (plus:SI
***************
*** 734,740 ****
                AS2 (andi, %B0,hi8(%2)) CR_TAB
  	      AS2 (andi, %C0,hlo8(%2)) CR_TAB
  	      AS2 (andi, %D0,hhi8(%2)));
!       }
  }"
    [(set_attr "length" "4,4")
     (set_attr "cc" "set_n,set_n")])
--- 735,742 ----
                AS2 (andi, %B0,hi8(%2)) CR_TAB
  	      AS2 (andi, %C0,hlo8(%2)) CR_TAB
  	      AS2 (andi, %D0,hhi8(%2)));
!     }
!   return \"bug\";
  }"
    [(set_attr "length" "4,4")
     (set_attr "cc" "set_n,set_n")])
***************
*** 1076,1081 ****
--- 1078,1084 ----
    [(set_attr "length" "5,6")
     (set_attr "cc" "clobber,clobber")])
  
+ ;; TODO: use "movw" if available
  (define_insn "extendhisi2"
    [(set (match_operand:SI 0 "register_operand"               "=r,&r")
          (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
***************
*** 1109,1114 ****
--- 1112,1118 ----
    [(set_attr "length" "3,4")
     (set_attr "cc" "set_n,set_n")])
  
+ ;; TODO: use "movw" if available
  (define_insn "zero_extendhisi2"
    [(set (match_operand:SI 0 "register_operand" "=r,&r")
          (zero_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
***************
*** 1211,1217 ****
      case 1:
        if (reg_unused_after (insn, operands[0])
            && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
!           && TEST_HARD_REG_CLASS (ADDW_REGS, true_regnum (operands[0])))
          return AS2 (sbiw,%0,%1);
         else
          return (AS2 (cpi,%0,%1) CR_TAB
--- 1215,1221 ----
      case 1:
        if (reg_unused_after (insn, operands[0])
            && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
!           && test_hard_reg_class (ADDW_REGS, operands[0]))
          return AS2 (sbiw,%0,%1);
         else
          return (AS2 (cpi,%0,%1) CR_TAB
***************
*** 1235,1240 ****
--- 1239,1245 ----
                AS2 (ldi, %2,hi8(%1)) CR_TAB
  	      AS2 (cpc, %B0,%2));
      }
+   return \"bug\";
  }" 
    [(set_attr "cc" "compare,compare,compare,compare,compare")
     (set_attr "length" "2,2,3,3,4")])
***************
*** 1257,1263 ****
      case 1:
        if (reg_unused_after (insn, operands[0])
            && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
!           && TEST_HARD_REG_CLASS (ADDW_REGS, true_regnum (operands[0])))
          return (AS2 (sbiw,%0,%1) CR_TAB
                  AS2 (cpc,%C0,__zero_reg__) CR_TAB
                  AS2 (cpc,%D0,__zero_reg__));
--- 1262,1268 ----
      case 1:
        if (reg_unused_after (insn, operands[0])
            && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
!           && test_hard_reg_class (ADDW_REGS, operands[0]))
          return (AS2 (sbiw,%0,%1) CR_TAB
                  AS2 (cpc,%C0,__zero_reg__) CR_TAB
                  AS2 (cpc,%D0,__zero_reg__));
***************
*** 1295,1301 ****
  	       AS2 (cpc, %C0,%2)       CR_TAB
  	       AS2 (ldi, %2,hhi8(%1)) CR_TAB
  	       AS2 (cpc, %D0,%2));
!    }
  }"
    [(set_attr "cc" "compare,compare,compare,compare,compare")
     (set_attr "length" "4,4,7,5,8")])
--- 1300,1307 ----
  	       AS2 (cpc, %C0,%2)       CR_TAB
  	       AS2 (ldi, %2,hhi8(%1)) CR_TAB
  	       AS2 (cpc, %D0,%2));
!     }
!   return \"bug\";
  }"
    [(set_attr "cc" "compare,compare,compare,compare,compare")
     (set_attr "length" "4,4,7,5,8")])
***************
*** 1610,1615 ****
--- 1616,1622 ----
    ""
    "")
  
+ ;; TODO: insn length for AVR_ENHANCED
  (define_insn "call_insn"
    [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "!z,*r,i"))
           (match_operand:HI 1 "general_operand" "X,X,X"))]
***************
*** 1645,1650 ****
--- 1652,1658 ----
  	       (const_int 2)]
  	(const_int 1)))])
  
+ ;; TODO: insn length for AVR_ENHANCED
  (define_insn "call_value_insn"
    [(set (match_operand 0 "register_operand" "=r,r,r")
          (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "!z,*r,i"))
***************
*** 1705,1710 ****
--- 1713,1720 ----
    "optimize"
    "")
  
+ ;; TODO: jump to __tabjejump__ in libgcc
+ 
  (define_insn "*tablejump_enh"
     [(set (pc) (mem:HI
  	       (plus:HI (match_operand:HI 0 "register_operand" "=&z")
***************
*** 1798,1804 ****
      && test_hard_reg_class (LD_REGS, operands[1]))"
    "*
  {
!   if (TEST_HARD_REG_CLASS (ADDW_REGS, true_regnum (operands[0])))
      output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
  		     AS2 (sbc,%C0,__zero_reg__) CR_TAB
  		     AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
--- 1808,1814 ----
      && test_hard_reg_class (LD_REGS, operands[1]))"
    "*
  {
!   if (test_hard_reg_class (ADDW_REGS, operands[0]))
      output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
  		     AS2 (sbc,%C0,__zero_reg__) CR_TAB
  		     AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
***************
*** 1836,1842 ****
      && test_hard_reg_class (LD_REGS, operands[1]))"
    "*
  {
!   if (TEST_HARD_REG_CLASS (ADDW_REGS, true_regnum (operands[0])))
      output_asm_insn (AS2 (sbiw,%0,1), operands);
    else
      output_asm_insn (AS2 (subi,%A0,1) CR_TAB
--- 1846,1852 ----
      && test_hard_reg_class (LD_REGS, operands[1]))"
    "*
  {
!   if (test_hard_reg_class (ADDW_REGS, operands[0]))
      output_asm_insn (AS2 (sbiw,%0,1), operands);
    else
      output_asm_insn (AS2 (subi,%A0,1) CR_TAB





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