Home | History | Annotate | Line # | Download | only in avr
      1 /* Subroutines for insn-output.cc for ATMEL AVR micro controllers
      2    Copyright (C) 1998-2024 Free Software Foundation, Inc.
      3    Contributed by Denis Chertykov (chertykov (at) gmail.com)
      4 
      5    This file is part of GCC.
      6 
      7    GCC is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    GCC is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GCC; see the file COPYING3.  If not see
     19    <http://www.gnu.org/licenses/>.  */
     20 
     21 #define IN_TARGET_CODE 1
     22 
     23 #include "config.h"
     24 #include "system.h"
     25 #include "intl.h"
     26 #include "coretypes.h"
     27 #include "backend.h"
     28 #include "target.h"
     29 #include "rtl.h"
     30 #include "tree.h"
     31 #include "stringpool.h"
     32 #include "attribs.h"
     33 #include "cgraph.h"
     34 #include "c-family/c-common.h"
     35 #include "cfghooks.h"
     36 #include "df.h"
     37 #include "memmodel.h"
     38 #include "tm_p.h"
     39 #include "optabs.h"
     40 #include "regs.h"
     41 #include "emit-rtl.h"
     42 #include "recog.h"
     43 #include "conditions.h"
     44 #include "insn-attr.h"
     45 #include "reload.h"
     46 #include "varasm.h"
     47 #include "calls.h"
     48 #include "stor-layout.h"
     49 #include "output.h"
     50 #include "explow.h"
     51 #include "expr.h"
     52 #include "langhooks.h"
     53 #include "cfgrtl.h"
     54 #include "builtins.h"
     55 #include "context.h"
     56 #include "tree-pass.h"
     57 #include "print-rtl.h"
     58 #include "rtl-iter.h"
     59 
     60 /* This file should be included last.  */
     61 #include "target-def.h"
     62 
     63 /* Maximal allowed offset for an address in the LD command */
     64 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
     65 
     66 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
     67    address space where data is to be located.
     68    As the only non-generic address spaces are all located in flash,
     69    this can be used to test if data shall go into some .progmem* section.
     70    This must be the rightmost field of machine dependent section flags.  */
     71 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
     72 
     73 /* Similar 4-bit region for SYMBOL_REF_FLAGS.  */
     74 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
     75 
     76 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
     77    Set address-space AS in SYMBOL_REF_FLAGS of SYM  */
     78 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS)                       \
     79   do {                                                          \
     80     SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM;         \
     81     SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP;      \
     82   } while (0)
     83 
     84 /* Read address-space from SYMBOL_REF_FLAGS of SYM  */
     85 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM)                          \
     86   ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM)           \
     87    / SYMBOL_FLAG_MACH_DEP)
     88 
     89 /* (AVR_TINY only): Symbol has attribute progmem */
     90 #define AVR_SYMBOL_FLAG_TINY_PM \
     91   (SYMBOL_FLAG_MACH_DEP << 7)
     92 
     93 /* (AVR_TINY only): Symbol has attribute absdata */
     94 #define AVR_SYMBOL_FLAG_TINY_ABSDATA \
     95   (SYMBOL_FLAG_MACH_DEP << 8)
     96 
     97 #define TINY_ADIW(REG1, REG2, I)                                \
     98     "subi " #REG1 ",lo8(-(" #I "))" CR_TAB                      \
     99     "sbci " #REG2 ",hi8(-(" #I "))"
    100 
    101 #define TINY_SBIW(REG1, REG2, I)                                \
    102     "subi " #REG1 ",lo8((" #I "))" CR_TAB                       \
    103     "sbci " #REG2 ",hi8((" #I "))"
    104 
    105 #define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
    106 #define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
    107 
    108 /* Known address spaces.  The order must be the same as in the respective
    109    enum from avr.h (or designated initialized must be used).  */
    110 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
    111 {
    112   { ADDR_SPACE_RAM,  0, 2, "", 0, NULL },
    113   { ADDR_SPACE_FLASH,  1, 2, "__flash",   0, ".progmem.data" },
    114   { ADDR_SPACE_FLASH1, 1, 2, "__flash1",  1, ".progmem1.data" },
    115   { ADDR_SPACE_FLASH2, 1, 2, "__flash2",  2, ".progmem2.data" },
    116   { ADDR_SPACE_FLASH3, 1, 2, "__flash3",  3, ".progmem3.data" },
    117   { ADDR_SPACE_FLASH4, 1, 2, "__flash4",  4, ".progmem4.data" },
    118   { ADDR_SPACE_FLASH5, 1, 2, "__flash5",  5, ".progmem5.data" },
    119   { ADDR_SPACE_MEMX, 1, 3, "__memx",  0, ".progmemx.data" },
    120 };
    121 
    122 
    123 /* Holding RAM addresses of some SFRs used by the compiler and that
    124    are unique over all devices in an architecture like 'avr4'.  */
    125 
    126 typedef struct
    127 {
    128   /* SREG: The processor status */
    129   int sreg;
    130 
    131   /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
    132   int ccp;
    133   int rampd;
    134   int rampx;
    135   int rampy;
    136 
    137   /* RAMPZ: The high byte of 24-bit address used with ELPM */
    138   int rampz;
    139 
    140   /* SP: The stack pointer and its low and high byte */
    141   int sp_l;
    142   int sp_h;
    143 } avr_addr_t;
    144 
    145 static avr_addr_t avr_addr;
    146 
    147 
    148 /* Prototypes for local helper functions.  */
    149 
    150 static const char *out_movqi_r_mr (rtx_insn *, rtx[], int *);
    151 static const char *out_movhi_r_mr (rtx_insn *, rtx[], int *);
    152 static const char *out_movsi_r_mr (rtx_insn *, rtx[], int *);
    153 static const char *out_movqi_mr_r (rtx_insn *, rtx[], int *);
    154 static const char *out_movhi_mr_r (rtx_insn *, rtx[], int *);
    155 static const char *out_movsi_mr_r (rtx_insn *, rtx[], int *);
    156 
    157 static int get_sequence_length (rtx_insn *insns);
    158 static int sequent_regs_live (void);
    159 static const char *ptrreg_to_str (int);
    160 static const char *cond_string (enum rtx_code);
    161 static int avr_num_arg_regs (machine_mode, const_tree);
    162 static int avr_operand_rtx_cost (rtx, machine_mode, enum rtx_code,
    163 				 int, bool);
    164 static void output_reload_in_const (rtx *, rtx, int *, bool);
    165 static struct machine_function *avr_init_machine_status (void);
    166 static bool _reg_unused_after (rtx_insn *insn, rtx reg, bool look_at_insn);
    167 
    168 
    169 /* Prototypes for hook implementors if needed before their implementation.  */
    170 
    171 static bool avr_rtx_costs (rtx, machine_mode, int, int, int *, bool);
    172 
    173 
    174 /* Allocate registers from r25 to r8 for parameters for function calls
    175    resp. r25 to r20 for reduced Tiny.  */
    176 #define FIRST_CUM_REG REG_26
    177 
    178 /* Last call saved register */
    179 #define LAST_CALLEE_SAVED_REG (AVR_TINY ? REG_19 : REG_17)
    180 
    181 /* Implicit target register of LPM instruction (R0) */
    182 extern GTY(()) rtx lpm_reg_rtx;
    183 rtx lpm_reg_rtx;
    184 
    185 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
    186 extern GTY(()) rtx lpm_addr_reg_rtx;
    187 rtx lpm_addr_reg_rtx;
    188 
    189 /* Temporary register RTX (reg:QI TMP_REGNO) */
    190 extern GTY(()) rtx tmp_reg_rtx;
    191 rtx tmp_reg_rtx;
    192 
    193 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
    194 extern GTY(()) rtx zero_reg_rtx;
    195 rtx zero_reg_rtx;
    196 
    197 /* Condition Code register RTX (reg:CC REG_CC) */
    198 extern GTY(()) rtx cc_reg_rtx;
    199 rtx cc_reg_rtx;
    200 
    201 /* RTXs for all general purpose registers as QImode */
    202 extern GTY(()) rtx all_regs_rtx[REG_32];
    203 rtx all_regs_rtx[REG_32];
    204 
    205 /* SREG, the processor status */
    206 extern GTY(()) rtx sreg_rtx;
    207 rtx sreg_rtx;
    208 
    209 /* RAMP* special function registers */
    210 extern GTY(()) rtx rampd_rtx;
    211 extern GTY(()) rtx rampx_rtx;
    212 extern GTY(()) rtx rampy_rtx;
    213 extern GTY(()) rtx rampz_rtx;
    214 rtx rampd_rtx;
    215 rtx rampx_rtx;
    216 rtx rampy_rtx;
    217 rtx rampz_rtx;
    218 
    219 /* RTX containing the strings "" and "e", respectively */
    220 static GTY(()) rtx xstring_empty;
    221 static GTY(()) rtx xstring_e;
    222 
    223 /* Current architecture.  */
    224 const avr_arch_t *avr_arch;
    225 enum avr_arch_id avr_arch_index;
    226 
    227 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
    228    or to address space __flash* or __memx.  Only used as singletons inside
    229    avr_asm_select_section, but it must not be local there because of GTY.  */
    230 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
    231 
    232 /* Condition for insns/expanders from avr-dimode.md.  */
    233 bool avr_have_dimode = true;
    234 
    235 /* To track if code will use .bss, .data, .rodata.  */
    236 bool avr_need_clear_bss_p = false;
    237 bool avr_need_copy_data_p = false;
    238 bool avr_has_rodata_p = false;
    239 
    240 
    241 /* Transform UP into lowercase and write the result to LO.
    243    You must provide enough space for LO.  Return LO.  */
    244 
    245 static char *
    246 avr_tolower (char *lo, const char *up)
    247 {
    248   char *lo0 = lo;
    249 
    250   for (; *up; up++, lo++)
    251     *lo = TOLOWER (*up);
    252 
    253   *lo = '\0';
    254 
    255   return lo0;
    256 }
    257 
    258 
    259 /* Constraint helper function.  XVAL is a CONST_INT or a CONST_DOUBLE.
    260    Return true if the least significant N_BYTES bytes of XVAL all have a
    261    popcount in POP_MASK and false, otherwise.  POP_MASK represents a subset
    262    of integers which contains an integer N iff bit N of POP_MASK is set.  */
    263 
    264 bool
    265 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
    266 {
    267   machine_mode mode = GET_MODE (xval);
    268 
    269   if (VOIDmode == mode)
    270     mode = SImode;
    271 
    272   for (int i = 0; i < n_bytes; i++)
    273     {
    274       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
    275       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
    276 
    277       if ((pop_mask & (1 << popcount_hwi (val8))) == 0)
    278 	return false;
    279     }
    280 
    281   return true;
    282 }
    283 
    284 
    285 /* Constraint helper function.  XVAL is a CONST_INT.  Return true if we
    286    can perform XOR without a clobber reg, provided the operation is on
    287    a d-register.  This means each byte is in { 0, 0xff, 0x80 }.  */
    288 
    289 bool
    290 avr_xor_noclobber_dconst (rtx xval, int n_bytes)
    291 {
    292   machine_mode mode = GET_MODE (xval);
    293 
    294   if (VOIDmode == mode)
    295     mode = SImode;
    296 
    297   for (int i = 0; i < n_bytes; ++i)
    298     {
    299       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
    300       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
    301 
    302       if (val8 != 0 && val8 != 0xff && val8 != 0x80)
    303 	return false;
    304     }
    305 
    306   return true;
    307 }
    308 
    309 
    310 /* Access some RTX as INT_MODE.  If X is a CONST_FIXED we can get
    311    the bit representation of X by "casting" it to CONST_INT.  */
    312 
    313 rtx
    314 avr_to_int_mode (rtx x)
    315 {
    316   machine_mode mode = GET_MODE (x);
    317 
    318   return VOIDmode == mode
    319     ? x
    320     : simplify_gen_subreg (int_mode_for_mode (mode).require (), x, mode, 0);
    321 }
    322 
    323 
    324 /* Return true if hard register REG supports the ADIW and SBIW instructions.  */
    325 
    326 bool
    327 avr_adiw_reg_p (rtx reg)
    328 {
    329   return (AVR_HAVE_ADIW
    330 	  && test_hard_reg_class (ADDW_REGS, reg));
    331 }
    332 
    333 
    334 namespace {
    335 
    336 static const pass_data avr_pass_data_recompute_notes =
    337 {
    338   RTL_PASS,      // type
    339   "",            // name (will be patched)
    340   OPTGROUP_NONE, // optinfo_flags
    341   TV_DF_SCAN,    // tv_id
    342   0,             // properties_required
    343   0,             // properties_provided
    344   0,             // properties_destroyed
    345   0,             // todo_flags_start
    346   TODO_df_finish | TODO_df_verify // todo_flags_finish
    347 };
    348 
    349 
    350 class avr_pass_recompute_notes : public rtl_opt_pass
    351 {
    352 public:
    353   avr_pass_recompute_notes (gcc::context *ctxt, const char *name)
    354     : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt)
    355   {
    356     this->name = name;
    357   }
    358 
    359   virtual unsigned int execute (function *)
    360   {
    361     df_note_add_problem ();
    362     df_analyze ();
    363 
    364     return 0;
    365   }
    366 }; // avr_pass_recompute_notes
    367 
    368 static const pass_data avr_pass_data_casesi =
    369 {
    370   RTL_PASS,      // type
    371   "",            // name (will be patched)
    372   OPTGROUP_NONE, // optinfo_flags
    373   TV_DF_SCAN,    // tv_id
    374   0,             // properties_required
    375   0,             // properties_provided
    376   0,             // properties_destroyed
    377   0,             // todo_flags_start
    378   0              // todo_flags_finish
    379 };
    380 
    381 
    382 class avr_pass_casesi : public rtl_opt_pass
    383 {
    384 public:
    385   avr_pass_casesi (gcc::context *ctxt, const char *name)
    386     : rtl_opt_pass (avr_pass_data_casesi, ctxt)
    387   {
    388     this->name = name;
    389   }
    390 
    391   void avr_rest_of_handle_casesi (function *);
    392 
    393   virtual bool gate (function *) { return optimize > 0; }
    394 
    395   virtual unsigned int execute (function *func)
    396   {
    397     avr_rest_of_handle_casesi (func);
    398 
    399     return 0;
    400   }
    401 }; // avr_pass_casesi
    402 
    403 
    404 static const pass_data avr_pass_data_ifelse =
    405 {
    406   RTL_PASS,      // type
    407   "",            // name (will be patched)
    408   OPTGROUP_NONE, // optinfo_flags
    409   TV_DF_SCAN,    // tv_id
    410   0,             // properties_required
    411   0,             // properties_provided
    412   0,             // properties_destroyed
    413   0,             // todo_flags_start
    414   TODO_df_finish | TODO_df_verify // todo_flags_finish
    415 };
    416 
    417 class avr_pass_ifelse : public rtl_opt_pass
    418 {
    419 public:
    420   avr_pass_ifelse (gcc::context *ctxt, const char *name)
    421     : rtl_opt_pass (avr_pass_data_ifelse, ctxt)
    422   {
    423     this->name = name;
    424   }
    425 
    426   void avr_rest_of_handle_ifelse (function *);
    427 
    428   virtual bool gate (function *) { return optimize > 0; }
    429 
    430   virtual unsigned int execute (function *func)
    431   {
    432     avr_rest_of_handle_ifelse (func);
    433 
    434     return 0;
    435   }
    436 }; // avr_pass_ifelse
    437 
    438 } // anon namespace
    439 
    440 rtl_opt_pass *
    441 make_avr_pass_recompute_notes (gcc::context *ctxt)
    442 {
    443   return new avr_pass_recompute_notes (ctxt, "avr-notes-free-cfg");
    444 }
    445 
    446 rtl_opt_pass *
    447 make_avr_pass_casesi (gcc::context *ctxt)
    448 {
    449   return new avr_pass_casesi (ctxt, "avr-casesi");
    450 }
    451 
    452 rtl_opt_pass *
    453 make_avr_pass_ifelse (gcc::context *ctxt)
    454 {
    455   return new avr_pass_ifelse (ctxt, "avr-ifelse");
    456 }
    457 
    458 
    459 /* Make one parallel insn with all the patterns from insns i[0]..i[5].  */
    460 
    461 static rtx_insn *
    462 avr_parallel_insn_from_insns (rtx_insn *i[5])
    463 {
    464   rtvec vec = gen_rtvec (5, PATTERN (i[0]), PATTERN (i[1]), PATTERN (i[2]),
    465 			 PATTERN (i[3]), PATTERN (i[4]));
    466   start_sequence();
    467   emit (gen_rtx_PARALLEL (VOIDmode, vec));
    468   rtx_insn *insn = get_insns();
    469   end_sequence();
    470 
    471   return insn;
    472 }
    473 
    474 
    475 /* Return true if we see an insn stream generated by casesi expander together
    476    with an extension to SImode of the switch value.
    477 
    478    If this is the case, fill in the insns from casesi to INSNS[1..5] and
    479    the SImode extension to INSNS[0].  Moreover, extract the operands of
    480    pattern casesi_<mode>_sequence forged from the sequence to recog_data.  */
    481 
    482 static bool
    483 avr_is_casesi_sequence (basic_block bb, rtx_insn *insn, rtx_insn *insns[5])
    484 {
    485   rtx set_4, set_0;
    486 
    487   /* A first and quick test for a casesi sequences.  As a side effect of
    488      the test, harvest respective insns to INSNS[0..4].  */
    489 
    490   if (!(JUMP_P (insns[4] = insn)
    491 	// casesi is the only insn that comes up with UNSPEC_INDEX_JMP,
    492 	// hence the following test ensures that we are actually dealing
    493 	// with code from casesi.
    494 	&& (set_4 = single_set (insns[4]))
    495 	&& UNSPEC == GET_CODE (SET_SRC (set_4))
    496 	&& UNSPEC_INDEX_JMP == XINT (SET_SRC (set_4), 1)
    497 
    498 	&& (insns[3] = prev_real_insn (insns[4]))
    499 	&& (insns[2] = prev_real_insn (insns[3]))
    500 	&& (insns[1] = prev_real_insn (insns[2]))
    501 
    502 	// Insn prior to casesi.
    503 	&& (insns[0] = prev_real_insn (insns[1]))
    504 	&& (set_0 = single_set (insns[0]))
    505 	&& extend_operator (SET_SRC (set_0), SImode)))
    506     {
    507       return false;
    508     }
    509 
    510   if (dump_file)
    511     {
    512       fprintf (dump_file, ";; Sequence from casesi in "
    513 	       "[bb %d]:\n\n", bb->index);
    514       for (int i = 0; i < 5; i++)
    515 	print_rtl_single (dump_file, insns[i]);
    516     }
    517 
    518   /* We have to deal with quite some operands.  Extracting them by hand
    519      would be tedious, therefore wrap the insn patterns into a parallel,
    520      run recog against it and then use insn extract to get the operands. */
    521 
    522   rtx_insn *xinsn = avr_parallel_insn_from_insns (insns);
    523 
    524   INSN_CODE (xinsn) = recog (PATTERN (xinsn), xinsn, NULL /* num_clobbers */);
    525 
    526   /* Failing to recognize means that someone changed the casesi expander or
    527      that some passes prior to this one performed some unexpected changes.
    528      Gracefully drop such situations instead of aborting.  */
    529 
    530   if (INSN_CODE (xinsn) < 0)
    531     {
    532       if (dump_file)
    533 	fprintf (dump_file, ";; Sequence not recognized, giving up.\n\n");
    534 
    535       return false;
    536     }
    537 
    538   gcc_assert (CODE_FOR_casesi_qi_sequence == INSN_CODE (xinsn)
    539 	      || CODE_FOR_casesi_hi_sequence == INSN_CODE (xinsn));
    540 
    541   extract_insn (xinsn);
    542 
    543   // Assert on the anatomy of xinsn's operands we are going to work with.
    544 
    545   gcc_assert (recog_data.n_operands == 11);
    546   gcc_assert (recog_data.n_dups == 4);
    547 
    548   if (dump_file)
    549     {
    550       fprintf (dump_file, ";; Operands extracted:\n");
    551       for (int i = 0; i < recog_data.n_operands; i++)
    552 	avr_fdump (dump_file, ";; $%d = %r\n", i, recog_data.operand[i]);
    553       fprintf (dump_file, "\n");
    554     }
    555 
    556   return true;
    557 }
    558 
    559 
    560 /* Perform some extra checks on operands of casesi_<mode>_sequence.
    561    Not all operand dependencies can be described by means of predicates.
    562    This function performs left over checks and should always return true.
    563    Returning false means that someone changed the casesi expander but did
    564    not adjust casesi_<mode>_sequence.  */
    565 
    566 bool
    567 avr_casei_sequence_check_operands (rtx *xop)
    568 {
    569   rtx sub_5 = NULL_RTX;
    570 
    571   if (AVR_HAVE_EIJMP_EICALL
    572       // The last clobber op of the tablejump.
    573       && xop[8] == all_regs_rtx[REG_24])
    574     {
    575       // $6 is: (subreg:SI ($5) 0)
    576       sub_5 = xop[6];
    577     }
    578 
    579   if (!AVR_HAVE_EIJMP_EICALL
    580       // $6 is: (plus:HI (subreg:SI ($5) 0)
    581       //		 (label_ref ($3)))
    582       && PLUS == GET_CODE (xop[6])
    583       && LABEL_REF == GET_CODE (XEXP (xop[6], 1))
    584       && rtx_equal_p (xop[3], XEXP (XEXP (xop[6], 1), 0))
    585       // The last clobber op of the tablejump.
    586       && xop[8] == const0_rtx)
    587     {
    588       sub_5 = XEXP (xop[6], 0);
    589     }
    590 
    591   if (sub_5
    592       && SUBREG_P (sub_5)
    593       && SUBREG_BYTE (sub_5) == 0
    594       && rtx_equal_p (xop[5], SUBREG_REG (sub_5)))
    595     return true;
    596 
    597   if (dump_file)
    598     fprintf (dump_file, "\n;; Failed condition for casesi_<mode>_sequence\n\n");
    599 
    600   return false;
    601 }
    602 
    603 
    604 /* INSNS[1..4] is a sequence as generated by casesi and INSNS[0] is an
    605    extension of an 8-bit or 16-bit integer to SImode.  XOP contains the
    606    operands of INSNS as extracted by insn_extract from pattern
    607    casesi_<mode>_sequence:
    608 
    609       $0: SImode reg switch value as result of $9.
    610       $1: Negative of smallest index in switch.
    611       $2: Number of entries in switch.
    612       $3: Label to table.
    613       $4: Label if out-of-bounds.
    614       $5: $0 + $1.
    615       $6: 3-byte PC: subreg:HI ($5) + label_ref ($3)
    616 	  2-byte PC: subreg:HI ($5)
    617       $7: HI reg index into table (Z or pseudo)
    618       $8: R24 or const0_rtx (to be clobbered)
    619       $9: Extension to SImode of an 8-bit or 16-bit integer register $10.
    620       $10: QImode or HImode register input of $9.
    621 
    622    Try to optimize this sequence, i.e. use the original HImode / QImode
    623    switch value instead of SImode.  */
    624 
    625 static void
    626 avr_optimize_casesi (rtx_insn *insns[5], rtx *xop)
    627 {
    628   // Original mode of the switch value; this is QImode or HImode.
    629   machine_mode mode = GET_MODE (xop[10]);
    630 
    631   // How the original switch value was extended to SImode; this is
    632   // SIGN_EXTEND or ZERO_EXTEND.
    633   enum rtx_code code = GET_CODE (xop[9]);
    634 
    635   // Lower index, upper index (plus one) and range of case calues.
    636   HOST_WIDE_INT low_idx = -INTVAL (xop[1]);
    637   HOST_WIDE_INT num_idx = INTVAL (xop[2]);
    638   HOST_WIDE_INT hig_idx = low_idx + num_idx;
    639 
    640   // Maximum ranges of (un)signed QImode resp. HImode.
    641   unsigned umax = QImode == mode ? 0xff : 0xffff;
    642   int imax = QImode == mode ? 0x7f : 0x7fff;
    643   int imin = -imax - 1;
    644 
    645   // Testing the case range and whether it fits into the range of the
    646   // (un)signed mode.  This test should actually always pass because it
    647   // makes no sense to have case values outside the mode range.  Notice
    648   // that case labels which are unreachable because they are outside the
    649   // mode of the switch value (e.g. "case -1" for uint8_t) have already
    650   // been thrown away by the middle-end.
    651 
    652   if (SIGN_EXTEND == code
    653       && low_idx >= imin
    654       && hig_idx <= imax)
    655     {
    656       // ok
    657     }
    658   else if (ZERO_EXTEND == code
    659 	   && low_idx >= 0
    660 	   && (unsigned) hig_idx <= umax)
    661     {
    662       // ok
    663     }
    664   else
    665     {
    666       if (dump_file)
    667 	fprintf (dump_file, ";; Case ranges too big, giving up.\n\n");
    668       return;
    669     }
    670 
    671   // Do normalization of switch value $10 and out-of-bound check in its
    672   // original mode instead of in SImode.  Use a newly created pseudo.
    673   // This will replace insns[1..2].
    674 
    675   start_sequence();
    676 
    677   rtx reg = copy_to_mode_reg (mode, xop[10]);
    678 
    679   rtx (*gen_add)(rtx,rtx,rtx) = QImode == mode ? gen_addqi3 : gen_addhi3;
    680   rtx (*gen_cbranch)(rtx,rtx,rtx,rtx)
    681     = QImode == mode ? gen_cbranchqi4 : gen_cbranchhi4;
    682 
    683   emit_insn (gen_add (reg, reg, gen_int_mode (-low_idx, mode)));
    684   rtx op0 = reg; rtx op1 = gen_int_mode (num_idx, mode);
    685   rtx labelref = copy_rtx (xop[4]);
    686   rtx xbranch = gen_cbranch (gen_rtx_fmt_ee (GTU, VOIDmode, op0, op1),
    687 			     op0, op1, labelref);
    688   rtx_insn *cbranch = emit_jump_insn (xbranch);
    689   JUMP_LABEL (cbranch) = xop[4];
    690   ++LABEL_NUSES (xop[4]);
    691 
    692   rtx_insn *seq1 = get_insns();
    693   rtx_insn *last1 = get_last_insn();
    694   end_sequence();
    695 
    696   emit_insn_after (seq1, insns[2]);
    697 
    698   // After the out-of-bounds test and corresponding branch, use a
    699   // 16-bit index.  If QImode is used, extend it to HImode first.
    700   // This will replace insns[4].
    701 
    702   start_sequence();
    703 
    704   if (QImode == mode)
    705     reg = force_reg (HImode, gen_rtx_fmt_e (code, HImode, reg));
    706 
    707   rtx pat_4 = AVR_3_BYTE_PC
    708     ? gen_movhi (xop[7], reg)
    709     : gen_addhi3 (xop[7], reg, gen_rtx_LABEL_REF (VOIDmode, xop[3]));
    710 
    711   emit_insn (pat_4);
    712 
    713   rtx_insn *seq2 = get_insns();
    714   rtx_insn *last2 = get_last_insn();
    715   end_sequence();
    716 
    717   emit_insn_after (seq2, insns[3]);
    718 
    719   if (dump_file)
    720     {
    721       fprintf (dump_file, ";; New insns: ");
    722 
    723       for (rtx_insn *insn = seq1; ; insn = NEXT_INSN (insn))
    724 	{
    725 	  fprintf (dump_file, "%d, ", INSN_UID (insn));
    726 	  if (insn == last1)
    727 	    break;
    728 	}
    729       for (rtx_insn *insn = seq2; ; insn = NEXT_INSN (insn))
    730 	{
    731 	  fprintf (dump_file, "%d%s", INSN_UID (insn),
    732 		   insn == last2 ? ".\n\n" : ", ");
    733 	  if (insn == last2)
    734 	    break;
    735 	}
    736 
    737       fprintf (dump_file, ";; Deleting insns: %d, %d, %d.\n\n",
    738 	       INSN_UID (insns[1]), INSN_UID (insns[2]), INSN_UID (insns[3]));
    739     }
    740 
    741   // Pseudodelete the SImode and subreg of SImode insns.  We don't care
    742   // about the extension insns[0]: Its result is now unused and other
    743   // passes will clean it up.
    744 
    745   SET_INSN_DELETED (insns[1]);
    746   SET_INSN_DELETED (insns[2]);
    747   SET_INSN_DELETED (insns[3]);
    748 }
    749 
    750 
    751 void
    752 avr_pass_casesi::avr_rest_of_handle_casesi (function *func)
    753 {
    754   basic_block bb;
    755 
    756   FOR_EACH_BB_FN (bb, func)
    757     {
    758       rtx_insn *insn, *insns[5];
    759 
    760       FOR_BB_INSNS (bb, insn)
    761 	{
    762 	  if (avr_is_casesi_sequence (bb, insn, insns))
    763 	    {
    764 	      avr_optimize_casesi (insns, recog_data.operand);
    765 	    }
    766 	}
    767     }
    768 }
    769 
    770 
    771 /* A helper for the next method.  Suppose we have two conditional branches
    772 
    773       if (reg <cond1> xval1) goto label1;
    774       if (reg <cond2> xval2) goto label2;
    775 
    776    If the second comparison is redundant and there is a code <cond> such
    777    that the sequence can be performed as
    778 
    779       REG_CC = compare (reg, xval1);
    780       if (REG_CC <cond1> 0)  goto label1;
    781       if (REG_CC <cond> 0)   goto label2;
    782 
    783    then return <cond>.  Otherwise, return UNKNOWN.
    784    xval1 and xval2 are CONST_INT, and mode is the scalar int mode in which
    785    the comparison will be carried out.  reverse_cond1 can be set to reverse
    786    condition cond1.  This is useful if the second comparison does not follow
    787    the first one, but is located after label1 like in:
    788 
    789       if (reg <cond1> xval1) goto label1;
    790       ...
    791       label1:
    792       if (reg <cond2> xval2) goto label2;  */
    793 
    794 static enum rtx_code
    795 avr_redundant_compare (enum rtx_code cond1, rtx xval1,
    796 		       enum rtx_code cond2, rtx xval2,
    797 		       machine_mode mode, bool reverse_cond1)
    798 {
    799   HOST_WIDE_INT ival1 = INTVAL (xval1);
    800   HOST_WIDE_INT ival2 = INTVAL (xval2);
    801 
    802   unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
    803   unsigned HOST_WIDE_INT uval1 = mask & UINTVAL (xval1);
    804   unsigned HOST_WIDE_INT uval2 = mask & UINTVAL (xval2);
    805 
    806   if (reverse_cond1)
    807     cond1 = reverse_condition (cond1);
    808 
    809   if (cond1 == EQ)
    810     {
    811       ////////////////////////////////////////////////
    812       // A sequence like
    813       //    if (reg == val)  goto label1;
    814       //    if (reg > val)   goto label2;
    815       // can be re-written using the same, simple comparison like in:
    816       //    REG_CC = compare (reg, val)
    817       //    if (REG_CC == 0)  goto label1;
    818       //    if (REG_CC >= 0)  goto label2;
    819       if (ival1 == ival2
    820 	  && (cond2 == GT || cond2 == GTU))
    821 	return avr_normalize_condition (cond2);
    822 
    823       // Similar, but the input sequence is like
    824       //    if (reg == val)  goto label1;
    825       //    if (reg >= val)  goto label2;
    826       if (ival1 == ival2
    827 	  && (cond2 == GE || cond2 == GEU))
    828 	return cond2;
    829 
    830       // Similar, but the input sequence is like
    831       //    if (reg == val)      goto label1;
    832       //    if (reg >= val + 1)  goto label2;
    833       if ((cond2 == GE && ival2 == 1 + ival1)
    834 	  || (cond2 == GEU && uval2 == 1 + uval1))
    835 	return cond2;
    836 
    837       // Similar, but the input sequence is like
    838       //    if (reg == val)      goto label1;
    839       //    if (reg >  val - 1)  goto label2;
    840       if ((cond2 == GT && ival2 == ival1 - 1)
    841 	  || (cond2 == GTU && uval2 == uval1 - 1))
    842 	return avr_normalize_condition (cond2);
    843 
    844       /////////////////////////////////////////////////////////
    845       // A sequence like
    846       //    if (reg == val)      goto label1;
    847       //    if (reg < 1 + val)   goto label2;
    848       // can be re-written as
    849       //    REG_CC = compare (reg, val)
    850       //    if (REG_CC == 0)  goto label1;
    851       //    if (REG_CC < 0)   goto label2;
    852       if ((cond2 == LT && ival2 == 1 + ival1)
    853 	  || (cond2 == LTU && uval2 == 1 + uval1))
    854 	return cond2;
    855 
    856       // Similar, but with an input sequence like
    857       //    if (reg == val)   goto label1;
    858       //    if (reg <= val)   goto label2;
    859       if (ival1 == ival2
    860 	  && (cond2 == LE || cond2 == LEU))
    861 	return avr_normalize_condition (cond2);
    862 
    863       // Similar, but with an input sequence like
    864       //    if (reg == val)  goto label1;
    865       //    if (reg < val)   goto label2;
    866       if (ival1 == ival2
    867 	  && (cond2 == LT || cond2 == LTU))
    868 	return cond2;
    869 
    870       // Similar, but with an input sequence like
    871       //    if (reg == val)      goto label1;
    872       //    if (reg <= val - 1)  goto label2;
    873       if ((cond2 == LE && ival2 == ival1 - 1)
    874 	  || (cond2 == LEU && uval2 == uval1 - 1))
    875 	return avr_normalize_condition (cond2);
    876 
    877     } // cond1 == EQ
    878 
    879   return UNKNOWN;
    880 }
    881 
    882 
    883 /* If-else decision trees generated for switch / case may produce sequences
    884    like
    885 
    886       SREG = compare (reg, val);
    887 	  if (SREG == 0)  goto label1;
    888       SREG = compare (reg, 1 + val);
    889 	  if (SREG >= 0)  goto label2;
    890 
    891    which can be optimized to
    892 
    893       SREG = compare (reg, val);
    894 	  if (SREG == 0)  goto label1;
    895 	  if (SREG >= 0)  goto label2;
    896 
    897    The optimal place for such a pass would be directly after expand, but
    898    it's not possible for a jump insn to target more than one code label.
    899    Hence, run a mini pass right before split2 which introduces REG_CC.  */
    900 
    901 void
    902 avr_pass_ifelse::avr_rest_of_handle_ifelse (function *)
    903 {
    904   rtx_insn *next_insn;
    905 
    906   for (rtx_insn *insn = get_insns(); insn; insn = next_insn)
    907     {
    908       next_insn = next_nonnote_nondebug_insn (insn);
    909 
    910       if (! next_insn)
    911 	break;
    912 
    913       // Search for two cbranch insns.  The first one is a cbranch.
    914       // Filter for "cbranch<mode>4_insn" with mode in QI, HI, PSI, SI.
    915 
    916       if (! JUMP_P (insn))
    917 	continue;
    918 
    919       int icode1 = recog_memoized (insn);
    920 
    921       if (icode1 != CODE_FOR_cbranchqi4_insn
    922 	  && icode1 != CODE_FOR_cbranchhi4_insn
    923 	  && icode1 != CODE_FOR_cbranchpsi4_insn
    924 	  && icode1 != CODE_FOR_cbranchsi4_insn)
    925 	continue;
    926 
    927       rtx_jump_insn *insn1 = as_a<rtx_jump_insn *> (insn);
    928       rtx_jump_insn *insn2 = nullptr;
    929       bool follow_label1 = false;
    930 
    931       // Extract the operands of the first insn:
    932       // $0 = comparison operator ($1, $2)
    933       // $1 = reg
    934       // $2 = reg or const_int
    935       // $3 = code_label
    936       // $4 = optional SCRATCH for HI, PSI, SI cases.
    937 
    938       const auto &op = recog_data.operand;
    939 
    940       extract_insn (insn1);
    941       rtx xop1[5] = { op[0], op[1], op[2], op[3], op[4] };
    942       int n_operands = recog_data.n_operands;
    943 
    944       // For now, we can optimize cbranches that follow an EQ cbranch,
    945       // and cbranches that follow the label of a NE cbranch.
    946 
    947       if (GET_CODE (xop1[0]) == EQ
    948 	  && JUMP_P (next_insn)
    949 	  && recog_memoized (next_insn) == icode1)
    950 	{
    951 	  // The 2nd cbranch insn follows insn1, i.e. is located in the
    952 	  // fallthrough path of insn1.
    953 
    954 	  insn2 = as_a<rtx_jump_insn *> (next_insn);
    955 	}
    956       else if (GET_CODE (xop1[0]) == NE)
    957 	{
    958 	  // insn1 might branch to a label followed by a cbranch.
    959 
    960 	  rtx target1 = JUMP_LABEL (insn1);
    961 	  rtx_insn *code_label1 = JUMP_LABEL_AS_INSN (insn1);
    962 	  rtx_insn *next = next_nonnote_nondebug_insn (code_label1);
    963 	  rtx_insn *barrier = prev_nonnote_nondebug_insn (code_label1);
    964 
    965 	  if (// Target label of insn1 is used exactly once and
    966 	      // is not a fallthru, i.e. is preceded by a barrier.
    967 	      LABEL_NUSES (target1) == 1
    968 	      && barrier
    969 	      && BARRIER_P (barrier)
    970 	      // Following the target label is a cbranch of the same kind.
    971 	      && next
    972 	      && JUMP_P (next)
    973 	      && recog_memoized (next) == icode1)
    974 	    {
    975 	      follow_label1 = true;
    976 	      insn2 = as_a<rtx_jump_insn *> (next);
    977 	    }
    978 	}
    979 
    980       if (! insn2)
    981 	continue;
    982 
    983       // Also extract operands of insn2, and filter for REG + CONST_INT
    984       // comparsons against the same register.
    985 
    986       extract_insn (insn2);
    987       rtx xop2[5] = { op[0], op[1], op[2], op[3], op[4] };
    988 
    989       if (! rtx_equal_p (xop1[1], xop2[1])
    990 	  || ! CONST_INT_P (xop1[2])
    991 	  || ! CONST_INT_P (xop2[2]))
    992 	continue;
    993 
    994       machine_mode mode = GET_MODE (xop1[1]);
    995       enum rtx_code code1 = GET_CODE (xop1[0]);
    996       enum rtx_code code2 = GET_CODE (xop2[0]);
    997 
    998       code2 = avr_redundant_compare (code1, xop1[2], code2, xop2[2],
    999 				     mode, follow_label1);
   1000       if (code2 == UNKNOWN)
   1001 	continue;
   1002 
   1003       //////////////////////////////////////////////////////
   1004       // Found a replacement.
   1005 
   1006       if (dump_file)
   1007 	{
   1008 	  fprintf (dump_file, "\n;; Found chain of jump_insn %d and"
   1009 		   " jump_insn %d, follow_label1=%d:\n",
   1010 		   INSN_UID (insn1), INSN_UID (insn2), follow_label1);
   1011 	  print_rtl_single (dump_file, PATTERN (insn1));
   1012 	  print_rtl_single (dump_file, PATTERN (insn2));
   1013 	}
   1014 
   1015       if (! follow_label1)
   1016 	next_insn = next_nonnote_nondebug_insn (insn2);
   1017 
   1018       // Pop the new branch conditions and the new comparison.
   1019       // Prematurely split into compare + branch so that we can drop
   1020       // the 2nd comparison.  The following pass, split2, splits all
   1021       // insns for REG_CC, and it should still work as usual even when
   1022       // there are already some REG_CC insns around.
   1023 
   1024       rtx xcond1 = gen_rtx_fmt_ee (code1, VOIDmode, cc_reg_rtx, const0_rtx);
   1025       rtx xcond2 = gen_rtx_fmt_ee (code2, VOIDmode, cc_reg_rtx, const0_rtx);
   1026       rtx xpat1 = gen_branch (xop1[3], xcond1);
   1027       rtx xpat2 = gen_branch (xop2[3], xcond2);
   1028       rtx xcompare = NULL_RTX;
   1029 
   1030       if (mode == QImode)
   1031 	{
   1032 	  gcc_assert (n_operands == 4);
   1033 	  xcompare = gen_cmpqi3 (xop1[1], xop1[2]);
   1034 	}
   1035       else
   1036 	{
   1037 	  gcc_assert (n_operands == 5);
   1038 	  rtx (*gen_cmp)(rtx,rtx,rtx)
   1039 	    = mode == HImode  ? gen_gen_comparehi
   1040 	    : mode == PSImode ? gen_gen_comparepsi
   1041 	    : gen_gen_comparesi; // SImode
   1042 	  xcompare = gen_cmp (xop1[1], xop1[2], xop1[4]);
   1043 	}
   1044 
   1045       // Emit that stuff.
   1046 
   1047       rtx_insn *cmp = emit_insn_before (xcompare, insn1);
   1048       rtx_jump_insn *branch1 = emit_jump_insn_before (xpat1, insn1);
   1049       rtx_jump_insn *branch2 = emit_jump_insn_before (xpat2, insn2);
   1050 
   1051       JUMP_LABEL (branch1) = xop1[3];
   1052       JUMP_LABEL (branch2) = xop2[3];
   1053       // delete_insn() decrements LABEL_NUSES when deleting a JUMP_INSN, but
   1054       // when we pop a new JUMP_INSN, do it by hand.
   1055       ++LABEL_NUSES (xop1[3]);
   1056       ++LABEL_NUSES (xop2[3]);
   1057 
   1058       delete_insn (insn1);
   1059       delete_insn (insn2);
   1060 
   1061       // As a side effect, also recog the new insns.
   1062       gcc_assert (valid_insn_p (cmp));
   1063       gcc_assert (valid_insn_p (branch1));
   1064       gcc_assert (valid_insn_p (branch2));
   1065     } // loop insns
   1066 }
   1067 
   1068 
   1069 /* Set `avr_arch' as specified by `-mmcu='.
   1070    Return true on success.  */
   1071 
   1072 static bool
   1073 avr_set_core_architecture (void)
   1074 {
   1075   /* Search for mcu core architecture.  */
   1076 
   1077   if (!avr_mmcu)
   1078     avr_mmcu = AVR_MMCU_DEFAULT;
   1079 
   1080   avr_arch = &avr_arch_types[0];
   1081 
   1082   for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++)
   1083     {
   1084       if (mcu->name == NULL)
   1085 	{
   1086 	  /* Reached the end of `avr_mcu_types'.  This should actually never
   1087 	     happen as options are provided by device-specs.  It could be a
   1088 	     typo in a device-specs or calling the compiler proper directly
   1089 	     with -mmcu=<device>. */
   1090 
   1091 	  error ("unknown core architecture %qs specified with %qs",
   1092 		 avr_mmcu, "-mmcu=");
   1093 	  avr_inform_core_architectures ();
   1094 	  break;
   1095 	}
   1096       else if (strcmp (mcu->name, avr_mmcu) == 0
   1097 	       // Is this a proper architecture ?
   1098 	       && mcu->macro == NULL)
   1099 	{
   1100 	  avr_arch = &avr_arch_types[mcu->arch_id];
   1101 	  avr_arch_index = mcu->arch_id;
   1102 	  if (avr_n_flash < 0)
   1103 	    avr_n_flash = 1 + (mcu->flash_size - 1) / 0x10000;
   1104 
   1105 	  return true;
   1106 	}
   1107     }
   1108 
   1109   return false;
   1110 }
   1111 
   1112 
   1113 /* Implement `TARGET_OPTION_OVERRIDE'.  */
   1114 
   1115 static void
   1116 avr_option_override (void)
   1117 {
   1118   /* caller-save.cc looks for call-clobbered hard registers that are assigned
   1119      to pseudos that cross calls and tries so save-restore them around calls
   1120      in order to reduce the number of stack slots needed.
   1121 
   1122      This might lead to situations where reload is no more able to cope
   1123      with the challenge of AVR's very few address registers and fails to
   1124      perform the requested spills.  */
   1125 
   1126   if (avr_strict_X)
   1127     flag_caller_saves = 0;
   1128 
   1129   /* Unwind tables currently require a frame pointer for correctness,
   1130      see toplev.cc:process_options().  */
   1131 
   1132   if ((flag_unwind_tables
   1133        || flag_non_call_exceptions
   1134        || flag_asynchronous_unwind_tables)
   1135       && !ACCUMULATE_OUTGOING_ARGS)
   1136     {
   1137       flag_omit_frame_pointer = 0;
   1138     }
   1139 
   1140   /* Disable flag_delete_null_pointer_checks if zero is a valid address. */
   1141   if (targetm.addr_space.zero_address_valid (ADDR_SPACE_GENERIC))
   1142     flag_delete_null_pointer_checks = 0;
   1143 
   1144   /* PR ipa/92606: Inter-procedural analysis optimizes data across
   1145      address-spaces and PROGMEM.  As of v14, the PROGMEM part is
   1146      still not fixed (and there is still no target hook as proposed
   1147      in PR92932).  Just disable respective bogus optimization.  */
   1148   flag_ipa_icf_variables = 0;
   1149 
   1150   if (flag_pic == 1)
   1151     warning (OPT_fpic, "%<-fpic%> is not supported");
   1152   if (flag_pic == 2)
   1153     warning (OPT_fPIC, "%<-fPIC%> is not supported");
   1154   if (flag_pie == 1)
   1155     warning (OPT_fpie, "%<-fpie%> is not supported");
   1156   if (flag_pie == 2)
   1157     warning (OPT_fPIE, "%<-fPIE%> is not supported");
   1158 
   1159 #if !defined (HAVE_AS_AVR_MGCCISR_OPTION)
   1160   avr_gasisr_prologues = 0;
   1161 #endif
   1162 
   1163   if (!avr_set_core_architecture())
   1164     return;
   1165 
   1166   /* Sould be set by avr-common.cc */
   1167   gcc_assert (avr_long_double >= avr_double && avr_double >= 32);
   1168 
   1169   /* RAM addresses of some SFRs common to all devices in respective arch. */
   1170 
   1171   /* SREG: Status Register containing flags like I (global IRQ) */
   1172   avr_addr.sreg = 0x3F + avr_arch->sfr_offset;
   1173 
   1174   /* RAMPZ: Address' high part when loading via ELPM */
   1175   avr_addr.rampz = 0x3B + avr_arch->sfr_offset;
   1176 
   1177   avr_addr.rampy = 0x3A + avr_arch->sfr_offset;
   1178   avr_addr.rampx = 0x39 + avr_arch->sfr_offset;
   1179   avr_addr.rampd = 0x38 + avr_arch->sfr_offset;
   1180   avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset;
   1181 
   1182   /* SP: Stack Pointer (SP_H:SP_L) */
   1183   avr_addr.sp_l = 0x3D + avr_arch->sfr_offset;
   1184   avr_addr.sp_h = avr_addr.sp_l + 1;
   1185 
   1186   init_machine_status = avr_init_machine_status;
   1187 
   1188   avr_log_set_avr_log();
   1189 }
   1190 
   1191 /* Function to set up the backend function structure.  */
   1192 
   1193 static struct machine_function *
   1194 avr_init_machine_status (void)
   1195 {
   1196   return ggc_cleared_alloc<machine_function> ();
   1197 }
   1198 
   1199 
   1200 /* Implement `INIT_EXPANDERS'.  */
   1201 /* The function works like a singleton.  */
   1202 
   1203 void
   1204 avr_init_expanders (void)
   1205 {
   1206   for (int regno = REG_0; regno < REG_32; regno ++)
   1207     all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
   1208 
   1209   lpm_reg_rtx  = all_regs_rtx[LPM_REGNO];
   1210   tmp_reg_rtx  = all_regs_rtx[AVR_TMP_REGNO];
   1211   zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
   1212 
   1213   cc_reg_rtx  = gen_rtx_REG (CCmode, REG_CC);
   1214 
   1215   lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
   1216 
   1217   sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
   1218   rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
   1219   rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
   1220   rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
   1221   rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
   1222 
   1223   xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
   1224   xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
   1225 
   1226   /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
   1227      to be present */
   1228   if (AVR_TINY)
   1229     avr_have_dimode = false;
   1230 }
   1231 
   1232 
   1233 /* Implement `REGNO_REG_CLASS'.  */
   1234 /* Return register class for register R.  */
   1235 
   1236 enum reg_class
   1237 avr_regno_reg_class (int r)
   1238 {
   1239   static const enum reg_class reg_class_tab[] =
   1240     {
   1241       R0_REG,
   1242       /* r1 - r15 */
   1243       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
   1244       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
   1245       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
   1246       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
   1247       /* r16 - r23 */
   1248       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
   1249       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
   1250       /* r24, r25 */
   1251       ADDW_REGS, ADDW_REGS,
   1252       /* X: r26, 27 */
   1253       POINTER_X_REGS, POINTER_X_REGS,
   1254       /* Y: r28, r29 */
   1255       POINTER_Y_REGS, POINTER_Y_REGS,
   1256       /* Z: r30, r31 */
   1257       POINTER_Z_REGS, POINTER_Z_REGS,
   1258       /* SP: SPL, SPH */
   1259       STACK_REG, STACK_REG
   1260     };
   1261 
   1262   if (r <= 33)
   1263     return reg_class_tab[r];
   1264 
   1265   if (r == REG_CC)
   1266     return CC_REG;
   1267 
   1268   return ALL_REGS;
   1269 }
   1270 
   1271 
   1272 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'.  */
   1273 
   1274 static bool
   1275 avr_scalar_mode_supported_p (scalar_mode mode)
   1276 {
   1277   if (ALL_FIXED_POINT_MODE_P (mode))
   1278     return true;
   1279 
   1280   if (PSImode == mode)
   1281     return true;
   1282 
   1283   return default_scalar_mode_supported_p (mode);
   1284 }
   1285 
   1286 
   1287 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise.  */
   1288 
   1289 static bool
   1290 avr_decl_flash_p (tree decl)
   1291 {
   1292   if (TREE_CODE (decl) != VAR_DECL
   1293       || TREE_TYPE (decl) == error_mark_node)
   1294     {
   1295       return false;
   1296     }
   1297 
   1298   return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
   1299 }
   1300 
   1301 
   1302 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash
   1303    address space and FALSE, otherwise.  */
   1304 
   1305 static bool
   1306 avr_decl_memx_p (tree decl)
   1307 {
   1308   if (TREE_CODE (decl) != VAR_DECL
   1309       || TREE_TYPE (decl) == error_mark_node)
   1310     {
   1311       return false;
   1312     }
   1313 
   1314   return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
   1315 }
   1316 
   1317 
   1318 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise.  */
   1319 
   1320 bool
   1321 avr_mem_flash_p (rtx x)
   1322 {
   1323   return (MEM_P (x)
   1324 	  && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
   1325 }
   1326 
   1327 
   1328 /* Return TRUE if X is a MEM rtx located in the 24-bit flash
   1329    address space and FALSE, otherwise.  */
   1330 
   1331 bool
   1332 avr_mem_memx_p (rtx x)
   1333 {
   1334   return (MEM_P (x)
   1335 	  && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
   1336 }
   1337 
   1338 
   1339 /* A helper for the subsequent function attribute used to dig for
   1340    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
   1341 
   1342 static inline bool
   1343 avr_lookup_function_attribute1 (const_tree func, const char *name)
   1344 {
   1345   if (FUNCTION_DECL == TREE_CODE (func))
   1346     {
   1347       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
   1348 	{
   1349 	  return true;
   1350 	}
   1351 
   1352       func = TREE_TYPE (func);
   1353     }
   1354 
   1355   gcc_assert (FUNC_OR_METHOD_TYPE_P (func));
   1356 
   1357   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
   1358 }
   1359 
   1360 /* Return nonzero if FUNC is a naked function.  */
   1361 
   1362 static bool
   1363 avr_naked_function_p (tree func)
   1364 {
   1365   return avr_lookup_function_attribute1 (func, "naked");
   1366 }
   1367 
   1368 /* Return nonzero if FUNC is an interrupt function as specified
   1369    by the "interrupt" attribute.  */
   1370 
   1371 static bool
   1372 avr_interrupt_function_p (tree func)
   1373 {
   1374   return avr_lookup_function_attribute1 (func, "interrupt");
   1375 }
   1376 
   1377 /* Return nonzero if FUNC is a signal function as specified
   1378    by the "signal" attribute.  */
   1379 
   1380 static bool
   1381 avr_signal_function_p (tree func)
   1382 {
   1383   return avr_lookup_function_attribute1 (func, "signal");
   1384 }
   1385 
   1386 /* Return nonzero if FUNC is an OS_task function.  */
   1387 
   1388 static bool
   1389 avr_OS_task_function_p (tree func)
   1390 {
   1391   return avr_lookup_function_attribute1 (func, "OS_task");
   1392 }
   1393 
   1394 /* Return nonzero if FUNC is an OS_main function.  */
   1395 
   1396 static bool
   1397 avr_OS_main_function_p (tree func)
   1398 {
   1399   return avr_lookup_function_attribute1 (func, "OS_main");
   1400 }
   1401 
   1402 
   1403 /* Return nonzero if FUNC is a no_gccisr function as specified
   1404    by the "no_gccisr" attribute.  */
   1405 
   1406 static bool
   1407 avr_no_gccisr_function_p (tree func)
   1408 {
   1409   return avr_lookup_function_attribute1 (func, "no_gccisr");
   1410 }
   1411 
   1412 
   1413 /* Implement `TARGET_CAN_INLINE_P'.  */
   1414 /* Some options like -mgas_isr_prologues depend on optimization level,
   1415    and the inliner might think that due to different options, inlining
   1416    is not permitted; see PR104327.  */
   1417 
   1418 static bool
   1419 avr_can_inline_p (tree /* caller */, tree /* callee */)
   1420 {
   1421   // No restrictions whatsoever.
   1422   return true;
   1423 }
   1424 
   1425 /* Implement `TARGET_SET_CURRENT_FUNCTION'.  */
   1426 /* Sanity cheching for above function attributes.  */
   1427 
   1428 static void
   1429 avr_set_current_function (tree decl)
   1430 {
   1431   if (decl == NULL_TREE
   1432       || current_function_decl == NULL_TREE
   1433       || current_function_decl == error_mark_node
   1434       || ! cfun->machine
   1435       || cfun->machine->attributes_checked_p)
   1436     return;
   1437 
   1438   location_t loc = DECL_SOURCE_LOCATION (decl);
   1439 
   1440   cfun->machine->is_naked = avr_naked_function_p (decl);
   1441   cfun->machine->is_signal = avr_signal_function_p (decl);
   1442   cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
   1443   cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
   1444   cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
   1445   cfun->machine->is_no_gccisr = avr_no_gccisr_function_p (decl);
   1446 
   1447   const char *isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
   1448 
   1449   /* Too much attributes make no sense as they request conflicting features. */
   1450 
   1451   if (cfun->machine->is_OS_task
   1452       && (cfun->machine->is_signal || cfun->machine->is_interrupt))
   1453     error_at (loc, "function attributes %qs and %qs are mutually exclusive",
   1454 	      "OS_task", isr);
   1455 
   1456   if (cfun->machine->is_OS_main
   1457       && (cfun->machine->is_signal || cfun->machine->is_interrupt))
   1458     error_at (loc, "function attributes %qs and %qs are mutually exclusive",
   1459 	      "OS_main", isr);
   1460 
   1461   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
   1462     {
   1463       tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
   1464       tree ret = TREE_TYPE (TREE_TYPE (decl));
   1465       const char *name;
   1466 
   1467       name = DECL_ASSEMBLER_NAME_SET_P (decl)
   1468 	? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
   1469 	: IDENTIFIER_POINTER (DECL_NAME (decl));
   1470 
   1471       /* Skip a leading '*' that might still prefix the assembler name,
   1472 	 e.g. in non-LTO runs.  */
   1473 
   1474       name = default_strip_name_encoding (name);
   1475 
   1476       /* Interrupt handlers must be  void __vector (void)  functions.  */
   1477 
   1478       if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
   1479 	error_at (loc, "%qs function cannot have arguments", isr);
   1480 
   1481       if (TREE_CODE (ret) != VOID_TYPE)
   1482 	error_at (loc, "%qs function cannot return a value", isr);
   1483 
   1484 #if defined WITH_AVRLIBC
   1485       /* Silently ignore 'signal' if 'interrupt' is present.  AVR-LibC startet
   1486 	 using this when it switched from SIGNAL and INTERRUPT to ISR.  */
   1487 
   1488       if (cfun->machine->is_interrupt)
   1489 	cfun->machine->is_signal = 0;
   1490 
   1491       /* If the function has the 'signal' or 'interrupt' attribute, ensure
   1492 	 that the name of the function is "__vector_NN" so as to catch
   1493 	 when the user misspells the vector name.  */
   1494 
   1495       if (!startswith (name, "__vector"))
   1496 	warning_at (loc, OPT_Wmisspelled_isr, "%qs appears to be a misspelled "
   1497 		    "%qs handler, missing %<__vector%> prefix", name, isr);
   1498 #endif // AVR-LibC naming conventions
   1499     }
   1500 
   1501 #if defined WITH_AVRLIBC
   1502   // Common problem is using "ISR" without first including avr/interrupt.h.
   1503   const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
   1504   name = default_strip_name_encoding (name);
   1505   if (strcmp ("ISR", name) == 0)
   1506     {
   1507       warning_at (loc, OPT_Wmisspelled_isr, "%qs is a reserved identifier"
   1508 		  " in AVR-LibC.  Consider %<#include <avr/interrupt.h>%>"
   1509 		  " before using the %qs macro", name, name);
   1510     }
   1511   if (strcmp ("INTERRUPT", name) == 0
   1512       || strcmp ("SIGNAL", name) == 0)
   1513     {
   1514       warning_at (loc, OPT_Wmisspelled_isr, "%qs is a deprecated identifier"
   1515 		  " in AVR-LibC.  Consider %<#include <avr/interrupt.h>%>"
   1516 		  " or %<#include <compat/deprecated.h>%>"
   1517 		  " before using the %qs macro", name, name);
   1518     }
   1519 #endif // AVR-LibC naming conventions
   1520 
   1521   /* Don't print the above diagnostics more than once.  */
   1522 
   1523   cfun->machine->attributes_checked_p = 1;
   1524 }
   1525 
   1526 
   1527 /* Implement `ACCUMULATE_OUTGOING_ARGS'.  */
   1528 
   1529 int
   1530 avr_accumulate_outgoing_args (void)
   1531 {
   1532   if (!cfun)
   1533     return TARGET_ACCUMULATE_OUTGOING_ARGS;
   1534 
   1535   /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
   1536 	what offset is correct.  In some cases it is relative to
   1537 	virtual_outgoing_args_rtx and in others it is relative to
   1538 	virtual_stack_vars_rtx.  For example code see
   1539 	    gcc.c-torture/execute/built-in-setjmp.c
   1540 	    gcc.c-torture/execute/builtins/sprintf-chk.c   */
   1541 
   1542   return (TARGET_ACCUMULATE_OUTGOING_ARGS
   1543 	  && !(cfun->calls_setjmp
   1544 	       || cfun->has_nonlocal_label));
   1545 }
   1546 
   1547 
   1548 /* Report contribution of accumulated outgoing arguments to stack size.  */
   1549 
   1550 static inline int
   1551 avr_outgoing_args_size (void)
   1552 {
   1553   return (ACCUMULATE_OUTGOING_ARGS
   1554 	  ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0);
   1555 }
   1556 
   1557 
   1558 /* Implement `TARGET_STARTING_FRAME_OFFSET'.  */
   1559 /* This is the offset from the frame pointer register to the first stack slot
   1560    that contains a variable living in the frame.  */
   1561 
   1562 static HOST_WIDE_INT
   1563 avr_starting_frame_offset (void)
   1564 {
   1565   return 1 + avr_outgoing_args_size ();
   1566 }
   1567 
   1568 
   1569 /* Return the number of hard registers to push/pop in the prologue/epilogue
   1570    of the current function, and optionally store these registers in SET.  */
   1571 
   1572 static int
   1573 avr_regs_to_save (HARD_REG_SET *set)
   1574 {
   1575   int count = 0;
   1576   int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
   1577 
   1578   if (set)
   1579     CLEAR_HARD_REG_SET (*set);
   1580 
   1581   /* No need to save any registers if the function never returns or
   1582      has the "OS_task" or "OS_main" attribute.  */
   1583 
   1584   if (TREE_THIS_VOLATILE (current_function_decl)
   1585       || cfun->machine->is_OS_task
   1586       || cfun->machine->is_OS_main)
   1587     return 0;
   1588 
   1589   for (int reg = REG_0; reg < REG_32; reg++)
   1590     {
   1591       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
   1592 	 any global register variables.  */
   1593 
   1594       if (fixed_regs[reg])
   1595 	continue;
   1596 
   1597       if ((int_or_sig_p && !crtl->is_leaf && call_used_or_fixed_reg_p (reg))
   1598 	  || (df_regs_ever_live_p (reg)
   1599 	      && (int_or_sig_p || !call_used_or_fixed_reg_p (reg))
   1600 	      /* Don't record frame pointer registers here.  They are treated
   1601 		 indivitually in prologue.  */
   1602 	      && !(frame_pointer_needed
   1603 		   && (reg == REG_Y || reg == REG_Y + 1))))
   1604 	{
   1605 	  if (set)
   1606 	    SET_HARD_REG_BIT (*set, reg);
   1607 	  count++;
   1608 	}
   1609     }
   1610   return count;
   1611 }
   1612 
   1613 
   1614 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
   1615 
   1616 static bool
   1617 avr_allocate_stack_slots_for_args (void)
   1618 {
   1619   return !cfun->machine->is_naked;
   1620 }
   1621 
   1622 
   1623 /* Implement `TARGET_CAN_ELIMINATE'.  */
   1624 /* Return true if register FROM can be eliminated via register TO.  */
   1625 
   1626 static bool
   1627 avr_can_eliminate (const int /*from*/, const int to)
   1628 {
   1629   return ((frame_pointer_needed && to == FRAME_POINTER_REGNUM)
   1630 	  || !frame_pointer_needed);
   1631 }
   1632 
   1633 
   1634 /* Implement `TARGET_WARN_FUNC_RETURN'.  */
   1635 
   1636 static bool
   1637 avr_warn_func_return (tree decl)
   1638 {
   1639   /* Naked functions are implemented entirely in assembly, including the
   1640      return sequence, so suppress warnings about this.  */
   1641 
   1642   return !avr_naked_function_p (decl);
   1643 }
   1644 
   1645 
   1646 /* Worker function for `INITIAL_ELIMINATION_OFFSET'.  */
   1647 /* Compute offset between arg_pointer and frame_pointer.  */
   1648 
   1649 int
   1650 avr_initial_elimination_offset (int from, int to)
   1651 {
   1652   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
   1653     return 0;
   1654   else
   1655     {
   1656       int offset = frame_pointer_needed ? 2 : 0;
   1657       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
   1658 
   1659       // If FROM is ARG_POINTER_REGNUM, we are not in an ISR as ISRs
   1660       // might not have arguments.  Hence the following is not affected
   1661       // by gasisr prologues.
   1662       offset += avr_regs_to_save (NULL);
   1663       return (get_frame_size () + avr_outgoing_args_size()
   1664 	      + avr_pc_size + 1 + offset);
   1665     }
   1666 }
   1667 
   1668 
   1669 /* Helper for the function below.  */
   1670 
   1671 static void
   1672 avr_adjust_type_node (tree *node, machine_mode mode, int sat_p)
   1673 {
   1674   *node = make_node (FIXED_POINT_TYPE);
   1675   TYPE_SATURATING (*node) = sat_p;
   1676   TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
   1677   TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
   1678   TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
   1679   TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
   1680   SET_TYPE_ALIGN (*node, 8);
   1681   SET_TYPE_MODE (*node, mode);
   1682 
   1683   layout_type (*node);
   1684 }
   1685 
   1686 
   1687 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'.  */
   1688 
   1689 static tree
   1690 avr_build_builtin_va_list (void)
   1691 {
   1692   /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
   1693      This is more appropriate for the 8-bit machine AVR than 128-bit modes.
   1694      The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
   1695      which is auto-generated by genmodes, but the compiler assigns [U]DAmode
   1696      to the long long accum modes instead of the desired [U]TAmode.
   1697 
   1698      Fix this now, right after node setup in tree.cc:build_common_tree_nodes().
   1699      This must run before c-cppbuiltin.cc:builtin_define_fixed_point_constants()
   1700      which built-in defines macros like __ULLACCUM_FBIT__ that are used by
   1701      libgcc to detect IBIT and FBIT.  */
   1702 
   1703   avr_adjust_type_node (&ta_type_node, TAmode, 0);
   1704   avr_adjust_type_node (&uta_type_node, UTAmode, 0);
   1705   avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
   1706   avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
   1707 
   1708   unsigned_long_long_accum_type_node = uta_type_node;
   1709   long_long_accum_type_node = ta_type_node;
   1710   sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
   1711   sat_long_long_accum_type_node = sat_ta_type_node;
   1712 
   1713   /* Dispatch to the default handler.  */
   1714 
   1715   return std_build_builtin_va_list ();
   1716 }
   1717 
   1718 
   1719 /* Worker function for `INCOMING_RETURN_ADDR_RTX'.  */
   1720 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
   1721    This is return address of function.  */
   1722 
   1723 rtx
   1724 avr_return_addr_rtx (int count, rtx tem)
   1725 {
   1726   rtx r;
   1727 
   1728   /* Can only return this function's return address. Others not supported.  */
   1729   if (count)
   1730     return NULL;
   1731 
   1732   if (AVR_3_BYTE_PC)
   1733     {
   1734       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
   1735       warning (0, "%<builtin_return_address%> contains only 2 bytes"
   1736 	       " of address");
   1737     }
   1738   else
   1739     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
   1740 
   1741   cfun->machine->use_L__stack_usage = 1;
   1742 
   1743   r = gen_rtx_PLUS (Pmode, tem, r);
   1744   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
   1745   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
   1746   return r;
   1747 }
   1748 
   1749 /* Return 1 if the function epilogue is just a single "ret".  */
   1750 
   1751 int
   1752 avr_simple_epilogue (void)
   1753 {
   1754   return (! frame_pointer_needed
   1755 	  && get_frame_size () == 0
   1756 	  && avr_outgoing_args_size() == 0
   1757 	  && avr_regs_to_save (NULL) == 0
   1758 	  && ! cfun->machine->is_interrupt
   1759 	  && ! cfun->machine->is_signal
   1760 	  && ! cfun->machine->is_naked
   1761 	  && ! TREE_THIS_VOLATILE (current_function_decl));
   1762 }
   1763 
   1764 /* This function checks sequence of live registers.  */
   1765 
   1766 static int
   1767 sequent_regs_live (void)
   1768 {
   1769   int live_seq = 0;
   1770   int cur_seq = 0;
   1771 
   1772   for (int reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
   1773     {
   1774       if (fixed_regs[reg])
   1775 	{
   1776 	  /* Don't recognize sequences that contain global register
   1777 	     variables.  */
   1778 
   1779 	  if (live_seq != 0)
   1780 	    return 0;
   1781 	  else
   1782 	    continue;
   1783 	}
   1784 
   1785       if (!call_used_or_fixed_reg_p (reg))
   1786 	{
   1787 	  if (df_regs_ever_live_p (reg))
   1788 	    {
   1789 	      ++live_seq;
   1790 	      ++cur_seq;
   1791 	    }
   1792 	  else
   1793 	    cur_seq = 0;
   1794 	}
   1795     }
   1796 
   1797   if (!frame_pointer_needed)
   1798     {
   1799       if (df_regs_ever_live_p (REG_Y))
   1800 	{
   1801 	  ++live_seq;
   1802 	  ++cur_seq;
   1803 	}
   1804       else
   1805 	cur_seq = 0;
   1806 
   1807       if (df_regs_ever_live_p (REG_Y + 1))
   1808 	{
   1809 	  ++live_seq;
   1810 	  ++cur_seq;
   1811 	}
   1812       else
   1813 	cur_seq = 0;
   1814     }
   1815   else
   1816     {
   1817       cur_seq += 2;
   1818       live_seq += 2;
   1819     }
   1820   return (cur_seq == live_seq) ? live_seq : 0;
   1821 }
   1822 
   1823 
   1824 namespace {
   1825 static const pass_data avr_pass_data_fuse_add =
   1826 {
   1827   RTL_PASS,	    // type
   1828   "",		    // name (will be patched)
   1829   OPTGROUP_NONE,    // optinfo_flags
   1830   TV_DF_SCAN,	    // tv_id
   1831   0,		    // properties_required
   1832   0,		    // properties_provided
   1833   0,		    // properties_destroyed
   1834   0,		    // todo_flags_start
   1835   TODO_df_finish    // todo_flags_finish
   1836 };
   1837 
   1838 
   1839 class avr_pass_fuse_add : public rtl_opt_pass
   1840 {
   1841 public:
   1842   avr_pass_fuse_add (gcc::context *ctxt, const char *name)
   1843     : rtl_opt_pass (avr_pass_data_fuse_add, ctxt)
   1844   {
   1845     this->name = name;
   1846   }
   1847 
   1848   virtual bool gate (function *) { return optimize && avr_fuse_add > 0; }
   1849 
   1850   virtual unsigned int execute (function *);
   1851 
   1852   struct Some_Insn
   1853   {
   1854     rtx_insn *insn = nullptr;
   1855     rtx dest, src;
   1856     bool valid () const { return insn != nullptr; }
   1857     void set_deleted ()
   1858     {
   1859       gcc_assert (insn);
   1860       SET_INSN_DELETED (insn);
   1861       insn = nullptr;
   1862     }
   1863   };
   1864 
   1865   // If .insn is not NULL, then this is a  reg:HI += const_int
   1866   // of an address register.
   1867   struct Add_Insn : Some_Insn
   1868   {
   1869     rtx addend;
   1870     int regno;
   1871     Add_Insn () {}
   1872     Add_Insn (rtx_insn *insn);
   1873   };
   1874 
   1875   // If .insn is not NULL, then this sets an address register
   1876   // to a constant value.
   1877   struct Ldi_Insn : Some_Insn
   1878   {
   1879     int regno;
   1880     Ldi_Insn () {}
   1881     Ldi_Insn (rtx_insn *insn);
   1882   };
   1883 
   1884   // If .insn is not NULL, then this is a load or store insn where the
   1885   // address is REG or POST_INC with an address register.
   1886   struct Mem_Insn : Some_Insn
   1887   {
   1888     rtx reg_or_0, mem, addr, addr_reg;
   1889     int addr_regno;
   1890     enum rtx_code addr_code;
   1891     machine_mode mode;
   1892     addr_space_t addr_space;
   1893     bool store_p, volatile_p;
   1894     Mem_Insn () {}
   1895     Mem_Insn (rtx_insn *insn);
   1896   };
   1897 
   1898   rtx_insn *fuse_ldi_add (Ldi_Insn &prev_ldi, Add_Insn &add);
   1899   rtx_insn *fuse_add_add (Add_Insn &prev_add, Add_Insn &add);
   1900   rtx_insn *fuse_add_mem (Add_Insn &prev_add, Mem_Insn &mem);
   1901   rtx_insn *fuse_mem_add (Mem_Insn &prev_mem, Add_Insn &add);
   1902 }; // avr_pass_fuse_add
   1903 
   1904 } // anon namespace
   1905 
   1906 rtl_opt_pass *
   1907 make_avr_pass_fuse_add (gcc::context *ctxt)
   1908 {
   1909   return new avr_pass_fuse_add (ctxt, "avr-fuse-add");
   1910 }
   1911 
   1912 /* Describe properties of AVR's indirect load and store instructions
   1913    LD, LDD, ST, STD, LPM, ELPM depending on register number, volatility etc.
   1914    Rules for "volatile" accesses are:
   1915 
   1916          | Xmega           |  non-Xmega
   1917    ------+-----------------+----------------
   1918    load  | read LSB first  | read LSB first
   1919    store | write LSB first | write MSB first
   1920 */
   1921 
   1922 struct AVR_LdSt_Props
   1923 {
   1924   bool has_postinc, has_predec, has_ldd;
   1925   // The insn printers will use POST_INC or PRE_DEC addressing, no matter
   1926   // what adressing modes we are feeding into them.
   1927   bool want_postinc, want_predec;
   1928 
   1929   AVR_LdSt_Props (int regno, bool store_p, bool volatile_p, addr_space_t as)
   1930   {
   1931     bool generic_p = ADDR_SPACE_GENERIC_P (as);
   1932     bool flashx_p = ! generic_p && as != ADDR_SPACE_MEMX;
   1933     has_postinc = generic_p || (flashx_p && regno == REG_Z);
   1934     has_predec = generic_p;
   1935     has_ldd = ! AVR_TINY && generic_p && (regno == REG_Y || regno == REG_Z);
   1936     want_predec  = volatile_p && generic_p && ! AVR_XMEGA && store_p;
   1937     want_postinc = volatile_p && generic_p && (AVR_XMEGA || ! store_p);
   1938     want_postinc |= flashx_p && regno == REG_Z;
   1939   }
   1940 
   1941   AVR_LdSt_Props (const avr_pass_fuse_add::Mem_Insn &m)
   1942     : AVR_LdSt_Props (m.addr_regno, m.store_p, m.volatile_p, m.addr_space)
   1943   {
   1944     gcc_assert (m.valid ());
   1945   }
   1946 };
   1947 
   1948 /* Emit a single_set that clobbers REG_CC.  */
   1949 
   1950 static rtx_insn *
   1951 emit_move_ccc (rtx dest, rtx src)
   1952 {
   1953   return emit_insn (gen_gen_move_clobbercc (dest, src));
   1954 }
   1955 
   1956 /* Emit a single_set that clobbers REG_CC after insn AFTER.  */
   1957 
   1958 static rtx_insn *
   1959 emit_move_ccc_after (rtx dest, rtx src, rtx_insn *after)
   1960 {
   1961   return emit_insn_after (gen_gen_move_clobbercc (dest, src), after);
   1962 }
   1963 
   1964 static bool
   1965 reg_seen_between_p (const_rtx reg, const rtx_insn *from, const rtx_insn *to)
   1966 {
   1967   return (reg_used_between_p (reg, from, to)
   1968 	  || reg_set_between_p (reg, from, to));
   1969 }
   1970 
   1971 
   1972 static void
   1973 avr_maybe_adjust_cfa (rtx_insn *insn, rtx reg, int addend)
   1974 {
   1975   if (addend
   1976       && frame_pointer_needed
   1977       && REGNO (reg) == FRAME_POINTER_REGNUM
   1978       && avr_fuse_add == 3)
   1979     {
   1980       rtx plus = plus_constant (Pmode, reg, addend);
   1981       RTX_FRAME_RELATED_P (insn) = 1;
   1982       add_reg_note (insn, REG_CFA_ADJUST_CFA, gen_rtx_SET (reg, plus));
   1983     }
   1984 }
   1985 
   1986 
   1987 // If successful, this represents a SET of a pointer register to a constant.
   1988 avr_pass_fuse_add::Ldi_Insn::Ldi_Insn (rtx_insn *insn)
   1989 {
   1990   rtx set = single_set (insn);
   1991   if (!set)
   1992     return;
   1993 
   1994   src = SET_SRC (set);
   1995   dest = SET_DEST (set);
   1996 
   1997   if (REG_P (dest)
   1998       && GET_MODE (dest) == Pmode
   1999       && IN_RANGE (regno = REGNO (dest), REG_X, REG_Z)
   2000       && CONSTANT_P (src))
   2001     {
   2002       this->insn = insn;
   2003     }
   2004 }
   2005 
   2006 // If successful, this represents a PLUS with CONST_INT of a pointer
   2007 // register X, Y or Z.  Otherwise, the object is not valid().
   2008 avr_pass_fuse_add::Add_Insn::Add_Insn (rtx_insn *insn)
   2009 {
   2010   rtx set = single_set (insn);
   2011   if (!set)
   2012     return;
   2013 
   2014   src = SET_SRC (set);
   2015   dest = SET_DEST (set);
   2016   if (REG_P (dest)
   2017       // We are only interested in PLUSes that change address regs.
   2018       && GET_MODE (dest) == Pmode
   2019       && IN_RANGE (regno = REGNO (dest), REG_X, REG_Z)
   2020       && PLUS == GET_CODE (src)
   2021       && rtx_equal_p (XEXP (src, 0), dest)
   2022       && CONST_INT_P (XEXP (src, 1)))
   2023     {
   2024       // This is reg:HI += const_int.
   2025       addend = XEXP (src, 1);
   2026       this->insn = insn;
   2027     }
   2028 }
   2029 
   2030 // If successful, this represents a load or store insn where the addressing
   2031 // mode uses pointer register X, Y or Z.  Otherwise, the object is not valid().
   2032 avr_pass_fuse_add::Mem_Insn::Mem_Insn (rtx_insn *insn)
   2033 {
   2034   rtx set = single_set (insn);
   2035   if (!set)
   2036     return;
   2037 
   2038   src = SET_SRC (set);
   2039   dest = SET_DEST (set);
   2040   mode = GET_MODE (dest);
   2041 
   2042   if (MEM_P (dest)
   2043       && (REG_P (src) || src == CONST0_RTX (mode)))
   2044     {
   2045       reg_or_0 = src;
   2046       mem = dest;
   2047     }
   2048   else if (REG_P (dest) && MEM_P (src))
   2049     {
   2050       reg_or_0 = dest;
   2051       mem = src;
   2052     }
   2053   else
   2054     return;
   2055 
   2056   if (avr_mem_memx_p (mem)
   2057       || avr_load_libgcc_p (mem))
   2058     return;
   2059 
   2060   addr = XEXP (mem, 0);
   2061   addr_code = GET_CODE (addr);
   2062 
   2063   if (addr_code == REG)
   2064     addr_reg = addr;
   2065   else if (addr_code == POST_INC || addr_code == PRE_DEC)
   2066     addr_reg = XEXP (addr, 0);
   2067   else
   2068     return;
   2069 
   2070   addr_regno = REGNO (addr_reg);
   2071 
   2072   if (avr_fuse_add == 2
   2073       && frame_pointer_needed
   2074       && addr_regno == FRAME_POINTER_REGNUM)
   2075     MEM_VOLATILE_P (mem) = 0;
   2076 
   2077   if (reg_overlap_mentioned_p (reg_or_0, addr) // Can handle CONSTANT_P.
   2078       || addr_regno > REG_Z
   2079       || avr_mem_memx_p (mem)
   2080       // The following optimizations only handle REG and POST_INC,
   2081       // so that's all what we allow here.
   2082       || (addr_code != REG && addr_code != POST_INC))
   2083     return;
   2084 
   2085   addr_space = MEM_ADDR_SPACE (mem);
   2086   volatile_p = MEM_VOLATILE_P (mem);
   2087   store_p = MEM_P (dest);
   2088 
   2089   // Turn this "valid".
   2090   this->insn = insn;
   2091 }
   2092 
   2093 /* Try to combine a Ldi insn with a PLUS CONST_INT addend to one Ldi insn.
   2094    If LDI is valid, then it precedes ADD in the same block.
   2095    When a replacement is found, a new insn is emitted and the old insns
   2096    are pseudo-deleted.  The returned insn is the point where the calling
   2097    scanner should continue.  When no replacement is found, nullptr is
   2098    returned and nothing changed.  */
   2099 
   2100 rtx_insn *
   2101 avr_pass_fuse_add::fuse_ldi_add (Ldi_Insn &ldi, Add_Insn &add)
   2102 {
   2103   if (! ldi.valid ()
   2104       || reg_seen_between_p (ldi.dest, ldi.insn, add.insn))
   2105     {
   2106       // If something is between the Ldi and the current insn, we can
   2107       // set the Ldi invalid to speed future scans.
   2108       return ldi.insn = nullptr;
   2109     }
   2110 
   2111   // Found a Ldi with const and a PLUS insns in the same BB,
   2112   // and with no interfering insns between them.
   2113 
   2114   // Emit new Ldi with the sum of the original offsets after the old Ldi.
   2115   rtx xval = plus_constant (Pmode, ldi.src, INTVAL (add.addend));
   2116 
   2117   rtx_insn *insn = emit_move_ccc_after (ldi.dest, xval, ldi.insn);
   2118   avr_dump (";; new Ldi[%d] insn %d after %d: R%d = %r\n\n", ldi.regno,
   2119 	    INSN_UID (insn), INSN_UID (ldi.insn), ldi.regno, xval);
   2120 
   2121   rtx_insn *next = NEXT_INSN (add.insn);
   2122   ldi.set_deleted ();
   2123   add.set_deleted ();
   2124 
   2125   return next;
   2126 }
   2127 
   2128 /* Try to combine two PLUS insns with CONST_INT addend to one such insn.
   2129    If PREV_ADD is valid, then it precedes ADD in the same basic block.
   2130    When a replacement is found, a new insn is emitted and the old insns
   2131    are pseudo-deleted.  The returned insn is the point where the calling
   2132    scanner should continue.  When no replacement is found, nullptr is
   2133    returned and nothing changed.  */
   2134 
   2135 rtx_insn *
   2136 avr_pass_fuse_add::fuse_add_add (Add_Insn &prev_add, Add_Insn &add)
   2137 {
   2138   if (! prev_add.valid ()
   2139       || reg_seen_between_p (add.dest, prev_add.insn, add.insn))
   2140     {
   2141       // If something is between the previous Add and the current insn,
   2142       // we can set the previous Add invalid to speed future scans.
   2143       return prev_add.insn = nullptr;
   2144     }
   2145 
   2146   // Found two PLUS insns in the same BB, and with no interfering
   2147   // insns between them.
   2148   rtx plus = plus_constant (Pmode, add.src, INTVAL (prev_add.addend));
   2149 
   2150   rtx_insn *next;
   2151   if (REG_P (plus))
   2152     {
   2153       avr_dump (";; Add[%d] from %d annihilates %d\n\n", add.regno,
   2154 		INSN_UID (prev_add.insn), INSN_UID (add.insn));
   2155       next = NEXT_INSN (add.insn);
   2156     }
   2157   else
   2158     {
   2159       // Emit after the current insn, so that it will be picked
   2160       // up as next valid Add insn.
   2161       next = emit_move_ccc_after (add.dest, plus, add.insn);
   2162       avr_dump (";; #1 new Add[%d] insn %d after %d: R%d += %d\n\n",
   2163 		add.regno, INSN_UID (next), INSN_UID (add.insn),
   2164 		add.regno, (int) INTVAL (XEXP (plus, 1)));
   2165       gcc_assert (GET_CODE (plus) == PLUS);
   2166     }
   2167 
   2168   add.set_deleted ();
   2169   prev_add.set_deleted ();
   2170 
   2171   return next;
   2172 }
   2173 
   2174 /* Try to combine a PLUS of the address register with a load or store insn.
   2175    If ADD is valid, then it precedes MEM in the same basic block.
   2176    When a replacement is found, a new insn is emitted and the old insns
   2177    are pseudo-deleted.  The returned insn is the point where the calling
   2178    scanner should continue.  When no replacement is found, nullptr is
   2179    returned and nothing changed.  */
   2180 
   2181 rtx_insn *
   2182 avr_pass_fuse_add::fuse_add_mem (Add_Insn &add, Mem_Insn &mem)
   2183 {
   2184   if (! add.valid ()
   2185       || reg_seen_between_p (add.dest, add.insn, mem.insn))
   2186     {
   2187       // If something is between the Add and the current insn, we can
   2188       // set the Add invalid to speed future scans.
   2189       return add.insn = nullptr;
   2190     }
   2191 
   2192   AVR_LdSt_Props ap { mem };
   2193 
   2194   int msize = GET_MODE_SIZE (mem.mode);
   2195 
   2196   // The mem insn really wants PRE_DEC.
   2197   bool case1 = ((mem.addr_code == REG || mem.addr_code == POST_INC)
   2198 		&& msize > 1 && ap.want_predec && ! ap.has_ldd);
   2199 
   2200   // The offset can be consumed by a PRE_DEC.
   2201   bool case2 = (- INTVAL (add.addend) == msize
   2202 		&& (mem.addr_code == REG || mem.addr_code == POST_INC)
   2203 		&& ap.has_predec && ! ap.want_postinc);
   2204 
   2205   if (! case1 && ! case2)
   2206     return nullptr;
   2207 
   2208   // Change from REG or POST_INC to PRE_DEC.
   2209   rtx xmem = change_address (mem.mem, mem.mode,
   2210 			     gen_rtx_PRE_DEC (Pmode, mem.addr_reg));
   2211   rtx dest = mem.store_p ? xmem : mem.reg_or_0;
   2212   rtx src  = mem.store_p ? mem.reg_or_0 : xmem;
   2213 
   2214   rtx_insn *next = emit_move_ccc_after (dest, src, mem.insn);
   2215   add_reg_note (next, REG_INC, mem.addr_reg);
   2216   avr_dump (";; new Mem[%d] insn %d after %d: %r = %r\n\n", mem.addr_regno,
   2217 	    INSN_UID (next), INSN_UID (mem.insn), dest, src);
   2218 
   2219   // Changing REG or POST_INC -> PRE_DEC means that the addend before
   2220   // the memory access must be increased by the size of the access,
   2221   rtx plus = plus_constant (Pmode, add.src, msize);
   2222   if (! REG_P (plus))
   2223     {
   2224       rtx_insn *insn = emit_move_ccc_after (add.dest, plus, add.insn);
   2225       avr_dump (";; #2 new Add[%d] insn %d after %d: R%d += %d\n\n",
   2226 		add.regno, INSN_UID (insn), INSN_UID (add.insn),
   2227 		add.regno, (int) INTVAL (XEXP (plus, 1)));
   2228       gcc_assert (GET_CODE (plus) == PLUS);
   2229     }
   2230   else
   2231     avr_dump (";; Add[%d] insn %d consumed into %d\n\n",
   2232 	      add.regno, INSN_UID (add.insn), INSN_UID (next));
   2233 
   2234   // Changing POST_INC -> PRE_DEC means that the addend after the mem has to be
   2235   // the size of the access.  The hope is that this new add insn may be unused.
   2236   if (mem.addr_code == POST_INC)
   2237     {
   2238       plus = plus_constant (Pmode, add.dest, msize);
   2239       rtx_insn *next2 = emit_move_ccc_after (add.dest, plus, next);
   2240       avr_dump (";; #3 new Add[%d] insn %d after %d: R%d += %d\n\n", add.regno,
   2241 		INSN_UID (next2), INSN_UID (next), add.regno, msize);
   2242       next = next2;
   2243     }
   2244 
   2245   add.set_deleted ();
   2246   mem.set_deleted ();
   2247 
   2248   return next;
   2249 }
   2250 
   2251 /* Try to combine a load or store insn with a PLUS of the address register.
   2252    If MEM is valid, then it precedes ADD in the same basic block.
   2253    When a replacement is found, a new insn is emitted and the old insns
   2254    are pseudo-deleted.  The returned insn is the point where the calling
   2255    scanner should continue.  When no replacement is found, nullptr is
   2256    returned and nothing changed.  */
   2257 
   2258 rtx_insn *
   2259 avr_pass_fuse_add::fuse_mem_add (Mem_Insn &mem, Add_Insn &add)
   2260 {
   2261   if (! mem.valid ()
   2262       || reg_seen_between_p (add.dest, mem.insn, add.insn))
   2263     {
   2264       // If something is between the Mem and the current insn, we can
   2265       // set the Mem invalid to speed future scans.
   2266       return mem.insn = nullptr;
   2267     }
   2268 
   2269   AVR_LdSt_Props ap { mem };
   2270 
   2271   int msize = GET_MODE_SIZE (mem.mode);
   2272 
   2273   // The add insn can be consumed by a POST_INC.
   2274   bool case1 = (mem.addr_code == REG
   2275 		&& INTVAL (add.addend) == msize
   2276 		&& ap.has_postinc && ! ap.want_predec);
   2277 
   2278   // There are cases where even a partial consumption of the offset is better.
   2279   // This are the cases where no LD+offset addressing is available, because
   2280   // the address register is obviously used after the mem insn, and a mem insn
   2281   // with REG addressing mode will have to restore the address.
   2282   bool case2 = (mem.addr_code == REG
   2283 		&& msize > 1 && ap.want_postinc && ! ap.has_ldd);
   2284 
   2285   if (! case1 && ! case2)
   2286     return nullptr;
   2287 
   2288   // Change addressing mode from REG to POST_INC.
   2289   rtx xmem = change_address (mem.mem, mem.mode,
   2290 			     gen_rtx_POST_INC (Pmode, mem.addr_reg));
   2291   rtx dest = mem.store_p ? xmem : mem.reg_or_0;
   2292   rtx src  = mem.store_p ? mem.reg_or_0 : xmem;
   2293 
   2294   rtx_insn *insn = emit_move_ccc_after (dest, src, mem.insn);
   2295   add_reg_note (insn, REG_INC, mem.addr_reg);
   2296   avr_dump (";; new Mem[%d] insn %d after %d: %r = %r\n\n", add.regno,
   2297 	    INSN_UID (insn), INSN_UID (mem.insn), dest, src);
   2298 
   2299   rtx_insn *next = NEXT_INSN (add.insn);
   2300 
   2301   // Changing REG -> POST_INC means that the post addend must be
   2302   // decreased by the size of the access.
   2303   rtx plus = plus_constant (Pmode, add.src, -msize);
   2304   if (! REG_P (plus))
   2305     {
   2306       next = emit_move_ccc_after (mem.addr_reg, plus, add.insn);
   2307       avr_dump (";; #4 new Add[%d] insn %d after %d: R%d += %d\n\n",
   2308 		add.regno, INSN_UID (next), INSN_UID (add.insn),
   2309 		add.regno, (int) INTVAL (XEXP (plus, 1)));
   2310       gcc_assert (GET_CODE (plus) == PLUS);
   2311     }
   2312   else
   2313     avr_dump (";; Add[%d] insn %d consumed into %d\n\n",
   2314 	      add.regno, INSN_UID (add.insn), INSN_UID (insn));
   2315 
   2316   add.set_deleted ();
   2317   mem.set_deleted ();
   2318 
   2319   return next;
   2320 }
   2321 
   2322 /* Try to post-reload combine PLUS with CONST_INt of pointer registers with:
   2323    - Sets to a constant address.
   2324    - PLUS insn of that kind.
   2325    - Indirect loads and stores.
   2326    In almost all cases, combine opportunities arise from the preparation
   2327    done by `avr_split_tiny_move', but in some rare cases combinations are
   2328    found for the ordinary cores, too.
   2329       As we consider at most one Mem insn per try, there may still be missed
   2330    optimizations like  POST_INC + PLUS + POST_INC  might be performed
   2331    as  PRE_DEC + PRE_DEC  for two adjacent locations.  */
   2332 
   2333 unsigned int
   2334 avr_pass_fuse_add::execute (function *func)
   2335 {
   2336   df_note_add_problem ();
   2337   df_analyze ();
   2338 
   2339   int n_add = 0, n_mem = 0, n_ldi = 0;
   2340   basic_block bb;
   2341 
   2342   FOR_EACH_BB_FN (bb, func)
   2343     {
   2344       Ldi_Insn prev_ldi_insns[REG_32];
   2345       Add_Insn prev_add_insns[REG_32];
   2346       Mem_Insn prev_mem_insns[REG_32];
   2347       rtx_insn *insn, *curr;
   2348 
   2349       avr_dump ("\n;; basic block %d\n\n", bb->index);
   2350 
   2351       FOR_BB_INSNS_SAFE (bb, insn, curr)
   2352 	{
   2353 	  rtx_insn *next = nullptr;
   2354 	  Ldi_Insn ldi_insn { insn };
   2355 	  Add_Insn add_insn { insn };
   2356 	  Mem_Insn mem_insn { insn };
   2357 
   2358 	  if (add_insn.valid ())
   2359 	    {
   2360 	      // Found reg:HI += const_int
   2361 	      avr_dump (";; insn %d: Add[%d]: R%d += %d\n\n",
   2362 			INSN_UID (add_insn.insn), add_insn.regno,
   2363 			add_insn.regno, (int) INTVAL (add_insn.addend));
   2364 	      Ldi_Insn &prev_ldi_insn = prev_ldi_insns[add_insn.regno];
   2365 	      Add_Insn &prev_add_insn = prev_add_insns[add_insn.regno];
   2366 	      Mem_Insn &prev_mem_insn = prev_mem_insns[add_insn.regno];
   2367 	      if ((next = fuse_ldi_add (prev_ldi_insn, add_insn)))
   2368 		curr = next, n_ldi += 1;
   2369 	      else if ((next = fuse_add_add (prev_add_insn, add_insn)))
   2370 		curr = next, n_add += 1;
   2371 	      else if ((next = fuse_mem_add (prev_mem_insn, add_insn)))
   2372 		curr = next, n_mem += 1;
   2373 	      else
   2374 		prev_add_insn = add_insn;
   2375 	    }
   2376 	  else if (mem_insn.valid ())
   2377 	    {
   2378 	      int addr_regno = REGNO (mem_insn.addr_reg);
   2379 	      avr_dump (";; insn %d: Mem[%d]: %r = %r\n\n",
   2380 			INSN_UID (mem_insn.insn), addr_regno,
   2381 			mem_insn.dest, mem_insn.src);
   2382 	      Add_Insn &prev_add_insn = prev_add_insns[addr_regno];
   2383 	      if ((next = fuse_add_mem (prev_add_insn, mem_insn)))
   2384 		curr = next, n_mem += 1;
   2385 	      else
   2386 		prev_mem_insns[addr_regno] = mem_insn;
   2387 	    }
   2388 	  else if (ldi_insn.valid ())
   2389 	    {
   2390 	      if (! CONST_INT_P (ldi_insn.src))
   2391 		avr_dump (";; insn %d: Ldi[%d]: R%d = %r\n\n",
   2392 			  INSN_UID (ldi_insn.insn), ldi_insn.regno,
   2393 			  ldi_insn.regno, ldi_insn.src);
   2394 	      prev_ldi_insns[ldi_insn.regno] = ldi_insn;
   2395 	    }
   2396 	} // for insns
   2397     } // for BBs
   2398 
   2399   avr_dump (";; Function %f: Found %d changes: %d ldi, %d add, %d mem.\n",
   2400 	    n_ldi + n_add + n_mem, n_ldi, n_add, n_mem);
   2401 
   2402   return 0;
   2403 }
   2404 
   2405 
   2406 namespace {
   2407 static const pass_data avr_pass_data_pre_proep =
   2408 {
   2409   RTL_PASS,      // type
   2410   "",	    // name (will be patched)
   2411   OPTGROUP_NONE, // optinfo_flags
   2412   TV_DF_SCAN,    // tv_id
   2413   0,	     // properties_required
   2414   0,	     // properties_provided
   2415   0,	     // properties_destroyed
   2416   0,	     // todo_flags_start
   2417   0	      // todo_flags_finish
   2418 };
   2419 
   2420 
   2421 class avr_pass_pre_proep : public rtl_opt_pass
   2422 {
   2423 public:
   2424   avr_pass_pre_proep (gcc::context *ctxt, const char *name)
   2425     : rtl_opt_pass (avr_pass_data_pre_proep, ctxt)
   2426   {
   2427     this->name = name;
   2428   }
   2429 
   2430   void compute_maybe_gasisr (function *);
   2431 
   2432   virtual unsigned int execute (function *fun)
   2433   {
   2434     if (avr_gasisr_prologues
   2435 	// Whether this function is an ISR worth scanning at all.
   2436 	&& !fun->machine->is_no_gccisr
   2437 	&& (fun->machine->is_interrupt
   2438 	    || fun->machine->is_signal)
   2439 	&& !cfun->machine->is_naked
   2440 	// Paranoia: Non-local gotos and labels that might escape.
   2441 	&& !cfun->calls_setjmp
   2442 	&& !cfun->has_nonlocal_label
   2443 	&& !cfun->has_forced_label_in_static)
   2444       {
   2445 	compute_maybe_gasisr (fun);
   2446       }
   2447 
   2448     return 0;
   2449   }
   2450 
   2451 }; // avr_pass_pre_proep
   2452 
   2453 } // anon namespace
   2454 
   2455 rtl_opt_pass *
   2456 make_avr_pass_pre_proep (gcc::context *ctxt)
   2457 {
   2458   return new avr_pass_pre_proep (ctxt, "avr-pre-proep");
   2459 }
   2460 
   2461 
   2462 /* Set fun->machine->gasisr.maybe provided we don't find anything that
   2463    prohibits GAS generating parts of ISR prologues / epilogues for us.  */
   2464 
   2465 void
   2466 avr_pass_pre_proep::compute_maybe_gasisr (function *fun)
   2467 {
   2468   // Don't use BB iterators so that we see JUMP_TABLE_DATA.
   2469 
   2470   for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
   2471     {
   2472       // Transparent calls always use [R]CALL and are filtered out by GAS.
   2473       // ISRs don't use -mcall-prologues, hence what remains to be filtered
   2474       // out are open coded (tail) calls.
   2475 
   2476       if (CALL_P (insn))
   2477 	return;
   2478 
   2479       // __tablejump2__ clobbers something and is targeted by JMP so
   2480       // that GAS won't see its usage.
   2481 
   2482       if (AVR_HAVE_JMP_CALL
   2483 	  && JUMP_TABLE_DATA_P (insn))
   2484 	return;
   2485 
   2486       // Non-local gotos not seen in *FUN.
   2487 
   2488       if (JUMP_P (insn)
   2489 	  && find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
   2490 	return;
   2491     }
   2492 
   2493   fun->machine->gasisr.maybe = 1;
   2494 }
   2495 
   2496 
   2497 /* Obtain the length sequence of insns.  */
   2498 
   2499 int
   2500 get_sequence_length (rtx_insn *insns)
   2501 {
   2502   int length = 0;
   2503 
   2504   for (rtx_insn *insn = insns; insn; insn = NEXT_INSN (insn))
   2505     length += get_attr_length (insn);
   2506 
   2507   return length;
   2508 }
   2509 
   2510 
   2511 /*  Implement `INCOMING_RETURN_ADDR_RTX'.  */
   2512 
   2513 rtx
   2514 avr_incoming_return_addr_rtx (void)
   2515 {
   2516   /* The return address is at the top of the stack.  Note that the push
   2517      was via post-decrement, which means the actual address is off by one.  */
   2518   return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
   2519 }
   2520 
   2521 
   2522 /* Unset a bit in *SET.  If successful, return the respective bit number.
   2523    Otherwise, return -1 and *SET is unaltered.  */
   2524 
   2525 static int
   2526 avr_hregs_split_reg (HARD_REG_SET *set)
   2527 {
   2528   for (int regno = REG_0; regno < REG_32; regno++)
   2529     if (TEST_HARD_REG_BIT (*set, regno))
   2530       {
   2531 	// Don't remove a register from *SET which might indicate that
   2532 	// some RAMP* register might need ISR prologue / epilogue treatment.
   2533 
   2534 	if (AVR_HAVE_RAMPX
   2535 	    && (REG_X == regno || REG_X + 1 == regno)
   2536 	    && TEST_HARD_REG_BIT (*set, REG_X)
   2537 	    && TEST_HARD_REG_BIT (*set, REG_X + 1))
   2538 	  continue;
   2539 
   2540 	if (AVR_HAVE_RAMPY
   2541 	    && !frame_pointer_needed
   2542 	    && (REG_Y == regno || REG_Y + 1 == regno)
   2543 	    && TEST_HARD_REG_BIT (*set, REG_Y)
   2544 	    && TEST_HARD_REG_BIT (*set, REG_Y + 1))
   2545 	  continue;
   2546 
   2547 	if (AVR_HAVE_RAMPZ
   2548 	    && (REG_Z == regno || REG_Z + 1 == regno)
   2549 	    && TEST_HARD_REG_BIT (*set, REG_Z)
   2550 	    && TEST_HARD_REG_BIT (*set, REG_Z + 1))
   2551 	  continue;
   2552 
   2553 	CLEAR_HARD_REG_BIT (*set, regno);
   2554 	return regno;
   2555       }
   2556 
   2557   return -1;
   2558 }
   2559 
   2560 
   2561 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
   2562 
   2563 static void
   2564 emit_push_byte (unsigned regno, bool frame_related_p)
   2565 {
   2566   rtx mem, reg;
   2567   rtx_insn *insn;
   2568 
   2569   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
   2570   mem = gen_frame_mem (QImode, mem);
   2571   reg = gen_rtx_REG (QImode, regno);
   2572 
   2573   insn = emit_insn (gen_rtx_SET (mem, reg));
   2574   if (frame_related_p)
   2575     RTX_FRAME_RELATED_P (insn) = 1;
   2576 
   2577   cfun->machine->stack_usage++;
   2578 }
   2579 
   2580 
   2581 /*  Helper for expand_prologue.  Emit a push of a SFR via register TREG.
   2582     SFR is a MEM representing the memory location of the SFR.
   2583     If CLR_P then clear the SFR after the push using zero_reg.  */
   2584 
   2585 static void
   2586 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p, int treg)
   2587 {
   2588   gcc_assert (MEM_P (sfr));
   2589 
   2590   /* IN treg, IO(SFR) */
   2591   rtx_insn *insn = emit_move_insn (all_regs_rtx[treg], sfr);
   2592   if (frame_related_p)
   2593     RTX_FRAME_RELATED_P (insn) = 1;
   2594 
   2595   /* PUSH treg */
   2596   emit_push_byte (treg, frame_related_p);
   2597 
   2598   if (clr_p)
   2599     {
   2600       /* OUT IO(SFR), __zero_reg__ */
   2601       insn = emit_move_insn (sfr, const0_rtx);
   2602       if (frame_related_p)
   2603 	RTX_FRAME_RELATED_P (insn) = 1;
   2604     }
   2605 }
   2606 
   2607 static void
   2608 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
   2609 {
   2610   rtx_insn *insn;
   2611   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
   2612   int live_seq = sequent_regs_live ();
   2613 
   2614   HOST_WIDE_INT size_max
   2615     = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
   2616 
   2617   bool minimize = (TARGET_CALL_PROLOGUES
   2618 		   && size < size_max
   2619 		   && live_seq
   2620 		   && !isr_p
   2621 		   && !cfun->machine->is_OS_task
   2622 		   && !cfun->machine->is_OS_main
   2623 		   && !AVR_TINY);
   2624 
   2625   if (minimize
   2626       && (frame_pointer_needed
   2627 	  || avr_outgoing_args_size() > 8
   2628 	  || (AVR_2_BYTE_PC && live_seq > 6)
   2629 	  || live_seq > 7))
   2630     {
   2631       rtx pattern;
   2632       int reg, offset;
   2633 
   2634       emit_move_insn (gen_rtx_REG (HImode, REG_X),
   2635 		      gen_int_mode (size, HImode));
   2636 
   2637       pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
   2638 					 gen_int_mode (live_seq+size, HImode));
   2639       insn = emit_insn (pattern);
   2640       RTX_FRAME_RELATED_P (insn) = 1;
   2641 
   2642       /* Describe the effect of the unspec_volatile call to prologue_saves.
   2643 	 Note that this formulation assumes that add_reg_note pushes the
   2644 	 notes to the front.  Thus we build them in the reverse order of
   2645 	 how we want dwarf2out to process them.  */
   2646 
   2647       /* The function does always set frame_pointer_rtx, but whether that
   2648 	 is going to be permanent in the function is frame_pointer_needed.  */
   2649 
   2650       add_reg_note (insn, REG_CFA_ADJUST_CFA,
   2651 		    gen_rtx_SET ((frame_pointer_needed
   2652 				  ? frame_pointer_rtx
   2653 				  : stack_pointer_rtx),
   2654 				 plus_constant (Pmode, stack_pointer_rtx,
   2655 						-(size + live_seq))));
   2656 
   2657       /* Note that live_seq always contains r28+r29, but the other
   2658 	 registers to be saved are all below 18.  */
   2659 
   2660       int first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
   2661 
   2662       for (reg = REG_29, offset = -live_seq + 1;
   2663 	   reg >= first_reg;
   2664 	   reg = (reg == REG_28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
   2665 	{
   2666 	  rtx m, r;
   2667 
   2668 	  m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
   2669 						  offset));
   2670 	  r = gen_rtx_REG (QImode, reg);
   2671 	  add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (m, r));
   2672 	}
   2673 
   2674       cfun->machine->stack_usage += size + live_seq;
   2675     }
   2676   else /* !minimize */
   2677     {
   2678       for (int reg = REG_0; reg < REG_32; ++reg)
   2679 	if (TEST_HARD_REG_BIT (set, reg))
   2680 	  emit_push_byte (reg, true);
   2681 
   2682       if (frame_pointer_needed
   2683 	  && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
   2684 	{
   2685 	  /* Push frame pointer.  Always be consistent about the
   2686 	     ordering of pushes -- epilogue_restores expects the
   2687 	     register pair to be pushed low byte first.  */
   2688 
   2689 	  emit_push_byte (REG_Y, true);
   2690 	  emit_push_byte (REG_Y + 1, true);
   2691 	}
   2692 
   2693       if (frame_pointer_needed
   2694 	  && size == 0)
   2695 	{
   2696 	  insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
   2697 	  RTX_FRAME_RELATED_P (insn) = 1;
   2698 	}
   2699 
   2700       if (size != 0)
   2701 	{
   2702 	  /*  Creating a frame can be done by direct manipulation of the
   2703 	      stack or via the frame pointer. These two methods are:
   2704 		  fp =  sp
   2705 		  fp -= size
   2706 		  sp =  fp
   2707 	      or
   2708 		  sp -= size
   2709 		  fp =  sp    (*)
   2710 	      the optimum method depends on function type, stack and
   2711 	      frame size.  To avoid a complex logic, both methods are
   2712 	      tested and shortest is selected.
   2713 
   2714 	      There is also the case where SIZE != 0 and no frame pointer is
   2715 	      needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
   2716 	      In that case, insn (*) is not needed in that case.
   2717 	      We use the X register as scratch. This is save because in X
   2718 	      is call-clobbered.
   2719 		 In an interrupt routine, the case of SIZE != 0 together with
   2720 	      !frame_pointer_needed can only occur if the function is not a
   2721 	      leaf function and thus X has already been saved.  */
   2722 
   2723 	  int irq_state = -1;
   2724 	  HOST_WIDE_INT size_cfa = size, neg_size;
   2725 	  rtx_insn *fp_plus_insns;
   2726 
   2727 	  gcc_assert (frame_pointer_needed
   2728 		      || !isr_p
   2729 		      || !crtl->is_leaf);
   2730 
   2731 	  rtx my_fp = (frame_pointer_needed
   2732 		       ? frame_pointer_rtx
   2733 		       : gen_rtx_REG (Pmode, REG_X));
   2734 	  rtx fp = my_fp;
   2735 
   2736 	  if (AVR_HAVE_8BIT_SP)
   2737 	    {
   2738 	      /* The high byte (r29) does not change:
   2739 		 Prefer SUBI (1 cycle) over SBIW (2 cycles, same size).  */
   2740 
   2741 	      my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
   2742 	    }
   2743 
   2744 	  /* Cut down size and avoid size = 0 so that we don't run
   2745 	     into ICE like PR52488 in the remainder.  */
   2746 
   2747 	  if (size > size_max)
   2748 	    {
   2749 	      /* Don't error so that insane code from newlib still compiles
   2750 		 and does not break building newlib.  As PR51345 is implemented
   2751 		 now, there are multilib variants with -msp8.
   2752 
   2753 		 If user wants sanity checks he can use -Wstack-usage=
   2754 		 or similar options.
   2755 
   2756 		 For CFA we emit the original, non-saturated size so that
   2757 		 the generic machinery is aware of the real stack usage and
   2758 		 will print the above diagnostic as expected.  */
   2759 
   2760 	      size = size_max;
   2761 	    }
   2762 
   2763 	  size = trunc_int_for_mode (size, GET_MODE (my_fp));
   2764 	  neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
   2765 
   2766 	  /************  Method 1: Adjust frame pointer  ************/
   2767 
   2768 	  start_sequence ();
   2769 
   2770 	  /* Normally, the dwarf2out frame-related-expr interpreter does
   2771 	     not expect to have the CFA change once the frame pointer is
   2772 	     set up.  Thus, we avoid marking the move insn below and
   2773 	     instead indicate that the entire operation is complete after
   2774 	     the frame pointer subtraction is done.  */
   2775 
   2776 	  insn = emit_move_insn (fp, stack_pointer_rtx);
   2777 	  if (frame_pointer_needed)
   2778 	    {
   2779 	      RTX_FRAME_RELATED_P (insn) = 1;
   2780 	      add_reg_note (insn, REG_CFA_ADJUST_CFA,
   2781 			    gen_rtx_SET (fp, stack_pointer_rtx));
   2782 	    }
   2783 
   2784 	  insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
   2785 						       my_fp, neg_size));
   2786 
   2787 	  if (frame_pointer_needed)
   2788 	    {
   2789 	      RTX_FRAME_RELATED_P (insn) = 1;
   2790 	      add_reg_note (insn, REG_CFA_ADJUST_CFA,
   2791 			    gen_rtx_SET (fp, plus_constant (Pmode, fp,
   2792 							    -size_cfa)));
   2793 	    }
   2794 
   2795 	  /* Copy to stack pointer.  Note that since we've already
   2796 	     changed the CFA to the frame pointer this operation
   2797 	     need not be annotated if frame pointer is needed.
   2798 	     Always move through unspec, see PR50063.
   2799 	     For meaning of irq_state see movhi_sp_r insn.  */
   2800 
   2801 	  if (cfun->machine->is_interrupt)
   2802 	    irq_state = 1;
   2803 
   2804 	  if (TARGET_NO_INTERRUPTS
   2805 	      || cfun->machine->is_signal
   2806 	      || cfun->machine->is_OS_main)
   2807 	    irq_state = 0;
   2808 
   2809 	  if (AVR_HAVE_8BIT_SP)
   2810 	    irq_state = 2;
   2811 
   2812 	  insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
   2813 					    fp, GEN_INT (irq_state)));
   2814 	  if (!frame_pointer_needed)
   2815 	    {
   2816 	      RTX_FRAME_RELATED_P (insn) = 1;
   2817 	      add_reg_note (insn, REG_CFA_ADJUST_CFA,
   2818 			    gen_rtx_SET (stack_pointer_rtx,
   2819 					 plus_constant (Pmode,
   2820 							stack_pointer_rtx,
   2821 							-size_cfa)));
   2822 	    }
   2823 
   2824 	  fp_plus_insns = get_insns ();
   2825 	  end_sequence ();
   2826 
   2827 	  /************  Method 2: Adjust Stack pointer  ************/
   2828 
   2829 	  /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
   2830 	     can only handle specific offsets.  */
   2831 
   2832 	  int n_rcall = size / (AVR_3_BYTE_PC ? 3 : 2);
   2833 
   2834 	  if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode)
   2835 	      // Don't use more than 3 RCALLs.
   2836 	      && n_rcall <= 3)
   2837 	    {
   2838 	      rtx_insn *sp_plus_insns;
   2839 
   2840 	      start_sequence ();
   2841 
   2842 	      insn = emit_move_insn (stack_pointer_rtx,
   2843 				     plus_constant (Pmode, stack_pointer_rtx,
   2844 						    -size));
   2845 	      RTX_FRAME_RELATED_P (insn) = 1;
   2846 	      add_reg_note (insn, REG_CFA_ADJUST_CFA,
   2847 			    gen_rtx_SET (stack_pointer_rtx,
   2848 					 plus_constant (Pmode,
   2849 							stack_pointer_rtx,
   2850 							-size_cfa)));
   2851 	      if (frame_pointer_needed)
   2852 		{
   2853 		  insn = emit_move_insn (fp, stack_pointer_rtx);
   2854 		  RTX_FRAME_RELATED_P (insn) = 1;
   2855 		}
   2856 
   2857 	      sp_plus_insns = get_insns ();
   2858 	      end_sequence ();
   2859 
   2860 	      /************ Use shortest method  ************/
   2861 
   2862 	      emit_insn (get_sequence_length (sp_plus_insns)
   2863 			 < get_sequence_length (fp_plus_insns)
   2864 			 ? sp_plus_insns
   2865 			 : fp_plus_insns);
   2866 	    }
   2867 	  else
   2868 	    {
   2869 	      emit_insn (fp_plus_insns);
   2870 	    }
   2871 
   2872 	  cfun->machine->stack_usage += size_cfa;
   2873 	} /* !minimize && size != 0 */
   2874     } /* !minimize */
   2875 }
   2876 
   2877 
   2878 /*  Output function prologue.  */
   2879 
   2880 void
   2881 avr_expand_prologue (void)
   2882 {
   2883   HARD_REG_SET set;
   2884   HOST_WIDE_INT size = get_frame_size() + avr_outgoing_args_size();
   2885 
   2886   cfun->machine->stack_usage = 0;
   2887 
   2888   /* Prologue: naked.  */
   2889   if (cfun->machine->is_naked)
   2890     {
   2891       return;
   2892     }
   2893 
   2894   avr_regs_to_save (&set);
   2895 
   2896   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
   2897     {
   2898       int treg = AVR_TMP_REGNO;
   2899       /* Enable interrupts.  */
   2900       if (cfun->machine->is_interrupt)
   2901 	emit_insn (gen_enable_interrupt ());
   2902 
   2903       if (cfun->machine->gasisr.maybe)
   2904 	{
   2905 	  /* Let GAS PR21472 emit prologue preamble for us which handles SREG,
   2906 	     ZERO_REG and TMP_REG and one additional, optional register for
   2907 	     us in an optimal way.  This even scans through inline asm.  */
   2908 
   2909 	  cfun->machine->gasisr.yes = 1;
   2910 
   2911 	  // The optional reg or TMP_REG if we don't need one.  If we need one,
   2912 	  // remove that reg from SET so that it's not puhed / popped twice.
   2913 	  // We also use it below instead of TMP_REG in some places.
   2914 
   2915 	  treg = avr_hregs_split_reg (&set);
   2916 	  if (treg < 0)
   2917 	    treg = AVR_TMP_REGNO;
   2918 	  cfun->machine->gasisr.regno = treg;
   2919 
   2920 	  // The worst case of pushes.  The exact number can be inferred
   2921 	  // at assembly time by magic expression __gcc_isr.n_pushed.
   2922 	  cfun->machine->stack_usage += 3 + (treg != AVR_TMP_REGNO);
   2923 
   2924 	  // Emit a Prologue chunk.  Epilogue chunk(s) might follow.
   2925 	  // The final Done chunk is emit by final postscan.
   2926 	  emit_insn (gen_gasisr (GEN_INT (GASISR_Prologue), GEN_INT (treg)));
   2927 	}
   2928       else // !TARGET_GASISR_PROLOGUES: Classic, dumb prologue preamble.
   2929 	{
   2930 	  /* Push zero reg.  */
   2931 	  emit_push_byte (AVR_ZERO_REGNO, true);
   2932 
   2933 	  /* Push tmp reg.  */
   2934 	  emit_push_byte (AVR_TMP_REGNO, true);
   2935 
   2936 	  /* Push SREG.  */
   2937 	  /* ??? There's no dwarf2 column reserved for SREG.  */
   2938 	  emit_push_sfr (sreg_rtx, false, false /* clr */, AVR_TMP_REGNO);
   2939 
   2940 	  /* Clear zero reg.  */
   2941 	  emit_move_insn (zero_reg_rtx, const0_rtx);
   2942 
   2943 	  /* Prevent any attempt to delete the setting of ZERO_REG!  */
   2944 	  emit_use (zero_reg_rtx);
   2945 	}
   2946 
   2947       /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
   2948 	 ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z.  */
   2949 
   2950       if (AVR_HAVE_RAMPD)
   2951 	emit_push_sfr (rampd_rtx, false /* frame */, true /* clr */, treg);
   2952 
   2953       if (AVR_HAVE_RAMPX
   2954 	  && TEST_HARD_REG_BIT (set, REG_X)
   2955 	  && TEST_HARD_REG_BIT (set, REG_X + 1))
   2956 	{
   2957 	  emit_push_sfr (rampx_rtx, false /* frame */, true /* clr */, treg);
   2958 	}
   2959 
   2960       if (AVR_HAVE_RAMPY
   2961 	  && (frame_pointer_needed
   2962 	      || (TEST_HARD_REG_BIT (set, REG_Y)
   2963 		  && TEST_HARD_REG_BIT (set, REG_Y + 1))))
   2964 	{
   2965 	  emit_push_sfr (rampy_rtx, false /* frame */, true /* clr */, treg);
   2966 	}
   2967 
   2968       if (AVR_HAVE_RAMPZ
   2969 	  && TEST_HARD_REG_BIT (set, REG_Z)
   2970 	  && TEST_HARD_REG_BIT (set, REG_Z + 1))
   2971 	{
   2972 	  emit_push_sfr (rampz_rtx, false /* frame */, AVR_HAVE_RAMPD, treg);
   2973 	}
   2974     }  /* is_interrupt is_signal */
   2975 
   2976   avr_prologue_setup_frame (size, set);
   2977 
   2978   if (flag_stack_usage_info)
   2979     current_function_static_stack_size
   2980       = cfun->machine->stack_usage + INCOMING_FRAME_SP_OFFSET;
   2981 }
   2982 
   2983 
   2984 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'.  */
   2985 /* Output summary at end of function prologue.  */
   2986 
   2987 static void
   2988 avr_asm_function_end_prologue (FILE *file)
   2989 {
   2990   if (cfun->machine->is_naked)
   2991     {
   2992       fputs ("/* prologue: naked */\n", file);
   2993     }
   2994   else
   2995     {
   2996       if (cfun->machine->is_interrupt)
   2997 	{
   2998 	  fputs ("/* prologue: Interrupt */\n", file);
   2999 	}
   3000       else if (cfun->machine->is_signal)
   3001 	{
   3002 	  fputs ("/* prologue: Signal */\n", file);
   3003 	}
   3004       else
   3005 	fputs ("/* prologue: function */\n", file);
   3006     }
   3007 
   3008   if (ACCUMULATE_OUTGOING_ARGS)
   3009     fprintf (file, "/* outgoing args size = %d */\n",
   3010 	     avr_outgoing_args_size());
   3011 
   3012   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
   3013 	   (HOST_WIDE_INT) get_frame_size());
   3014 
   3015   if (!cfun->machine->gasisr.yes)
   3016     {
   3017       fprintf (file, "/* stack size = %d */\n", cfun->machine->stack_usage);
   3018       // Create symbol stack offset so all functions have it. Add 1 to stack
   3019       // usage for offset so that SP + .L__stack_offset = return address.
   3020       fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
   3021     }
   3022   else
   3023     {
   3024       int used_by_gasisr = 3 + (cfun->machine->gasisr.regno != AVR_TMP_REGNO);
   3025       int to = cfun->machine->stack_usage;
   3026       int from = to - used_by_gasisr;
   3027       // Number of pushed regs is only known at assembly-time.
   3028       fprintf (file, "/* stack size = %d...%d */\n", from , to);
   3029       fprintf (file, ".L__stack_usage = %d + __gcc_isr.n_pushed\n", from);
   3030     }
   3031 }
   3032 
   3033 
   3034 /* Worker function for `EPILOGUE_USES'.  */
   3035 
   3036 int
   3037 avr_epilogue_uses (int /*regno*/)
   3038 {
   3039   if (reload_completed
   3040       && cfun->machine
   3041       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
   3042     return 1;
   3043   return 0;
   3044 }
   3045 
   3046 /*  Helper for avr_expand_epilogue.  Emit a pop of a byte register.  */
   3047 
   3048 static void
   3049 emit_pop_byte (unsigned regno)
   3050 {
   3051   rtx mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
   3052   mem = gen_frame_mem (QImode, mem);
   3053   rtx reg = gen_rtx_REG (QImode, regno);
   3054 
   3055   emit_insn (gen_rtx_SET (reg, mem));
   3056 }
   3057 
   3058 /*  Output RTL epilogue.  */
   3059 
   3060 void
   3061 avr_expand_epilogue (bool sibcall_p)
   3062 {
   3063   HARD_REG_SET set;
   3064   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
   3065 
   3066   HOST_WIDE_INT size = get_frame_size() + avr_outgoing_args_size();
   3067 
   3068   /* epilogue: naked  */
   3069   if (cfun->machine->is_naked)
   3070     {
   3071       gcc_assert (!sibcall_p);
   3072 
   3073       emit_jump_insn (gen_return ());
   3074       return;
   3075     }
   3076 
   3077   avr_regs_to_save (&set);
   3078   int live_seq = sequent_regs_live ();
   3079 
   3080   bool minimize = (TARGET_CALL_PROLOGUES
   3081 		   && live_seq
   3082 		   && !isr_p
   3083 		   && !cfun->machine->is_OS_task
   3084 		   && !cfun->machine->is_OS_main
   3085 		   && !AVR_TINY);
   3086 
   3087   if (minimize
   3088       && (live_seq > 4
   3089 	  || frame_pointer_needed
   3090 	  || size))
   3091     {
   3092       /*  Get rid of frame.  */
   3093 
   3094       if (!frame_pointer_needed)
   3095 	{
   3096 	  emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
   3097 	}
   3098 
   3099       if (size)
   3100 	{
   3101 	  emit_move_insn (frame_pointer_rtx,
   3102 			  plus_constant (Pmode, frame_pointer_rtx, size));
   3103 	}
   3104 
   3105       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
   3106       return;
   3107     }
   3108 
   3109   if (size)
   3110     {
   3111       /* Try two methods to adjust stack and select shortest.  */
   3112 
   3113       int irq_state = -1;
   3114 
   3115       gcc_assert (frame_pointer_needed
   3116 		  || !isr_p
   3117 		  || !crtl->is_leaf);
   3118 
   3119       rtx my_fp = (frame_pointer_needed
   3120 		   ? frame_pointer_rtx
   3121 		   : gen_rtx_REG (Pmode, REG_X));
   3122       rtx fp = my_fp;
   3123 
   3124       if (AVR_HAVE_8BIT_SP)
   3125 	{
   3126 	  /* The high byte (r29) does not change:
   3127 	     Prefer SUBI (1 cycle) over SBIW (2 cycles).  */
   3128 
   3129 	  my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
   3130 	}
   3131 
   3132       /* For rationale see comment in prologue generation.  */
   3133 
   3134       HOST_WIDE_INT size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
   3135       if (size > size_max)
   3136 	size = size_max;
   3137       size = trunc_int_for_mode (size, GET_MODE (my_fp));
   3138 
   3139       /********** Method 1: Adjust fp register  **********/
   3140 
   3141       start_sequence ();
   3142 
   3143       if (!frame_pointer_needed)
   3144 	emit_move_insn (fp, stack_pointer_rtx);
   3145 
   3146       emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
   3147 
   3148       /* Copy to stack pointer.  */
   3149 
   3150       if (TARGET_NO_INTERRUPTS)
   3151 	irq_state = 0;
   3152 
   3153       if (AVR_HAVE_8BIT_SP)
   3154 	irq_state = 2;
   3155 
   3156       emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
   3157 				 GEN_INT (irq_state)));
   3158 
   3159       rtx_insn *fp_plus_insns = get_insns ();
   3160       end_sequence ();
   3161 
   3162       /********** Method 2: Adjust Stack pointer  **********/
   3163 
   3164       if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
   3165 	{
   3166 	  start_sequence ();
   3167 
   3168 	  emit_move_insn (stack_pointer_rtx,
   3169 			  plus_constant (Pmode, stack_pointer_rtx, size));
   3170 
   3171 	  rtx_insn *sp_plus_insns = get_insns ();
   3172 	  end_sequence ();
   3173 
   3174 	  /************ Use shortest method  ************/
   3175 
   3176 	  emit_insn (get_sequence_length (sp_plus_insns)
   3177 		     < get_sequence_length (fp_plus_insns)
   3178 		     ? sp_plus_insns
   3179 		     : fp_plus_insns);
   3180 	}
   3181       else
   3182 	emit_insn (fp_plus_insns);
   3183     } /* size != 0 */
   3184 
   3185   if (frame_pointer_needed
   3186       && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
   3187     {
   3188       /* Restore previous frame_pointer.  See avr_expand_prologue for
   3189 	 rationale for not using pophi.  */
   3190 
   3191       emit_pop_byte (REG_Y + 1);
   3192       emit_pop_byte (REG_Y);
   3193     }
   3194 
   3195   /* Restore used registers.  */
   3196 
   3197   int treg = AVR_TMP_REGNO;
   3198 
   3199   if (isr_p
   3200       && cfun->machine->gasisr.yes)
   3201     {
   3202       treg = cfun->machine->gasisr.regno;
   3203       CLEAR_HARD_REG_BIT (set, treg);
   3204     }
   3205 
   3206   for (int reg = REG_31; reg >= REG_0; --reg)
   3207     if (TEST_HARD_REG_BIT (set, reg))
   3208       emit_pop_byte (reg);
   3209 
   3210   if (isr_p)
   3211     {
   3212       /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
   3213 	 The conditions to restore them must be tha same as in prologue.  */
   3214 
   3215       if (AVR_HAVE_RAMPZ
   3216 	  && TEST_HARD_REG_BIT (set, REG_Z)
   3217 	  && TEST_HARD_REG_BIT (set, REG_Z + 1))
   3218 	{
   3219 	  emit_pop_byte (treg);
   3220 	  emit_move_insn (rampz_rtx, all_regs_rtx[treg]);
   3221 	}
   3222 
   3223       if (AVR_HAVE_RAMPY
   3224 	  && (frame_pointer_needed
   3225 	      || (TEST_HARD_REG_BIT (set, REG_Y)
   3226 		  && TEST_HARD_REG_BIT (set, REG_Y + 1))))
   3227 	{
   3228 	  emit_pop_byte (treg);
   3229 	  emit_move_insn (rampy_rtx, all_regs_rtx[treg]);
   3230 	}
   3231 
   3232       if (AVR_HAVE_RAMPX
   3233 	  && TEST_HARD_REG_BIT (set, REG_X)
   3234 	  && TEST_HARD_REG_BIT (set, REG_X + 1))
   3235 	{
   3236 	  emit_pop_byte (treg);
   3237 	  emit_move_insn (rampx_rtx, all_regs_rtx[treg]);
   3238 	}
   3239 
   3240       if (AVR_HAVE_RAMPD)
   3241 	{
   3242 	  emit_pop_byte (treg);
   3243 	  emit_move_insn (rampd_rtx, all_regs_rtx[treg]);
   3244 	}
   3245 
   3246       if (cfun->machine->gasisr.yes)
   3247 	{
   3248 	  // Emit an Epilogue chunk.
   3249 	  emit_insn (gen_gasisr (GEN_INT (GASISR_Epilogue),
   3250 				 GEN_INT (cfun->machine->gasisr.regno)));
   3251 	}
   3252       else // !TARGET_GASISR_PROLOGUES
   3253 	{
   3254 	  /* Restore SREG using tmp_reg as scratch.  */
   3255 
   3256 	  emit_pop_byte (AVR_TMP_REGNO);
   3257 	  emit_move_insn (sreg_rtx, tmp_reg_rtx);
   3258 
   3259 	  /* Restore tmp REG.  */
   3260 	  emit_pop_byte (AVR_TMP_REGNO);
   3261 
   3262 	  /* Restore zero REG.  */
   3263 	  emit_pop_byte (AVR_ZERO_REGNO);
   3264 	}
   3265     }
   3266 
   3267   if (!sibcall_p)
   3268     emit_jump_insn (gen_return ());
   3269 }
   3270 
   3271 
   3272 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'.  */
   3273 
   3274 static void
   3275 avr_asm_function_begin_epilogue (FILE *file)
   3276 {
   3277   app_disable();
   3278   fprintf (file, "/* epilogue start */\n");
   3279 }
   3280 
   3281 
   3282 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'.  */
   3283 
   3284 static bool
   3285 avr_cannot_modify_jumps_p (void)
   3286 {
   3287   /* Naked Functions must not have any instructions after
   3288      their epilogue, see PR42240 */
   3289 
   3290   return (reload_completed
   3291 	  && cfun->machine
   3292 	  && cfun->machine->is_naked);
   3293 }
   3294 
   3295 
   3296 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'.  */
   3297 
   3298 static bool
   3299 avr_mode_dependent_address_p (const_rtx /*addr*/, addr_space_t as)
   3300 {
   3301   /* FIXME:  Non-generic addresses are not mode-dependent in themselves.
   3302        This hook just serves to hack around PR rtl-optimization/52543 by
   3303        claiming that non-generic addresses were mode-dependent so that
   3304        lower-subreg.cc will skip these addresses.  lower-subreg.cc sets up fake
   3305        RTXes to probe SET and MEM costs and assumes that MEM is always in the
   3306        generic address space which is not true.  */
   3307 
   3308   return !ADDR_SPACE_GENERIC_P (as);
   3309 }
   3310 
   3311 
   3312 /* Return true if rtx X is a CONST_INT, CONST or SYMBOL_REF
   3313    address with the `absdata' variable attribute, i.e. respective
   3314    data can be read / written by LDS / STS instruction.
   3315    This is used only for AVR_TINY.  */
   3316 
   3317 static bool
   3318 avr_address_tiny_absdata_p (rtx x, machine_mode mode)
   3319 {
   3320   if (CONST == GET_CODE (x))
   3321     x = XEXP (XEXP (x, 0), 0);
   3322 
   3323   if (SYMBOL_REF_P (x))
   3324     return SYMBOL_REF_FLAGS (x) & AVR_SYMBOL_FLAG_TINY_ABSDATA;
   3325 
   3326   if (CONST_INT_P (x)
   3327       && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode)))
   3328     return true;
   3329 
   3330   return false;
   3331 }
   3332 
   3333 
   3334 /* Helper function for `avr_legitimate_address_p'.  */
   3335 
   3336 static inline bool
   3337 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
   3338 		       RTX_CODE outer_code, bool strict)
   3339 {
   3340   return (REG_P (reg)
   3341 	  && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
   3342 						 as, outer_code, UNKNOWN)
   3343 	      || (!strict
   3344 		  && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
   3345 }
   3346 
   3347 
   3348 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
   3349    machine for a memory operand of mode MODE.  */
   3350 
   3351 static bool
   3352 avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
   3353 {
   3354   bool ok = CONSTANT_ADDRESS_P (x);
   3355 
   3356   switch (GET_CODE (x))
   3357     {
   3358     case REG:
   3359       ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
   3360 				  MEM, strict);
   3361 
   3362       if (strict
   3363 	  && GET_MODE_SIZE (mode) > 4
   3364 	  && REG_X == REGNO (x))
   3365 	{
   3366 	  ok = false;
   3367 	}
   3368       break;
   3369 
   3370     case POST_INC:
   3371     case PRE_DEC:
   3372       ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
   3373 				  GET_CODE (x), strict);
   3374       break;
   3375 
   3376     case PLUS:
   3377       {
   3378 	rtx reg = XEXP (x, 0);
   3379 	rtx op1 = XEXP (x, 1);
   3380 
   3381 	if (REG_P (reg)
   3382 	    && CONST_INT_P (op1)
   3383 	    && INTVAL (op1) >= 0)
   3384 	  {
   3385 	    bool fit = (IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode))
   3386 			// Reduced Tiny does not support PLUS addressing
   3387 			// anyway, so we are not restricted to LD offset.
   3388 			|| AVR_TINY);
   3389 
   3390 	    if (fit)
   3391 	      {
   3392 		ok = (! strict
   3393 		      || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
   3394 						PLUS, strict));
   3395 
   3396 		if (reg == frame_pointer_rtx
   3397 		    || reg == arg_pointer_rtx)
   3398 		  {
   3399 		    ok = true;
   3400 		  }
   3401 	      }
   3402 	    else if (frame_pointer_needed
   3403 		     && reg == frame_pointer_rtx)
   3404 	      {
   3405 		ok = true;
   3406 	      }
   3407 	  }
   3408       }
   3409       break;
   3410 
   3411     default:
   3412       break;
   3413     }
   3414 
   3415   if (AVR_TINY
   3416       && CONSTANT_ADDRESS_P (x))
   3417     {
   3418       /* avrtiny's load / store instructions only cover addresses 0..0xbf:
   3419 	 IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf.  */
   3420 
   3421       ok = avr_address_tiny_absdata_p (x, mode);
   3422     }
   3423 
   3424   if (avr_log.legitimate_address_p)
   3425     {
   3426       avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
   3427 		 "reload_completed=%d reload_in_progress=%d %s:",
   3428 		 ok, mode, strict, reload_completed, reload_in_progress,
   3429 		 reg_renumber ? "(reg_renumber)" : "");
   3430 
   3431       if (GET_CODE (x) == PLUS
   3432 	  && REG_P (XEXP (x, 0))
   3433 	  && CONST_INT_P (XEXP (x, 1))
   3434 	  && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
   3435 	  && reg_renumber)
   3436 	{
   3437 	  avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
   3438 		     true_regnum (XEXP (x, 0)));
   3439 	}
   3440 
   3441       avr_edump ("\n%r\n", x);
   3442     }
   3443 
   3444   return ok;
   3445 }
   3446 
   3447 
   3448 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
   3449    now only a helper for avr_addr_space_legitimize_address.  */
   3450 /* Attempts to replace X with a valid
   3451    memory address for an operand of mode MODE  */
   3452 
   3453 static rtx
   3454 avr_legitimize_address (rtx x, rtx oldx, machine_mode mode)
   3455 {
   3456   bool big_offset_p = false;
   3457 
   3458   x = oldx;
   3459 
   3460   if (AVR_TINY)
   3461     {
   3462       if (CONSTANT_ADDRESS_P (x)
   3463 	  && ! avr_address_tiny_absdata_p (x, mode))
   3464 	{
   3465 	  x = force_reg (Pmode, x);
   3466 	}
   3467     }
   3468 
   3469   if (GET_CODE (oldx) == PLUS
   3470       && REG_P (XEXP (oldx, 0)))
   3471     {
   3472       if (REG_P (XEXP (oldx, 1)))
   3473 	x = force_reg (GET_MODE (oldx), oldx);
   3474       else if (CONST_INT_P (XEXP (oldx, 1)))
   3475 	{
   3476 	  int offs = INTVAL (XEXP (oldx, 1));
   3477 	  if (frame_pointer_rtx != XEXP (oldx, 0)
   3478 	      && offs > MAX_LD_OFFSET (mode))
   3479 	    {
   3480 	      big_offset_p = true;
   3481 	      x = force_reg (GET_MODE (oldx), oldx);
   3482 	    }
   3483 	}
   3484     }
   3485 
   3486   if (avr_log.legitimize_address)
   3487     {
   3488       avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
   3489 
   3490       if (x != oldx)
   3491 	avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
   3492     }
   3493 
   3494   return x;
   3495 }
   3496 
   3497 
   3498 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'.  */
   3499 /* This will allow register R26/27 to be used where it is no worse than normal
   3500    base pointers R28/29 or R30/31.  For example, if base offset is greater
   3501    than 63 bytes or for R++ or --R addressing.  */
   3502 
   3503 rtx
   3504 avr_legitimize_reload_address (rtx *px, machine_mode mode, int opnum,
   3505 			       int type, int addr_type, int /*ind_levels*/,
   3506 			       rtx (*mk_memloc)(rtx,int))
   3507 {
   3508   rtx x = *px;
   3509 
   3510   if (avr_log.legitimize_reload_address)
   3511     avr_edump ("\n%?:%m %r\n", mode, x);
   3512 
   3513   if (1 && (GET_CODE (x) == POST_INC
   3514 	    || GET_CODE (x) == PRE_DEC))
   3515     {
   3516       push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
   3517 		   POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
   3518 		   opnum, RELOAD_OTHER);
   3519 
   3520       if (avr_log.legitimize_reload_address)
   3521 	avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
   3522 		   POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
   3523 
   3524       return x;
   3525     }
   3526 
   3527   if (GET_CODE (x) == PLUS
   3528       && REG_P (XEXP (x, 0))
   3529       && reg_equiv_constant (REGNO (XEXP (x, 0))) == 0
   3530       && CONST_INT_P (XEXP (x, 1))
   3531       && INTVAL (XEXP (x, 1)) >= 1)
   3532     {
   3533       bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
   3534 
   3535       if (fit)
   3536 	{
   3537 	  if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
   3538 	    {
   3539 	      int regno = REGNO (XEXP (x, 0));
   3540 	      rtx mem = mk_memloc (x, regno);
   3541 
   3542 	      push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
   3543 			   POINTER_REGS, Pmode, VOIDmode, 0, 0,
   3544 			   1, (enum reload_type) addr_type);
   3545 
   3546 	      if (avr_log.legitimize_reload_address)
   3547 		avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
   3548 			   POINTER_REGS, XEXP (mem, 0), NULL_RTX);
   3549 
   3550 	      push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
   3551 			   BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
   3552 			   opnum, (enum reload_type) type);
   3553 
   3554 	      if (avr_log.legitimize_reload_address)
   3555 		avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
   3556 			   BASE_POINTER_REGS, mem, NULL_RTX);
   3557 
   3558 	      return x;
   3559 	    }
   3560 	}
   3561       else if (! (frame_pointer_needed
   3562 		  && XEXP (x, 0) == frame_pointer_rtx))
   3563 	{
   3564 	  push_reload (x, NULL_RTX, px, NULL,
   3565 		       POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
   3566 		       opnum, (enum reload_type) type);
   3567 
   3568 	  if (avr_log.legitimize_reload_address)
   3569 	    avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
   3570 		       POINTER_REGS, x, NULL_RTX);
   3571 
   3572 	  return x;
   3573 	}
   3574     }
   3575 
   3576   return NULL_RTX;
   3577 }
   3578 
   3579 
   3580 /* Helper function to print assembler resp. track instruction
   3581    sequence lengths.  Always return "".
   3582 
   3583    If PLEN == NULL:
   3584        Output assembler code from template TPL with operands supplied
   3585        by OPERANDS.  This is just forwarding to output_asm_insn.
   3586 
   3587    If PLEN != NULL:
   3588        If N_WORDS >= 0  Add N_WORDS to *PLEN.
   3589        If N_WORDS < 0   Set *PLEN to -N_WORDS.
   3590        Don't output anything.
   3591 */
   3592 
   3593 static const char *
   3594 avr_asm_len (const char *tpl, rtx *operands, int *plen, int n_words)
   3595 {
   3596   if (plen == NULL)
   3597     output_asm_insn (tpl, operands);
   3598   else
   3599     {
   3600       if (n_words < 0)
   3601 	*plen = -n_words;
   3602       else
   3603 	*plen += n_words;
   3604     }
   3605 
   3606   return "";
   3607 }
   3608 
   3609 
   3610 /* Return a pointer register name as a string.  */
   3611 
   3612 static const char *
   3613 ptrreg_to_str (int regno)
   3614 {
   3615   switch (regno)
   3616     {
   3617     case REG_X: return "X";
   3618     case REG_Y: return "Y";
   3619     case REG_Z: return "Z";
   3620     default:
   3621       output_operand_lossage ("address operand requires constraint for"
   3622 			      " X, Y, or Z register");
   3623     }
   3624   return NULL;
   3625 }
   3626 
   3627 /* Return the condition name as a string.
   3628    Used in conditional jump constructing  */
   3629 
   3630 static const char *
   3631 cond_string (enum rtx_code code)
   3632 {
   3633   bool cc_overflow_unusable = false;
   3634 
   3635   switch (code)
   3636     {
   3637     case NE:
   3638       return "ne";
   3639     case EQ:
   3640       return "eq";
   3641     case GE:
   3642       if (cc_overflow_unusable)
   3643 	return "pl";
   3644       else
   3645 	return "ge";
   3646     case LT:
   3647       if (cc_overflow_unusable)
   3648 	return "mi";
   3649       else
   3650 	return "lt";
   3651     case GEU:
   3652       return "sh";
   3653     case LTU:
   3654       return "lo";
   3655     default:
   3656       gcc_unreachable ();
   3657     }
   3658 
   3659   return "";
   3660 }
   3661 
   3662 
   3663 /* Return true if rtx X is a CONST or SYMBOL_REF with progmem.
   3664    This must be used for AVR_TINY only because on other cores
   3665    the flash memory is not visible in the RAM address range and
   3666    cannot be read by, say,  LD instruction.  */
   3667 
   3668 static bool
   3669 avr_address_tiny_pm_p (rtx x)
   3670 {
   3671   if (CONST == GET_CODE (x))
   3672     x = XEXP (XEXP (x, 0), 0);
   3673 
   3674   if (SYMBOL_REF_P (x))
   3675     return SYMBOL_REF_FLAGS (x) & AVR_SYMBOL_FLAG_TINY_PM;
   3676 
   3677   return false;
   3678 }
   3679 
   3680 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'.  */
   3681 /* Output ADDR to FILE as address.  */
   3682 
   3683 static void
   3684 avr_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
   3685 {
   3686   if (AVR_TINY
   3687       && avr_address_tiny_pm_p (addr))
   3688     {
   3689       addr = plus_constant (Pmode, addr, avr_arch->flash_pm_offset);
   3690     }
   3691 
   3692   switch (GET_CODE (addr))
   3693     {
   3694     case REG:
   3695       fprintf (file, "%s", ptrreg_to_str (REGNO (addr)));
   3696       break;
   3697 
   3698     case PRE_DEC:
   3699       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
   3700       break;
   3701 
   3702     case POST_INC:
   3703       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
   3704       break;
   3705 
   3706     default:
   3707       if (CONSTANT_ADDRESS_P (addr)
   3708 	  && text_segment_operand (addr, VOIDmode))
   3709 	{
   3710 	  rtx x = addr;
   3711 	  if (GET_CODE (x) == CONST)
   3712 	    x = XEXP (x, 0);
   3713 	  if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
   3714 	    {
   3715 	      /* Assembler gs() will implant word address.  Make offset
   3716 		 a byte offset inside gs() for assembler.  This is
   3717 		 needed because the more logical (constant+gs(sym)) is not
   3718 		 accepted by gas.  For 128K and smaller devices this is ok.
   3719 		 For large devices it will create a trampoline to offset
   3720 		 from symbol which may not be what the user really wanted.  */
   3721 
   3722 	      fprintf (file, "gs(");
   3723 	      output_addr_const (file, XEXP (x, 0));
   3724 	      fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
   3725 		       2 * INTVAL (XEXP (x, 1)));
   3726 	      if (AVR_3_BYTE_PC)
   3727 		if (warning (0, "pointer offset from symbol maybe incorrect"))
   3728 		  {
   3729 		    output_addr_const (stderr, addr);
   3730 		    fprintf (stderr, "\n");
   3731 		  }
   3732 	    }
   3733 	  else
   3734 	    {
   3735 	      fprintf (file, "gs(");
   3736 	      output_addr_const (file, addr);
   3737 	      fprintf (file, ")");
   3738 	    }
   3739 	}
   3740       else
   3741 	output_addr_const (file, addr);
   3742     }
   3743 }
   3744 
   3745 
   3746 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'.  */
   3747 
   3748 static bool
   3749 avr_print_operand_punct_valid_p (unsigned char code)
   3750 {
   3751   return code == '~' || code == '!';
   3752 }
   3753 
   3754 
   3755 /* Implement `TARGET_PRINT_OPERAND'.  */
   3756 /* Output X as assembler operand to file FILE.
   3757    For a description of supported %-codes, see top of avr.md.  */
   3758 
   3759 static void
   3760 avr_print_operand (FILE *file, rtx x, int code)
   3761 {
   3762   int abcd = 0, ef = 0, ij = 0;
   3763 
   3764   if (code >= 'A' && code <= 'D')
   3765     abcd = code - 'A';
   3766   else if (code == 'E' || code == 'F')
   3767     ef = code - 'E';
   3768   else if (code == 'I' || code == 'J')
   3769     ij = code - 'I';
   3770 
   3771   if (code == '~')
   3772     {
   3773       if (!AVR_HAVE_JMP_CALL)
   3774 	fputc ('r', file);
   3775     }
   3776   else if (code == '!')
   3777     {
   3778       if (AVR_HAVE_EIJMP_EICALL)
   3779 	fputc ('e', file);
   3780     }
   3781   else if (code == 't'
   3782 	   || code == 'T')
   3783     {
   3784       static int t_regno = -1;
   3785       static int t_nbits = -1;
   3786 
   3787       if (REG_P (x) && t_regno < 0 && code == 'T')
   3788 	{
   3789 	  t_regno = REGNO (x);
   3790 	  t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
   3791 	}
   3792       else if (CONST_INT_P (x) && t_regno >= 0
   3793 	       && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
   3794 	{
   3795 	  int bpos = INTVAL (x);
   3796 
   3797 	  fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
   3798 	  if (code == 'T')
   3799 	    fprintf (file, ",%d", bpos % 8);
   3800 
   3801 	  t_regno = -1;
   3802 	}
   3803       else
   3804 	fatal_insn ("operands to %T/%t must be reg + const_int:", x);
   3805     }
   3806   else if (code == 'E' || code == 'F')
   3807     {
   3808       rtx op = XEXP (x, 0);
   3809       fprintf (file, "%s", reg_names[REGNO (op) + ef]);
   3810     }
   3811   else if (code == 'I' || code == 'J')
   3812     {
   3813       rtx op = XEXP (XEXP (x, 0), 0);
   3814       fprintf (file, "%s", reg_names[REGNO (op) + ij]);
   3815     }
   3816   else if (code == 'i')
   3817     {
   3818       const int sfr0 = avr_arch->sfr_offset;
   3819       bool lossage_p = false;
   3820 
   3821       switch (GET_CODE (x))
   3822 	{
   3823 	default:
   3824 	  lossage_p = true;
   3825 	  break;
   3826 
   3827 	case CONST_INT:
   3828 	  {
   3829 	    const auto ival = INTVAL (x);
   3830 
   3831 	    if (io_address_operand (x, VOIDmode))
   3832 	      {
   3833 		if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
   3834 		  fprintf (file, "__RAMPZ__");
   3835 		else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
   3836 		  fprintf (file, "__RAMPY__");
   3837 		else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
   3838 		  fprintf (file, "__RAMPX__");
   3839 		else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
   3840 		  fprintf (file, "__RAMPD__");
   3841 		else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
   3842 		  fprintf (file, "__CCP__");
   3843 		else if (ival == avr_addr.sreg)   fprintf (file, "__SREG__");
   3844 		else if (ival == avr_addr.sp_l)   fprintf (file, "__SP_L__");
   3845 		else if (ival == avr_addr.sp_h)   fprintf (file, "__SP_H__");
   3846 		else
   3847 		  fprintf (file, HOST_WIDE_INT_PRINT_HEX, ival - sfr0);
   3848 	      }
   3849 	    else
   3850 	      output_operand_lossage
   3851 		("bad I/O address 0x" HOST_WIDE_INT_PRINT_HEX_PURE
   3852 		 " outside of valid range [0x%x, 0x%x] for %%i operand",
   3853 		 ival, sfr0, sfr0 + 0x3f);
   3854 	  }
   3855 	  break; // CONST_INT
   3856 
   3857 	case MEM:
   3858 	  if (io_address_operand (XEXP (x, 0), VOIDmode))
   3859 	    avr_print_operand (file, XEXP (x, 0), 'i');
   3860 	  else
   3861 	    lossage_p = true;
   3862 	  break;
   3863 
   3864 	case SYMBOL_REF:
   3865 	  if (io_address_operand (x, VOIDmode))
   3866 	    {
   3867 	      rtx addr = plus_constant (HImode, x, -sfr0);
   3868 	      avr_print_operand_address (file, VOIDmode, addr);
   3869 	    }
   3870 	  else
   3871 	    lossage_p = true;
   3872 	  break;
   3873 	} // switch code
   3874 
   3875       if (lossage_p)
   3876 	output_operand_lossage ("%s operand cannot be used as %%i I/O "
   3877 				"address operand", rtx_name[GET_CODE (x)]);
   3878     } // code = i
   3879   else if (REG_P (x))
   3880     {
   3881       if (x == zero_reg_rtx)
   3882 	fprintf (file, "__zero_reg__");
   3883       else if (code == 'r' && REGNO (x) < REG_32)
   3884 	fprintf (file, "%d", (int) REGNO (x));
   3885       else
   3886 	fprintf (file, "%s", reg_names[REGNO (x) + abcd]);
   3887     }
   3888   else if (CONST_INT_P (x))
   3889     {
   3890       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
   3891     }
   3892   else if (MEM_P (x))
   3893     {
   3894       rtx addr = XEXP (x, 0);
   3895 
   3896       if (code == 'm')
   3897 	{
   3898 	  if (!CONSTANT_P (addr))
   3899 	    fatal_insn ("bad address, not a constant:", addr);
   3900 	  /* Assembler template with m-code is data - not progmem section */
   3901 	  if (text_segment_operand (addr, VOIDmode))
   3902 	    if (warning (0, "accessing data memory with"
   3903 			 " program memory address"))
   3904 	      {
   3905 		output_addr_const (stderr, addr);
   3906 		fprintf(stderr,"\n");
   3907 	      }
   3908 	  output_addr_const (file, addr);
   3909 	}
   3910       else if (code == 'o')
   3911 	{
   3912 	  if (GET_CODE (addr) != PLUS)
   3913 	    fatal_insn ("bad address, not (reg+disp):", addr);
   3914 
   3915 	  avr_print_operand (file, XEXP (addr, 1), 0);
   3916 	}
   3917       else if (code == 'b')
   3918 	{
   3919 	  if (GET_CODE (addr) != PLUS)
   3920 	    fatal_insn ("bad address, not (reg+disp):", addr);
   3921 
   3922 	  avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
   3923 	}
   3924       else if (code == 'p' || code == 'r')
   3925 	{
   3926 	  if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
   3927 	    fatal_insn ("bad address, not post_inc or pre_dec:", addr);
   3928 
   3929 	  if (code == 'p')
   3930 	    /* X, Y, Z */
   3931 	    avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
   3932 	  else
   3933 	    avr_print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
   3934 	}
   3935       else if (GET_CODE (addr) == PLUS)
   3936 	{
   3937 	  avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
   3938 	  if (REGNO (XEXP (addr, 0)) == REG_X)
   3939 	    fatal_insn ("internal compiler error.  Bad address:"
   3940 			,addr);
   3941 	  fputc ('+', file);
   3942 	  avr_print_operand (file, XEXP (addr, 1), code);
   3943 	}
   3944       else
   3945 	avr_print_operand_address (file, VOIDmode, addr);
   3946     }
   3947   else if (code == 'x')
   3948     {
   3949       /* Constant progmem address - like used in jmp or call */
   3950       if (text_segment_operand (x, VOIDmode) == 0)
   3951 	if (warning (0, "accessing program memory"
   3952 		     " with data memory address"))
   3953 	  {
   3954 	    output_addr_const (stderr, x);
   3955 	    fprintf(stderr,"\n");
   3956 	  }
   3957       /* Use normal symbol for direct address no linker trampoline needed */
   3958       output_addr_const (file, x);
   3959     }
   3960   else if (CONST_FIXED_P (x))
   3961     {
   3962       HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
   3963       if (code != 0)
   3964 	output_operand_lossage ("Unsupported code '%c' for fixed-point:",
   3965 				code);
   3966       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
   3967     }
   3968   else if (CONST_DOUBLE_P (x))
   3969     {
   3970       if (GET_MODE (x) == SFmode)
   3971 	{
   3972 	  long val;
   3973 	  REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
   3974 	  fprintf (file, "0x%lx", val);
   3975 	}
   3976       else if (GET_MODE (x) == DFmode)
   3977 	{
   3978 	  long l[2];
   3979 	  REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   3980 	  fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
   3981 	}
   3982       else
   3983 	fatal_insn ("internal compiler error.  Unknown mode:", x);
   3984     }
   3985   else if (GET_CODE (x) == CONST_STRING)
   3986     fputs (XSTR (x, 0), file);
   3987   else if (code == 'j')
   3988     fputs (cond_string (GET_CODE (x)), file);
   3989   else if (code == 'k')
   3990     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
   3991   else
   3992     avr_print_operand_address (file, VOIDmode, x);
   3993 }
   3994 
   3995 
   3996 /* Implement `TARGET_USE_BY_PIECES_INFRASTRUCTURE_P'.  */
   3997 /* Prefer sequence of loads/stores for moves of size upto
   3998    two - two pairs of load/store instructions are always better
   3999    than the 5 instruction sequence for a loop (1 instruction
   4000    for loop counter setup, and 4 for the body of the loop). */
   4001 
   4002 static bool
   4003 avr_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
   4004 				    unsigned int align,
   4005 				    enum by_pieces_operation op, bool speed_p)
   4006 {
   4007   if (op != MOVE_BY_PIECES
   4008       || (speed_p && size > MOVE_MAX_PIECES))
   4009     return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
   4010 
   4011   return size <= MOVE_MAX_PIECES;
   4012 }
   4013 
   4014 /* Choose mode for jump insn:
   4015    1 - relative jump in range -63 <= x <= 62 ;
   4016    2 - relative jump in range -2046 <= x <= 2045 ;
   4017    3 - absolute jump (only when we have JMP / CALL).
   4018 
   4019    When jumping backwards, assume the jump offset is EXTRA words
   4020    bigger than inferred from insn addresses.  */
   4021 
   4022 int
   4023 avr_jump_mode (rtx x, rtx_insn *insn, int extra)
   4024 {
   4025   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
   4026 					    ? XEXP (x, 0) : x));
   4027   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
   4028   int jump_distance = cur_addr - dest_addr;
   4029 
   4030   if (IN_RANGE (jump_distance, -63, 62 - extra))
   4031     return 1;
   4032   else if (IN_RANGE (jump_distance, -2046, 2045 - extra))
   4033     return 2;
   4034   else if (AVR_HAVE_JMP_CALL)
   4035     return 3;
   4036 
   4037   return 2;
   4038 }
   4039 
   4040 /* Return an AVR condition jump commands.
   4041    X is a comparison RTX.
   4042    LEN is a number returned by avr_jump_mode function.
   4043    If REVERSE nonzero then condition code in X must be reversed.  */
   4044 
   4045 const char *
   4046 ret_cond_branch (rtx x, int len, int reverse)
   4047 {
   4048   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
   4049   bool cc_overflow_unusable = false;
   4050 
   4051   switch (cond)
   4052     {
   4053     case GT:
   4054       if (cc_overflow_unusable)
   4055 	return (len == 1 ? ("breq .+2" CR_TAB
   4056 			    "brpl %0") :
   4057 		len == 2 ? ("breq .+4" CR_TAB
   4058 			    "brmi .+2" CR_TAB
   4059 			    "rjmp %0") :
   4060 		("breq .+6" CR_TAB
   4061 		 "brmi .+4" CR_TAB
   4062 		 "jmp %0"));
   4063 
   4064       else
   4065 	return (len == 1 ? ("breq .+2" CR_TAB
   4066 			    "brge %0") :
   4067 		len == 2 ? ("breq .+4" CR_TAB
   4068 			    "brlt .+2" CR_TAB
   4069 			    "rjmp %0") :
   4070 		("breq .+6" CR_TAB
   4071 		 "brlt .+4" CR_TAB
   4072 		 "jmp %0"));
   4073     case GTU:
   4074       return (len == 1 ? ("breq .+2" CR_TAB
   4075 			  "brsh %0") :
   4076 	      len == 2 ? ("breq .+4" CR_TAB
   4077 			  "brlo .+2" CR_TAB
   4078 			  "rjmp %0") :
   4079 	      ("breq .+6" CR_TAB
   4080 	       "brlo .+4" CR_TAB
   4081 	       "jmp %0"));
   4082     case LE:
   4083       if (cc_overflow_unusable)
   4084 	return (len == 1 ? ("breq %0" CR_TAB
   4085 			    "brmi %0") :
   4086 		len == 2 ? ("breq .+2" CR_TAB
   4087 			    "brpl .+2" CR_TAB
   4088 			    "rjmp %0") :
   4089 		("breq .+2" CR_TAB
   4090 		 "brpl .+4" CR_TAB
   4091 		 "jmp %0"));
   4092       else
   4093 	return (len == 1 ? ("breq %0" CR_TAB
   4094 			    "brlt %0") :
   4095 		len == 2 ? ("breq .+2" CR_TAB
   4096 			    "brge .+2" CR_TAB
   4097 			    "rjmp %0") :
   4098 		("breq .+2" CR_TAB
   4099 		 "brge .+4" CR_TAB
   4100 		 "jmp %0"));
   4101     case LEU:
   4102       return (len == 1 ? ("breq %0" CR_TAB
   4103 			  "brlo %0") :
   4104 	      len == 2 ? ("breq .+2" CR_TAB
   4105 			  "brsh .+2" CR_TAB
   4106 			  "rjmp %0") :
   4107 	      ("breq .+2" CR_TAB
   4108 	       "brsh .+4" CR_TAB
   4109 	       "jmp %0"));
   4110     default:
   4111       if (reverse)
   4112 	{
   4113 	  switch (len)
   4114 	    {
   4115 	    case 1:
   4116 	      return "br%k1 %0";
   4117 	    case 2:
   4118 	      return ("br%j1 .+2" CR_TAB
   4119 		      "rjmp %0");
   4120 	    default:
   4121 	      return ("br%j1 .+4" CR_TAB
   4122 		      "jmp %0");
   4123 	    }
   4124 	}
   4125       else
   4126 	{
   4127 	  switch (len)
   4128 	    {
   4129 	    case 1:
   4130 	      return "br%j1 %0";
   4131 	    case 2:
   4132 	      return ("br%k1 .+2" CR_TAB
   4133 		      "rjmp %0");
   4134 	    default:
   4135 	      return ("br%k1 .+4" CR_TAB
   4136 		      "jmp %0");
   4137 	    }
   4138 	}
   4139     }
   4140   return "";
   4141 }
   4142 
   4143 
   4144 /* Worker function for `FINAL_PRESCAN_INSN'.  */
   4145 /* Output insn cost for next insn.  */
   4146 
   4147 void
   4148 avr_final_prescan_insn (rtx_insn *insn, rtx * /*operands*/,
   4149 			int /*num_operands*/)
   4150 {
   4151   if (avr_log.rtx_costs)
   4152     {
   4153       rtx set = single_set (insn);
   4154 
   4155       if (set)
   4156 	fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
   4157 		 set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)),
   4158 			       optimize_insn_for_speed_p ()));
   4159       else
   4160 	fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
   4161 		 rtx_cost (PATTERN (insn), VOIDmode, INSN, 0,
   4162 			   optimize_insn_for_speed_p()));
   4163     }
   4164 
   4165   if (avr_log.insn_addresses)
   4166     fprintf (asm_out_file, ";; ADDR = %d\n",
   4167 	     (int) INSN_ADDRESSES (INSN_UID (insn)));
   4168 }
   4169 
   4170 
   4171 /* Implement `TARGET_ASM_FINAL_POSTSCAN_INSN'.  */
   4172 /* When GAS generates (parts of) ISR prologue / epilogue for us, we must
   4173    hint GAS about the end of the code to scan.  There migh be code located
   4174    after the last epilogue.  */
   4175 
   4176 static void
   4177 avr_asm_final_postscan_insn (FILE *stream, rtx_insn *insn, rtx *, int)
   4178 {
   4179   if (cfun->machine->gasisr.yes
   4180       && !next_real_insn (insn))
   4181     {
   4182       app_disable();
   4183       fprintf (stream, "\t__gcc_isr %d,r%d\n", GASISR_Done,
   4184 	       cfun->machine->gasisr.regno);
   4185     }
   4186 }
   4187 
   4188 
   4189 /* Worker function for `FUNCTION_ARG_REGNO_P'.  */
   4190 /* Returns nonzero if REGNO is the number of a hard
   4191    register in which function arguments are sometimes passed.  */
   4192 
   4193 int
   4194 avr_function_arg_regno_p (int r)
   4195 {
   4196   return AVR_TINY
   4197     ? IN_RANGE (r, REG_20, REG_25)
   4198     : IN_RANGE (r, REG_8, REG_25);
   4199 }
   4200 
   4201 
   4202 /* Worker function for `INIT_CUMULATIVE_ARGS'.  */
   4203 /* Initializing the variable cum for the state at the beginning
   4204    of the argument list.  */
   4205 
   4206 void
   4207 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
   4208 			  tree /*fndecl*/)
   4209 {
   4210   cum->nregs = AVR_TINY ? 1 + REG_25 - REG_20 : 1 + REG_25 - REG_8;
   4211   cum->regno = FIRST_CUM_REG;
   4212   cum->has_stack_args = 0;
   4213   if (!libname && stdarg_p (fntype))
   4214     cum->nregs = 0;
   4215 
   4216   /* Assume the calle may be tail called */
   4217 
   4218   cfun->machine->sibcall_fails = 0;
   4219 }
   4220 
   4221 /* Returns the number of registers to allocate for a function argument.  */
   4222 
   4223 static int
   4224 avr_num_arg_regs (machine_mode mode, const_tree type)
   4225 {
   4226   int size = (mode == BLKmode
   4227 	      ? int_size_in_bytes (type)
   4228 	      : GET_MODE_SIZE (mode));
   4229 
   4230   /* Align all function arguments to start in even-numbered registers.
   4231      Odd-sized arguments leave holes above them.  */
   4232 
   4233   return (size + 1) & ~1;
   4234 }
   4235 
   4236 
   4237 /* Implement `TARGET_FUNCTION_ARG'.  */
   4238 /* Controls whether a function argument is passed
   4239    in a register, and which register.  */
   4240 
   4241 static rtx
   4242 avr_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
   4243 {
   4244   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   4245   int bytes = avr_num_arg_regs (arg.mode, arg.type);
   4246 
   4247   if (cum->nregs && bytes <= cum->nregs)
   4248     return gen_rtx_REG (arg.mode, cum->regno - bytes);
   4249 
   4250   cum->has_stack_args = 1;
   4251 
   4252   return NULL_RTX;
   4253 }
   4254 
   4255 
   4256 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'.  */
   4257 /* Update the summarizer variable CUM to advance past an argument
   4258    in the argument list.  */
   4259 
   4260 static void
   4261 avr_function_arg_advance (cumulative_args_t cum_v, const function_arg_info &arg)
   4262 {
   4263   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   4264   int bytes = avr_num_arg_regs (arg.mode, arg.type);
   4265 
   4266   cum->nregs -= bytes;
   4267   cum->regno -= bytes;
   4268 
   4269   /* A parameter is being passed in a call-saved register.  As the original
   4270      contents of these regs has to be restored before leaving the function,
   4271      a function must not pass arguments in call-saved regs in order to get
   4272      tail-called.  */
   4273 
   4274   if (cum->regno >= REG_8
   4275       && cum->nregs >= 0
   4276       && !call_used_or_fixed_reg_p (cum->regno))
   4277     {
   4278       /* FIXME: We ship info on failing tail-call in struct machine_function.
   4279 	 This uses internals of calls.cc:expand_call() and the way args_so_far
   4280 	 is used.  targetm.function_ok_for_sibcall() needs to be extended to
   4281 	 pass &args_so_far, too.  At present, CUMULATIVE_ARGS is target
   4282 	 dependent so that such an extension is not wanted.  */
   4283 
   4284       cfun->machine->sibcall_fails = 1;
   4285     }
   4286 
   4287   /* Test if all registers needed by the ABI are actually available.  If the
   4288      user has fixed a GPR needed to pass an argument, an (implicit) function
   4289      call will clobber that fixed register.  See PR45099 for an example.  */
   4290 
   4291   if (cum->regno >= REG_8
   4292       && cum->nregs >= 0)
   4293     {
   4294       for (int regno = cum->regno; regno < cum->regno + bytes; regno++)
   4295 	if (fixed_regs[regno])
   4296 	  warning (0, "fixed register %s used to pass parameter to function",
   4297 		   reg_names[regno]);
   4298     }
   4299 
   4300   if (cum->nregs <= 0)
   4301     {
   4302       cum->nregs = 0;
   4303       cum->regno = FIRST_CUM_REG;
   4304     }
   4305 }
   4306 
   4307 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
   4308 /* Decide whether we can make a sibling call to a function.  DECL is the
   4309    declaration of the function being targeted by the call and EXP is the
   4310    CALL_EXPR representing the call.  */
   4311 
   4312 static bool
   4313 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
   4314 {
   4315   /* Tail-calling must fail if callee-saved regs are used to pass
   4316      function args.  We must not tail-call when `epilogue_restores'
   4317      is used.  Unfortunately, we cannot tell at this point if that
   4318      actually will happen or not, and we cannot step back from
   4319      tail-calling.  Thus, we inhibit tail-calling with -mcall-prologues.  */
   4320 
   4321   if (cfun->machine->sibcall_fails
   4322       || TARGET_CALL_PROLOGUES)
   4323     {
   4324       return false;
   4325     }
   4326 
   4327   tree fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
   4328 
   4329   if (decl_callee)
   4330     {
   4331       decl_callee = TREE_TYPE (decl_callee);
   4332     }
   4333   else
   4334     {
   4335       decl_callee = fntype_callee;
   4336 
   4337       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
   4338 	     && METHOD_TYPE != TREE_CODE (decl_callee))
   4339 	{
   4340 	  decl_callee = TREE_TYPE (decl_callee);
   4341 	}
   4342     }
   4343 
   4344   /* Ensure that caller and callee have compatible epilogues */
   4345 
   4346   if (cfun->machine->is_interrupt
   4347       || cfun->machine->is_signal
   4348       || cfun->machine->is_naked
   4349       || avr_naked_function_p (decl_callee))
   4350     {
   4351       return false;
   4352     }
   4353 
   4354   return true;
   4355 }
   4356 
   4357 /***********************************************************************
   4358   Functions for outputting various mov's for a various modes
   4359 ************************************************************************/
   4360 
   4361 /* Return true if a value of mode MODE is read from flash by
   4362    __load_* function from libgcc.  */
   4363 
   4364 bool
   4365 avr_load_libgcc_p (rtx op)
   4366 {
   4367   machine_mode mode = GET_MODE (op);
   4368   int n_bytes = GET_MODE_SIZE (mode);
   4369 
   4370   return (n_bytes > 2
   4371 	  && !AVR_HAVE_LPMX
   4372 	  && avr_mem_flash_p (op));
   4373 }
   4374 
   4375 /* Return true if a value of mode MODE is read by __xload_* function.  */
   4376 
   4377 bool
   4378 avr_xload_libgcc_p (machine_mode mode)
   4379 {
   4380   int n_bytes = GET_MODE_SIZE (mode);
   4381 
   4382   return (n_bytes > 1
   4383 	  || avr_n_flash > 1);
   4384 }
   4385 
   4386 
   4387 /* Fixme: This is a hack because secondary reloads don't works as expected.
   4388 
   4389    Find an unused d-register to be used as scratch in INSN.
   4390    EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
   4391    is a register, skip all possible return values that overlap EXCLUDE.
   4392    The policy for the returned register is similar to that of
   4393    `reg_unused_after', i.e. the returned register may overlap the SET_DEST
   4394    of INSN.
   4395 
   4396    Return a QImode d-register or NULL_RTX if nothing found.  */
   4397 
   4398 static rtx
   4399 avr_find_unused_d_reg (rtx_insn *insn, rtx exclude)
   4400 {
   4401   bool isr_p = (avr_interrupt_function_p (current_function_decl)
   4402 		|| avr_signal_function_p (current_function_decl));
   4403 
   4404   for (int regno = REG_16; regno < REG_32; regno++)
   4405     {
   4406       rtx reg = all_regs_rtx[regno];
   4407 
   4408       if ((exclude
   4409 	   && reg_overlap_mentioned_p (exclude, reg))
   4410 	  || fixed_regs[regno])
   4411 	{
   4412 	  continue;
   4413 	}
   4414 
   4415       /* Try non-live register */
   4416 
   4417       if (!df_regs_ever_live_p (regno)
   4418 	  && (TREE_THIS_VOLATILE (current_function_decl)
   4419 	      || cfun->machine->is_OS_task
   4420 	      || cfun->machine->is_OS_main
   4421 	      || (!isr_p && call_used_or_fixed_reg_p (regno))))
   4422 	{
   4423 	  return reg;
   4424 	}
   4425 
   4426       /* Any live register can be used if it is unused after.
   4427 	 Prologue/epilogue will care for it as needed.  */
   4428 
   4429       if (df_regs_ever_live_p (regno)
   4430 	  && reg_unused_after (insn, reg))
   4431 	{
   4432 	  return reg;
   4433 	}
   4434     }
   4435 
   4436   return NULL_RTX;
   4437 }
   4438 
   4439 
   4440 /* Helper function for the next function in the case where only restricted
   4441    version of LPM instruction is available.  */
   4442 
   4443 static const char *
   4444 avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
   4445 {
   4446   rtx dest = xop[0];
   4447   rtx addr = xop[1];
   4448   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
   4449   int regno_dest;
   4450 
   4451   regno_dest = REGNO (dest);
   4452 
   4453   /* The implicit target register of LPM.  */
   4454   xop[3] = lpm_reg_rtx;
   4455 
   4456   switch (GET_CODE (addr))
   4457     {
   4458     default:
   4459       gcc_unreachable();
   4460 
   4461     case REG:
   4462 
   4463       gcc_assert (REG_Z == REGNO (addr));
   4464 
   4465       switch (n_bytes)
   4466 	{
   4467 	default:
   4468 	  gcc_unreachable();
   4469 
   4470 	case 1:
   4471 	  avr_asm_len ("%4lpm", xop, plen, 1);
   4472 
   4473 	  if (regno_dest != LPM_REGNO)
   4474 	    avr_asm_len ("mov %0,%3", xop, plen, 1);
   4475 
   4476 	  return "";
   4477 
   4478 	case 2:
   4479 	  if (REGNO (dest) == REG_Z)
   4480 	    return avr_asm_len ("%4lpm"      CR_TAB
   4481 				"push %3"    CR_TAB
   4482 				"adiw %2,1"  CR_TAB
   4483 				"%4lpm"      CR_TAB
   4484 				"mov %B0,%3" CR_TAB
   4485 				"pop %A0", xop, plen, 6);
   4486 
   4487 	  avr_asm_len ("%4lpm"      CR_TAB
   4488 		       "mov %A0,%3" CR_TAB
   4489 		       "adiw %2,1"  CR_TAB
   4490 		       "%4lpm"      CR_TAB
   4491 		       "mov %B0,%3", xop, plen, 5);
   4492 
   4493 	  if (!reg_unused_after (insn, addr))
   4494 	    avr_asm_len ("sbiw %2,1", xop, plen, 1);
   4495 
   4496 	  break; /* 2 */
   4497 	}
   4498 
   4499       break; /* REG */
   4500 
   4501     case POST_INC:
   4502 
   4503       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
   4504 		  && n_bytes <= 4);
   4505 
   4506       if (regno_dest == LPM_REGNO)
   4507 	avr_asm_len ("%4lpm"      CR_TAB
   4508 		     "adiw %2,1", xop, plen, 2);
   4509       else
   4510 	avr_asm_len ("%4lpm"      CR_TAB
   4511 		     "mov %A0,%3" CR_TAB
   4512 		     "adiw %2,1", xop, plen, 3);
   4513 
   4514       if (n_bytes >= 2)
   4515 	avr_asm_len ("%4lpm"      CR_TAB
   4516 		     "mov %B0,%3" CR_TAB
   4517 		     "adiw %2,1", xop, plen, 3);
   4518 
   4519       if (n_bytes >= 3)
   4520 	avr_asm_len ("%4lpm"      CR_TAB
   4521 		     "mov %C0,%3" CR_TAB
   4522 		     "adiw %2,1", xop, plen, 3);
   4523 
   4524       if (n_bytes >= 4)
   4525 	avr_asm_len ("%4lpm"      CR_TAB
   4526 		     "mov %D0,%3" CR_TAB
   4527 		     "adiw %2,1", xop, plen, 3);
   4528 
   4529       break; /* POST_INC */
   4530 
   4531     } /* switch CODE (addr) */
   4532 
   4533   return "";
   4534 }
   4535 
   4536 
   4537 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
   4538    OP[1] in AS1 to register OP[0].
   4539    If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
   4540    Return "".  */
   4541 
   4542 const char *
   4543 avr_out_lpm (rtx_insn *insn, rtx *op, int *plen)
   4544 {
   4545   rtx xop[7];
   4546   rtx dest = op[0];
   4547   rtx src = SET_SRC (single_set (insn));
   4548   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
   4549   addr_space_t as = MEM_ADDR_SPACE (src);
   4550 
   4551   if (plen)
   4552     *plen = 0;
   4553 
   4554   if (MEM_P (dest))
   4555     {
   4556       warning (0, "writing to address space %qs not supported",
   4557 	       avr_addrspace[MEM_ADDR_SPACE (dest)].name);
   4558 
   4559       return "";
   4560     }
   4561 
   4562   rtx addr = XEXP (src, 0);
   4563   RTX_CODE code = GET_CODE (addr);
   4564 
   4565   gcc_assert (REG_P (dest));
   4566   gcc_assert (REG == code || POST_INC == code);
   4567 
   4568   xop[0] = dest;
   4569   xop[1] = addr;
   4570   xop[2] = lpm_addr_reg_rtx;
   4571   xop[4] = xstring_empty;
   4572   xop[5] = tmp_reg_rtx;
   4573   xop[6] = XEXP (rampz_rtx, 0);
   4574 
   4575   int segment = avr_addrspace[as].segment;
   4576 
   4577   /* Set RAMPZ as needed.  */
   4578 
   4579   if (segment)
   4580     {
   4581       xop[4] = GEN_INT (segment);
   4582       xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
   4583 
   4584       if (xop[3] != NULL_RTX)
   4585 	{
   4586 	  avr_asm_len ("ldi %3,%4" CR_TAB
   4587 		       "out %i6,%3", xop, plen, 2);
   4588 	}
   4589       else if (segment == 1)
   4590 	{
   4591 	  avr_asm_len ("clr %5" CR_TAB
   4592 		       "inc %5" CR_TAB
   4593 		       "out %i6,%5", xop, plen, 3);
   4594 	}
   4595       else
   4596 	{
   4597 	  avr_asm_len ("mov %5,%2"   CR_TAB
   4598 		       "ldi %2,%4"   CR_TAB
   4599 		       "out %i6,%2"  CR_TAB
   4600 		       "mov %2,%5", xop, plen, 4);
   4601 	}
   4602 
   4603       xop[4] = xstring_e;
   4604 
   4605       if (!AVR_HAVE_ELPMX)
   4606 	return avr_out_lpm_no_lpmx (insn, xop, plen);
   4607     }
   4608   else if (!AVR_HAVE_LPMX)
   4609     {
   4610       return avr_out_lpm_no_lpmx (insn, xop, plen);
   4611     }
   4612 
   4613   /* We have [E]LPMX: Output reading from Flash the comfortable way.  */
   4614 
   4615   switch (GET_CODE (addr))
   4616     {
   4617     default:
   4618       gcc_unreachable();
   4619 
   4620     case REG:
   4621 
   4622       gcc_assert (REG_Z == REGNO (addr));
   4623 
   4624       switch (n_bytes)
   4625 	{
   4626 	default:
   4627 	  gcc_unreachable();
   4628 
   4629 	case 1:
   4630 	  avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
   4631 	  break;
   4632 
   4633 	case 2:
   4634 	  if (REGNO (dest) == REG_Z)
   4635 	    avr_asm_len ("%4lpm %5,%a2+" CR_TAB
   4636 			 "%4lpm %B0,%a2" CR_TAB
   4637 			 "mov %A0,%5", xop, plen, 3);
   4638 	  else
   4639 	    {
   4640 	      avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
   4641 			   "%4lpm %B0,%a2", xop, plen, 2);
   4642 
   4643 	      if (!reg_unused_after (insn, addr))
   4644 		avr_asm_len ("sbiw %2,1", xop, plen, 1);
   4645 	    }
   4646 
   4647 	  break; /* 2 */
   4648 
   4649 	case 3:
   4650 
   4651 	  avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
   4652 		       "%4lpm %B0,%a2+" CR_TAB
   4653 		       "%4lpm %C0,%a2", xop, plen, 3);
   4654 
   4655 	  if (!reg_unused_after (insn, addr))
   4656 	    avr_asm_len ("sbiw %2,2", xop, plen, 1);
   4657 
   4658 	  break; /* 3 */
   4659 
   4660 	case 4:
   4661 
   4662 	  avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
   4663 		       "%4lpm %B0,%a2+", xop, plen, 2);
   4664 
   4665 	  if (REGNO (dest) == REG_Z - 2)
   4666 	    avr_asm_len ("%4lpm %5,%a2+" CR_TAB
   4667 			 "%4lpm %C0,%a2" CR_TAB
   4668 			 "mov %D0,%5", xop, plen, 3);
   4669 	  else
   4670 	    {
   4671 	      avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
   4672 			   "%4lpm %D0,%a2", xop, plen, 2);
   4673 
   4674 	      if (!reg_unused_after (insn, addr))
   4675 		avr_asm_len ("sbiw %2,3", xop, plen, 1);
   4676 	    }
   4677 
   4678 	  break; /* 4 */
   4679 	} /* n_bytes */
   4680 
   4681       break; /* REG */
   4682 
   4683     case POST_INC:
   4684 
   4685       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
   4686 		  && n_bytes <= 4);
   4687 
   4688       avr_asm_len		    ("%4lpm %A0,%a2+", xop, plen, 1);
   4689       if (n_bytes >= 2)  avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
   4690       if (n_bytes >= 3)  avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
   4691       if (n_bytes >= 4)  avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
   4692 
   4693       break; /* POST_INC */
   4694 
   4695     } /* switch CODE (addr) */
   4696 
   4697   if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
   4698     {
   4699       /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM.  */
   4700 
   4701       xop[0] = zero_reg_rtx;
   4702       avr_asm_len ("out %i6,%0", xop, plen, 1);
   4703     }
   4704 
   4705   return "";
   4706 }
   4707 
   4708 
   4709 /* Worker function for xload_8 insn.  */
   4710 
   4711 const char *
   4712 avr_out_xload (rtx_insn * /*insn*/, rtx *op, int *plen)
   4713 {
   4714   rtx xop[4];
   4715 
   4716   xop[0] = op[0];
   4717   xop[1] = op[1];
   4718   xop[2] = lpm_addr_reg_rtx;
   4719   xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
   4720 
   4721   if (plen)
   4722     *plen = 0;
   4723 
   4724   if (reg_overlap_mentioned_p (xop[3], lpm_addr_reg_rtx))
   4725     avr_asm_len ("sbrs %1,7", xop, plen, 1);
   4726 
   4727   avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, 1);
   4728 
   4729   avr_asm_len ("sbrc %1,7" CR_TAB
   4730 	       "ld %3,%a2", xop, plen, 2);
   4731 
   4732   if (REGNO (xop[0]) != REGNO (xop[3]))
   4733     avr_asm_len ("mov %0,%3", xop, plen, 1);
   4734 
   4735   return "";
   4736 }
   4737 
   4738 
   4739 const char *
   4740 output_movqi (rtx_insn *insn, rtx operands[], int *plen)
   4741 {
   4742   rtx dest = operands[0];
   4743   rtx src = operands[1];
   4744 
   4745   if (avr_mem_flash_p (src)
   4746       || avr_mem_flash_p (dest))
   4747     {
   4748       return avr_out_lpm (insn, operands, plen);
   4749     }
   4750 
   4751   gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 1);
   4752 
   4753   if (REG_P (dest))
   4754     {
   4755       if (REG_P (src)) /* mov r,r */
   4756 	{
   4757 	  if (test_hard_reg_class (STACK_REG, dest))
   4758 	    return avr_asm_len ("out %0,%1", operands, plen, -1);
   4759 	  else if (test_hard_reg_class (STACK_REG, src))
   4760 	    return avr_asm_len ("in %0,%1", operands, plen, -1);
   4761 
   4762 	  return avr_asm_len ("mov %0,%1", operands, plen, -1);
   4763 	}
   4764       else if (CONSTANT_P (src))
   4765 	{
   4766 	  output_reload_in_const (operands, NULL_RTX, plen, false);
   4767 	  return "";
   4768 	}
   4769       else if (MEM_P (src))
   4770 	return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
   4771     }
   4772   else if (MEM_P (dest))
   4773     {
   4774       rtx xop[2];
   4775 
   4776       xop[0] = dest;
   4777       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
   4778 
   4779       return out_movqi_mr_r (insn, xop, plen);
   4780     }
   4781 
   4782   return "";
   4783 }
   4784 
   4785 
   4786 const char *
   4787 output_movhi (rtx_insn *insn, rtx xop[], int *plen)
   4788 {
   4789   rtx dest = xop[0];
   4790   rtx src = xop[1];
   4791 
   4792   gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
   4793 
   4794   if (avr_mem_flash_p (src)
   4795       || avr_mem_flash_p (dest))
   4796     {
   4797       return avr_out_lpm (insn, xop, plen);
   4798     }
   4799 
   4800   if (REG_P (dest))
   4801     {
   4802       if (REG_P (src)) /* mov r,r */
   4803 	{
   4804 	  if (test_hard_reg_class (STACK_REG, dest))
   4805 	    {
   4806 	      if (AVR_HAVE_8BIT_SP)
   4807 		return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
   4808 
   4809 	      if (AVR_XMEGA)
   4810 		return avr_asm_len ("out __SP_L__,%A1" CR_TAB
   4811 				    "out __SP_H__,%B1", xop, plen, -2);
   4812 
   4813 	      /* Use simple load of SP if no interrupts are  used.  */
   4814 
   4815 	      return TARGET_NO_INTERRUPTS
   4816 		? avr_asm_len ("out __SP_H__,%B1" CR_TAB
   4817 			       "out __SP_L__,%A1", xop, plen, -2)
   4818 		: avr_asm_len ("in __tmp_reg__,__SREG__"  CR_TAB
   4819 			       "cli"                      CR_TAB
   4820 			       "out __SP_H__,%B1"         CR_TAB
   4821 			       "out __SREG__,__tmp_reg__" CR_TAB
   4822 			       "out __SP_L__,%A1", xop, plen, -5);
   4823 	    }
   4824 	  else if (test_hard_reg_class (STACK_REG, src))
   4825 	    {
   4826 	      return !AVR_HAVE_SPH
   4827 		? avr_asm_len ("in %A0,__SP_L__" CR_TAB
   4828 			       "clr %B0", xop, plen, -2)
   4829 
   4830 		: avr_asm_len ("in %A0,__SP_L__" CR_TAB
   4831 			       "in %B0,__SP_H__", xop, plen, -2);
   4832 	    }
   4833 
   4834 	  return AVR_HAVE_MOVW
   4835 	    ? avr_asm_len ("movw %0,%1", xop, plen, -1)
   4836 
   4837 	    : avr_asm_len ("mov %A0,%A1" CR_TAB
   4838 			   "mov %B0,%B1", xop, plen, -2);
   4839 	} /* REG_P (src) */
   4840       else if (CONSTANT_P (src))
   4841 	{
   4842 	  return output_reload_inhi (xop, NULL, plen);
   4843 	}
   4844       else if (MEM_P (src))
   4845 	{
   4846 	  return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
   4847 	}
   4848     }
   4849   else if (MEM_P (dest))
   4850     {
   4851       rtx xop[2];
   4852 
   4853       xop[0] = dest;
   4854       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
   4855 
   4856       return out_movhi_mr_r (insn, xop, plen);
   4857     }
   4858 
   4859   fatal_insn ("invalid insn:", insn);
   4860 
   4861   return "";
   4862 }
   4863 
   4864 
   4865 /* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
   4866 
   4867 static const char *
   4868 avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
   4869 {
   4870   rtx dest = op[0];
   4871   rtx src = op[1];
   4872   rtx x = XEXP (src, 0);
   4873   rtx base = XEXP (x, 0);
   4874 
   4875   if (plen)
   4876     *plen = 0;
   4877 
   4878   if (!reg_overlap_mentioned_p (dest, base))
   4879     {
   4880       avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
   4881 		   "ld %0,%b1", op, plen, 3);
   4882       if (!reg_unused_after (insn, base))
   4883 	avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
   4884     }
   4885   else
   4886     {
   4887       // PR98762: The base register overlaps dest and is only partly clobbered.
   4888       rtx base2 = all_regs_rtx[1 ^ REGNO (dest)];
   4889 
   4890       if (!reg_unused_after (insn, base2))
   4891 	avr_asm_len ("mov __tmp_reg__,%0", &base2, plen, 1);
   4892       avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
   4893 		   "ld %0,%b1", op, plen, 3);
   4894       if (!reg_unused_after (insn, base2))
   4895 	avr_asm_len ("mov %0,__tmp_reg__", &base2, plen, 1);
   4896     }
   4897 
   4898   return "";
   4899 }
   4900 
   4901 static const char *
   4902 out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen)
   4903 {
   4904   rtx dest = op[0];
   4905   rtx src = op[1];
   4906   rtx x = XEXP (src, 0);
   4907 
   4908   if (CONSTANT_ADDRESS_P (x))
   4909     {
   4910       int n_words = AVR_TINY ? 1 : 2;
   4911       return io_address_operand (x, QImode)
   4912 	? avr_asm_len ("in %0,%i1", op, plen, -1)
   4913 	: avr_asm_len ("lds %0,%m1", op, plen, -n_words);
   4914     }
   4915 
   4916   if (GET_CODE (x) == PLUS
   4917       && REG_P (XEXP (x, 0))
   4918       && CONST_INT_P (XEXP (x, 1)))
   4919     {
   4920       /* memory access by reg+disp */
   4921 
   4922       if (AVR_TINY)
   4923 	return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
   4924 
   4925       if (plen)
   4926 	*plen = 0;
   4927 
   4928       int disp = INTVAL (XEXP (x, 1));
   4929       rtx base = XEXP (x, 0);
   4930       rtx base2 = all_regs_rtx[1 ^ REGNO (dest)];
   4931       bool partial_clobber = (reg_overlap_mentioned_p (dest, base)
   4932 			      && ! reg_unused_after (insn, base2));
   4933 
   4934       if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
   4935 	{
   4936 	  // PR117744: The base register overlaps dest and is
   4937 	  // only partially clobbered.
   4938 	  if (partial_clobber)
   4939 	    avr_asm_len ("mov __tmp_reg__,%0", &base2, plen, 1);
   4940 
   4941 	  if (REGNO (XEXP (x, 0)) != REG_Y)
   4942 	    fatal_insn ("incorrect insn:",insn);
   4943 
   4944 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
   4945 	    avr_asm_len ("adiw r28,%o1-63" CR_TAB
   4946 			 "ldd %0,Y+63"     CR_TAB
   4947 			 "sbiw r28,%o1-63", op, plen, 3);
   4948 	  else
   4949 	    avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
   4950 			 "sbci r29,hi8(-%o1)" CR_TAB
   4951 			 "ld %0,Y"            CR_TAB
   4952 			 "subi r28,lo8(%o1)"  CR_TAB
   4953 			 "sbci r29,hi8(%o1)", op, plen, 5);
   4954 
   4955 	  if (partial_clobber)
   4956 	    avr_asm_len ("mov __tmp_reg__,%0", &base2, plen, 1);
   4957 
   4958 	  return "";
   4959 	}
   4960       else if (REGNO (XEXP (x, 0)) == REG_X)
   4961 	{
   4962 	  /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
   4963 	     it but I have this situation with extremal optimizing options.  */
   4964 
   4965 	  // PR117744: The base register overlaps dest and is
   4966 	  // only partially clobbered.
   4967 	  bool clobber_r26 = (partial_clobber
   4968 			      && REGNO (base) == (REGNO (base) & ~1));
   4969 	  if (partial_clobber
   4970 	      && ! clobber_r26)
   4971 	    avr_asm_len ("mov __tmp_reg__,%0", &base2, plen, 1);
   4972 
   4973 	  avr_asm_len ("adiw r26,%o1" CR_TAB
   4974 		       "ld %0,X", op, plen, 2);
   4975 
   4976 	  if (clobber_r26)
   4977 	    avr_asm_len ("subi r26,lo8(%o1)", op, plen, 1);
   4978 	  else if (partial_clobber)
   4979 	    avr_asm_len ("mov %0,__tmp_reg__", &base2, plen, 1);
   4980 	  else if (! reg_unused_after (insn, base))
   4981 	    avr_asm_len ("sbiw r26,%o1", op, plen, 1);
   4982 
   4983 	  return "";
   4984 	}
   4985 
   4986       return avr_asm_len ("ldd %0,%1", op, plen, -1);
   4987     }
   4988 
   4989   return avr_asm_len ("ld %0,%1", op, plen, -1);
   4990 }
   4991 
   4992 
   4993 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
   4994 
   4995 static const char *
   4996 avr_out_movhi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
   4997 {
   4998   rtx dest = op[0];
   4999   rtx src = op[1];
   5000   rtx base = XEXP (src, 0);
   5001 
   5002   int reg_dest = true_regnum (dest);
   5003   int reg_base = true_regnum (base);
   5004 
   5005   if (reg_dest == reg_base)  /* R = (R) */
   5006     return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
   5007 			"ld %B0,%1"          CR_TAB
   5008 			"mov %A0,__tmp_reg__", op, plen, -3);
   5009 
   5010   avr_asm_len ("ld %A0,%1+" CR_TAB
   5011 	       "ld %B0,%1", op, plen, -2);
   5012 
   5013   if (!reg_unused_after (insn, base))
   5014     avr_asm_len (TINY_SBIW (%E1, %F1, 1), op, plen, 2);
   5015 
   5016   return "";
   5017 }
   5018 
   5019 
   5020 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
   5021 
   5022 static const char *
   5023 avr_out_movhi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
   5024 {
   5025   rtx dest = op[0];
   5026   rtx src = op[1];
   5027   rtx base = XEXP (src, 0);
   5028 
   5029   int reg_dest = true_regnum (dest);
   5030   int reg_base = true_regnum (XEXP (base, 0));
   5031 
   5032   if (reg_base == reg_dest)
   5033     {
   5034       return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
   5035 			  "ld __tmp_reg__,%b1+"     CR_TAB
   5036 			  "ld %B0,%b1"              CR_TAB
   5037 			  "mov %A0,__tmp_reg__", op, plen, -5);
   5038     }
   5039   else
   5040     {
   5041       avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
   5042 		   "ld %A0,%b1+"             CR_TAB
   5043 		   "ld %B0,%b1", op, plen, -4);
   5044 
   5045       if (!reg_unused_after (insn, XEXP (base, 0)))
   5046 	avr_asm_len (TINY_SBIW (%I1, %J1, %o1+1), op, plen, 2);
   5047 
   5048       return "";
   5049     }
   5050 }
   5051 
   5052 
   5053 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
   5054 
   5055 static const char *
   5056 avr_out_movhi_r_mr_pre_dec_tiny (rtx_insn *insn, rtx op[], int *plen)
   5057 {
   5058   rtx dest = op[0];
   5059   rtx src = op[1];
   5060   rtx base = XEXP (src, 0);
   5061 
   5062   /* "volatile" forces reading low byte first, even if less efficient,
   5063      for correct operation with 16-bit I/O registers.  */
   5064   bool mem_volatile_p = MEM_VOLATILE_P (src);
   5065 
   5066   if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
   5067     fatal_insn ("incorrect insn:", insn);
   5068 
   5069   if (!mem_volatile_p)
   5070     return avr_asm_len ("ld %B0,%1" CR_TAB
   5071 			"ld %A0,%1", op, plen, -2);
   5072 
   5073   return avr_asm_len (TINY_SBIW (%I1, %J1, 2)  CR_TAB
   5074 		      "ld %A0,%p1+"            CR_TAB
   5075 		      "ld %B0,%p1"             CR_TAB
   5076 		      TINY_SBIW (%I1, %J1, 1), op, plen, -6);
   5077 }
   5078 
   5079 
   5080 static const char *
   5081 out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen)
   5082 {
   5083   rtx dest = op[0];
   5084   rtx src = op[1];
   5085   rtx base = XEXP (src, 0);
   5086   int reg_dest = true_regnum (dest);
   5087   int reg_base = true_regnum (base);
   5088   /* "volatile" forces reading low byte first, even if less efficient,
   5089      for correct operation with 16-bit I/O registers.  */
   5090   bool mem_volatile_p = MEM_VOLATILE_P (src);
   5091 
   5092   if (reg_base > 0)
   5093     {
   5094       if (AVR_TINY)
   5095 	return avr_out_movhi_r_mr_reg_no_disp_tiny (insn, op, plen);
   5096 
   5097       if (reg_dest == reg_base)         /* R = (R) */
   5098 	return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
   5099 			    "ld %B0,%1"          CR_TAB
   5100 			    "mov %A0,__tmp_reg__", op, plen, -3);
   5101 
   5102       if (reg_base != REG_X)
   5103 	return avr_asm_len ("ld %A0,%1" CR_TAB
   5104 			    "ldd %B0,%1+1", op, plen, -2);
   5105 
   5106       avr_asm_len ("ld %A0,X+" CR_TAB
   5107 		   "ld %B0,X", op, plen, -2);
   5108 
   5109       if (!reg_unused_after (insn, base))
   5110 	avr_asm_len ("sbiw r26,1", op, plen, 1);
   5111 
   5112       return "";
   5113     }
   5114   else if (GET_CODE (base) == PLUS) /* (R + i) */
   5115     {
   5116       int disp = INTVAL (XEXP (base, 1));
   5117       int reg_base = true_regnum (XEXP (base, 0));
   5118 
   5119       if (AVR_TINY)
   5120 	return avr_out_movhi_r_mr_reg_disp_tiny (insn, op, plen);
   5121 
   5122       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
   5123 	{
   5124 	  if (REGNO (XEXP (base, 0)) != REG_Y)
   5125 	    fatal_insn ("incorrect insn:",insn);
   5126 
   5127 	  return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
   5128 	    ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
   5129 			   "ldd %A0,Y+62"    CR_TAB
   5130 			   "ldd %B0,Y+63"    CR_TAB
   5131 			   "sbiw r28,%o1-62", op, plen, -4)
   5132 
   5133 	    : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
   5134 			   "sbci r29,hi8(-%o1)" CR_TAB
   5135 			   "ld %A0,Y"           CR_TAB
   5136 			   "ldd %B0,Y+1"        CR_TAB
   5137 			   "subi r28,lo8(%o1)"  CR_TAB
   5138 			   "sbci r29,hi8(%o1)", op, plen, -6);
   5139 	}
   5140 
   5141       /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
   5142 	 it but I have this situation with extremal
   5143 	 optimization options.  */
   5144 
   5145       if (reg_base == REG_X)
   5146 	{
   5147 	  if (reg_base == reg_dest)
   5148 	    return avr_asm_len ("adiw r26,%o1"      CR_TAB
   5149 				"ld __tmp_reg__,X+" CR_TAB
   5150 				"ld %B0,X"          CR_TAB
   5151 				"mov %A0,__tmp_reg__", op, plen, -4);
   5152 
   5153 	  avr_asm_len ("adiw r26,%o1" CR_TAB
   5154 		       "ld %A0,X+"    CR_TAB
   5155 		       "ld %B0,X", op, plen, -3);
   5156 
   5157 	  if (!reg_unused_after (insn, XEXP (base, 0)))
   5158 	    avr_asm_len ("sbiw r26,%o1+1", op, plen, 1);
   5159 
   5160 	  return "";
   5161 	}
   5162 
   5163       return reg_base == reg_dest
   5164 	? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
   5165 		       "ldd %B0,%B1"         CR_TAB
   5166 		       "mov %A0,__tmp_reg__", op, plen, -3)
   5167 
   5168 	: avr_asm_len ("ldd %A0,%A1" CR_TAB
   5169 		       "ldd %B0,%B1", op, plen, -2);
   5170     }
   5171   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
   5172     {
   5173       if (AVR_TINY)
   5174 	return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
   5175 
   5176       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
   5177 	fatal_insn ("incorrect insn:", insn);
   5178 
   5179       if (!mem_volatile_p)
   5180 	return avr_asm_len ("ld %B0,%1" CR_TAB
   5181 			    "ld %A0,%1", op, plen, -2);
   5182 
   5183       return REGNO (XEXP (base, 0)) == REG_X
   5184 	? avr_asm_len ("sbiw r26,2"  CR_TAB
   5185 		       "ld %A0,X+"   CR_TAB
   5186 		       "ld %B0,X"    CR_TAB
   5187 		       "sbiw r26,1", op, plen, -4)
   5188 
   5189 	: avr_asm_len ("sbiw %r1,2"  CR_TAB
   5190 		       "ld %A0,%p1"  CR_TAB
   5191 		       "ldd %B0,%p1+1", op, plen, -3);
   5192     }
   5193   else if (GET_CODE (base) == POST_INC) /* (R++) */
   5194     {
   5195       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
   5196 	fatal_insn ("incorrect insn:", insn);
   5197 
   5198       return avr_asm_len ("ld %A0,%1"  CR_TAB
   5199 			  "ld %B0,%1", op, plen, -2);
   5200     }
   5201   else if (CONSTANT_ADDRESS_P (base))
   5202     {
   5203       int n_words = AVR_TINY ? 2 : 4;
   5204       return io_address_operand (base, HImode)
   5205 	? avr_asm_len ("in %A0,%i1" CR_TAB
   5206 		       "in %B0,%i1+1", op, plen, -2)
   5207 
   5208 	: avr_asm_len ("lds %A0,%m1" CR_TAB
   5209 		       "lds %B0,%m1+1", op, plen, -n_words);
   5210     }
   5211 
   5212   fatal_insn ("unknown move insn:",insn);
   5213   return "";
   5214 }
   5215 
   5216 static const char *
   5217 avr_out_movsi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
   5218 {
   5219   rtx dest = op[0];
   5220   rtx src = op[1];
   5221   rtx base = XEXP (src, 0);
   5222   int reg_dest = true_regnum (dest);
   5223   int reg_base = true_regnum (base);
   5224 
   5225   if (reg_dest == reg_base)
   5226     {
   5227       /* "ld r26,-X" is undefined */
   5228       return *l = 9, (TINY_ADIW (%E1, %F1, 3) CR_TAB
   5229 		      "ld %D0,%1"             CR_TAB
   5230 		      "ld %C0,-%1"            CR_TAB
   5231 		      "ld __tmp_reg__,-%1"    CR_TAB
   5232 		      TINY_SBIW (%E1, %F1, 1) CR_TAB
   5233 		      "ld %A0,%1"             CR_TAB
   5234 		      "mov %B0,__tmp_reg__");
   5235     }
   5236   else if (reg_dest == reg_base - 2)
   5237     {
   5238       return *l = 5, ("ld %A0,%1+"            CR_TAB
   5239 		      "ld %B0,%1+"            CR_TAB
   5240 		      "ld __tmp_reg__,%1+"    CR_TAB
   5241 		      "ld %D0,%1"             CR_TAB
   5242 		      "mov %C0,__tmp_reg__");
   5243     }
   5244   else if (reg_unused_after (insn, base))
   5245     {
   5246       return *l = 4, ("ld %A0,%1+"    CR_TAB
   5247 		      "ld %B0,%1+"    CR_TAB
   5248 		      "ld %C0,%1+"    CR_TAB
   5249 		      "ld %D0,%1");
   5250     }
   5251   else
   5252     {
   5253       return *l = 6, ("ld %A0,%1+"    CR_TAB
   5254 		      "ld %B0,%1+"    CR_TAB
   5255 		      "ld %C0,%1+"    CR_TAB
   5256 		      "ld %D0,%1"     CR_TAB
   5257 		      TINY_SBIW (%E1, %F1, 3));
   5258     }
   5259 }
   5260 
   5261 
   5262 static const char *
   5263 avr_out_movsi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *l)
   5264 {
   5265   rtx dest = op[0];
   5266   rtx src = op[1];
   5267   rtx base = XEXP (src, 0);
   5268   int reg_dest = true_regnum (dest);
   5269   int reg_base = true_regnum (XEXP (base, 0));
   5270 
   5271   if (reg_dest == reg_base)
   5272     {
   5273       /* "ld r26,-X" is undefined */
   5274       return *l = 9, (TINY_ADIW (%I1, %J1, %o1+3) CR_TAB
   5275 		      "ld %D0,%b1"                CR_TAB
   5276 		      "ld %C0,-%b1"               CR_TAB
   5277 		      "ld __tmp_reg__,-%b1"       CR_TAB
   5278 		      TINY_SBIW (%I1, %J1, 1)     CR_TAB
   5279 		      "ld %A0,%b1"                CR_TAB
   5280 		      "mov %B0,__tmp_reg__");
   5281     }
   5282   else if (reg_dest == reg_base - 2)
   5283     {
   5284       return *l = 7, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
   5285 		      "ld %A0,%b1+"             CR_TAB
   5286 		      "ld %B0,%b1+"             CR_TAB
   5287 		      "ld __tmp_reg__,%b1+"     CR_TAB
   5288 		      "ld %D0,%b1"              CR_TAB
   5289 		      "mov %C0,__tmp_reg__");
   5290     }
   5291   else if (reg_unused_after (insn, XEXP (base, 0)))
   5292     {
   5293       return *l = 6, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
   5294 		      "ld %A0,%b1+"             CR_TAB
   5295 		      "ld %B0,%b1+"             CR_TAB
   5296 		      "ld %C0,%b1+"             CR_TAB
   5297 		      "ld %D0,%b1");
   5298     }
   5299   else
   5300     {
   5301       return *l = 8, (TINY_ADIW (%I1, %J1, %o1)  CR_TAB
   5302 		      "ld %A0,%b1+"              CR_TAB
   5303 		      "ld %B0,%b1+"              CR_TAB
   5304 		      "ld %C0,%b1+"              CR_TAB
   5305 		      "ld %D0,%b1"               CR_TAB
   5306 		      TINY_SBIW (%I1, %J1, %o1+3));
   5307     }
   5308 }
   5309 
   5310 static const char *
   5311 out_movsi_r_mr (rtx_insn *insn, rtx op[], int *l)
   5312 {
   5313   rtx dest = op[0];
   5314   rtx src = op[1];
   5315   rtx base = XEXP (src, 0);
   5316   int reg_dest = true_regnum (dest);
   5317   int reg_base = true_regnum (base);
   5318   int tmp;
   5319 
   5320   if (!l)
   5321     l = &tmp;
   5322 
   5323   if (reg_base > 0)
   5324     {
   5325       if (AVR_TINY)
   5326 	return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
   5327 
   5328       if (reg_base == REG_X)  /* (R26) */
   5329 	{
   5330 	  if (reg_dest == REG_X)
   5331 	    /* "ld r26,-X" is undefined */
   5332 	    return *l=7, ("adiw r26,3"        CR_TAB
   5333 			  "ld r29,X"          CR_TAB
   5334 			  "ld r28,-X"         CR_TAB
   5335 			  "ld __tmp_reg__,-X" CR_TAB
   5336 			  "sbiw r26,1"        CR_TAB
   5337 			  "ld r26,X"          CR_TAB
   5338 			  "mov r27,__tmp_reg__");
   5339 	  else if (reg_dest == REG_X - 2)
   5340 	    return *l=5, ("ld %A0,X+"          CR_TAB
   5341 			  "ld %B0,X+"          CR_TAB
   5342 			  "ld __tmp_reg__,X+"  CR_TAB
   5343 			  "ld %D0,X"           CR_TAB
   5344 			  "mov %C0,__tmp_reg__");
   5345 	  else if (reg_unused_after (insn, base))
   5346 	    return  *l=4, ("ld %A0,X+" CR_TAB
   5347 			   "ld %B0,X+" CR_TAB
   5348 			   "ld %C0,X+" CR_TAB
   5349 			   "ld %D0,X");
   5350 	  else
   5351 	    return  *l=5, ("ld %A0,X+" CR_TAB
   5352 			   "ld %B0,X+" CR_TAB
   5353 			   "ld %C0,X+" CR_TAB
   5354 			   "ld %D0,X"  CR_TAB
   5355 			   "sbiw r26,3");
   5356 	}
   5357       else
   5358 	{
   5359 	  if (reg_dest == reg_base)
   5360 	    return *l=5, ("ldd %D0,%1+3" CR_TAB
   5361 			  "ldd %C0,%1+2" CR_TAB
   5362 			  "ldd __tmp_reg__,%1+1"  CR_TAB
   5363 			  "ld %A0,%1"  CR_TAB
   5364 			  "mov %B0,__tmp_reg__");
   5365 	  else if (reg_base == reg_dest + 2)
   5366 	    return *l=5, ("ld %A0,%1"             CR_TAB
   5367 			  "ldd %B0,%1+1"          CR_TAB
   5368 			  "ldd __tmp_reg__,%1+2"  CR_TAB
   5369 			  "ldd %D0,%1+3"          CR_TAB
   5370 			  "mov %C0,__tmp_reg__");
   5371 	  else
   5372 	    return *l=4, ("ld %A0,%1"    CR_TAB
   5373 			  "ldd %B0,%1+1" CR_TAB
   5374 			  "ldd %C0,%1+2" CR_TAB
   5375 			  "ldd %D0,%1+3");
   5376 	}
   5377     }
   5378   else if (GET_CODE (base) == PLUS) /* (R + i) */
   5379     {
   5380       int disp = INTVAL (XEXP (base, 1));
   5381 
   5382       if (AVR_TINY)
   5383 	return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
   5384 
   5385       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
   5386 	{
   5387 	  if (REGNO (XEXP (base, 0)) != REG_Y)
   5388 	    fatal_insn ("incorrect insn:",insn);
   5389 
   5390 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
   5391 	    return *l = 6, ("adiw r28,%o1-60" CR_TAB
   5392 			    "ldd %A0,Y+60"    CR_TAB
   5393 			    "ldd %B0,Y+61"    CR_TAB
   5394 			    "ldd %C0,Y+62"    CR_TAB
   5395 			    "ldd %D0,Y+63"    CR_TAB
   5396 			    "sbiw r28,%o1-60");
   5397 
   5398 	  return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
   5399 			  "sbci r29,hi8(-%o1)" CR_TAB
   5400 			  "ld %A0,Y"           CR_TAB
   5401 			  "ldd %B0,Y+1"        CR_TAB
   5402 			  "ldd %C0,Y+2"        CR_TAB
   5403 			  "ldd %D0,Y+3"        CR_TAB
   5404 			  "subi r28,lo8(%o1)"  CR_TAB
   5405 			  "sbci r29,hi8(%o1)");
   5406 	}
   5407 
   5408       reg_base = true_regnum (XEXP (base, 0));
   5409       if (reg_base == REG_X)
   5410 	{
   5411 	  /* R = (X + d) */
   5412 	  if (reg_dest == REG_X)
   5413 	    {
   5414 	      *l = 7;
   5415 	      /* "ld r26,-X" is undefined */
   5416 	      return ("adiw r26,%o1+3"    CR_TAB
   5417 		      "ld r29,X"          CR_TAB
   5418 		      "ld r28,-X"         CR_TAB
   5419 		      "ld __tmp_reg__,-X" CR_TAB
   5420 		      "sbiw r26,1"        CR_TAB
   5421 		      "ld r26,X"          CR_TAB
   5422 		      "mov r27,__tmp_reg__");
   5423 	    }
   5424 	  *l = 6;
   5425 	  if (reg_dest == REG_X - 2)
   5426 	    return ("adiw r26,%o1"      CR_TAB
   5427 		    "ld r24,X+"         CR_TAB
   5428 		    "ld r25,X+"         CR_TAB
   5429 		    "ld __tmp_reg__,X+" CR_TAB
   5430 		    "ld r27,X"          CR_TAB
   5431 		    "mov r26,__tmp_reg__");
   5432 
   5433 	  return ("adiw r26,%o1" CR_TAB
   5434 		  "ld %A0,X+"    CR_TAB
   5435 		  "ld %B0,X+"    CR_TAB
   5436 		  "ld %C0,X+"    CR_TAB
   5437 		  "ld %D0,X"     CR_TAB
   5438 		  "sbiw r26,%o1+3");
   5439 	}
   5440       if (reg_dest == reg_base)
   5441 	return *l=5, ("ldd %D0,%D1"          CR_TAB
   5442 		      "ldd %C0,%C1"          CR_TAB
   5443 		      "ldd __tmp_reg__,%B1"  CR_TAB
   5444 		      "ldd %A0,%A1"          CR_TAB
   5445 		      "mov %B0,__tmp_reg__");
   5446       else if (reg_dest == reg_base - 2)
   5447 	return *l=5, ("ldd %A0,%A1"          CR_TAB
   5448 		      "ldd %B0,%B1"          CR_TAB
   5449 		      "ldd __tmp_reg__,%C1"  CR_TAB
   5450 		      "ldd %D0,%D1"          CR_TAB
   5451 		      "mov %C0,__tmp_reg__");
   5452       return *l=4, ("ldd %A0,%A1" CR_TAB
   5453 		    "ldd %B0,%B1" CR_TAB
   5454 		    "ldd %C0,%C1" CR_TAB
   5455 		    "ldd %D0,%D1");
   5456     }
   5457   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
   5458     return *l=4, ("ld %D0,%1" CR_TAB
   5459 		  "ld %C0,%1" CR_TAB
   5460 		  "ld %B0,%1" CR_TAB
   5461 		  "ld %A0,%1");
   5462   else if (GET_CODE (base) == POST_INC) /* (R++) */
   5463     return *l=4, ("ld %A0,%1" CR_TAB
   5464 		  "ld %B0,%1" CR_TAB
   5465 		  "ld %C0,%1" CR_TAB
   5466 		  "ld %D0,%1");
   5467   else if (CONSTANT_ADDRESS_P (base))
   5468     {
   5469       if (io_address_operand (base, SImode))
   5470 	{
   5471 	  *l = 4;
   5472 	  return ("in %A0,%i1"   CR_TAB
   5473 		  "in %B0,%i1+1" CR_TAB
   5474 		  "in %C0,%i1+2" CR_TAB
   5475 		  "in %D0,%i1+3");
   5476 	}
   5477       else
   5478 	{
   5479 	  *l = AVR_TINY ? 4 : 8;
   5480 	  return ("lds %A0,%m1"   CR_TAB
   5481 		  "lds %B0,%m1+1" CR_TAB
   5482 		  "lds %C0,%m1+2" CR_TAB
   5483 		  "lds %D0,%m1+3");
   5484 	}
   5485     }
   5486 
   5487   fatal_insn ("unknown move insn:",insn);
   5488   return "";
   5489 }
   5490 
   5491 static const char *
   5492 avr_out_movsi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
   5493 {
   5494   rtx dest = op[0];
   5495   rtx src = op[1];
   5496   rtx base = XEXP (dest, 0);
   5497   int reg_base = true_regnum (base);
   5498   int reg_src = true_regnum (src);
   5499 
   5500   if (reg_base == reg_src)
   5501     {
   5502       /* "ld r26,-X" is undefined */
   5503       if (reg_unused_after (insn, base))
   5504 	{
   5505 	  return *l = 7, ("mov __tmp_reg__, %B1"  CR_TAB
   5506 			  "st %0,%A1"             CR_TAB
   5507 			  TINY_ADIW (%E0, %F0, 1) CR_TAB
   5508 			  "st %0+,__tmp_reg__"    CR_TAB
   5509 			  "st %0+,%C1"            CR_TAB
   5510 			  "st %0+,%D1");
   5511 	}
   5512       else
   5513 	{
   5514 	  return *l = 9, ("mov __tmp_reg__, %B1"  CR_TAB
   5515 			  "st %0,%A1"             CR_TAB
   5516 			  TINY_ADIW (%E0, %F0, 1) CR_TAB
   5517 			  "st %0+,__tmp_reg__"    CR_TAB
   5518 			  "st %0+,%C1"            CR_TAB
   5519 			  "st %0+,%D1"            CR_TAB
   5520 			  TINY_SBIW (%E0, %F0, 3));
   5521 	}
   5522     }
   5523   else if (reg_base == reg_src + 2)
   5524     {
   5525       if (reg_unused_after (insn, base))
   5526 	return *l = 7, ("mov __zero_reg__,%C1" CR_TAB
   5527 			"mov __tmp_reg__,%D1"  CR_TAB
   5528 			"st %0+,%A1"           CR_TAB
   5529 			"st %0+,%B1"           CR_TAB
   5530 			"st %0+,__zero_reg__"  CR_TAB
   5531 			"st %0,__tmp_reg__"    CR_TAB
   5532 			"clr __zero_reg__");
   5533       else
   5534 	return *l = 9, ("mov __zero_reg__,%C1" CR_TAB
   5535 			"mov __tmp_reg__,%D1"  CR_TAB
   5536 			"st %0+,%A1"           CR_TAB
   5537 			"st %0+,%B1"           CR_TAB
   5538 			"st %0+,__zero_reg__"  CR_TAB
   5539 			"st %0,__tmp_reg__"    CR_TAB
   5540 			"clr __zero_reg__"     CR_TAB
   5541 			TINY_SBIW (%E0, %F0, 3));
   5542     }
   5543 
   5544   return *l = 6, ("st %0+,%A1" CR_TAB
   5545 		  "st %0+,%B1" CR_TAB
   5546 		  "st %0+,%C1" CR_TAB
   5547 		  "st %0,%D1"  CR_TAB
   5548 		  TINY_SBIW (%E0, %F0, 3));
   5549 }
   5550 
   5551 static const char *
   5552 avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
   5553 {
   5554   rtx dest = op[0];
   5555   rtx src = op[1];
   5556   rtx base = XEXP (dest, 0);
   5557   int reg_base = REGNO (XEXP (base, 0));
   5558   int reg_src = true_regnum (src);
   5559 
   5560   if (reg_base == reg_src)
   5561     {
   5562       *l = 11;
   5563       return ("mov __tmp_reg__,%A1"        CR_TAB
   5564 	      "mov __zero_reg__,%B1"       CR_TAB
   5565 	      TINY_ADIW (%I0, %J0, %o0)    CR_TAB
   5566 	      "st %b0+,__tmp_reg__"        CR_TAB
   5567 	      "st %b0+,__zero_reg__"       CR_TAB
   5568 	      "st %b0+,%C1"                CR_TAB
   5569 	      "st %b0,%D1"                 CR_TAB
   5570 	      "clr __zero_reg__"           CR_TAB
   5571 	      TINY_SBIW (%I0, %J0, %o0+3));
   5572     }
   5573   else if (reg_src == reg_base - 2)
   5574     {
   5575       // This awkward case can occur when ext-dce turns zero-extend:SI(HI)
   5576       // into a paradoxical subreg, which register allocation may turn into
   5577       // something like *(R28:HI + 7) = R26:SI.  There is actually no need
   5578       // to store the upper 2 bytes of R26:SI as they are unused rubbish.
   5579       // See PR116390.
   5580       *l = 6;
   5581       return (TINY_ADIW (%I0, %J0, %o0)     CR_TAB
   5582 	      "st %b0+,%A1"                 CR_TAB
   5583 	      "st %b0,%B1"                  CR_TAB
   5584 	      TINY_SBIW (%I0, %J0, %o0+1));
   5585     }
   5586   *l = 8;
   5587   return (TINY_ADIW (%I0, %J0, %o0)     CR_TAB
   5588 	  "st %b0+,%A1"                 CR_TAB
   5589 	  "st %b0+,%B1"                 CR_TAB
   5590 	  "st %b0+,%C1"                 CR_TAB
   5591 	  "st %b0,%D1"                  CR_TAB
   5592 	  TINY_SBIW (%I0, %J0, %o0+3));
   5593 }
   5594 
   5595 static const char *
   5596 out_movsi_mr_r (rtx_insn *insn, rtx op[], int *l)
   5597 {
   5598   rtx dest = op[0];
   5599   rtx src = op[1];
   5600   rtx base = XEXP (dest, 0);
   5601   int reg_base = true_regnum (base);
   5602   int reg_src = true_regnum (src);
   5603   int tmp;
   5604 
   5605   if (!l)
   5606     l = &tmp;
   5607 
   5608   if (CONSTANT_ADDRESS_P (base))
   5609     {
   5610       if (io_address_operand (base, SImode))
   5611 	{
   5612 	  return *l=4,("out %i0, %A1"  CR_TAB
   5613 		       "out %i0+1,%B1" CR_TAB
   5614 		       "out %i0+2,%C1" CR_TAB
   5615 		       "out %i0+3,%D1");
   5616 	}
   5617       else
   5618 	{
   5619 	  *l = AVR_TINY ? 4 : 8;
   5620 	  return ("sts %m0,%A1"   CR_TAB
   5621 		  "sts %m0+1,%B1" CR_TAB
   5622 		  "sts %m0+2,%C1" CR_TAB
   5623 		  "sts %m0+3,%D1");
   5624 	}
   5625     }
   5626 
   5627   if (reg_base > 0)  /* (r) */
   5628     {
   5629       if (AVR_TINY)
   5630 	return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l);
   5631 
   5632       if (reg_base == REG_X)  /* (R26) */
   5633 	{
   5634 	  if (reg_src == REG_X)
   5635 	    {
   5636 	      /* "st X+,r26" is undefined */
   5637 	      if (reg_unused_after (insn, base))
   5638 		return *l=6, ("mov __tmp_reg__,r27" CR_TAB
   5639 			      "st X,r26"            CR_TAB
   5640 			      "adiw r26,1"          CR_TAB
   5641 			      "st X+,__tmp_reg__"   CR_TAB
   5642 			      "st X+,r28"           CR_TAB
   5643 			      "st X,r29");
   5644 	      else
   5645 		return *l=7, ("mov __tmp_reg__,r27" CR_TAB
   5646 			      "st X,r26"            CR_TAB
   5647 			      "adiw r26,1"          CR_TAB
   5648 			      "st X+,__tmp_reg__"   CR_TAB
   5649 			      "st X+,r28"           CR_TAB
   5650 			      "st X,r29"            CR_TAB
   5651 			      "sbiw r26,3");
   5652 	    }
   5653 	  else if (reg_base == reg_src + 2)
   5654 	    {
   5655 	      if (reg_unused_after (insn, base))
   5656 		return *l=7, ("mov __zero_reg__,%C1" CR_TAB
   5657 			      "mov __tmp_reg__,%D1"  CR_TAB
   5658 			      "st %0+,%A1"           CR_TAB
   5659 			      "st %0+,%B1"           CR_TAB
   5660 			      "st %0+,__zero_reg__"  CR_TAB
   5661 			      "st %0,__tmp_reg__"    CR_TAB
   5662 			      "clr __zero_reg__");
   5663 	      else
   5664 		return *l=8, ("mov __zero_reg__,%C1" CR_TAB
   5665 			      "mov __tmp_reg__,%D1"  CR_TAB
   5666 			      "st %0+,%A1"           CR_TAB
   5667 			      "st %0+,%B1"           CR_TAB
   5668 			      "st %0+,__zero_reg__"  CR_TAB
   5669 			      "st %0,__tmp_reg__"    CR_TAB
   5670 			      "clr __zero_reg__"     CR_TAB
   5671 			      "sbiw r26,3");
   5672 	    }
   5673 	  return *l=5, ("st %0+,%A1" CR_TAB
   5674 			"st %0+,%B1" CR_TAB
   5675 			"st %0+,%C1" CR_TAB
   5676 			"st %0,%D1"  CR_TAB
   5677 			"sbiw r26,3");
   5678 	}
   5679       else
   5680 	return *l=4, ("st %0,%A1"    CR_TAB
   5681 		      "std %0+1,%B1" CR_TAB
   5682 		      "std %0+2,%C1" CR_TAB
   5683 		      "std %0+3,%D1");
   5684     }
   5685   else if (GET_CODE (base) == PLUS) /* (R + i) */
   5686     {
   5687       int disp = INTVAL (XEXP (base, 1));
   5688 
   5689       if (AVR_TINY)
   5690 	return avr_out_movsi_mr_r_reg_disp_tiny (op, l);
   5691 
   5692       reg_base = REGNO (XEXP (base, 0));
   5693       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
   5694 	{
   5695 	  if (reg_base != REG_Y)
   5696 	    fatal_insn ("incorrect insn:",insn);
   5697 
   5698 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
   5699 	    return *l = 6, ("adiw r28,%o0-60" CR_TAB
   5700 			    "std Y+60,%A1"    CR_TAB
   5701 			    "std Y+61,%B1"    CR_TAB
   5702 			    "std Y+62,%C1"    CR_TAB
   5703 			    "std Y+63,%D1"    CR_TAB
   5704 			    "sbiw r28,%o0-60");
   5705 
   5706 	  return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
   5707 			  "sbci r29,hi8(-%o0)" CR_TAB
   5708 			  "st Y,%A1"           CR_TAB
   5709 			  "std Y+1,%B1"        CR_TAB
   5710 			  "std Y+2,%C1"        CR_TAB
   5711 			  "std Y+3,%D1"        CR_TAB
   5712 			  "subi r28,lo8(%o0)"  CR_TAB
   5713 			  "sbci r29,hi8(%o0)");
   5714 	}
   5715       if (reg_base == REG_X)
   5716 	{
   5717 	  /* (X + d) = R */
   5718 	  if (reg_src == REG_X)
   5719 	    {
   5720 	      *l = 9;
   5721 	      return ("mov __tmp_reg__,r26"  CR_TAB
   5722 		      "mov __zero_reg__,r27" CR_TAB
   5723 		      "adiw r26,%o0"         CR_TAB
   5724 		      "st X+,__tmp_reg__"    CR_TAB
   5725 		      "st X+,__zero_reg__"   CR_TAB
   5726 		      "st X+,r28"            CR_TAB
   5727 		      "st X,r29"             CR_TAB
   5728 		      "clr __zero_reg__"     CR_TAB
   5729 		      "sbiw r26,%o0+3");
   5730 	    }
   5731 	  else if (reg_src == REG_X - 2)
   5732 	    {
   5733 	      *l = 9;
   5734 	      return ("mov __tmp_reg__,r26"  CR_TAB
   5735 		      "mov __zero_reg__,r27" CR_TAB
   5736 		      "adiw r26,%o0"         CR_TAB
   5737 		      "st X+,r24"            CR_TAB
   5738 		      "st X+,r25"            CR_TAB
   5739 		      "st X+,__tmp_reg__"    CR_TAB
   5740 		      "st X,__zero_reg__"    CR_TAB
   5741 		      "clr __zero_reg__"     CR_TAB
   5742 		      "sbiw r26,%o0+3");
   5743 	    }
   5744 	  *l = 6;
   5745 	  return ("adiw r26,%o0" CR_TAB
   5746 		  "st X+,%A1"    CR_TAB
   5747 		  "st X+,%B1"    CR_TAB
   5748 		  "st X+,%C1"    CR_TAB
   5749 		  "st X,%D1"     CR_TAB
   5750 		  "sbiw r26,%o0+3");
   5751 	}
   5752       return *l=4, ("std %A0,%A1" CR_TAB
   5753 		    "std %B0,%B1" CR_TAB
   5754 		    "std %C0,%C1" CR_TAB
   5755 		    "std %D0,%D1");
   5756     }
   5757   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
   5758     return *l=4, ("st %0,%D1" CR_TAB
   5759 		  "st %0,%C1" CR_TAB
   5760 		  "st %0,%B1" CR_TAB
   5761 		  "st %0,%A1");
   5762   else if (GET_CODE (base) == POST_INC) /* (R++) */
   5763     return *l=4, ("st %0,%A1" CR_TAB
   5764 		  "st %0,%B1" CR_TAB
   5765 		  "st %0,%C1" CR_TAB
   5766 		  "st %0,%D1");
   5767   fatal_insn ("unknown move insn:",insn);
   5768   return "";
   5769 }
   5770 
   5771 const char *
   5772 output_movsisf (rtx_insn *insn, rtx operands[], int *l)
   5773 {
   5774   int dummy;
   5775   rtx dest = operands[0];
   5776   rtx src = operands[1];
   5777   int *real_l = l;
   5778 
   5779   if (avr_mem_flash_p (src)
   5780       || avr_mem_flash_p (dest))
   5781     {
   5782       return avr_out_lpm (insn, operands, real_l);
   5783     }
   5784 
   5785   if (!l)
   5786     l = &dummy;
   5787 
   5788   gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 4);
   5789 
   5790   if (REG_P (dest))
   5791     {
   5792       if (REG_P (src)) /* mov r,r */
   5793 	{
   5794 	  if (true_regnum (dest) > true_regnum (src))
   5795 	    {
   5796 	      if (AVR_HAVE_MOVW)
   5797 		{
   5798 		  *l = 2;
   5799 		  return ("movw %C0,%C1" CR_TAB
   5800 			  "movw %A0,%A1");
   5801 		}
   5802 	      *l = 4;
   5803 	      return ("mov %D0,%D1" CR_TAB
   5804 		      "mov %C0,%C1" CR_TAB
   5805 		      "mov %B0,%B1" CR_TAB
   5806 		      "mov %A0,%A1");
   5807 	    }
   5808 	  else
   5809 	    {
   5810 	      if (AVR_HAVE_MOVW)
   5811 		{
   5812 		  *l = 2;
   5813 		  return ("movw %A0,%A1" CR_TAB
   5814 			  "movw %C0,%C1");
   5815 		}
   5816 	      *l = 4;
   5817 	      return ("mov %A0,%A1" CR_TAB
   5818 		      "mov %B0,%B1" CR_TAB
   5819 		      "mov %C0,%C1" CR_TAB
   5820 		      "mov %D0,%D1");
   5821 	    }
   5822 	}
   5823       else if (CONSTANT_P (src))
   5824 	{
   5825 	  return output_reload_insisf (operands, NULL_RTX, real_l);
   5826 	}
   5827       else if (MEM_P (src))
   5828 	return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
   5829     }
   5830   else if (MEM_P (dest))
   5831     {
   5832       const char *templ;
   5833 
   5834       if (src == CONST0_RTX (GET_MODE (dest)))
   5835 	operands[1] = zero_reg_rtx;
   5836 
   5837       templ = out_movsi_mr_r (insn, operands, real_l);
   5838 
   5839       if (!real_l)
   5840 	output_asm_insn (templ, operands);
   5841 
   5842       operands[1] = src;
   5843       return "";
   5844     }
   5845   fatal_insn ("invalid insn:", insn);
   5846   return "";
   5847 }
   5848 
   5849 
   5850 /* Handle loads of 24-bit types from memory to register.  */
   5851 
   5852 static const char *
   5853 avr_out_load_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
   5854 {
   5855   rtx dest = op[0];
   5856   rtx src = op[1];
   5857   rtx base = XEXP (src, 0);
   5858   int reg_dest = true_regnum (dest);
   5859   int reg_base = true_regnum (base);
   5860 
   5861   if (reg_base == reg_dest)
   5862     {
   5863       return avr_asm_len (TINY_ADIW (%E1, %F1, 2)   CR_TAB
   5864 			  "ld %C0,%1"               CR_TAB
   5865 			  "ld __tmp_reg__,-%1"      CR_TAB
   5866 			  TINY_SBIW (%E1, %F1, 1)   CR_TAB
   5867 			  "ld %A0,%1"               CR_TAB
   5868 			  "mov %B0,__tmp_reg__", op, plen, -8);
   5869     }
   5870   else
   5871     {
   5872       avr_asm_len ("ld %A0,%1+"  CR_TAB
   5873 		   "ld %B0,%1+"  CR_TAB
   5874 		   "ld %C0,%1", op, plen, -3);
   5875 
   5876       if (reg_dest != reg_base - 2
   5877 	  && !reg_unused_after (insn, base))
   5878 	{
   5879 	  avr_asm_len (TINY_SBIW (%E1, %F1, 2), op, plen, 2);
   5880 	}
   5881       return "";
   5882     }
   5883 }
   5884 
   5885 static const char *
   5886 avr_out_load_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
   5887 {
   5888   rtx dest = op[0];
   5889   rtx src = op[1];
   5890   rtx base = XEXP (src, 0);
   5891   int reg_dest = true_regnum (dest);
   5892   int reg_base = true_regnum (base);
   5893 
   5894   reg_base = true_regnum (XEXP (base, 0));
   5895   if (reg_base == reg_dest)
   5896     {
   5897       return avr_asm_len (TINY_ADIW (%I1, %J1, %o1+2) CR_TAB
   5898 			  "ld %C0,%b1"                CR_TAB
   5899 			  "ld __tmp_reg__,-%b1"       CR_TAB
   5900 			  TINY_SBIW (%I1, %J1, 1)     CR_TAB
   5901 			  "ld %A0,%b1"                CR_TAB
   5902 			  "mov %B0,__tmp_reg__", op, plen, -8);
   5903     }
   5904   else
   5905     {
   5906       avr_asm_len (TINY_ADIW (%I1, %J1, %o1)   CR_TAB
   5907 		   "ld %A0,%b1+"               CR_TAB
   5908 		   "ld %B0,%b1+"               CR_TAB
   5909 		   "ld %C0,%b1", op, plen, -5);
   5910 
   5911       if (reg_dest != reg_base - 2
   5912 	  && !reg_unused_after (insn, XEXP (base, 0)))
   5913 	avr_asm_len (TINY_SBIW (%I1, %J1, %o1+2), op, plen, 2);
   5914 
   5915       return "";
   5916     }
   5917 }
   5918 
   5919 static const char *
   5920 avr_out_load_psi (rtx_insn *insn, rtx *op, int *plen)
   5921 {
   5922   rtx dest = op[0];
   5923   rtx src = op[1];
   5924   rtx base = XEXP (src, 0);
   5925   int reg_dest = true_regnum (dest);
   5926   int reg_base = true_regnum (base);
   5927 
   5928   if (reg_base > 0)
   5929     {
   5930       if (AVR_TINY)
   5931 	return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen);
   5932 
   5933       if (reg_base == REG_X)  /* (R26) */
   5934 	{
   5935 	  if (reg_dest == REG_X)
   5936 	    /* "ld r26,-X" is undefined */
   5937 	    return avr_asm_len ("adiw r26,2"        CR_TAB
   5938 				"ld r28,X"          CR_TAB
   5939 				"ld __tmp_reg__,-X" CR_TAB
   5940 				"sbiw r26,1"        CR_TAB
   5941 				"ld r26,X"          CR_TAB
   5942 				"mov r27,__tmp_reg__", op, plen, -6);
   5943 	  else
   5944 	    {
   5945 	      avr_asm_len ("ld %A0,X+" CR_TAB
   5946 			   "ld %B0,X+" CR_TAB
   5947 			   "ld %C0,X", op, plen, -3);
   5948 
   5949 	      if (reg_dest != REG_X - 2
   5950 		  && !reg_unused_after (insn, base))
   5951 		{
   5952 		  avr_asm_len ("sbiw r26,2", op, plen, 1);
   5953 		}
   5954 
   5955 	      return "";
   5956 	    }
   5957 	}
   5958       else /* reg_base != REG_X */
   5959 	{
   5960 	  if (reg_dest == reg_base)
   5961 	    return avr_asm_len ("ldd %C0,%1+2"          CR_TAB
   5962 				"ldd __tmp_reg__,%1+1"  CR_TAB
   5963 				"ld  %A0,%1"            CR_TAB
   5964 				"mov %B0,__tmp_reg__", op, plen, -4);
   5965 	  else
   5966 	    return avr_asm_len ("ld  %A0,%1"    CR_TAB
   5967 				"ldd %B0,%1+1"  CR_TAB
   5968 				"ldd %C0,%1+2", op, plen, -3);
   5969 	}
   5970     }
   5971   else if (GET_CODE (base) == PLUS) /* (R + i) */
   5972     {
   5973       int disp = INTVAL (XEXP (base, 1));
   5974 
   5975       if (AVR_TINY)
   5976 	return avr_out_load_psi_reg_disp_tiny (insn, op, plen);
   5977 
   5978       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
   5979 	{
   5980 	  if (REGNO (XEXP (base, 0)) != REG_Y)
   5981 	    fatal_insn ("incorrect insn:",insn);
   5982 
   5983 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
   5984 	    return avr_asm_len ("adiw r28,%o1-61" CR_TAB
   5985 				"ldd %A0,Y+61"    CR_TAB
   5986 				"ldd %B0,Y+62"    CR_TAB
   5987 				"ldd %C0,Y+63"    CR_TAB
   5988 				"sbiw r28,%o1-61", op, plen, -5);
   5989 
   5990 	  return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
   5991 			      "sbci r29,hi8(-%o1)" CR_TAB
   5992 			      "ld  %A0,Y"          CR_TAB
   5993 			      "ldd %B0,Y+1"        CR_TAB
   5994 			      "ldd %C0,Y+2"        CR_TAB
   5995 			      "subi r28,lo8(%o1)"  CR_TAB
   5996 			      "sbci r29,hi8(%o1)", op, plen, -7);
   5997 	}
   5998 
   5999       reg_base = true_regnum (XEXP (base, 0));
   6000       if (reg_base == REG_X)
   6001 	{
   6002 	  /* R = (X + d) */
   6003 	  if (reg_dest == REG_X)
   6004 	    {
   6005 	      /* "ld r26,-X" is undefined */
   6006 	      return avr_asm_len ("adiw r26,%o1+2"     CR_TAB
   6007 				  "ld  r28,X"          CR_TAB
   6008 				  "ld  __tmp_reg__,-X" CR_TAB
   6009 				  "sbiw r26,1"         CR_TAB
   6010 				  "ld  r26,X"          CR_TAB
   6011 				  "mov r27,__tmp_reg__", op, plen, -6);
   6012 	    }
   6013 
   6014 	  avr_asm_len ("adiw r26,%o1" CR_TAB
   6015 		       "ld %A0,X+"    CR_TAB
   6016 		       "ld %B0,X+"    CR_TAB
   6017 		       "ld %C0,X", op, plen, -4);
   6018 
   6019 	  if (reg_dest != REG_W
   6020 	      && !reg_unused_after (insn, XEXP (base, 0)))
   6021 	    avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
   6022 
   6023 	  return "";
   6024 	}
   6025 
   6026       if (reg_dest == reg_base)
   6027 	return avr_asm_len ("ldd %C0,%C1"          CR_TAB
   6028 			    "ldd __tmp_reg__,%B1"  CR_TAB
   6029 			    "ldd %A0,%A1"          CR_TAB
   6030 			    "mov %B0,__tmp_reg__", op, plen, -4);
   6031 
   6032       return avr_asm_len ("ldd %A0,%A1" CR_TAB
   6033 			  "ldd %B0,%B1" CR_TAB
   6034 			  "ldd %C0,%C1", op, plen, -3);
   6035     }
   6036   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
   6037     return avr_asm_len ("ld %C0,%1" CR_TAB
   6038 			"ld %B0,%1" CR_TAB
   6039 			"ld %A0,%1", op, plen, -3);
   6040   else if (GET_CODE (base) == POST_INC) /* (R++) */
   6041     return avr_asm_len ("ld %A0,%1" CR_TAB
   6042 			"ld %B0,%1" CR_TAB
   6043 			"ld %C0,%1", op, plen, -3);
   6044 
   6045   else if (CONSTANT_ADDRESS_P (base))
   6046     {
   6047       int n_words = AVR_TINY ? 3 : 6;
   6048       return avr_asm_len ("lds %A0,%m1"   CR_TAB
   6049 			  "lds %B0,%m1+1" CR_TAB
   6050 			  "lds %C0,%m1+2", op, plen , -n_words);
   6051     }
   6052 
   6053   fatal_insn ("unknown move insn:",insn);
   6054   return "";
   6055 }
   6056 
   6057 
   6058 static const char *
   6059 avr_out_store_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
   6060 {
   6061   rtx dest = op[0];
   6062   rtx src = op[1];
   6063   rtx base = XEXP (dest, 0);
   6064   int reg_base = true_regnum (base);
   6065   int reg_src = true_regnum (src);
   6066 
   6067   if (reg_base == reg_src)
   6068     {
   6069       avr_asm_len ("st %0,%A1"              CR_TAB
   6070 		   "mov __tmp_reg__,%B1"    CR_TAB
   6071 		   TINY_ADIW (%E0, %F0, 1)  CR_TAB /* st X+, r27 is undefined */
   6072 		   "st %0+,__tmp_reg__"     CR_TAB
   6073 		   "st %0,%C1", op, plen, -6);
   6074 
   6075     }
   6076   else if (reg_src == reg_base - 2)
   6077     {
   6078       avr_asm_len ("st %0,%A1"              CR_TAB
   6079 		   "mov __tmp_reg__,%C1"    CR_TAB
   6080 		   TINY_ADIW (%E0, %F0, 1)  CR_TAB
   6081 		   "st %0+,%B1"             CR_TAB
   6082 		   "st %0,__tmp_reg__", op, plen, 6);
   6083     }
   6084   else
   6085     {
   6086       avr_asm_len ("st %0+,%A1"  CR_TAB
   6087 		   "st %0+,%B1" CR_TAB
   6088 		   "st %0,%C1", op, plen, -3);
   6089     }
   6090 
   6091   if (!reg_unused_after (insn, base))
   6092     avr_asm_len (TINY_SBIW (%E0, %F0, 2), op, plen, 2);
   6093 
   6094   return "";
   6095 }
   6096 
   6097 static const char *
   6098 avr_out_store_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
   6099 {
   6100   rtx dest = op[0];
   6101   rtx src = op[1];
   6102   rtx base = XEXP (dest, 0);
   6103   int reg_base = REGNO (XEXP (base, 0));
   6104   int reg_src = true_regnum (src);
   6105 
   6106   if (reg_src == reg_base)
   6107     avr_asm_len ("mov __tmp_reg__,%A1"          CR_TAB
   6108 		 "mov __zero_reg__,%B1"         CR_TAB
   6109 		 TINY_ADIW (%I0, %J0, %o0)      CR_TAB
   6110 		 "st %b0+,__tmp_reg__"          CR_TAB
   6111 		 "st %b0+,__zero_reg__"         CR_TAB
   6112 		 "st %b0,%C1"                   CR_TAB
   6113 		 "clr __zero_reg__", op, plen, -8);
   6114   else if (reg_src == reg_base - 2)
   6115     avr_asm_len ("mov __tmp_reg__,%C1"          CR_TAB
   6116 		 TINY_ADIW (%I0, %J0, %o0)      CR_TAB
   6117 		 "st %b0+,%A1"                  CR_TAB
   6118 		 "st %b0+,%B1"                  CR_TAB
   6119 		 "st %b0,__tmp_reg__", op, plen, -6);
   6120   else
   6121     avr_asm_len (TINY_ADIW (%I0, %J0, %o0)      CR_TAB
   6122 		 "st %b0+,%A1"                  CR_TAB
   6123 		 "st %b0+,%B1"                  CR_TAB
   6124 		 "st %b0,%C1", op, plen, -5);
   6125 
   6126   if (!reg_unused_after (insn, XEXP (base, 0)))
   6127     avr_asm_len (TINY_SBIW (%I0, %J0, %o0+2), op, plen, 2);
   6128 
   6129   return "";
   6130 }
   6131 
   6132 /* Handle store of 24-bit type from register or zero to memory.  */
   6133 
   6134 static const char *
   6135 avr_out_store_psi (rtx_insn *insn, rtx *op, int *plen)
   6136 {
   6137   rtx dest = op[0];
   6138   rtx src = op[1];
   6139   rtx base = XEXP (dest, 0);
   6140   int reg_base = true_regnum (base);
   6141 
   6142   if (CONSTANT_ADDRESS_P (base))
   6143     {
   6144       int n_words = AVR_TINY ? 3 : 6;
   6145       return avr_asm_len ("sts %m0,%A1"   CR_TAB
   6146 			  "sts %m0+1,%B1" CR_TAB
   6147 			  "sts %m0+2,%C1", op, plen, -n_words);
   6148     }
   6149 
   6150   if (reg_base > 0)  /* (r) */
   6151     {
   6152       if (AVR_TINY)
   6153 	return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen);
   6154 
   6155       if (reg_base == REG_X)  /* (R26) */
   6156 	{
   6157 	  gcc_assert (!reg_overlap_mentioned_p (base, src));
   6158 
   6159 	  avr_asm_len ("st %0+,%A1"  CR_TAB
   6160 		       "st %0+,%B1" CR_TAB
   6161 		       "st %0,%C1", op, plen, -3);
   6162 
   6163 	  if (!reg_unused_after (insn, base))
   6164 	    avr_asm_len ("sbiw r26,2", op, plen, 1);
   6165 
   6166 	  return "";
   6167 	}
   6168       else
   6169 	return avr_asm_len ("st %0,%A1"    CR_TAB
   6170 			    "std %0+1,%B1" CR_TAB
   6171 			    "std %0+2,%C1", op, plen, -3);
   6172     }
   6173   else if (GET_CODE (base) == PLUS) /* (R + i) */
   6174     {
   6175       int disp = INTVAL (XEXP (base, 1));
   6176 
   6177       if (AVR_TINY)
   6178 	return avr_out_store_psi_reg_disp_tiny (insn, op, plen);
   6179 
   6180       reg_base = REGNO (XEXP (base, 0));
   6181 
   6182       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
   6183 	{
   6184 	  if (reg_base != REG_Y)
   6185 	    fatal_insn ("incorrect insn:",insn);
   6186 
   6187 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
   6188 	    return avr_asm_len ("adiw r28,%o0-61" CR_TAB
   6189 				"std Y+61,%A1"    CR_TAB
   6190 				"std Y+62,%B1"    CR_TAB
   6191 				"std Y+63,%C1"    CR_TAB
   6192 				"sbiw r28,%o0-61", op, plen, -5);
   6193 
   6194 	  return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
   6195 			      "sbci r29,hi8(-%o0)" CR_TAB
   6196 			      "st Y,%A1"           CR_TAB
   6197 			      "std Y+1,%B1"        CR_TAB
   6198 			      "std Y+2,%C1"        CR_TAB
   6199 			      "subi r28,lo8(%o0)"  CR_TAB
   6200 			      "sbci r29,hi8(%o0)", op, plen, -7);
   6201 	}
   6202       if (reg_base == REG_X)
   6203 	{
   6204 	  /* (X + d) = R */
   6205 	  gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
   6206 
   6207 	  avr_asm_len ("adiw r26,%o0" CR_TAB
   6208 		       "st X+,%A1"    CR_TAB
   6209 		       "st X+,%B1"    CR_TAB
   6210 		       "st X,%C1", op, plen, -4);
   6211 
   6212 	  if (!reg_unused_after (insn, XEXP (base, 0)))
   6213 	    avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
   6214 
   6215 	  return "";
   6216 	}
   6217 
   6218       return avr_asm_len ("std %A0,%A1" CR_TAB
   6219 			  "std %B0,%B1" CR_TAB
   6220 			  "std %C0,%C1", op, plen, -3);
   6221     }
   6222   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
   6223     return avr_asm_len ("st %0,%C1" CR_TAB
   6224 			"st %0,%B1" CR_TAB
   6225 			"st %0,%A1", op, plen, -3);
   6226   else if (GET_CODE (base) == POST_INC) /* (R++) */
   6227     return avr_asm_len ("st %0,%A1" CR_TAB
   6228 			"st %0,%B1" CR_TAB
   6229 			"st %0,%C1", op, plen, -3);
   6230 
   6231   fatal_insn ("unknown move insn:",insn);
   6232   return "";
   6233 }
   6234 
   6235 
   6236 /* Move around 24-bit stuff.  */
   6237 
   6238 const char *
   6239 avr_out_movpsi (rtx_insn *insn, rtx *op, int *plen)
   6240 {
   6241   rtx dest = op[0];
   6242   rtx src = op[1];
   6243 
   6244   if (avr_mem_flash_p (src)
   6245       || avr_mem_flash_p (dest))
   6246     {
   6247       return avr_out_lpm (insn, op, plen);
   6248     }
   6249 
   6250   if (register_operand (dest, VOIDmode))
   6251     {
   6252       if (register_operand (src, VOIDmode)) /* mov r,r */
   6253 	{
   6254 	  if (true_regnum (dest) > true_regnum (src))
   6255 	    {
   6256 	      avr_asm_len ("mov %C0,%C1", op, plen, -1);
   6257 
   6258 	      if (AVR_HAVE_MOVW)
   6259 		return avr_asm_len ("movw %A0,%A1", op, plen, 1);
   6260 	      else
   6261 		return avr_asm_len ("mov %B0,%B1"  CR_TAB
   6262 				    "mov %A0,%A1", op, plen, 2);
   6263 	    }
   6264 	  else
   6265 	    {
   6266 	      if (AVR_HAVE_MOVW)
   6267 		avr_asm_len ("movw %A0,%A1", op, plen, -1);
   6268 	      else
   6269 		avr_asm_len ("mov %A0,%A1"  CR_TAB
   6270 			     "mov %B0,%B1", op, plen, -2);
   6271 
   6272 	      return avr_asm_len ("mov %C0,%C1", op, plen, 1);
   6273 	    }
   6274 	}
   6275       else if (CONSTANT_P (src))
   6276 	{
   6277 	  return avr_out_reload_inpsi (op, NULL_RTX, plen);
   6278 	}
   6279       else if (MEM_P (src))
   6280 	return avr_out_load_psi (insn, op, plen); /* mov r,m */
   6281     }
   6282   else if (MEM_P (dest))
   6283     {
   6284       rtx xop[2];
   6285 
   6286       xop[0] = dest;
   6287       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
   6288 
   6289       return avr_out_store_psi (insn, xop, plen);
   6290     }
   6291 
   6292   fatal_insn ("invalid insn:", insn);
   6293   return "";
   6294 }
   6295 
   6296 static const char *
   6297 avr_out_movqi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
   6298 {
   6299   rtx dest = op[0];
   6300   rtx src = op[1];
   6301   rtx x = XEXP (dest, 0);
   6302 
   6303   if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
   6304     {
   6305       avr_asm_len ("mov __tmp_reg__,%1"      CR_TAB
   6306 		   TINY_ADIW (%I0, %J0, %o0) CR_TAB
   6307 		   "st %b0,__tmp_reg__", op, plen, -4);
   6308     }
   6309   else
   6310     {
   6311       avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
   6312 		   "st %b0,%1", op, plen, -3);
   6313     }
   6314 
   6315   if (!reg_unused_after (insn, XEXP (x, 0)))
   6316     avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
   6317 
   6318   return "";
   6319 }
   6320 
   6321 static const char *
   6322 out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen)
   6323 {
   6324   rtx dest = op[0];
   6325   rtx src = op[1];
   6326   rtx x = XEXP (dest, 0);
   6327 
   6328   if (CONSTANT_ADDRESS_P (x))
   6329     {
   6330       int n_words = AVR_TINY ? 1 : 2;
   6331       return io_address_operand (x, QImode)
   6332 	? avr_asm_len ("out %i0,%1", op, plen, -1)
   6333 	: avr_asm_len ("sts %m0,%1", op, plen, -n_words);
   6334     }
   6335   else if (GET_CODE (x) == PLUS
   6336 	   && REG_P (XEXP (x, 0))
   6337 	   && CONST_INT_P (XEXP (x, 1)))
   6338     {
   6339       /* memory access by reg+disp */
   6340 
   6341       int disp = INTVAL (XEXP (x, 1));
   6342 
   6343       if (AVR_TINY)
   6344 	return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen);
   6345 
   6346       if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
   6347 	{
   6348 	  if (REGNO (XEXP (x, 0)) != REG_Y)
   6349 	    fatal_insn ("incorrect insn:",insn);
   6350 
   6351 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
   6352 	    return avr_asm_len ("adiw r28,%o0-63" CR_TAB
   6353 				"std Y+63,%1"     CR_TAB
   6354 				"sbiw r28,%o0-63", op, plen, -3);
   6355 
   6356 	  return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
   6357 			      "sbci r29,hi8(-%o0)" CR_TAB
   6358 			      "st Y,%1"            CR_TAB
   6359 			      "subi r28,lo8(%o0)"  CR_TAB
   6360 			      "sbci r29,hi8(%o0)", op, plen, -5);
   6361 	}
   6362       else if (REGNO (XEXP (x, 0)) == REG_X)
   6363 	{
   6364 	  if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
   6365 	    {
   6366 	      avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
   6367 			   "adiw r26,%o0"       CR_TAB
   6368 			   "st X,__tmp_reg__", op, plen, -3);
   6369 	    }
   6370 	  else
   6371 	    {
   6372 	      avr_asm_len ("adiw r26,%o0" CR_TAB
   6373 			   "st X,%1", op, plen, -2);
   6374 	    }
   6375 
   6376 	  if (!reg_unused_after (insn, XEXP (x, 0)))
   6377 	    avr_asm_len ("sbiw r26,%o0", op, plen, 1);
   6378 
   6379 	  return "";
   6380 	}
   6381 
   6382       return avr_asm_len ("std %0,%1", op, plen, -1);
   6383     }
   6384 
   6385   return avr_asm_len ("st %0,%1", op, plen, -1);
   6386 }
   6387 
   6388 
   6389 /* Helper for the next function for XMEGA.  It does the same
   6390    but with low byte first.  */
   6391 
   6392 static const char *
   6393 avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen)
   6394 {
   6395   rtx dest = op[0];
   6396   rtx src = op[1];
   6397   rtx base = XEXP (dest, 0);
   6398   int reg_base = true_regnum (base);
   6399   int reg_src = true_regnum (src);
   6400 
   6401   /* "volatile" forces writing low byte first, even if less efficient,
   6402      for correct operation with 16-bit I/O registers like SP.  */
   6403   bool mem_volatile_p = MEM_VOLATILE_P (dest);
   6404 
   6405   if (CONSTANT_ADDRESS_P (base))
   6406     {
   6407       return io_address_operand (base, HImode)
   6408 	? avr_asm_len ("out %i0,%A1" CR_TAB
   6409 		       "out %i0+1,%B1", op, plen, -2)
   6410 
   6411 	: avr_asm_len ("sts %m0,%A1" CR_TAB
   6412 		       "sts %m0+1,%B1", op, plen, -4);
   6413     }
   6414 
   6415   if (reg_base > 0)
   6416     {
   6417       if (reg_base != REG_X)
   6418 	return avr_asm_len ("st %0,%A1" CR_TAB
   6419 			    "std %0+1,%B1", op, plen, -2);
   6420 
   6421       if (reg_src == REG_X)
   6422 	/* "st X+,r26" and "st -X,r26" are undefined.  */
   6423 	avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
   6424 		     "st X,r26"            CR_TAB
   6425 		     "adiw r26,1"          CR_TAB
   6426 		     "st X,__tmp_reg__", op, plen, -4);
   6427       else
   6428 	avr_asm_len ("st X+,%A1" CR_TAB
   6429 		     "st X,%B1", op, plen, -2);
   6430 
   6431       return reg_unused_after (insn, base)
   6432 	? ""
   6433 	: avr_asm_len ("sbiw r26,1", op, plen, 1);
   6434     }
   6435   else if (GET_CODE (base) == PLUS)
   6436     {
   6437       int disp = INTVAL (XEXP (base, 1));
   6438       reg_base = REGNO (XEXP (base, 0));
   6439       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
   6440 	{
   6441 	  if (reg_base != REG_Y)
   6442 	    fatal_insn ("incorrect insn:",insn);
   6443 
   6444 	  return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
   6445 	    ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
   6446 			   "std Y+62,%A1"    CR_TAB
   6447 			   "std Y+63,%B1"    CR_TAB
   6448 			   "sbiw r28,%o0-62", op, plen, -4)
   6449 
   6450 	    : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
   6451 			   "sbci r29,hi8(-%o0)" CR_TAB
   6452 			   "st Y,%A1"           CR_TAB
   6453 			   "std Y+1,%B1"        CR_TAB
   6454 			   "subi r28,lo8(%o0)"  CR_TAB
   6455 			   "sbci r29,hi8(%o0)", op, plen, -6);
   6456 	}
   6457 
   6458       if (reg_base != REG_X)
   6459 	return avr_asm_len ("std %A0,%A1" CR_TAB
   6460 			    "std %B0,%B1", op, plen, -2);
   6461       /* (X + d) = R */
   6462       return reg_src == REG_X
   6463 	? avr_asm_len ("mov __tmp_reg__,r26"  CR_TAB
   6464 		       "mov __zero_reg__,r27" CR_TAB
   6465 		       "adiw r26,%o0"         CR_TAB
   6466 		       "st X+,__tmp_reg__"    CR_TAB
   6467 		       "st X,__zero_reg__"    CR_TAB
   6468 		       "clr __zero_reg__"     CR_TAB
   6469 		       "sbiw r26,%o0+1", op, plen, -7)
   6470 
   6471 	: avr_asm_len ("adiw r26,%o0" CR_TAB
   6472 		       "st X+,%A1"    CR_TAB
   6473 		       "st X,%B1"     CR_TAB
   6474 		       "sbiw r26,%o0+1", op, plen, -4);
   6475     }
   6476   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
   6477     {
   6478       if (!mem_volatile_p)
   6479 	return avr_asm_len ("st %0,%B1" CR_TAB
   6480 			    "st %0,%A1", op, plen, -2);
   6481 
   6482       return REGNO (XEXP (base, 0)) == REG_X
   6483 	? avr_asm_len ("sbiw r26,2"  CR_TAB
   6484 		       "st X+,%A1"   CR_TAB
   6485 		       "st X,%B1"    CR_TAB
   6486 		       "sbiw r26,1", op, plen, -4)
   6487 
   6488 	: avr_asm_len ("sbiw %r0,2"  CR_TAB
   6489 		       "st %p0,%A1"  CR_TAB
   6490 		       "std %p0+1,%B1", op, plen, -3);
   6491     }
   6492   else if (GET_CODE (base) == POST_INC) /* (R++) */
   6493     {
   6494       return avr_asm_len ("st %0,%A1"  CR_TAB
   6495 			  "st %0,%B1", op, plen, -2);
   6496 
   6497     }
   6498   fatal_insn ("unknown move insn:",insn);
   6499   return "";
   6500 }
   6501 
   6502 static const char *
   6503 avr_out_movhi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
   6504 {
   6505   rtx dest = op[0];
   6506   rtx src = op[1];
   6507   rtx base = XEXP (dest, 0);
   6508   int reg_base = true_regnum (base);
   6509   int reg_src = true_regnum (src);
   6510   bool mem_volatile_p = MEM_VOLATILE_P (dest);
   6511 
   6512   if (reg_base == reg_src)
   6513     {
   6514       return !mem_volatile_p && reg_unused_after (insn, src)
   6515 	? avr_asm_len ("mov __tmp_reg__,%B1"   CR_TAB
   6516 		       "st %0,%A1"             CR_TAB
   6517 		       TINY_ADIW (%E0, %F0, 1) CR_TAB
   6518 		       "st %0,__tmp_reg__", op, plen, -5)
   6519 	: avr_asm_len ("mov __tmp_reg__,%B1"   CR_TAB
   6520 		       TINY_ADIW (%E0, %F0, 1) CR_TAB
   6521 		       "st %0,__tmp_reg__"     CR_TAB
   6522 		       TINY_SBIW (%E0, %F0, 1) CR_TAB
   6523 		       "st %0, %A1", op, plen, -7);
   6524     }
   6525 
   6526   return !mem_volatile_p && reg_unused_after (insn, base)
   6527     ? avr_asm_len ("st %0+,%A1" CR_TAB
   6528 		   "st %0,%B1", op, plen, -2)
   6529     : avr_asm_len (TINY_ADIW (%E0, %F0, 1) CR_TAB
   6530 		   "st %0,%B1"             CR_TAB
   6531 		   "st -%0,%A1", op, plen, -4);
   6532 }
   6533 
   6534 static const char *
   6535 avr_out_movhi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
   6536 {
   6537   rtx dest = op[0];
   6538   rtx src = op[1];
   6539   rtx base = XEXP (dest, 0);
   6540   int reg_base = REGNO (XEXP (base, 0));
   6541   int reg_src = true_regnum (src);
   6542 
   6543   if (reg_src == reg_base)
   6544     avr_asm_len ("mov __tmp_reg__,%A1"          CR_TAB
   6545 		 "mov __zero_reg__,%B1"         CR_TAB
   6546 		 TINY_ADIW (%I0, %J0, %o0+1)    CR_TAB
   6547 		 "st %b0,__zero_reg__"          CR_TAB
   6548 		 "st -%b0,__tmp_reg__"          CR_TAB
   6549 		 "clr __zero_reg__", op, plen, -7);
   6550   else
   6551     avr_asm_len (TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
   6552 		 "st %b0,%B1"                CR_TAB
   6553 		 "st -%b0,%A1", op, plen, -4);
   6554 
   6555   if (!reg_unused_after (insn, XEXP (base, 0)))
   6556     avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
   6557 
   6558   return "";
   6559 }
   6560 
   6561 static const char *
   6562 avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen)
   6563 {
   6564   return avr_asm_len (TINY_ADIW (%I0, %J0, 1)  CR_TAB
   6565 		      "st %p0,%B1"    CR_TAB
   6566 		      "st -%p0,%A1"   CR_TAB
   6567 		      TINY_ADIW (%I0, %J0, 2), op, plen, -6);
   6568 }
   6569 
   6570 static const char *
   6571 out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen)
   6572 {
   6573   rtx dest = op[0];
   6574   rtx src = op[1];
   6575   rtx base = XEXP (dest, 0);
   6576   int reg_base = true_regnum (base);
   6577   int reg_src = true_regnum (src);
   6578 
   6579   /* "volatile" forces writing high-byte first (no-xmega) resp.
   6580      low-byte first (xmega) even if less efficient, for correct
   6581      operation with 16-bit I/O registers like.  */
   6582 
   6583   if (AVR_XMEGA)
   6584     return avr_out_movhi_mr_r_xmega (insn, op, plen);
   6585 
   6586   bool mem_volatile_p = MEM_VOLATILE_P (dest);
   6587 
   6588   if (CONSTANT_ADDRESS_P (base))
   6589     {
   6590       int n_words = AVR_TINY ? 2 : 4;
   6591       return io_address_operand (base, HImode)
   6592 	? avr_asm_len ("out %i0+1,%B1" CR_TAB
   6593 		       "out %i0,%A1", op, plen, -2)
   6594 
   6595 	: avr_asm_len ("sts %m0+1,%B1" CR_TAB
   6596 		       "sts %m0,%A1", op, plen, -n_words);
   6597     }
   6598 
   6599   if (reg_base > 0)
   6600     {
   6601       if (AVR_TINY)
   6602 	return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen);
   6603 
   6604       if (reg_base != REG_X)
   6605 	return avr_asm_len ("std %0+1,%B1" CR_TAB
   6606 			    "st %0,%A1", op, plen, -2);
   6607 
   6608       if (reg_src == REG_X)
   6609 	/* "st X+,r26" and "st -X,r26" are undefined.  */
   6610 	return !mem_volatile_p && reg_unused_after (insn, src)
   6611 	  ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
   6612 			 "st X,r26"            CR_TAB
   6613 			 "adiw r26,1"          CR_TAB
   6614 			 "st X,__tmp_reg__", op, plen, -4)
   6615 
   6616 	  : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
   6617 			 "adiw r26,1"          CR_TAB
   6618 			 "st X,__tmp_reg__"    CR_TAB
   6619 			 "sbiw r26,1"          CR_TAB
   6620 			 "st X,r26", op, plen, -5);
   6621 
   6622       return !mem_volatile_p && reg_unused_after (insn, base)
   6623 	? avr_asm_len ("st X+,%A1" CR_TAB
   6624 		       "st X,%B1", op, plen, -2)
   6625 	: avr_asm_len ("adiw r26,1" CR_TAB
   6626 		       "st X,%B1"   CR_TAB
   6627 		       "st -X,%A1", op, plen, -3);
   6628     }
   6629   else if (GET_CODE (base) == PLUS)
   6630     {
   6631       int disp = INTVAL (XEXP (base, 1));
   6632 
   6633       if (AVR_TINY)
   6634 	return avr_out_movhi_mr_r_reg_disp_tiny (insn, op, plen);
   6635 
   6636       reg_base = REGNO (XEXP (base, 0));
   6637       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
   6638 	{
   6639 	  if (reg_base != REG_Y)
   6640 	    fatal_insn ("incorrect insn:",insn);
   6641 
   6642 	  return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
   6643 	    ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
   6644 			   "std Y+63,%B1"    CR_TAB
   6645 			   "std Y+62,%A1"    CR_TAB
   6646 			   "sbiw r28,%o0-62", op, plen, -4)
   6647 
   6648 	    : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
   6649 			   "sbci r29,hi8(-%o0)" CR_TAB
   6650 			   "std Y+1,%B1"        CR_TAB
   6651 			   "st Y,%A1"           CR_TAB
   6652 			   "subi r28,lo8(%o0)"  CR_TAB
   6653 			   "sbci r29,hi8(%o0)", op, plen, -6);
   6654 	}
   6655 
   6656       if (reg_base != REG_X)
   6657 	return avr_asm_len ("std %B0,%B1" CR_TAB
   6658 			    "std %A0,%A1", op, plen, -2);
   6659       /* (X + d) = R */
   6660       return reg_src == REG_X
   6661 	? avr_asm_len ("mov __tmp_reg__,r26"  CR_TAB
   6662 		       "mov __zero_reg__,r27" CR_TAB
   6663 		       "adiw r26,%o0+1"       CR_TAB
   6664 		       "st X,__zero_reg__"    CR_TAB
   6665 		       "st -X,__tmp_reg__"    CR_TAB
   6666 		       "clr __zero_reg__"     CR_TAB
   6667 		       "sbiw r26,%o0", op, plen, -7)
   6668 
   6669 	: avr_asm_len ("adiw r26,%o0+1" CR_TAB
   6670 		       "st X,%B1"       CR_TAB
   6671 		       "st -X,%A1"      CR_TAB
   6672 		       "sbiw r26,%o0", op, plen, -4);
   6673     }
   6674   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
   6675     {
   6676       return avr_asm_len ("st %0,%B1" CR_TAB
   6677 			  "st %0,%A1", op, plen, -2);
   6678     }
   6679   else if (GET_CODE (base) == POST_INC) /* (R++) */
   6680     {
   6681       if (!mem_volatile_p)
   6682 	return avr_asm_len ("st %0,%A1"  CR_TAB
   6683 			    "st %0,%B1", op, plen, -2);
   6684 
   6685       if (AVR_TINY)
   6686 	return avr_out_movhi_mr_r_post_inc_tiny (op, plen);
   6687 
   6688       return REGNO (XEXP (base, 0)) == REG_X
   6689 	? avr_asm_len ("adiw r26,1"  CR_TAB
   6690 		       "st X,%B1"    CR_TAB
   6691 		       "st -X,%A1"   CR_TAB
   6692 		       "adiw r26,2", op, plen, -4)
   6693 
   6694 	: avr_asm_len ("std %p0+1,%B1" CR_TAB
   6695 		       "st %p0,%A1"    CR_TAB
   6696 		       "adiw %r0,2", op, plen, -3);
   6697     }
   6698   fatal_insn ("unknown move insn:",insn);
   6699   return "";
   6700 }
   6701 
   6702 
   6703 /* During reload, we allow much more addresses than Reduced Tiny actually
   6704    supports.  Split them after reload in order to get closer to the
   6705    core's capabilities.  This sets the stage for pass .avr-fuse-add.  */
   6706 
   6707 bool
   6708 avr_split_tiny_move (rtx_insn * /*insn*/, rtx *xop)
   6709 {
   6710   bool store_p = false;
   6711   rtx mem, reg_or_0;
   6712 
   6713   if (REG_P (xop[0]) && MEM_P (xop[1]))
   6714     {
   6715       reg_or_0 = xop[0];
   6716       mem = xop[1];
   6717     }
   6718   else if (MEM_P (xop[0])
   6719 	   && (REG_P (xop[1])
   6720 	       || xop[1] == CONST0_RTX (GET_MODE (xop[0]))))
   6721     {
   6722       mem = xop[0];
   6723       reg_or_0 = xop[1];
   6724       store_p = true;
   6725     }
   6726   else
   6727     return false;
   6728 
   6729   machine_mode mode = GET_MODE (mem);
   6730   rtx base, addr = XEXP (mem, 0);
   6731   enum rtx_code addr_code = GET_CODE (addr);
   6732 
   6733   if (REG_P (reg_or_0)
   6734       && reg_overlap_mentioned_p (reg_or_0, addr))
   6735     return false;
   6736   else if (addr_code == PLUS || addr_code == PRE_DEC || addr_code == POST_INC)
   6737     base = XEXP (addr, 0);
   6738   else if (addr_code == REG)
   6739     base = addr;
   6740   else
   6741     return false;
   6742 
   6743   if (REGNO (base) > REG_Z)
   6744     return false;
   6745 
   6746   bool volatile_p = MEM_VOLATILE_P (mem);
   6747   bool mem_volatile_p = false;
   6748   if (frame_pointer_needed
   6749       && REGNO (base) == FRAME_POINTER_REGNUM)
   6750     {
   6751       if (avr_fuse_add < 2
   6752 	  // Be a projection (we always split PLUS).
   6753 	  || (avr_fuse_add == 2 && volatile_p && addr_code != PLUS))
   6754 	return false;
   6755 
   6756       // Changing the frame pointer locally may confuse later passes
   6757       // like .dse2 which don't track changes of FP, not even when
   6758       // respective CFA notes are present.  An example is pr22141-1.c.
   6759       if (avr_fuse_add == 2)
   6760 	mem_volatile_p = true;
   6761     }
   6762 
   6763   enum rtx_code new_code = UNKNOWN;
   6764   HOST_WIDE_INT add = 0, sub = 0;
   6765   int msize = GET_MODE_SIZE (mode);
   6766 
   6767   AVR_LdSt_Props ap { REGNO (base), store_p, volatile_p, ADDR_SPACE_GENERIC };
   6768 
   6769   switch (addr_code)
   6770     {
   6771     default:
   6772       return false;
   6773 
   6774     case PLUS:
   6775       add = INTVAL (XEXP (addr, 1));
   6776       if (msize == 1)
   6777 	{
   6778 	  new_code = REG;
   6779 	  sub = -add;
   6780 	}
   6781       else if (ap.want_predec)
   6782 	{
   6783 	  // volatile stores prefer PRE_DEC (MSB first)
   6784 	  sub = -add;
   6785 	  add += msize;
   6786 	  new_code = PRE_DEC;
   6787 	}
   6788       else
   6789 	{
   6790 	  new_code = POST_INC;
   6791 	  sub = -add - msize;
   6792 	}
   6793       break;
   6794 
   6795     case POST_INC:
   6796       // volatile stores prefer PRE_DEC (MSB first)
   6797       if (msize > 1 && ap.want_predec)
   6798 	{
   6799 	  add = msize;
   6800 	  new_code = PRE_DEC;
   6801 	  sub = msize;
   6802 	  break;
   6803 	}
   6804       return false;
   6805 
   6806     case PRE_DEC:
   6807       // volatile loads prefer POST_INC (LSB first)
   6808       if (msize > 1 && ap.want_postinc)
   6809 	{
   6810 	  add = -msize;
   6811 	  new_code = POST_INC;
   6812 	  sub = -msize;
   6813 	  break;
   6814 	}
   6815       return false;
   6816 
   6817     case REG:
   6818       if (msize == 1)
   6819 	return false;
   6820 
   6821       if (ap.want_predec)
   6822 	{
   6823 	  add = msize;
   6824 	  new_code = PRE_DEC;
   6825 	  sub = 0;
   6826 	}
   6827       else
   6828 	{
   6829 	  add = 0;
   6830 	  new_code = POST_INC;
   6831 	  sub = -msize;
   6832 	}
   6833       break;
   6834     } // switch addr_code
   6835 
   6836   rtx_insn *insn;
   6837 
   6838   if (add)
   6839     {
   6840       insn = emit_move_ccc (base, plus_constant (Pmode, base, add));
   6841       avr_maybe_adjust_cfa (insn, base, add);
   6842     }
   6843 
   6844   rtx new_addr = new_code == REG
   6845     ? base
   6846     : gen_rtx_fmt_e (new_code, Pmode, base);
   6847 
   6848   rtx new_mem = change_address (mem, mode, new_addr);
   6849   if (mem_volatile_p)
   6850     MEM_VOLATILE_P (new_mem) = 1;
   6851 
   6852   insn = emit_move_ccc (store_p ? new_mem : reg_or_0,
   6853 			store_p ? reg_or_0 : new_mem);
   6854   if (auto_inc_p (new_addr))
   6855     {
   6856       add_reg_note (insn, REG_INC, base);
   6857       int off = new_code == POST_INC ? msize : -msize;
   6858       avr_maybe_adjust_cfa (insn, base, off);
   6859     }
   6860 
   6861   if (sub)
   6862     {
   6863       insn = emit_move_ccc (base, plus_constant (Pmode, base, sub));
   6864       avr_maybe_adjust_cfa (insn, base, sub);
   6865     }
   6866 
   6867   return true;
   6868 }
   6869 
   6870 
   6871 /* Implement `TARGET_FRAME_POINTER_REQUIRED'.  */
   6872 /* Return 1 if frame pointer for current function required.  */
   6873 
   6874 static bool
   6875 avr_frame_pointer_required_p (void)
   6876 {
   6877   return (cfun->calls_alloca
   6878 	  || cfun->calls_setjmp
   6879 	  || cfun->has_nonlocal_label
   6880 	  || crtl->args.info.has_stack_args
   6881 	  || get_frame_size () > 0);
   6882 }
   6883 
   6884 
   6885 /* Returns the condition of the branch following INSN, where INSN is some
   6886    comparison.  If the next insn is not a branch or the condition code set
   6887    by INSN might be used by more insns than the next one, return UNKNOWN.
   6888    For now, just look at the next insn, which misses some opportunities like
   6889    following jumps.  */
   6890 
   6891 static RTX_CODE
   6892 compare_condition (rtx_insn *insn)
   6893 {
   6894   rtx set;
   6895   rtx_insn *next = next_real_nondebug_insn (insn);
   6896 
   6897   if (next
   6898       && JUMP_P (next)
   6899       // If SREG does not die in the next insn, it is used in more than one
   6900       // branch.  This can happen due to pass .avr-ifelse optimizations.
   6901       && dead_or_set_regno_p (next, REG_CC)
   6902       // Branches are (set (pc) (if_then_else (COND (...)))).
   6903       && (set = single_set (next))
   6904       && GET_CODE (SET_SRC (set)) == IF_THEN_ELSE)
   6905     {
   6906       return GET_CODE (XEXP (SET_SRC (set), 0));
   6907     }
   6908 
   6909   return UNKNOWN;
   6910 }
   6911 
   6912 
   6913 /* Returns true if INSN is a tst insn that only tests the sign.  */
   6914 
   6915 static bool
   6916 compare_sign_p (rtx_insn *insn)
   6917 {
   6918   RTX_CODE cond = compare_condition (insn);
   6919   return (cond == GE || cond == LT);
   6920 }
   6921 
   6922 
   6923 /* Returns true if INSN is a compare insn with the EQ or NE condition.  */
   6924 
   6925 static bool
   6926 compare_eq_p (rtx_insn *insn)
   6927 {
   6928   RTX_CODE cond = compare_condition (insn);
   6929   return (cond == EQ || cond == NE);
   6930 }
   6931 
   6932 
   6933 /* Implement `TARGET_CANONICALIZE_COMPARISON'.  */
   6934 /* Basically tries to convert "difficult" comparisons like GT[U]
   6935    and LE[U] to simple ones.  Some asymmetric comparisons can be
   6936    transformed to EQ or NE against zero.  */
   6937 
   6938 static void
   6939 avr_canonicalize_comparison (int *icode, rtx *op0, rtx *op1, bool op0_fixed)
   6940 {
   6941   enum rtx_code code = (enum rtx_code) *icode;
   6942   machine_mode mode = GET_MODE (*op0);
   6943 
   6944   bool signed_p = code == GT || code == LE;
   6945   bool unsigned_p = code == GTU || code == LEU;
   6946   bool difficult_p = signed_p || unsigned_p;
   6947 
   6948   if (// Only do integers and fixed-points.
   6949       (! SCALAR_INT_MODE_P (mode)
   6950        && ! ALL_SCALAR_FIXED_POINT_MODE_P (mode))
   6951       // Only do comparisons against a register.
   6952       || ! register_operand (*op0, mode))
   6953     return;
   6954 
   6955   // Canonicalize "difficult" reg-reg comparisons.
   6956 
   6957   if (! op0_fixed
   6958       && difficult_p
   6959       && register_operand (*op1, mode))
   6960     {
   6961       std::swap (*op0, *op1);
   6962       *icode = (int) swap_condition (code);
   6963       return;
   6964     }
   6965 
   6966   // Canonicalize comparisons against compile-time constants.
   6967 
   6968   if (CONST_INT_P (*op1)
   6969       || CONST_FIXED_P (*op1))
   6970     {
   6971       // INT_MODE of the same size.
   6972       scalar_int_mode imode = int_mode_for_mode (mode).require ();
   6973 
   6974       unsigned HOST_WIDE_INT mask = GET_MODE_MASK (imode);
   6975       unsigned HOST_WIDE_INT maxval = signed_p ? mask >> 1 : mask;
   6976 
   6977       // Convert value *op1 to imode.
   6978       rtx xval = simplify_gen_subreg (imode, *op1, mode, 0);
   6979 
   6980       // Canonicalize difficult comparisons against const.
   6981       if (difficult_p
   6982 	  && (UINTVAL (xval) & mask) != maxval)
   6983 	{
   6984 	  // Convert *op0 > *op1  to *op0 >= 1 + *op1.
   6985 	  // Convert *op0 <= *op1 to *op0 <  1 + *op1.
   6986 	  xval = simplify_binary_operation (PLUS, imode, xval, const1_rtx);
   6987 
   6988 	  // Convert value back to its original mode.
   6989 	  *op1 = simplify_gen_subreg (mode, xval, imode, 0);
   6990 
   6991 	  // Map  >  to  >=  and  <=  to  <.
   6992 	  *icode = (int) avr_normalize_condition (code);
   6993 
   6994 	  return;
   6995 	}
   6996 
   6997       // Some asymmetric comparisons can be turned into EQ or NE.
   6998       if (code == LTU && xval == const1_rtx)
   6999 	{
   7000 	  *icode = (int) EQ;
   7001 	  *op1 = CONST0_RTX (mode);
   7002 	  return;
   7003 	}
   7004 
   7005       if (code == GEU && xval == const1_rtx)
   7006 	{
   7007 	  *icode = (int) NE;
   7008 	  *op1 = CONST0_RTX (mode);
   7009 	  return;
   7010 	}
   7011     }
   7012 }
   7013 
   7014 
   7015 /* Output compare instruction
   7016 
   7017       compare (XOP[0], XOP[1])
   7018 
   7019    for a register XOP[0] and a compile-time constant XOP[1].  Return "".
   7020    XOP[2] is an 8-bit scratch register as needed.
   7021 
   7022    PLEN == NULL:  Output instructions.
   7023    PLEN != NULL:  Set *PLEN to the length (in words) of the sequence.
   7024                   Don't output anything.  */
   7025 
   7026 const char *
   7027 avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
   7028 {
   7029   /* Register to compare and value to compare against. */
   7030   rtx xreg = xop[0];
   7031   rtx xval = xop[1];
   7032 
   7033   /* Number of bytes to operate on.  */
   7034   int n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
   7035 
   7036   /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown.  */
   7037   int clobber_val = -1;
   7038 
   7039   /* Map fixed mode operands to integer operands with the same binary
   7040      representation.  They are easier to handle in the remainder.  */
   7041 
   7042   if (CONST_FIXED_P (xval))
   7043     {
   7044       xreg = avr_to_int_mode (xop[0]);
   7045       xval = avr_to_int_mode (xop[1]);
   7046     }
   7047 
   7048   /* MODE of the comparison.  */
   7049   machine_mode mode = GET_MODE (xreg);
   7050 
   7051   gcc_assert (REG_P (xreg));
   7052   gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
   7053 	      || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
   7054 
   7055   if (plen)
   7056     *plen = 0;
   7057 
   7058   /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
   7059      against 0 by ORing the bytes.  This is one instruction shorter.
   7060      Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
   7061      and therefore don't use this.  */
   7062 
   7063   if (!test_hard_reg_class (LD_REGS, xreg)
   7064       && compare_eq_p (insn)
   7065       && reg_unused_after (insn, xreg))
   7066     {
   7067       if (xval == const1_rtx)
   7068 	{
   7069 	  avr_asm_len ("dec %A0" CR_TAB
   7070 		       "or %A0,%B0", xop, plen, 2);
   7071 
   7072 	  if (n_bytes >= 3)
   7073 	    avr_asm_len ("or %A0,%C0", xop, plen, 1);
   7074 
   7075 	  if (n_bytes >= 4)
   7076 	    avr_asm_len ("or %A0,%D0", xop, plen, 1);
   7077 
   7078 	  return "";
   7079 	}
   7080       else if (xval == constm1_rtx)
   7081 	{
   7082 	  if (n_bytes >= 4)
   7083 	    avr_asm_len ("and %A0,%D0", xop, plen, 1);
   7084 
   7085 	  if (n_bytes >= 3)
   7086 	    avr_asm_len ("and %A0,%C0", xop, plen, 1);
   7087 
   7088 	  return avr_asm_len ("and %A0,%B0" CR_TAB
   7089 			      "com %A0", xop, plen, 2);
   7090 	}
   7091     }
   7092 
   7093   /* Comparisons == -1 and != -1 of a d-register that's used after the
   7094      comparison.  (If it's unused after we use CPI / SBCI or ADIW sequence
   7095      from below.)  Instead of  CPI Rlo,-1 / LDI Rx,-1 / CPC Rhi,Rx  we can
   7096      use  CPI Rlo,-1 / CPC Rhi,Rlo  which is 1 instruction shorter:
   7097      If CPI is true then Rlo contains -1 and we can use Rlo instead of Rx
   7098      when CPC'ing the high part.  If CPI is false then CPC cannot render
   7099      the result to true.  This also works for the more generic case where
   7100      the constant is of the form 0xabab.  */
   7101 
   7102   if (n_bytes == 2
   7103       && xval != const0_rtx
   7104       && test_hard_reg_class (LD_REGS, xreg)
   7105       && compare_eq_p (insn)
   7106       && !reg_unused_after (insn, xreg))
   7107     {
   7108       rtx xlo8 = simplify_gen_subreg (QImode, xval, mode, 0);
   7109       rtx xhi8 = simplify_gen_subreg (QImode, xval, mode, 1);
   7110 
   7111       if (INTVAL (xlo8) == INTVAL (xhi8))
   7112 	{
   7113 	  xop[0] = xreg;
   7114 	  xop[1] = xlo8;
   7115 
   7116 	  return avr_asm_len ("cpi %A0,%1"  CR_TAB
   7117 			      "cpc %B0,%A0", xop, plen, 2);
   7118 	}
   7119     }
   7120 
   7121   for (int i = 0; i < n_bytes; i++)
   7122     {
   7123       /* We compare byte-wise.  */
   7124       rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
   7125       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
   7126 
   7127       /* 8-bit value to compare with this byte.  */
   7128       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
   7129 
   7130       /* Registers R16..R31 can operate with immediate.  */
   7131       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
   7132 
   7133       xop[0] = reg8;
   7134       xop[1] = gen_int_mode (val8, QImode);
   7135 
   7136       /* Word registers >= R24 can use SBIW/ADIW with 0..63.  */
   7137 
   7138       if (i == 0
   7139 	  && avr_adiw_reg_p (reg8))
   7140 	{
   7141 	  int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
   7142 
   7143 	  if (IN_RANGE (val16, 0, 63)
   7144 	      && (val8 == 0
   7145 		  || reg_unused_after (insn, xreg)))
   7146 	    {
   7147 	      avr_asm_len ("sbiw %0,%1", xop, plen, 1);
   7148 
   7149 	      i++;
   7150 	      continue;
   7151 	    }
   7152 
   7153 	  if (n_bytes == 2
   7154 	      && IN_RANGE (val16, -63, -1)
   7155 	      && compare_eq_p (insn)
   7156 	      && reg_unused_after (insn, xreg))
   7157 	    {
   7158 	      return avr_asm_len ("adiw %0,%n1", xop, plen, 1);
   7159 	    }
   7160 	}
   7161 
   7162       /* Comparing against 0 is easy.  */
   7163 
   7164       if (val8 == 0)
   7165 	{
   7166 	  avr_asm_len (i == 0
   7167 		       ? "cp %0,__zero_reg__"
   7168 		       : "cpc %0,__zero_reg__", xop, plen, 1);
   7169 	  continue;
   7170 	}
   7171 
   7172       /* Upper registers can compare and subtract-with-carry immediates.
   7173 	 Notice that compare instructions do the same as respective subtract
   7174 	 instruction; the only difference is that comparisons don't write
   7175 	 the result back to the target register.  */
   7176 
   7177       if (ld_reg_p)
   7178 	{
   7179 	  if (i == 0)
   7180 	    {
   7181 	      avr_asm_len ("cpi %0,%1", xop, plen, 1);
   7182 	      continue;
   7183 	    }
   7184 	  else if (reg_unused_after (insn, xreg))
   7185 	    {
   7186 	      avr_asm_len ("sbci %0,%1", xop, plen, 1);
   7187 	      continue;
   7188 	    }
   7189 	}
   7190 
   7191       /* Must load the value into the scratch register.  */
   7192 
   7193       gcc_assert (REG_P (xop[2]));
   7194 
   7195       if (clobber_val != (int) val8)
   7196 	avr_asm_len ("ldi %2,%1", xop, plen, 1);
   7197       clobber_val = (int) val8;
   7198 
   7199       avr_asm_len (i == 0
   7200 		   ? "cp %0,%2"
   7201 		   : "cpc %0,%2", xop, plen, 1);
   7202     }
   7203 
   7204   return "";
   7205 }
   7206 
   7207 
   7208 /* Prepare operands of compare_const_di2 to be used with avr_out_compare.  */
   7209 
   7210 const char *
   7211 avr_out_compare64 (rtx_insn *insn, rtx *op, int *plen)
   7212 {
   7213   rtx xop[3] = { gen_rtx_REG (DImode, ACC_A), op[0], op[1] };
   7214 
   7215   return avr_out_compare (insn, xop, plen);
   7216 }
   7217 
   7218 /* Output test instruction for HImode.  */
   7219 
   7220 const char *
   7221 avr_out_tsthi (rtx_insn *insn, rtx *op, int *plen)
   7222 {
   7223   if (compare_sign_p (insn))
   7224     {
   7225       avr_asm_len ("tst %B0", op, plen, -1);
   7226     }
   7227   else if (reg_unused_after (insn, op[0])
   7228 	   && compare_eq_p (insn))
   7229     {
   7230       /* Faster than sbiw if we can clobber the operand.  */
   7231       avr_asm_len ("or %A0,%B0", op, plen, -1);
   7232     }
   7233   else
   7234     {
   7235       avr_out_compare (insn, op, plen);
   7236     }
   7237 
   7238   return "";
   7239 }
   7240 
   7241 
   7242 /* Output test instruction for PSImode.  */
   7243 
   7244 const char *
   7245 avr_out_tstpsi (rtx_insn *insn, rtx *op, int *plen)
   7246 {
   7247   if (compare_sign_p (insn))
   7248     {
   7249       avr_asm_len ("tst %C0", op, plen, -1);
   7250     }
   7251   else if (reg_unused_after (insn, op[0])
   7252 	   && compare_eq_p (insn))
   7253     {
   7254       /* Faster than sbiw if we can clobber the operand.  */
   7255       avr_asm_len ("or %A0,%B0" CR_TAB
   7256 		   "or %A0,%C0", op, plen, -2);
   7257     }
   7258   else
   7259     {
   7260       avr_out_compare (insn, op, plen);
   7261     }
   7262 
   7263   return "";
   7264 }
   7265 
   7266 
   7267 /* Output test instruction for SImode.  */
   7268 
   7269 const char *
   7270 avr_out_tstsi (rtx_insn *insn, rtx *op, int *plen)
   7271 {
   7272   if (compare_sign_p (insn))
   7273     {
   7274       avr_asm_len ("tst %D0", op, plen, -1);
   7275     }
   7276   else if (reg_unused_after (insn, op[0])
   7277 	   && compare_eq_p (insn))
   7278     {
   7279       /* Faster than sbiw if we can clobber the operand.  */
   7280       avr_asm_len ("or %A0,%B0" CR_TAB
   7281 		   "or %A0,%C0" CR_TAB
   7282 		   "or %A0,%D0", op, plen, -3);
   7283     }
   7284   else
   7285     {
   7286       avr_out_compare (insn, op, plen);
   7287     }
   7288 
   7289   return "";
   7290 }
   7291 
   7292 
   7293 /* Output a comparison of a zero- or sign-extended register against a
   7294    plain register.  CODE is SIGN_EXTEND or ZERO_EXTEND.  Return "".
   7295 
   7296    PLEN != 0: Set *PLEN to the code length in words. Don't output anything.
   7297    PLEN == 0: Print instructions.  */
   7298 
   7299 const char *
   7300 avr_out_cmp_ext (rtx xop[], enum rtx_code code, int *plen)
   7301 {
   7302   // The smaller reg is the one that's to be extended.  Get its index as z.
   7303   int z = GET_MODE_SIZE (GET_MODE (xop[1])) < GET_MODE_SIZE (GET_MODE (xop[0]));
   7304   rtx zreg = xop[z];
   7305   rtx reg = xop[1 - z];
   7306   machine_mode mode = GET_MODE (reg);
   7307   machine_mode zmode = GET_MODE (zreg);
   7308   rtx zex;
   7309 
   7310   if (plen)
   7311     *plen = 0;
   7312 
   7313   // zex holds the extended bytes above zreg.  This is 0 for ZERO_EXTEND,
   7314   // and 0 or -1 for SIGN_EXTEND.
   7315 
   7316   if (code == SIGN_EXTEND)
   7317     {
   7318       // Sign-extend the high-byte of zreg to tmp_reg.
   7319       int zmsb = GET_MODE_SIZE (zmode) - 1;
   7320       rtx xzmsb = simplify_gen_subreg (QImode, zreg, zmode, zmsb);
   7321 
   7322       avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
   7323 		   "rol __tmp_reg__"    CR_TAB
   7324 		   "sbc __tmp_reg__,__tmp_reg__", &xzmsb, plen, 3);
   7325       zex = tmp_reg_rtx;
   7326     }
   7327   else if (code == ZERO_EXTEND)
   7328     {
   7329       zex = zero_reg_rtx;
   7330     }
   7331   else
   7332     gcc_unreachable();
   7333 
   7334   // Now output n_bytes bytes of the very comparison.
   7335 
   7336   int n_bytes = GET_MODE_SIZE (mode);
   7337 
   7338   avr_asm_len ("cp %0,%1", xop, plen, 1);
   7339 
   7340   for (int b = 1; b < n_bytes; ++b)
   7341     {
   7342       rtx regs[2];
   7343       regs[1 - z] = simplify_gen_subreg (QImode, reg, mode, b);
   7344       regs[z] = (b < GET_MODE_SIZE (zmode)
   7345 		 ? simplify_gen_subreg (QImode, zreg, zmode, b)
   7346 		 : zex);
   7347 
   7348       avr_asm_len ("cpc %0,%1", regs, plen, 1);
   7349     }
   7350 
   7351   return "";
   7352 }
   7353 
   7354 
   7355 /* Generate asm equivalent for various shifts.  This only handles cases
   7356    that are not already carefully hand-optimized in ?sh??i3_out.
   7357 
   7358    OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
   7359    OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
   7360    OPERANDS[3] is a QImode scratch register from LD regs if
   7361                available and SCRATCH, otherwise (no scratch available)
   7362 
   7363    TEMPL is an assembler template that shifts by one position.
   7364    T_LEN is the length of this template.  */
   7365 
   7366 void
   7367 out_shift_with_cnt (const char *templ, rtx_insn *insn, rtx operands[],
   7368 		    int *plen, int t_len)
   7369 {
   7370   bool second_label = true;
   7371   bool saved_in_tmp = false;
   7372   bool use_zero_reg = false;
   7373   rtx op[5];
   7374 
   7375   op[0] = operands[0];
   7376   op[1] = operands[1];
   7377   op[2] = operands[2];
   7378   op[3] = operands[3];
   7379 
   7380   if (plen)
   7381     *plen = 0;
   7382 
   7383   if (CONST_INT_P (operands[2]))
   7384     {
   7385       /* Operand 3 is a scratch register if this is a
   7386          parallel with three elements i.e. a set,
   7387          a clobber of a scratch, and clobber of REG_CC.
   7388          If a scratch reg is not available, then the parallel
   7389          will contain only a set and clobber of REG_CC. */
   7390       bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
   7391 		      && XVECLEN (PATTERN (insn), 0) == 3
   7392 		      && REG_P (operands[3]));
   7393       int count = INTVAL (operands[2]);
   7394       int max_len = 10;  /* If larger than this, always use a loop.  */
   7395 
   7396       if (count <= 0)
   7397 	return;
   7398 
   7399       if (count < 8 && !scratch)
   7400 	use_zero_reg = true;
   7401 
   7402       if (optimize_size)
   7403 	max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
   7404 
   7405       if (t_len * count <= max_len)
   7406 	{
   7407 	  /* Output shifts inline with no loop - faster.  */
   7408 
   7409 	  while (count-- > 0)
   7410 	    avr_asm_len (templ, op, plen, t_len);
   7411 
   7412 	  return;
   7413 	}
   7414 
   7415       if (scratch)
   7416 	{
   7417 	  avr_asm_len ("ldi %3,%2", op, plen, 1);
   7418 	}
   7419       else if (use_zero_reg)
   7420 	{
   7421 	  /* Hack to save one word: use __zero_reg__ as loop counter.
   7422 	     Set one bit, then shift in a loop until it is 0 again.  */
   7423 
   7424 	  op[3] = zero_reg_rtx;
   7425 
   7426 	  avr_asm_len ("set" CR_TAB
   7427 		       "bld %3,%2-1", op, plen, 2);
   7428 	}
   7429       else
   7430 	{
   7431 	  /* No scratch register available, use one from LD_REGS (saved in
   7432 	     __tmp_reg__) that doesn't overlap with registers to shift.  */
   7433 
   7434 	  op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + REG_16];
   7435 	  op[4] = tmp_reg_rtx;
   7436 	  saved_in_tmp = true;
   7437 
   7438 	  avr_asm_len ("mov %4,%3" CR_TAB
   7439 		       "ldi %3,%2", op, plen, 2);
   7440 	}
   7441 
   7442       second_label = false;
   7443     }
   7444   else if (MEM_P (op[2]))
   7445     {
   7446       rtx op_mov[2];
   7447 
   7448       op_mov[0] = op[3] = tmp_reg_rtx;
   7449       op_mov[1] = op[2];
   7450 
   7451       out_movqi_r_mr (insn, op_mov, plen);
   7452     }
   7453   else if (register_operand (op[2], QImode))
   7454     {
   7455       op[3] = op[2];
   7456 
   7457       if (!reg_unused_after (insn, op[2])
   7458 	  || reg_overlap_mentioned_p (op[0], op[2]))
   7459 	{
   7460 	  op[3] = tmp_reg_rtx;
   7461 	  avr_asm_len ("mov %3,%2", op, plen, 1);
   7462 	}
   7463     }
   7464   else
   7465     fatal_insn ("bad shift insn:", insn);
   7466 
   7467   if (second_label)
   7468     avr_asm_len ("rjmp 2f", op, plen, 1);
   7469 
   7470   avr_asm_len ("1:", op, plen, 0);
   7471   avr_asm_len (templ, op, plen, t_len);
   7472 
   7473   if (second_label)
   7474     avr_asm_len ("2:", op, plen, 0);
   7475 
   7476   avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
   7477   avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
   7478 
   7479   if (saved_in_tmp)
   7480     avr_asm_len ("mov %3,%4", op, plen, 1);
   7481 }
   7482 
   7483 
   7484 /* 8bit shift left ((char)x << i)   */
   7485 
   7486 const char *
   7487 ashlqi3_out (rtx_insn *insn, rtx operands[], int *len)
   7488 {
   7489   if (CONST_INT_P (operands[2]))
   7490     {
   7491       int k;
   7492 
   7493       if (!len)
   7494 	len = &k;
   7495 
   7496       switch (INTVAL (operands[2]))
   7497 	{
   7498 	default:
   7499 	  if (INTVAL (operands[2]) < 8)
   7500 	    break;
   7501 
   7502 	  *len = 1;
   7503 	  return "clr %0";
   7504 
   7505 	case 1:
   7506 	  *len = 1;
   7507 	  return "lsl %0";
   7508 
   7509 	case 2:
   7510 	  *len = 2;
   7511 	  return ("lsl %0" CR_TAB
   7512 		  "lsl %0");
   7513 
   7514 	case 3:
   7515 	  *len = 3;
   7516 	  return ("lsl %0" CR_TAB
   7517 		  "lsl %0" CR_TAB
   7518 		  "lsl %0");
   7519 
   7520 	case 4:
   7521 	  if (test_hard_reg_class (LD_REGS, operands[0]))
   7522 	    {
   7523 	      *len = 2;
   7524 	      return ("swap %0" CR_TAB
   7525 		      "andi %0,0xf0");
   7526 	    }
   7527 	  *len = 4;
   7528 	  return ("lsl %0" CR_TAB
   7529 		  "lsl %0" CR_TAB
   7530 		  "lsl %0" CR_TAB
   7531 		  "lsl %0");
   7532 
   7533 	case 5:
   7534 	  if (test_hard_reg_class (LD_REGS, operands[0]))
   7535 	    {
   7536 	      *len = 3;
   7537 	      return ("swap %0" CR_TAB
   7538 		      "lsl %0"  CR_TAB
   7539 		      "andi %0,0xe0");
   7540 	    }
   7541 	  *len = 5;
   7542 	  return ("lsl %0" CR_TAB
   7543 		  "lsl %0" CR_TAB
   7544 		  "lsl %0" CR_TAB
   7545 		  "lsl %0" CR_TAB
   7546 		  "lsl %0");
   7547 
   7548 	case 6:
   7549 	  if (test_hard_reg_class (LD_REGS, operands[0]))
   7550 	    {
   7551 	      *len = 4;
   7552 	      return ("swap %0" CR_TAB
   7553 		      "lsl %0"  CR_TAB
   7554 		      "lsl %0"  CR_TAB
   7555 		      "andi %0,0xc0");
   7556 	    }
   7557 	  *len = 6;
   7558 	  return ("lsl %0" CR_TAB
   7559 		  "lsl %0" CR_TAB
   7560 		  "lsl %0" CR_TAB
   7561 		  "lsl %0" CR_TAB
   7562 		  "lsl %0" CR_TAB
   7563 		  "lsl %0");
   7564 
   7565 	case 7:
   7566 	  *len = 3;
   7567 	  return ("ror %0" CR_TAB
   7568 		  "clr %0" CR_TAB
   7569 		  "ror %0");
   7570 	}
   7571     }
   7572   else if (CONSTANT_P (operands[2]))
   7573     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
   7574 
   7575   out_shift_with_cnt ("lsl %0",
   7576 		      insn, operands, len, 1);
   7577   return "";
   7578 }
   7579 
   7580 
   7581 /* 16bit shift left ((short)x << i)   */
   7582 
   7583 const char *
   7584 ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
   7585 {
   7586   if (CONST_INT_P (operands[2]))
   7587     {
   7588       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
   7589 		     && XVECLEN (PATTERN (insn), 0) == 3
   7590 		     && REG_P (operands[3]));
   7591       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
   7592       int k;
   7593       int *t = len;
   7594 
   7595       if (!len)
   7596 	len = &k;
   7597 
   7598       switch (INTVAL (operands[2]))
   7599 	{
   7600 	default:
   7601 	  if (INTVAL (operands[2]) < 16)
   7602 	    break;
   7603 
   7604 	  *len = 2;
   7605 	  return ("clr %B0" CR_TAB
   7606 		  "clr %A0");
   7607 
   7608 	case 4:
   7609 	  if (optimize_size && scratch)
   7610 	    break;  /* 5 */
   7611 	  if (ldi_ok)
   7612 	    {
   7613 	      *len = 6;
   7614 	      return ("swap %A0"      CR_TAB
   7615 		      "swap %B0"      CR_TAB
   7616 		      "andi %B0,0xf0" CR_TAB
   7617 		      "eor %B0,%A0"   CR_TAB
   7618 		      "andi %A0,0xf0" CR_TAB
   7619 		      "eor %B0,%A0");
   7620 	    }
   7621 	  if (scratch)
   7622 	    {
   7623 	      *len = 7;
   7624 	      return ("swap %A0"    CR_TAB
   7625 		      "swap %B0"    CR_TAB
   7626 		      "ldi %3,0xf0" CR_TAB
   7627 		      "and %B0,%3"  CR_TAB
   7628 		      "eor %B0,%A0" CR_TAB
   7629 		      "and %A0,%3"  CR_TAB
   7630 		      "eor %B0,%A0");
   7631 	    }
   7632 	  break;  /* optimize_size ? 6 : 8 */
   7633 
   7634 	case 5:
   7635 	  if (optimize_size)
   7636 	    break;  /* scratch ? 5 : 6 */
   7637 	  if (ldi_ok)
   7638 	    {
   7639 	      *len = 8;
   7640 	      return ("lsl %A0"       CR_TAB
   7641 		      "rol %B0"       CR_TAB
   7642 		      "swap %A0"      CR_TAB
   7643 		      "swap %B0"      CR_TAB
   7644 		      "andi %B0,0xf0" CR_TAB
   7645 		      "eor %B0,%A0"   CR_TAB
   7646 		      "andi %A0,0xf0" CR_TAB
   7647 		      "eor %B0,%A0");
   7648 	    }
   7649 	  if (scratch)
   7650 	    {
   7651 	      *len = 9;
   7652 	      return ("lsl %A0"     CR_TAB
   7653 		      "rol %B0"     CR_TAB
   7654 		      "swap %A0"    CR_TAB
   7655 		      "swap %B0"    CR_TAB
   7656 		      "ldi %3,0xf0" CR_TAB
   7657 		      "and %B0,%3"  CR_TAB
   7658 		      "eor %B0,%A0" CR_TAB
   7659 		      "and %A0,%3"  CR_TAB
   7660 		      "eor %B0,%A0");
   7661 	    }
   7662 	  break;  /* 10 */
   7663 
   7664 	case 6:
   7665 	  if (optimize_size)
   7666 	    break;  /* scratch ? 5 : 6 */
   7667 	  *len = 9;
   7668 	  return ("clr __tmp_reg__" CR_TAB
   7669 		  "lsr %B0"         CR_TAB
   7670 		  "ror %A0"         CR_TAB
   7671 		  "ror __tmp_reg__" CR_TAB
   7672 		  "lsr %B0"         CR_TAB
   7673 		  "ror %A0"         CR_TAB
   7674 		  "ror __tmp_reg__" CR_TAB
   7675 		  "mov %B0,%A0"     CR_TAB
   7676 		  "mov %A0,__tmp_reg__");
   7677 
   7678 	case 7:
   7679 	  *len = 5;
   7680 	  return ("lsr %B0"     CR_TAB
   7681 		  "mov %B0,%A0" CR_TAB
   7682 		  "clr %A0"     CR_TAB
   7683 		  "ror %B0"     CR_TAB
   7684 		  "ror %A0");
   7685 
   7686 	case 8:
   7687 	  return *len = 2, ("mov %B0,%A1" CR_TAB
   7688 			    "clr %A0");
   7689 
   7690 	case 9:
   7691 	  *len = 3;
   7692 	  return ("mov %B0,%A0" CR_TAB
   7693 		  "clr %A0"     CR_TAB
   7694 		  "lsl %B0");
   7695 
   7696 	case 10:
   7697 	  *len = 4;
   7698 	  return ("mov %B0,%A0" CR_TAB
   7699 		  "clr %A0"     CR_TAB
   7700 		  "lsl %B0"     CR_TAB
   7701 		  "lsl %B0");
   7702 
   7703 	case 11:
   7704 	  *len = 5;
   7705 	  return ("mov %B0,%A0" CR_TAB
   7706 		  "clr %A0"     CR_TAB
   7707 		  "lsl %B0"     CR_TAB
   7708 		  "lsl %B0"     CR_TAB
   7709 		  "lsl %B0");
   7710 
   7711 	case 12:
   7712 	  if (ldi_ok)
   7713 	    {
   7714 	      *len = 4;
   7715 	      return ("mov %B0,%A0" CR_TAB
   7716 		      "clr %A0"     CR_TAB
   7717 		      "swap %B0"    CR_TAB
   7718 		      "andi %B0,0xf0");
   7719 	    }
   7720 	  if (scratch)
   7721 	    {
   7722 	      *len = 5;
   7723 	      return ("mov %B0,%A0" CR_TAB
   7724 		      "clr %A0"     CR_TAB
   7725 		      "swap %B0"    CR_TAB
   7726 		      "ldi %3,0xf0" CR_TAB
   7727 		      "and %B0,%3");
   7728 	    }
   7729 	  *len = 6;
   7730 	  return ("mov %B0,%A0" CR_TAB
   7731 		  "clr %A0"     CR_TAB
   7732 		  "lsl %B0"     CR_TAB
   7733 		  "lsl %B0"     CR_TAB
   7734 		  "lsl %B0"     CR_TAB
   7735 		  "lsl %B0");
   7736 
   7737 	case 13:
   7738 	  if (ldi_ok)
   7739 	    {
   7740 	      *len = 5;
   7741 	      return ("mov %B0,%A0" CR_TAB
   7742 		      "clr %A0"     CR_TAB
   7743 		      "swap %B0"    CR_TAB
   7744 		      "lsl %B0"     CR_TAB
   7745 		      "andi %B0,0xe0");
   7746 	    }
   7747 	  if (AVR_HAVE_MUL && scratch)
   7748 	    {
   7749 	      *len = 5;
   7750 	      return ("ldi %3,0x20" CR_TAB
   7751 		      "mul %A0,%3"  CR_TAB
   7752 		      "mov %B0,r0"  CR_TAB
   7753 		      "clr %A0"     CR_TAB
   7754 		      "clr __zero_reg__");
   7755 	    }
   7756 	  if (optimize_size && scratch)
   7757 	    break;  /* 5 */
   7758 	  if (scratch)
   7759 	    {
   7760 	      *len = 6;
   7761 	      return ("mov %B0,%A0" CR_TAB
   7762 		      "clr %A0"     CR_TAB
   7763 		      "swap %B0"    CR_TAB
   7764 		      "lsl %B0"     CR_TAB
   7765 		      "ldi %3,0xe0" CR_TAB
   7766 		      "and %B0,%3");
   7767 	    }
   7768 	  if (AVR_HAVE_MUL)
   7769 	    {
   7770 	      *len = 6;
   7771 	      return ("set"        CR_TAB
   7772 		      "bld r1,5"   CR_TAB
   7773 		      "mul %A0,r1" CR_TAB
   7774 		      "mov %B0,r0" CR_TAB
   7775 		      "clr %A0"    CR_TAB
   7776 		      "clr __zero_reg__");
   7777 	    }
   7778 	  *len = 7;
   7779 	  return ("mov %B0,%A0" CR_TAB
   7780 		  "clr %A0"     CR_TAB
   7781 		  "lsl %B0"     CR_TAB
   7782 		  "lsl %B0"     CR_TAB
   7783 		  "lsl %B0"     CR_TAB
   7784 		  "lsl %B0"     CR_TAB
   7785 		  "lsl %B0");
   7786 
   7787 	case 14:
   7788 	  if (AVR_HAVE_MUL && ldi_ok)
   7789 	    {
   7790 	      *len = 5;
   7791 	      return ("ldi %B0,0x40" CR_TAB
   7792 		      "mul %A0,%B0"  CR_TAB
   7793 		      "mov %B0,r0"   CR_TAB
   7794 		      "clr %A0"      CR_TAB
   7795 		      "clr __zero_reg__");
   7796 	    }
   7797 	  if (AVR_HAVE_MUL && scratch)
   7798 	    {
   7799 	      *len = 5;
   7800 	      return ("ldi %3,0x40" CR_TAB
   7801 		      "mul %A0,%3"  CR_TAB
   7802 		      "mov %B0,r0"  CR_TAB
   7803 		      "clr %A0"     CR_TAB
   7804 		      "clr __zero_reg__");
   7805 	    }
   7806 	  if (optimize_size && ldi_ok)
   7807 	    {
   7808 	      *len = 5;
   7809 	      return ("mov %B0,%A0" CR_TAB
   7810 		      "ldi %A0,6" "\n1:\t"
   7811 		      "lsl %B0"     CR_TAB
   7812 		      "dec %A0"     CR_TAB
   7813 		      "brne 1b");
   7814 	    }
   7815 	  if (optimize_size && scratch)
   7816 	    break;  /* 5 */
   7817 	  *len = 6;
   7818 	  return ("clr %B0" CR_TAB
   7819 		  "lsr %A0" CR_TAB
   7820 		  "ror %B0" CR_TAB
   7821 		  "lsr %A0" CR_TAB
   7822 		  "ror %B0" CR_TAB
   7823 		  "clr %A0");
   7824 
   7825 	case 15:
   7826 	  *len = 4;
   7827 	  return ("clr %B0" CR_TAB
   7828 		  "lsr %A0" CR_TAB
   7829 		  "ror %B0" CR_TAB
   7830 		  "clr %A0");
   7831 	}
   7832       len = t;
   7833     }
   7834   out_shift_with_cnt ("lsl %A0" CR_TAB
   7835 		      "rol %B0", insn, operands, len, 2);
   7836   return "";
   7837 }
   7838 
   7839 
   7840 /* 24-bit shift left */
   7841 
   7842 const char *
   7843 avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen)
   7844 {
   7845   if (plen)
   7846     *plen = 0;
   7847 
   7848   if (CONST_INT_P (op[2]))
   7849     {
   7850       switch (INTVAL (op[2]))
   7851 	{
   7852 	default:
   7853 	  if (INTVAL (op[2]) < 24)
   7854 	    break;
   7855 
   7856 	  return avr_asm_len ("clr %A0" CR_TAB
   7857 			      "clr %B0" CR_TAB
   7858 			      "clr %C0", op, plen, 3);
   7859 
   7860 	case 8:
   7861 	  {
   7862 	    int reg0 = REGNO (op[0]);
   7863 	    int reg1 = REGNO (op[1]);
   7864 
   7865 	    if (reg0 >= reg1)
   7866 	      return avr_asm_len ("mov %C0,%B1"  CR_TAB
   7867 				  "mov %B0,%A1"  CR_TAB
   7868 				  "clr %A0", op, plen, 3);
   7869 	    else
   7870 	      return avr_asm_len ("clr %A0"      CR_TAB
   7871 				  "mov %B0,%A1"  CR_TAB
   7872 				  "mov %C0,%B1", op, plen, 3);
   7873 	  }
   7874 
   7875 	case 16:
   7876 	  {
   7877 	    int reg0 = REGNO (op[0]);
   7878 	    int reg1 = REGNO (op[1]);
   7879 
   7880 	    if (reg0 + 2 != reg1)
   7881 	      avr_asm_len ("mov %C0,%A1", op, plen, 1);
   7882 
   7883 	    return avr_asm_len ("clr %B0"  CR_TAB
   7884 				"clr %A0", op, plen, 2);
   7885 	  }
   7886 
   7887 	case 23:
   7888 	  return avr_asm_len ("clr %C0" CR_TAB
   7889 			      "lsr %A0" CR_TAB
   7890 			      "ror %C0" CR_TAB
   7891 			      "clr %B0" CR_TAB
   7892 			      "clr %A0", op, plen, 5);
   7893 	}
   7894     }
   7895 
   7896   out_shift_with_cnt ("lsl %A0" CR_TAB
   7897 		      "rol %B0" CR_TAB
   7898 		      "rol %C0", insn, op, plen, 3);
   7899   return "";
   7900 }
   7901 
   7902 
   7903 /* 32bit shift left ((long)x << i)   */
   7904 
   7905 const char *
   7906 ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
   7907 {
   7908   if (CONST_INT_P (operands[2]))
   7909     {
   7910       int k;
   7911       int *t = len;
   7912 
   7913       if (!len)
   7914 	len = &k;
   7915 
   7916       switch (INTVAL (operands[2]))
   7917 	{
   7918 	default:
   7919 	  if (INTVAL (operands[2]) < 32)
   7920 	    break;
   7921 
   7922 	  if (AVR_HAVE_MOVW)
   7923 	    return *len = 3, ("clr %D0" CR_TAB
   7924 			      "clr %C0" CR_TAB
   7925 			      "movw %A0,%C0");
   7926 	  *len = 4;
   7927 	  return ("clr %D0" CR_TAB
   7928 		  "clr %C0" CR_TAB
   7929 		  "clr %B0" CR_TAB
   7930 		  "clr %A0");
   7931 
   7932 	case 8:
   7933 	  {
   7934 	    int reg0 = true_regnum (operands[0]);
   7935 	    int reg1 = true_regnum (operands[1]);
   7936 	    *len = 4;
   7937 	    if (reg0 >= reg1)
   7938 	      return ("mov %D0,%C1"  CR_TAB
   7939 		      "mov %C0,%B1"  CR_TAB
   7940 		      "mov %B0,%A1"  CR_TAB
   7941 		      "clr %A0");
   7942 	    else
   7943 	      return ("clr %A0"      CR_TAB
   7944 		      "mov %B0,%A1"  CR_TAB
   7945 		      "mov %C0,%B1"  CR_TAB
   7946 		      "mov %D0,%C1");
   7947 	  }
   7948 
   7949 	case 16:
   7950 	  {
   7951 	    int reg0 = true_regnum (operands[0]);
   7952 	    int reg1 = true_regnum (operands[1]);
   7953 	    if (reg0 + 2 == reg1)
   7954 	      return *len = 2, ("clr %B0"      CR_TAB
   7955 				"clr %A0");
   7956 	    if (AVR_HAVE_MOVW)
   7957 	      return *len = 3, ("movw %C0,%A1" CR_TAB
   7958 				"clr %B0"      CR_TAB
   7959 				"clr %A0");
   7960 	    else
   7961 	      return *len = 4, ("mov %C0,%A1"  CR_TAB
   7962 				"mov %D0,%B1"  CR_TAB
   7963 				"clr %B0"      CR_TAB
   7964 				"clr %A0");
   7965 	  }
   7966 
   7967 	case 24:
   7968 	  *len = 4;
   7969 	  return ("mov %D0,%A1"  CR_TAB
   7970 		  "clr %C0"      CR_TAB
   7971 		  "clr %B0"      CR_TAB
   7972 		  "clr %A0");
   7973 
   7974 	case 31:
   7975 	  *len = 6;
   7976 	  return ("clr %D0" CR_TAB
   7977 		  "lsr %A0" CR_TAB
   7978 		  "ror %D0" CR_TAB
   7979 		  "clr %C0" CR_TAB
   7980 		  "clr %B0" CR_TAB
   7981 		  "clr %A0");
   7982 	}
   7983       len = t;
   7984     }
   7985   out_shift_with_cnt ("lsl %A0" CR_TAB
   7986 		      "rol %B0" CR_TAB
   7987 		      "rol %C0" CR_TAB
   7988 		      "rol %D0", insn, operands, len, 4);
   7989   return "";
   7990 }
   7991 
   7992 /* 8bit arithmetic shift right  ((signed char)x >> i) */
   7993 
   7994 const char *
   7995 ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
   7996 {
   7997   if (CONST_INT_P (operands[2]))
   7998     {
   7999       int k;
   8000 
   8001       if (!len)
   8002 	len = &k;
   8003 
   8004       switch (INTVAL (operands[2]))
   8005 	{
   8006 	case 1:
   8007 	  *len = 1;
   8008 	  return "asr %0";
   8009 
   8010 	case 2:
   8011 	  *len = 2;
   8012 	  return ("asr %0" CR_TAB
   8013 		  "asr %0");
   8014 
   8015 	case 3:
   8016 	  *len = 3;
   8017 	  return ("asr %0" CR_TAB
   8018 		  "asr %0" CR_TAB
   8019 		  "asr %0");
   8020 
   8021 	case 4:
   8022 	  *len = 4;
   8023 	  return ("asr %0" CR_TAB
   8024 		  "asr %0" CR_TAB
   8025 		  "asr %0" CR_TAB
   8026 		  "asr %0");
   8027 
   8028 	case 5:
   8029 	  *len = 5;
   8030 	  return ("asr %0" CR_TAB
   8031 		  "asr %0" CR_TAB
   8032 		  "asr %0" CR_TAB
   8033 		  "asr %0" CR_TAB
   8034 		  "asr %0");
   8035 
   8036 	case 6:
   8037 	  *len = 4;
   8038 	  return ("bst %0,6"  CR_TAB
   8039 		  "lsl %0"    CR_TAB
   8040 		  "sbc %0,%0" CR_TAB
   8041 		  "bld %0,0");
   8042 
   8043 	default:
   8044 	  if (INTVAL (operands[2]) < 8)
   8045 	    break;
   8046 
   8047 	  /* fall through */
   8048 
   8049 	case 7:
   8050 	  *len = 2;
   8051 	  return ("lsl %0" CR_TAB
   8052 		  "sbc %0,%0");
   8053 	}
   8054     }
   8055   else if (CONSTANT_P (operands[2]))
   8056     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
   8057 
   8058   out_shift_with_cnt ("asr %0",
   8059 		      insn, operands, len, 1);
   8060   return "";
   8061 }
   8062 
   8063 
   8064 /* 16bit arithmetic shift right  ((signed short)x >> i) */
   8065 
   8066 const char *
   8067 ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
   8068 {
   8069   if (CONST_INT_P (operands[2]))
   8070     {
   8071       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
   8072 		     && XVECLEN (PATTERN (insn), 0) == 3
   8073 		     && REG_P (operands[3]));
   8074       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
   8075       int k;
   8076       int *t = len;
   8077 
   8078       if (!len)
   8079 	len = &k;
   8080 
   8081       switch (INTVAL (operands[2]))
   8082 	{
   8083 	case 4:
   8084 	case 5:
   8085 	  /* XXX try to optimize this too? */
   8086 	  break;
   8087 
   8088 	case 6:
   8089 	  if (optimize_size)
   8090 	    break;  /* scratch ? 5 : 6 */
   8091 	  *len = 8;
   8092 	  return ("mov __tmp_reg__,%A0" CR_TAB
   8093 		  "mov %A0,%B0"         CR_TAB
   8094 		  "lsl __tmp_reg__"     CR_TAB
   8095 		  "rol %A0"             CR_TAB
   8096 		  "sbc %B0,%B0"         CR_TAB
   8097 		  "lsl __tmp_reg__"     CR_TAB
   8098 		  "rol %A0"             CR_TAB
   8099 		  "rol %B0");
   8100 
   8101 	case 7:
   8102 	  *len = 4;
   8103 	  return ("lsl %A0"     CR_TAB
   8104 		  "mov %A0,%B0" CR_TAB
   8105 		  "rol %A0"     CR_TAB
   8106 		  "sbc %B0,%B0");
   8107 
   8108 	case 8:
   8109 	  {
   8110 	    int reg0 = true_regnum (operands[0]);
   8111 	    int reg1 = true_regnum (operands[1]);
   8112 
   8113 	    if (reg0 == reg1)
   8114 	      return *len = 3, ("mov %A0,%B0" CR_TAB
   8115 				"lsl %B0"     CR_TAB
   8116 				"sbc %B0,%B0");
   8117 	    else
   8118 	      return *len = 4, ("mov %A0,%B1" CR_TAB
   8119 				"clr %B0"     CR_TAB
   8120 				"sbrc %A0,7"  CR_TAB
   8121 				"dec %B0");
   8122 	  }
   8123 
   8124 	case 9:
   8125 	  *len = 4;
   8126 	  return ("mov %A0,%B0" CR_TAB
   8127 		  "lsl %B0"      CR_TAB
   8128 		  "sbc %B0,%B0" CR_TAB
   8129 		  "asr %A0");
   8130 
   8131 	case 10:
   8132 	  *len = 5;
   8133 	  return ("mov %A0,%B0" CR_TAB
   8134 		  "lsl %B0"     CR_TAB
   8135 		  "sbc %B0,%B0" CR_TAB
   8136 		  "asr %A0"     CR_TAB
   8137 		  "asr %A0");
   8138 
   8139 	case 11:
   8140 	  if (AVR_HAVE_MUL && ldi_ok)
   8141 	    {
   8142 	      *len = 5;
   8143 	      return ("ldi %A0,0x20" CR_TAB
   8144 		      "muls %B0,%A0" CR_TAB
   8145 		      "mov %A0,r1"   CR_TAB
   8146 		      "sbc %B0,%B0"  CR_TAB
   8147 		      "clr __zero_reg__");
   8148 	    }
   8149 	  if (optimize_size && scratch)
   8150 	    break;  /* 5 */
   8151 	  *len = 6;
   8152 	  return ("mov %A0,%B0" CR_TAB
   8153 		  "lsl %B0"     CR_TAB
   8154 		  "sbc %B0,%B0" CR_TAB
   8155 		  "asr %A0"     CR_TAB
   8156 		  "asr %A0"     CR_TAB
   8157 		  "asr %A0");
   8158 
   8159 	case 12:
   8160 	  if (AVR_HAVE_MUL && ldi_ok)
   8161 	    {
   8162 	      *len = 5;
   8163 	      return ("ldi %A0,0x10" CR_TAB
   8164 		      "muls %B0,%A0" CR_TAB
   8165 		      "mov %A0,r1"   CR_TAB
   8166 		      "sbc %B0,%B0"  CR_TAB
   8167 		      "clr __zero_reg__");
   8168 	    }
   8169 	  if (optimize_size && scratch)
   8170 	    break;  /* 5 */
   8171 	  *len = 7;
   8172 	  return ("mov %A0,%B0" CR_TAB
   8173 		  "lsl %B0"     CR_TAB
   8174 		  "sbc %B0,%B0" CR_TAB
   8175 		  "asr %A0"     CR_TAB
   8176 		  "asr %A0"     CR_TAB
   8177 		  "asr %A0"     CR_TAB
   8178 		  "asr %A0");
   8179 
   8180 	case 13:
   8181 	  if (AVR_HAVE_MUL && ldi_ok)
   8182 	    {
   8183 	      *len = 5;
   8184 	      return ("ldi %A0,0x08" CR_TAB
   8185 		      "muls %B0,%A0" CR_TAB
   8186 		      "mov %A0,r1"   CR_TAB
   8187 		      "sbc %B0,%B0"  CR_TAB
   8188 		      "clr __zero_reg__");
   8189 	    }
   8190 	  if (optimize_size)
   8191 	    break;  /* scratch ? 5 : 7 */
   8192 	  *len = 8;
   8193 	  return ("mov %A0,%B0" CR_TAB
   8194 		  "lsl %B0"     CR_TAB
   8195 		  "sbc %B0,%B0" CR_TAB
   8196 		  "asr %A0"     CR_TAB
   8197 		  "asr %A0"     CR_TAB
   8198 		  "asr %A0"     CR_TAB
   8199 		  "asr %A0"     CR_TAB
   8200 		  "asr %A0");
   8201 
   8202 	case 14:
   8203 	  *len = 5;
   8204 	  return ("lsl %B0"     CR_TAB
   8205 		  "sbc %A0,%A0" CR_TAB
   8206 		  "lsl %B0"     CR_TAB
   8207 		  "mov %B0,%A0" CR_TAB
   8208 		  "rol %A0");
   8209 
   8210 	default:
   8211 	  if (INTVAL (operands[2]) < 16)
   8212 	    break;
   8213 
   8214 	  /* fall through */
   8215 
   8216 	case 15:
   8217 	  return *len = 3, ("lsl %B0"     CR_TAB
   8218 			    "sbc %A0,%A0" CR_TAB
   8219 			    "mov %B0,%A0");
   8220 	}
   8221       len = t;
   8222     }
   8223   out_shift_with_cnt ("asr %B0" CR_TAB
   8224 		      "ror %A0", insn, operands, len, 2);
   8225   return "";
   8226 }
   8227 
   8228 
   8229 /* 24-bit arithmetic shift right */
   8230 
   8231 const char *
   8232 avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
   8233 {
   8234   int dest = REGNO (op[0]);
   8235   int src = REGNO (op[1]);
   8236 
   8237   if (CONST_INT_P (op[2]))
   8238     {
   8239       if (plen)
   8240 	*plen = 0;
   8241 
   8242       switch (INTVAL (op[2]))
   8243 	{
   8244 	case 8:
   8245 	  if (dest <= src)
   8246 	    return avr_asm_len ("mov %A0,%B1" CR_TAB
   8247 				"mov %B0,%C1" CR_TAB
   8248 				"clr %C0"     CR_TAB
   8249 				"sbrc %B0,7"  CR_TAB
   8250 				"dec %C0", op, plen, 5);
   8251 	  else
   8252 	    return avr_asm_len ("clr %C0"     CR_TAB
   8253 				"sbrc %C1,7"  CR_TAB
   8254 				"dec %C0"     CR_TAB
   8255 				"mov %B0,%C1" CR_TAB
   8256 				"mov %A0,%B1", op, plen, 5);
   8257 
   8258 	case 16:
   8259 	  if (dest != src + 2)
   8260 	    avr_asm_len ("mov %A0,%C1", op, plen, 1);
   8261 
   8262 	  return avr_asm_len ("clr %B0"     CR_TAB
   8263 			      "sbrc %A0,7"  CR_TAB
   8264 			      "com %B0"     CR_TAB
   8265 			      "mov %C0,%B0", op, plen, 4);
   8266 
   8267 	default:
   8268 	  if (INTVAL (op[2]) < 24)
   8269 	    break;
   8270 
   8271 	  /* fall through */
   8272 
   8273 	case 23:
   8274 	  return avr_asm_len ("lsl %C0"     CR_TAB
   8275 			      "sbc %A0,%A0" CR_TAB
   8276 			      "mov %B0,%A0" CR_TAB
   8277 			      "mov %C0,%A0", op, plen, 4);
   8278 	} /* switch */
   8279     }
   8280 
   8281   out_shift_with_cnt ("asr %C0" CR_TAB
   8282 		      "ror %B0" CR_TAB
   8283 		      "ror %A0", insn, op, plen, 3);
   8284   return "";
   8285 }
   8286 
   8287 
   8288 /* 32-bit arithmetic shift right  ((signed long)x >> i) */
   8289 
   8290 const char *
   8291 ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
   8292 {
   8293   if (CONST_INT_P (operands[2]))
   8294     {
   8295       int k;
   8296       int *t = len;
   8297 
   8298       if (!len)
   8299 	len = &k;
   8300 
   8301       switch (INTVAL (operands[2]))
   8302 	{
   8303 	case 8:
   8304 	  {
   8305 	    int reg0 = true_regnum (operands[0]);
   8306 	    int reg1 = true_regnum (operands[1]);
   8307 	    *len=6;
   8308 	    if (reg0 <= reg1)
   8309 	      return ("mov %A0,%B1" CR_TAB
   8310 		      "mov %B0,%C1" CR_TAB
   8311 		      "mov %C0,%D1" CR_TAB
   8312 		      "clr %D0"     CR_TAB
   8313 		      "sbrc %C0,7"  CR_TAB
   8314 		      "dec %D0");
   8315 	    else
   8316 	      return ("clr %D0"     CR_TAB
   8317 		      "sbrc %D1,7"  CR_TAB
   8318 		      "dec %D0"     CR_TAB
   8319 		      "mov %C0,%D1" CR_TAB
   8320 		      "mov %B0,%C1" CR_TAB
   8321 		      "mov %A0,%B1");
   8322 	  }
   8323 
   8324 	case 16:
   8325 	  {
   8326 	    int reg0 = true_regnum (operands[0]);
   8327 	    int reg1 = true_regnum (operands[1]);
   8328 
   8329 	    if (reg0 == reg1 + 2)
   8330 	      return *len = 4, ("clr %D0"     CR_TAB
   8331 				"sbrc %B0,7"  CR_TAB
   8332 				"com %D0"     CR_TAB
   8333 				"mov %C0,%D0");
   8334 	    if (AVR_HAVE_MOVW)
   8335 	      return *len = 5, ("movw %A0,%C1" CR_TAB
   8336 				"clr %D0"      CR_TAB
   8337 				"sbrc %B0,7"   CR_TAB
   8338 				"com %D0"      CR_TAB
   8339 				"mov %C0,%D0");
   8340 	    else
   8341 	      return *len = 6, ("mov %B0,%D1" CR_TAB
   8342 				"mov %A0,%C1" CR_TAB
   8343 				"clr %D0"     CR_TAB
   8344 				"sbrc %B0,7"  CR_TAB
   8345 				"com %D0"     CR_TAB
   8346 				"mov %C0,%D0");
   8347 	  }
   8348 
   8349 	case 24:
   8350 	  return *len = 6, ("mov %A0,%D1" CR_TAB
   8351 			    "clr %D0"     CR_TAB
   8352 			    "sbrc %A0,7"  CR_TAB
   8353 			    "com %D0"     CR_TAB
   8354 			    "mov %B0,%D0" CR_TAB
   8355 			    "mov %C0,%D0");
   8356 
   8357 	default:
   8358 	  if (INTVAL (operands[2]) < 32)
   8359 	    break;
   8360 
   8361 	  /* fall through */
   8362 
   8363 	case 31:
   8364 	  if (AVR_HAVE_MOVW)
   8365 	    return *len = 4, ("lsl %D0"     CR_TAB
   8366 			      "sbc %A0,%A0" CR_TAB
   8367 			      "mov %B0,%A0" CR_TAB
   8368 			      "movw %C0,%A0");
   8369 	  else
   8370 	    return *len = 5, ("lsl %D0"     CR_TAB
   8371 			      "sbc %A0,%A0" CR_TAB
   8372 			      "mov %B0,%A0" CR_TAB
   8373 			      "mov %C0,%A0" CR_TAB
   8374 			      "mov %D0,%A0");
   8375 	}
   8376       len = t;
   8377     }
   8378   out_shift_with_cnt ("asr %D0" CR_TAB
   8379 		      "ror %C0" CR_TAB
   8380 		      "ror %B0" CR_TAB
   8381 		      "ror %A0", insn, operands, len, 4);
   8382   return "";
   8383 }
   8384 
   8385 /* 8-bit logic shift right ((unsigned char)x >> i) */
   8386 
   8387 const char *
   8388 lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
   8389 {
   8390   if (CONST_INT_P (operands[2]))
   8391     {
   8392       int k;
   8393 
   8394       if (!len)
   8395 	len = &k;
   8396 
   8397       switch (INTVAL (operands[2]))
   8398 	{
   8399 	default:
   8400 	  if (INTVAL (operands[2]) < 8)
   8401 	    break;
   8402 
   8403 	  *len = 1;
   8404 	  return "clr %0";
   8405 
   8406 	case 1:
   8407 	  *len = 1;
   8408 	  return "lsr %0";
   8409 
   8410 	case 2:
   8411 	  *len = 2;
   8412 	  return ("lsr %0" CR_TAB
   8413 		  "lsr %0");
   8414 	case 3:
   8415 	  *len = 3;
   8416 	  return ("lsr %0" CR_TAB
   8417 		  "lsr %0" CR_TAB
   8418 		  "lsr %0");
   8419 
   8420 	case 4:
   8421 	  if (test_hard_reg_class (LD_REGS, operands[0]))
   8422 	    {
   8423 	      *len=2;
   8424 	      return ("swap %0" CR_TAB
   8425 		      "andi %0,0x0f");
   8426 	    }
   8427 	  *len = 4;
   8428 	  return ("lsr %0" CR_TAB
   8429 		  "lsr %0" CR_TAB
   8430 		  "lsr %0" CR_TAB
   8431 		  "lsr %0");
   8432 
   8433 	case 5:
   8434 	  if (test_hard_reg_class (LD_REGS, operands[0]))
   8435 	    {
   8436 	      *len = 3;
   8437 	      return ("swap %0" CR_TAB
   8438 		      "lsr %0"  CR_TAB
   8439 		      "andi %0,0x7");
   8440 	    }
   8441 	  *len = 5;
   8442 	  return ("lsr %0" CR_TAB
   8443 		  "lsr %0" CR_TAB
   8444 		  "lsr %0" CR_TAB
   8445 		  "lsr %0" CR_TAB
   8446 		  "lsr %0");
   8447 
   8448 	case 6:
   8449 	  if (test_hard_reg_class (LD_REGS, operands[0]))
   8450 	    {
   8451 	      *len = 4;
   8452 	      return ("swap %0" CR_TAB
   8453 		      "lsr %0"  CR_TAB
   8454 		      "lsr %0"  CR_TAB
   8455 		      "andi %0,0x3");
   8456 	    }
   8457 	  *len = 6;
   8458 	  return ("lsr %0" CR_TAB
   8459 		  "lsr %0" CR_TAB
   8460 		  "lsr %0" CR_TAB
   8461 		  "lsr %0" CR_TAB
   8462 		  "lsr %0" CR_TAB
   8463 		  "lsr %0");
   8464 
   8465 	case 7:
   8466 	  *len = 3;
   8467 	  return ("bst %1,7" CR_TAB
   8468 		  "clr %0"   CR_TAB
   8469 		  "bld %0,0");
   8470 	}
   8471     }
   8472   else if (CONSTANT_P (operands[2]))
   8473     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
   8474 
   8475   out_shift_with_cnt ("lsr %0",
   8476 		      insn, operands, len, 1);
   8477   return "";
   8478 }
   8479 
   8480 /* 16-bit logic shift right ((unsigned short)x >> i) */
   8481 
   8482 const char *
   8483 lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
   8484 {
   8485   if (CONST_INT_P (operands[2]))
   8486     {
   8487       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
   8488 		     && XVECLEN (PATTERN (insn), 0) == 3
   8489 		     && REG_P (operands[3]));
   8490       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
   8491       int k;
   8492       int *t = len;
   8493 
   8494       if (!len)
   8495 	len = &k;
   8496 
   8497       switch (INTVAL (operands[2]))
   8498 	{
   8499 	default:
   8500 	  if (INTVAL (operands[2]) < 16)
   8501 	    break;
   8502 
   8503 	  *len = 2;
   8504 	  return ("clr %B0" CR_TAB
   8505 		  "clr %A0");
   8506 
   8507 	case 4:
   8508 	  if (optimize_size && scratch)
   8509 	    break;  /* 5 */
   8510 	  if (ldi_ok)
   8511 	    {
   8512 	      *len = 6;
   8513 	      return ("swap %B0"      CR_TAB
   8514 		      "swap %A0"      CR_TAB
   8515 		      "andi %A0,0x0f" CR_TAB
   8516 		      "eor %A0,%B0"   CR_TAB
   8517 		      "andi %B0,0x0f" CR_TAB
   8518 		      "eor %A0,%B0");
   8519 	    }
   8520 	  if (scratch)
   8521 	    {
   8522 	      *len = 7;
   8523 	      return ("swap %B0"    CR_TAB
   8524 		      "swap %A0"    CR_TAB
   8525 		      "ldi %3,0x0f" CR_TAB
   8526 		      "and %A0,%3"  CR_TAB
   8527 		      "eor %A0,%B0" CR_TAB
   8528 		      "and %B0,%3"  CR_TAB
   8529 		      "eor %A0,%B0");
   8530 	    }
   8531 	  break;  /* optimize_size ? 6 : 8 */
   8532 
   8533 	case 5:
   8534 	  if (optimize_size)
   8535 	    break;  /* scratch ? 5 : 6 */
   8536 	  if (ldi_ok)
   8537 	    {
   8538 	      *len = 8;
   8539 	      return ("lsr %B0"       CR_TAB
   8540 		      "ror %A0"       CR_TAB
   8541 		      "swap %B0"      CR_TAB
   8542 		      "swap %A0"      CR_TAB
   8543 		      "andi %A0,0x0f" CR_TAB
   8544 		      "eor %A0,%B0"   CR_TAB
   8545 		      "andi %B0,0x0f" CR_TAB
   8546 		      "eor %A0,%B0");
   8547 	    }
   8548 	  if (scratch)
   8549 	    {
   8550 	      *len = 9;
   8551 	      return ("lsr %B0"     CR_TAB
   8552 		      "ror %A0"     CR_TAB
   8553 		      "swap %B0"    CR_TAB
   8554 		      "swap %A0"    CR_TAB
   8555 		      "ldi %3,0x0f" CR_TAB
   8556 		      "and %A0,%3"  CR_TAB
   8557 		      "eor %A0,%B0" CR_TAB
   8558 		      "and %B0,%3"  CR_TAB
   8559 		      "eor %A0,%B0");
   8560 	    }
   8561 	  break;  /* 10 */
   8562 
   8563 	case 6:
   8564 	  if (optimize_size)
   8565 	    break;  /* scratch ? 5 : 6 */
   8566 	  *len = 9;
   8567 	  return ("clr __tmp_reg__" CR_TAB
   8568 		  "lsl %A0"         CR_TAB
   8569 		  "rol %B0"         CR_TAB
   8570 		  "rol __tmp_reg__" CR_TAB
   8571 		  "lsl %A0"         CR_TAB
   8572 		  "rol %B0"         CR_TAB
   8573 		  "rol __tmp_reg__" CR_TAB
   8574 		  "mov %A0,%B0"     CR_TAB
   8575 		  "mov %B0,__tmp_reg__");
   8576 
   8577 	case 7:
   8578 	  *len = 5;
   8579 	  return ("lsl %A0"     CR_TAB
   8580 		  "mov %A0,%B0" CR_TAB
   8581 		  "rol %A0"     CR_TAB
   8582 		  "sbc %B0,%B0" CR_TAB
   8583 		  "neg %B0");
   8584 
   8585 	case 8:
   8586 	  return *len = 2, ("mov %A0,%B1" CR_TAB
   8587 			    "clr %B0");
   8588 
   8589 	case 9:
   8590 	  *len = 3;
   8591 	  return ("mov %A0,%B0" CR_TAB
   8592 		  "clr %B0"     CR_TAB
   8593 		  "lsr %A0");
   8594 
   8595 	case 10:
   8596 	  *len = 4;
   8597 	  return ("mov %A0,%B0" CR_TAB
   8598 		  "clr %B0"     CR_TAB
   8599 		  "lsr %A0"     CR_TAB
   8600 		  "lsr %A0");
   8601 
   8602 	case 11:
   8603 	  *len = 5;
   8604 	  return ("mov %A0,%B0" CR_TAB
   8605 		  "clr %B0"     CR_TAB
   8606 		  "lsr %A0"     CR_TAB
   8607 		  "lsr %A0"     CR_TAB
   8608 		  "lsr %A0");
   8609 
   8610 	case 12:
   8611 	  if (ldi_ok)
   8612 	    {
   8613 	      *len = 4;
   8614 	      return ("mov %A0,%B0" CR_TAB
   8615 		      "clr %B0"     CR_TAB
   8616 		      "swap %A0"    CR_TAB
   8617 		      "andi %A0,0x0f");
   8618 	    }
   8619 	  if (scratch)
   8620 	    {
   8621 	      *len = 5;
   8622 	      return ("mov %A0,%B0" CR_TAB
   8623 		      "clr %B0"     CR_TAB
   8624 		      "swap %A0"    CR_TAB
   8625 		      "ldi %3,0x0f" CR_TAB
   8626 		      "and %A0,%3");
   8627 	    }
   8628 	  *len = 6;
   8629 	  return ("mov %A0,%B0" CR_TAB
   8630 		  "clr %B0"     CR_TAB
   8631 		  "lsr %A0"     CR_TAB
   8632 		  "lsr %A0"     CR_TAB
   8633 		  "lsr %A0"     CR_TAB
   8634 		  "lsr %A0");
   8635 
   8636 	case 13:
   8637 	  if (ldi_ok)
   8638 	    {
   8639 	      *len = 5;
   8640 	      return ("mov %A0,%B0" CR_TAB
   8641 		      "clr %B0"     CR_TAB
   8642 		      "swap %A0"    CR_TAB
   8643 		      "lsr %A0"     CR_TAB
   8644 		      "andi %A0,0x07");
   8645 	    }
   8646 	  if (AVR_HAVE_MUL && scratch)
   8647 	    {
   8648 	      *len = 5;
   8649 	      return ("ldi %3,0x08" CR_TAB
   8650 		      "mul %B0,%3"  CR_TAB
   8651 		      "mov %A0,r1"  CR_TAB
   8652 		      "clr %B0"     CR_TAB
   8653 		      "clr __zero_reg__");
   8654 	    }
   8655 	  if (optimize_size && scratch)
   8656 	    break;  /* 5 */
   8657 	  if (scratch)
   8658 	    {
   8659 	      *len = 6;
   8660 	      return ("mov %A0,%B0" CR_TAB
   8661 		      "clr %B0"     CR_TAB
   8662 		      "swap %A0"    CR_TAB
   8663 		      "lsr %A0"     CR_TAB
   8664 		      "ldi %3,0x07" CR_TAB
   8665 		      "and %A0,%3");
   8666 	    }
   8667 	  if (AVR_HAVE_MUL)
   8668 	    {
   8669 	      *len = 6;
   8670 	      return ("set"        CR_TAB
   8671 		      "bld r1,3"   CR_TAB
   8672 		      "mul %B0,r1" CR_TAB
   8673 		      "mov %A0,r1" CR_TAB
   8674 		      "clr %B0"    CR_TAB
   8675 		      "clr __zero_reg__");
   8676 	    }
   8677 	  *len = 7;
   8678 	  return ("mov %A0,%B0" CR_TAB
   8679 		  "clr %B0"     CR_TAB
   8680 		  "lsr %A0"     CR_TAB
   8681 		  "lsr %A0"     CR_TAB
   8682 		  "lsr %A0"     CR_TAB
   8683 		  "lsr %A0"     CR_TAB
   8684 		  "lsr %A0");
   8685 
   8686 	case 14:
   8687 	  if (AVR_HAVE_MUL && ldi_ok)
   8688 	    {
   8689 	      *len = 5;
   8690 	      return ("ldi %A0,0x04" CR_TAB
   8691 		      "mul %B0,%A0"  CR_TAB
   8692 		      "mov %A0,r1"   CR_TAB
   8693 		      "clr %B0"      CR_TAB
   8694 		      "clr __zero_reg__");
   8695 	    }
   8696 	  if (AVR_HAVE_MUL && scratch)
   8697 	    {
   8698 	      *len = 5;
   8699 	      return ("ldi %3,0x04" CR_TAB
   8700 		      "mul %B0,%3"  CR_TAB
   8701 		      "mov %A0,r1"  CR_TAB
   8702 		      "clr %B0"     CR_TAB
   8703 		      "clr __zero_reg__");
   8704 	    }
   8705 	  if (optimize_size && ldi_ok)
   8706 	    {
   8707 	      *len = 5;
   8708 	      return ("mov %A0,%B0" CR_TAB
   8709 		      "ldi %B0,6" "\n1:\t"
   8710 		      "lsr %A0"     CR_TAB
   8711 		      "dec %B0"     CR_TAB
   8712 		      "brne 1b");
   8713 	    }
   8714 	  if (optimize_size && scratch)
   8715 	    break;  /* 5 */
   8716 	  *len = 6;
   8717 	  return ("clr %A0" CR_TAB
   8718 		  "lsl %B0" CR_TAB
   8719 		  "rol %A0" CR_TAB
   8720 		  "lsl %B0" CR_TAB
   8721 		  "rol %A0" CR_TAB
   8722 		  "clr %B0");
   8723 
   8724 	case 15:
   8725 	  *len = 4;
   8726 	  return ("bst %B1,7" CR_TAB
   8727 		  "clr %A0"   CR_TAB
   8728 		  "clr %B0"   CR_TAB
   8729 		  "bld %A0,0");
   8730 	}
   8731       len = t;
   8732     }
   8733   out_shift_with_cnt ("lsr %B0" CR_TAB
   8734 		      "ror %A0", insn, operands, len, 2);
   8735   return "";
   8736 }
   8737 
   8738 
   8739 /* 24-bit logic shift right */
   8740 
   8741 const char *
   8742 avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
   8743 {
   8744   int dest = REGNO (op[0]);
   8745   int src = REGNO (op[1]);
   8746 
   8747   if (CONST_INT_P (op[2]))
   8748     {
   8749       if (plen)
   8750 	*plen = 0;
   8751 
   8752       switch (INTVAL (op[2]))
   8753 	{
   8754 	case 8:
   8755 	  if (dest <= src)
   8756 	    return avr_asm_len ("mov %A0,%B1" CR_TAB
   8757 				"mov %B0,%C1" CR_TAB
   8758 				"clr %C0", op, plen, 3);
   8759 	  else
   8760 	    return avr_asm_len ("clr %C0"     CR_TAB
   8761 				"mov %B0,%C1" CR_TAB
   8762 				"mov %A0,%B1", op, plen, 3);
   8763 
   8764 	case 16:
   8765 	  if (dest != src + 2)
   8766 	    avr_asm_len ("mov %A0,%C1", op, plen, 1);
   8767 
   8768 	  return avr_asm_len ("clr %B0"  CR_TAB
   8769 			      "clr %C0", op, plen, 2);
   8770 
   8771 	default:
   8772 	  if (INTVAL (op[2]) < 24)
   8773 	    break;
   8774 
   8775 	  /* fall through */
   8776 
   8777 	case 23:
   8778 	  return avr_asm_len ("bst %C1,7" CR_TAB
   8779 			      "clr %A0"   CR_TAB
   8780 			      "clr %B0"   CR_TAB
   8781 			      "clr %C0"   CR_TAB
   8782 			      "bld %A0,0", op, plen, 5);
   8783 	} /* switch */
   8784     }
   8785 
   8786   out_shift_with_cnt ("lsr %C0" CR_TAB
   8787 		      "ror %B0" CR_TAB
   8788 		      "ror %A0", insn, op, plen, 3);
   8789   return "";
   8790 }
   8791 
   8792 
   8793 /* 32-bit logic shift right ((unsigned int)x >> i) */
   8794 
   8795 const char *
   8796 lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
   8797 {
   8798   if (CONST_INT_P (operands[2]))
   8799     {
   8800       int k;
   8801       int *t = len;
   8802 
   8803       if (!len)
   8804 	len = &k;
   8805 
   8806       switch (INTVAL (operands[2]))
   8807 	{
   8808 	default:
   8809 	  if (INTVAL (operands[2]) < 32)
   8810 	    break;
   8811 
   8812 	  if (AVR_HAVE_MOVW)
   8813 	    return *len = 3, ("clr %D0" CR_TAB
   8814 			      "clr %C0" CR_TAB
   8815 			      "movw %A0,%C0");
   8816 	  *len = 4;
   8817 	  return ("clr %D0" CR_TAB
   8818 		  "clr %C0" CR_TAB
   8819 		  "clr %B0" CR_TAB
   8820 		  "clr %A0");
   8821 
   8822 	case 8:
   8823 	  {
   8824 	    int reg0 = true_regnum (operands[0]);
   8825 	    int reg1 = true_regnum (operands[1]);
   8826 	    *len = 4;
   8827 	    if (reg0 <= reg1)
   8828 	      return ("mov %A0,%B1" CR_TAB
   8829 		      "mov %B0,%C1" CR_TAB
   8830 		      "mov %C0,%D1" CR_TAB
   8831 		      "clr %D0");
   8832 	    else
   8833 	      return ("clr %D0"     CR_TAB
   8834 		      "mov %C0,%D1" CR_TAB
   8835 		      "mov %B0,%C1" CR_TAB
   8836 		      "mov %A0,%B1");
   8837 	  }
   8838 
   8839 	case 16:
   8840 	  {
   8841 	    int reg0 = true_regnum (operands[0]);
   8842 	    int reg1 = true_regnum (operands[1]);
   8843 
   8844 	    if (reg0 == reg1 + 2)
   8845 	      return *len = 2, ("clr %C0"     CR_TAB
   8846 				"clr %D0");
   8847 	    if (AVR_HAVE_MOVW)
   8848 	      return *len = 3, ("movw %A0,%C1" CR_TAB
   8849 				"clr %C0"      CR_TAB
   8850 				"clr %D0");
   8851 	    else
   8852 	      return *len = 4, ("mov %B0,%D1" CR_TAB
   8853 				"mov %A0,%C1" CR_TAB
   8854 				"clr %C0"     CR_TAB
   8855 				"clr %D0");
   8856 	  }
   8857 
   8858 	case 24:
   8859 	  return *len = 4, ("mov %A0,%D1" CR_TAB
   8860 			    "clr %B0"     CR_TAB
   8861 			    "clr %C0"     CR_TAB
   8862 			    "clr %D0");
   8863 
   8864 	case 31:
   8865 	  if (AVR_HAVE_MOVW)
   8866 	    return *len = 5, ("bst %D1,7"    CR_TAB
   8867 			      "clr %A0"      CR_TAB
   8868 			      "clr %B0"      CR_TAB
   8869 			      "movw %C0,%A0" CR_TAB
   8870 			      "bld %A0,0");
   8871 	  *len = 6;
   8872 	  return ("bst %D1,7" CR_TAB
   8873 		  "clr %A0"   CR_TAB
   8874 		  "clr %B0"   CR_TAB
   8875 		  "clr %C0"   CR_TAB
   8876 		  "clr %D0"   CR_TAB
   8877 		  "bld %A0,0");
   8878 	}
   8879       len = t;
   8880     }
   8881   out_shift_with_cnt ("lsr %D0" CR_TAB
   8882 		      "ror %C0" CR_TAB
   8883 		      "ror %B0" CR_TAB
   8884 		      "ror %A0", insn, operands, len, 4);
   8885   return "";
   8886 }
   8887 
   8888 
   8889 /* Output addition of register XOP[0] and compile time constant XOP[2].
   8890    INSN is a single_set insn or an insn pattern.
   8891    CODE == PLUS:  perform addition by using ADD instructions or
   8892    CODE == MINUS: perform addition by using SUB instructions:
   8893 
   8894       XOP[0] = XOP[0] + XOP[2]
   8895 
   8896    Or perform addition/subtraction with register XOP[2] depending on CODE:
   8897 
   8898       XOP[0] = XOP[0] +/- XOP[2]
   8899 
   8900    If PLEN == NULL, print assembler instructions to perform the operation;
   8901    otherwise, set *PLEN to the length of the instruction sequence (in words)
   8902    printed with PLEN == NULL.  XOP[3] is an 8-bit scratch register or NULL_RTX.
   8903 
   8904    CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
   8905    CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
   8906    If  CODE_SAT != UNKNOWN  then SIGN contains the sign of the summand resp.
   8907    the subtrahend in the original insn, provided it is a compile time constant.
   8908    In all other cases, SIGN is 0.
   8909 
   8910    If OUT_LABEL is true, print the final 0: label which is needed for
   8911    saturated addition / subtraction.  The only case where OUT_LABEL = false
   8912    is useful is for saturated addition / subtraction performed during
   8913    fixed-point rounding, cf. `avr_out_round'.  */
   8914 
   8915 static void
   8916 avr_out_plus_1 (rtx insn, rtx *xop, int *plen, enum rtx_code code,
   8917 		enum rtx_code code_sat, int sign, bool out_label)
   8918 {
   8919   /* MODE of the operation.  */
   8920   machine_mode mode = GET_MODE (xop[0]);
   8921 
   8922   /* INT_MODE of the same size.  */
   8923   scalar_int_mode imode = int_mode_for_mode (mode).require ();
   8924 
   8925   /* Number of bytes to operate on.  */
   8926   int n_bytes = GET_MODE_SIZE (mode);
   8927 
   8928   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
   8929   int clobber_val = -1;
   8930 
   8931   /* op[0]: 8-bit destination register
   8932      op[1]: 8-bit const int
   8933      op[2]: 8-bit scratch register */
   8934   rtx op[3];
   8935 
   8936   /* Started the operation?  Before starting the operation we may skip
   8937      adding 0.  This is no more true after the operation started because
   8938      carry must be taken into account.  */
   8939   bool started = false;
   8940 
   8941   /* Value to add.  There are two ways to add VAL: R += VAL and R -= -VAL.  */
   8942   rtx xval = xop[2];
   8943 
   8944   /* Output a BRVC instruction.  Only needed with saturation.  */
   8945   bool out_brvc = true;
   8946 
   8947   if (plen)
   8948     *plen = 0;
   8949 
   8950   if (REG_P (xop[2]))
   8951     {
   8952       for (int i = 0; i < n_bytes; i++)
   8953 	{
   8954 	  /* We operate byte-wise on the destination.  */
   8955 	  op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
   8956 	  op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
   8957 
   8958 	  if (i == 0)
   8959 	    avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
   8960 			 op, plen, 1);
   8961 	  else
   8962 	    avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
   8963 			 op, plen, 1);
   8964 	}
   8965 
   8966       if (reg_overlap_mentioned_p (xop[0], xop[2]))
   8967 	{
   8968 	  gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
   8969 
   8970 	  if (MINUS == code)
   8971 	    return;
   8972 	}
   8973 
   8974       goto saturate;
   8975     }
   8976 
   8977   if (CONST_FIXED_P (xval))
   8978     xval = avr_to_int_mode (xval);
   8979 
   8980   /* Adding/Subtracting zero is a no-op.  */
   8981 
   8982   if (xval == const0_rtx)
   8983     return;
   8984 
   8985   if (MINUS == code)
   8986     xval = simplify_unary_operation (NEG, imode, xval, imode);
   8987 
   8988   op[2] = xop[3];
   8989 
   8990   if (SS_PLUS == code_sat && MINUS == code
   8991       && sign < 0
   8992       && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
   8993 		  & GET_MODE_MASK (QImode)))
   8994     {
   8995       /* We compute x + 0x80 by means of SUB instructions.  We negated the
   8996 	 constant subtrahend above and are left with  x - (-128)  so that we
   8997 	 need something like SUBI r,128 which does not exist because SUBI sets
   8998 	 V according to the sign of the subtrahend.  Notice the only case
   8999 	 where this must be done is when NEG overflowed in case [2s] because
   9000 	 the V computation needs the right sign of the subtrahend.  */
   9001 
   9002       rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes - 1);
   9003 
   9004       avr_asm_len ("subi %0,128" CR_TAB
   9005 		   "brmi 0f", &msb, plen, 2);
   9006       out_brvc = false;
   9007 
   9008       goto saturate;
   9009     }
   9010 
   9011   for (int i = 0; i < n_bytes; i++)
   9012     {
   9013       /* We operate byte-wise on the destination.  */
   9014       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
   9015       rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
   9016 
   9017       /* 8-bit value to operate with this byte. */
   9018       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
   9019 
   9020       /* Registers R16..R31 can operate with immediate.  */
   9021       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
   9022 
   9023       op[0] = reg8;
   9024       op[1] = gen_int_mode (val8, QImode);
   9025 
   9026       /* To get usable cc0 no low-bytes must have been skipped.  */
   9027 
   9028       if (!started
   9029 	  && i % 2 == 0
   9030 	  && i + 2 <= n_bytes
   9031 	  && avr_adiw_reg_p (reg8))
   9032 	{
   9033 	  rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
   9034 	  unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
   9035 
   9036 	  /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
   9037 	     i.e. operate word-wise.  */
   9038 
   9039 	  if (val16 < 64)
   9040 	    {
   9041 	      if (val16 != 0)
   9042 		{
   9043 		  started = true;
   9044 		  avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
   9045 			       op, plen, 1);
   9046 		}
   9047 
   9048 	      i++;
   9049 	      continue;
   9050 	    }
   9051 	}
   9052 
   9053       if (AVR_TINY
   9054 	  && optimize
   9055 	  && i == 0
   9056 	  && n_bytes == 2
   9057 	  // When that pass adjusts the frame pointer, then we know that
   9058 	  // reg Y points to ordinary memory, and the only side-effect
   9059 	  // of -Y and Y+ is the side effect on Y.
   9060 	  && avr_fuse_add >= 2
   9061 	  && frame_pointer_needed
   9062 	  && REGNO (xop[0]) == FRAME_POINTER_REGNUM)
   9063 	{
   9064 	  if (INSN_P (insn)
   9065 	      && _reg_unused_after (as_a <rtx_insn *> (insn), xop[0], false))
   9066 	    return;
   9067 
   9068 	  if (AVR_HAVE_8BIT_SP)
   9069 	    {
   9070 	      avr_asm_len ("subi %A0,%n2", xop, plen, 1);
   9071 	      return;
   9072 	    }
   9073 	  else if (xop[2] == const1_rtx || xop[2] == constm1_rtx)
   9074 	    {
   9075 	      avr_asm_len (xop[2] == const1_rtx
   9076 			   ? "ld __tmp_reg__,%a0+"
   9077 			   : "ld __tmp_reg__,-%a0", xop, plen, 1);
   9078 	      return;
   9079 	    }
   9080 	}
   9081 
   9082       if (val8 == 0)
   9083 	{
   9084 	  if (started)
   9085 	    avr_asm_len (code == PLUS
   9086 			 ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
   9087 			 op, plen, 1);
   9088 	  continue;
   9089 	}
   9090       else if ((val8 == 1 || val8 == 0xff)
   9091 	       && UNKNOWN == code_sat
   9092 	       && !started
   9093 	       && i == n_bytes - 1)
   9094 	{
   9095 	  avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
   9096 		       op, plen, 1);
   9097 	  break;
   9098 	}
   9099 
   9100       switch (code)
   9101 	{
   9102 	case PLUS:
   9103 
   9104 	  gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
   9105 
   9106 	  if (plen != NULL && UNKNOWN != code_sat)
   9107 	    {
   9108 	      /* This belongs to the x + 0x80 corner case.  The code with
   9109 		 ADD instruction is not smaller, thus make this case
   9110 		 expensive so that the caller won't pick it.  */
   9111 
   9112 	      *plen += 10;
   9113 	      break;
   9114 	    }
   9115 
   9116 	  if (clobber_val != (int) val8)
   9117 	    avr_asm_len ("ldi %2,%1", op, plen, 1);
   9118 	  clobber_val = (int) val8;
   9119 
   9120 	  avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
   9121 
   9122 	  break; /* PLUS */
   9123 
   9124 	case MINUS:
   9125 
   9126 	  if (ld_reg_p)
   9127 	    avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
   9128 	  else
   9129 	    {
   9130 	      gcc_assert (plen != NULL || REG_P (op[2]));
   9131 
   9132 	      if (clobber_val != (int) val8)
   9133 		avr_asm_len ("ldi %2,%1", op, plen, 1);
   9134 	      clobber_val = (int) val8;
   9135 
   9136 	      avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
   9137 	    }
   9138 
   9139 	  break; /* MINUS */
   9140 
   9141 	default:
   9142 	  /* Unknown code */
   9143 	  gcc_unreachable();
   9144 	}
   9145 
   9146       started = true;
   9147 
   9148     } /* for all sub-bytes */
   9149 
   9150  saturate:
   9151 
   9152   if (UNKNOWN == code_sat)
   9153     return;
   9154 
   9155   /* Vanilla addition/subtraction is done.  We are left with saturation.
   9156 
   9157      We have to compute  A = A <op> B  where  A  is a register and
   9158      B is a register or a non-zero compile time constant CONST.
   9159      A is register class "r" if unsigned && B is REG.  Otherwise, A is in "d".
   9160      B stands for the original operand $2 in INSN.  In the case of B = CONST,
   9161      SIGN in { -1, 1 } is the sign of B.  Otherwise, SIGN is 0.
   9162 
   9163      CODE is the instruction flavor we use in the asm sequence to perform <op>.
   9164 
   9165 
   9166      unsigned
   9167      operation        |  code |  sat if  |    b is      | sat value |  case
   9168      -----------------+-------+----------+--------------+-----------+-------
   9169      +  as  a + b     |  add  |  C == 1  |  const, reg  | u+ = 0xff |  [1u]
   9170      +  as  a - (-b)  |  sub  |  C == 0  |  const       | u+ = 0xff |  [2u]
   9171      -  as  a - b     |  sub  |  C == 1  |  const, reg  | u- = 0    |  [3u]
   9172      -  as  a + (-b)  |  add  |  C == 0  |  const       | u- = 0    |  [4u]
   9173 
   9174 
   9175      signed
   9176      operation        |  code |  sat if  |    b is      | sat value |  case
   9177      -----------------+-------+----------+--------------+-----------+-------
   9178      +  as  a + b     |  add  |  V == 1  |  const, reg  | s+        |  [1s]
   9179      +  as  a - (-b)  |  sub  |  V == 1  |  const       | s+        |  [2s]
   9180      -  as  a - b     |  sub  |  V == 1  |  const, reg  | s-        |  [3s]
   9181      -  as  a + (-b)  |  add  |  V == 1  |  const       | s-        |  [4s]
   9182 
   9183      s+  =  b < 0  ?  -0x80 :  0x7f
   9184      s-  =  b < 0  ?   0x7f : -0x80
   9185 
   9186      The cases a - b actually perform  a - (-(-b))  if B is CONST.
   9187   */
   9188 
   9189   op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
   9190   op[1] = n_bytes > 1
   9191     ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
   9192     : NULL_RTX;
   9193 
   9194   bool need_copy = true;
   9195   int len_call = 1 + AVR_HAVE_JMP_CALL;
   9196 
   9197   switch (code_sat)
   9198     {
   9199     default:
   9200       gcc_unreachable();
   9201 
   9202     case SS_PLUS:
   9203     case SS_MINUS:
   9204 
   9205       if (out_brvc)
   9206 	avr_asm_len ("brvc 0f", op, plen, 1);
   9207 
   9208       if (reg_overlap_mentioned_p (xop[0], xop[2]))
   9209 	{
   9210 	  /* [1s,reg] */
   9211 
   9212 	  if (n_bytes == 1)
   9213 	    avr_asm_len ("ldi %0,0x7f" CR_TAB
   9214 			 "adc %0,__zero_reg__", op, plen, 2);
   9215 	  else
   9216 	    avr_asm_len ("ldi %0,0x7f" CR_TAB
   9217 			 "ldi %1,0xff" CR_TAB
   9218 			 "adc %1,__zero_reg__" CR_TAB
   9219 			 "adc %0,__zero_reg__", op, plen, 4);
   9220 	}
   9221       else if (sign == 0 && PLUS == code)
   9222 	{
   9223 	  /* [1s,reg] */
   9224 
   9225 	  op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
   9226 
   9227 	  if (n_bytes == 1)
   9228 	    avr_asm_len ("ldi %0,0x80" CR_TAB
   9229 			 "sbrs %2,7"   CR_TAB
   9230 			 "dec %0", op, plen, 3);
   9231 	  else
   9232 	    avr_asm_len ("ldi %0,0x80" CR_TAB
   9233 			 "cp %2,%0"    CR_TAB
   9234 			 "sbc %1,%1"   CR_TAB
   9235 			 "sbci %0,0", op, plen, 4);
   9236 	}
   9237       else if (sign == 0 && MINUS == code)
   9238 	{
   9239 	  /* [3s,reg] */
   9240 
   9241 	  op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
   9242 
   9243 	  if (n_bytes == 1)
   9244 	    avr_asm_len ("ldi %0,0x7f" CR_TAB
   9245 			 "sbrs %2,7"   CR_TAB
   9246 			 "inc %0", op, plen, 3);
   9247 	  else
   9248 	    avr_asm_len ("ldi %0,0x7f" CR_TAB
   9249 			 "cp %0,%2"    CR_TAB
   9250 			 "sbc %1,%1"   CR_TAB
   9251 			 "sbci %0,-1", op, plen, 4);
   9252 	}
   9253       else if ((sign < 0) ^ (SS_MINUS == code_sat))
   9254 	{
   9255 	  /* [1s,const,B < 0] [2s,B < 0] */
   9256 	  /* [3s,const,B > 0] [4s,B > 0] */
   9257 
   9258 	  if (n_bytes == 8)
   9259 	    {
   9260 	      avr_asm_len ("%~call __clr_8", op, plen, len_call);
   9261 	      need_copy = false;
   9262 	    }
   9263 
   9264 	  avr_asm_len ("ldi %0,0x80", op, plen, 1);
   9265 	  if (n_bytes > 1 && need_copy)
   9266 	    avr_asm_len ("clr %1", op, plen, 1);
   9267 	}
   9268       else if ((sign > 0) ^ (SS_MINUS == code_sat))
   9269 	{
   9270 	  /* [1s,const,B > 0] [2s,B > 0] */
   9271 	  /* [3s,const,B < 0] [4s,B < 0] */
   9272 
   9273 	  if (n_bytes == 8)
   9274 	    {
   9275 	      avr_asm_len ("sec" CR_TAB
   9276 			   "%~call __sbc_8", op, plen, 1 + len_call);
   9277 	      need_copy = false;
   9278 	    }
   9279 
   9280 	  avr_asm_len ("ldi %0,0x7f", op, plen, 1);
   9281 	  if (n_bytes > 1 && need_copy)
   9282 	    avr_asm_len ("ldi %1,0xff", op, plen, 1);
   9283 	}
   9284       else
   9285 	gcc_unreachable();
   9286 
   9287       break;
   9288 
   9289     case US_PLUS:
   9290       /* [1u] : [2u] */
   9291 
   9292       avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
   9293 
   9294       if (n_bytes == 8)
   9295 	{
   9296 	  if (MINUS == code)
   9297 	    avr_asm_len ("sec", op, plen, 1);
   9298 	  avr_asm_len ("%~call __sbc_8", op, plen, len_call);
   9299 
   9300 	  need_copy = false;
   9301 	}
   9302       else
   9303 	{
   9304 	  if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
   9305 	    avr_asm_len ("sec" CR_TAB
   9306 			 "sbc %0,%0", op, plen, 2);
   9307 	  else
   9308 	    avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
   9309 			 op, plen, 1);
   9310 	}
   9311       break; /* US_PLUS */
   9312 
   9313     case US_MINUS:
   9314       /* [4u] : [3u] */
   9315 
   9316       avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
   9317 
   9318       if (n_bytes == 8)
   9319 	{
   9320 	  avr_asm_len ("%~call __clr_8", op, plen, len_call);
   9321 	  need_copy = false;
   9322 	}
   9323       else
   9324 	avr_asm_len ("clr %0", op, plen, 1);
   9325 
   9326       break;
   9327     }
   9328 
   9329   /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
   9330      Now copy the right value to the LSBs.  */
   9331 
   9332   if (need_copy && n_bytes > 1)
   9333     {
   9334       if (US_MINUS == code_sat || US_PLUS == code_sat)
   9335 	{
   9336 	  avr_asm_len ("mov %1,%0", op, plen, 1);
   9337 
   9338 	  if (n_bytes > 2)
   9339 	    {
   9340 	      op[0] = xop[0];
   9341 	      if (AVR_HAVE_MOVW)
   9342 		avr_asm_len ("movw %0,%1", op, plen, 1);
   9343 	      else
   9344 		avr_asm_len ("mov %A0,%1" CR_TAB
   9345 			     "mov %B0,%1", op, plen, 2);
   9346 	    }
   9347 	}
   9348       else if (n_bytes > 2)
   9349 	{
   9350 	  op[0] = xop[0];
   9351 	  avr_asm_len ("mov %A0,%1" CR_TAB
   9352 		       "mov %B0,%1", op, plen, 2);
   9353 	}
   9354     }
   9355 
   9356   if (need_copy && n_bytes == 8)
   9357     {
   9358       if (AVR_HAVE_MOVW)
   9359 	avr_asm_len ("movw %r0+2,%0" CR_TAB
   9360 		     "movw %r0+4,%0", xop, plen, 2);
   9361       else
   9362 	avr_asm_len ("mov %r0+2,%0" CR_TAB
   9363 		     "mov %r0+3,%0" CR_TAB
   9364 		     "mov %r0+4,%0" CR_TAB
   9365 		     "mov %r0+5,%0", xop, plen, 4);
   9366     }
   9367 
   9368   if (out_label)
   9369     avr_asm_len ("0:", op, plen, 0);
   9370 }
   9371 
   9372 
   9373 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
   9374    is not a compile-time constant:
   9375 
   9376       XOP[0] = XOP[0] +/- XOP[2]
   9377 
   9378    This is a helper for the function below.  The only insns that need this
   9379    are additions/subtraction for pointer modes, i.e. HImode and PSImode.  */
   9380 
   9381 static const char *
   9382 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen)
   9383 {
   9384   machine_mode mode = GET_MODE (xop[0]);
   9385 
   9386   /* Only pointer modes want to add symbols.  */
   9387 
   9388   gcc_assert (mode == HImode || mode == PSImode);
   9389 
   9390   avr_asm_len (PLUS == code
   9391 	       ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
   9392 	       : "subi %A0,lo8(%2)"    CR_TAB "sbci %B0,hi8(%2)",
   9393 	       xop, plen, -2);
   9394 
   9395   if (PSImode == mode)
   9396     avr_asm_len (PLUS == code
   9397 		 ? "sbci %C0,hlo8(-(%2))"
   9398 		 : "sbci %C0,hlo8(%2)", xop, plen, 1);
   9399   return "";
   9400 }
   9401 
   9402 
   9403 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
   9404 
   9405    INSN is a single_set insn or an insn pattern with a binary operation as
   9406    SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
   9407 
   9408    XOP are the operands of INSN.  In the case of 64-bit operations with
   9409    constant XOP[] has just one element:  The summand/subtrahend in XOP[0].
   9410    The non-saturating insns up to 32 bits may or may not supply a "d" class
   9411    scratch as XOP[3].
   9412 
   9413    If PLEN == NULL output the instructions.
   9414    If PLEN != NULL set *PLEN to the length of the sequence in words.
   9415 
   9416    PLEN defaults to NULL.
   9417 
   9418    OUT_LABEL defaults to TRUE.  For a description, see AVR_OUT_PLUS_1.
   9419 
   9420    Return ""  */
   9421 
   9422 const char *
   9423 avr_out_plus (rtx insn, rtx *xop, int *plen, bool out_label)
   9424 {
   9425   int len_plus, len_minus;
   9426   rtx op[4];
   9427   rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
   9428   rtx xdest = SET_DEST (xpattern);
   9429   machine_mode mode = GET_MODE (xdest);
   9430   scalar_int_mode imode = int_mode_for_mode (mode).require ();
   9431   int n_bytes = GET_MODE_SIZE (mode);
   9432   enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
   9433   enum rtx_code code
   9434     = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
   9435        ? PLUS : MINUS);
   9436 
   9437   /* PLUS and MINUS don't saturate:  Use modular wrap-around.  */
   9438 
   9439   if (PLUS == code_sat || MINUS == code_sat)
   9440     code_sat = UNKNOWN;
   9441 
   9442   if (n_bytes <= 4 && REG_P (xop[2]))
   9443     {
   9444       avr_out_plus_1 (insn, xop, plen, code, code_sat, 0, out_label);
   9445       return "";
   9446     }
   9447 
   9448   if (n_bytes == 8)
   9449     {
   9450       op[0] = gen_rtx_REG (DImode, ACC_A);
   9451       op[1] = gen_rtx_REG (DImode, ACC_A);
   9452       op[2] = avr_to_int_mode (xop[0]);
   9453     }
   9454   else
   9455     {
   9456       if (!REG_P (xop[2])
   9457 	  && !CONST_INT_P (xop[2])
   9458 	  && !CONST_FIXED_P (xop[2]))
   9459 	{
   9460 	  return avr_out_plus_symbol (xop, code, plen);
   9461 	}
   9462 
   9463       op[0] = avr_to_int_mode (xop[0]);
   9464       op[1] = avr_to_int_mode (xop[1]);
   9465       op[2] = avr_to_int_mode (xop[2]);
   9466     }
   9467 
   9468   /* Saturations and 64-bit operations don't have a clobber operand.
   9469      For the other cases, the caller will provide a proper XOP[3].  */
   9470 
   9471   xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
   9472   op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
   9473 
   9474   /* Saturation will need the sign of the original operand.  */
   9475 
   9476   rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
   9477   int sign = INTVAL (xmsb) < 0 ? -1 : 1;
   9478 
   9479   /* If we subtract and the subtrahend is a constant, then negate it
   9480      so that avr_out_plus_1 can be used.  */
   9481 
   9482   if (MINUS == code)
   9483     op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
   9484 
   9485   /* Work out the shortest sequence.  */
   9486 
   9487   avr_out_plus_1 (insn, op, &len_minus, MINUS, code_sat, sign, out_label);
   9488   avr_out_plus_1 (insn, op, &len_plus, PLUS, code_sat, sign, out_label);
   9489 
   9490   if (plen)
   9491     *plen = (len_minus <= len_plus) ? len_minus : len_plus;
   9492   else if (len_minus <= len_plus)
   9493     avr_out_plus_1 (insn, op, NULL, MINUS, code_sat, sign, out_label);
   9494   else
   9495     avr_out_plus_1 (insn, op, NULL, PLUS, code_sat, sign, out_label);
   9496 
   9497   return "";
   9498 }
   9499 
   9500 
   9501 /* Output an instruction sequence for addition of REG in XOP[0] and CONST_INT
   9502    in XOP[1] in such a way that SREG.Z and SREG.N are set according to the
   9503    result.  XOP[2] might be a d-regs clobber register.  If XOP[2] is SCRATCH,
   9504    then the addition can be performed without a clobber reg.  Return "".
   9505 
   9506    If PLEN == NULL, then output the instructions.
   9507    If PLEN != NULL, then set *PLEN to the length of the sequence in words. */
   9508 
   9509 const char *
   9510 avr_out_plus_set_ZN (rtx *xop, int *plen)
   9511 {
   9512   if (plen)
   9513     *plen = 0;
   9514 
   9515   // Register to compare and value to compare against.
   9516   rtx xreg = xop[0];
   9517   rtx xval = xop[1];
   9518 
   9519   machine_mode mode = GET_MODE (xreg);
   9520 
   9521   // Number of bytes to operate on.
   9522   int n_bytes = GET_MODE_SIZE (mode);
   9523 
   9524   if (n_bytes == 1)
   9525     {
   9526       if (INTVAL (xval) == 1)
   9527 	return avr_asm_len ("inc %0", xop, plen, 1);
   9528 
   9529       if (INTVAL (xval) == -1)
   9530 	return avr_asm_len ("dec %0", xop, plen, 1);
   9531     }
   9532 
   9533   if (n_bytes == 2
   9534       && avr_adiw_reg_p (xreg)
   9535       && IN_RANGE (INTVAL (xval), 1, 63))
   9536     {
   9537       // Add 16-bit value in [1..63] to a w register.
   9538       return avr_asm_len ("adiw %0, %1", xop, plen, 1);
   9539     }
   9540 
   9541   // Addition won't work; subtract the negative of XVAL instead.
   9542   xval = simplify_unary_operation (NEG, mode, xval, mode);
   9543 
   9544   // Value (0..0xff) held in clobber register xop[2] or -1 if unknown.
   9545   int clobber_val = -1;
   9546 
   9547   // [0] = Current sub-register.
   9548   // [1] = Current partial xval.
   9549   // [2] = 8-bit clobber d-register or SCRATCH.
   9550   rtx op[3];
   9551   op[2] = xop[2];
   9552 
   9553   // Work byte-wise from LSB to MSB.  The lower two bytes might be
   9554   // SBIW'ed in one go.
   9555   for (int i = 0; i < n_bytes; ++i)
   9556     {
   9557       op[0] = simplify_gen_subreg (QImode, xreg, mode, i);
   9558 
   9559       if (i == 0
   9560 	  && n_bytes >= 2
   9561 	  && avr_adiw_reg_p (op[0]))
   9562 	{
   9563 	  op[1] = simplify_gen_subreg (HImode, xval, mode, 0);
   9564 	  if (IN_RANGE (INTVAL (op[1]), 0, 63))
   9565 	    {
   9566 	      // SBIW can handle the lower 16 bits.
   9567 	      avr_asm_len ("sbiw %0, %1", op, plen, 1);
   9568 
   9569 	      // Next byte has already been handled: Skip it.
   9570 	      ++i;
   9571 	      continue;
   9572 	    }
   9573 	}
   9574 
   9575       op[1] = simplify_gen_subreg (QImode, xval, mode, i);
   9576 
   9577       if (test_hard_reg_class (LD_REGS, op[0]))
   9578 	{
   9579 	  // d-regs can subtract immediates.
   9580 	  avr_asm_len (i == 0
   9581 		       ? "subi %0, %1"
   9582 		       : "sbci %0, %1", op, plen, 1);
   9583 	}
   9584       else
   9585 	{
   9586 	  int val8 = 0xff & INTVAL (op[1]);
   9587 	  if (val8 == 0)
   9588 	    {
   9589 	      // Any register can subtract 0.
   9590 	      avr_asm_len (i == 0
   9591 			   ? "sub %0, __zero_reg__"
   9592 			   : "sbc %0, __zero_reg__", op, plen, 1);
   9593 	    }
   9594 	  else
   9595 	    {
   9596 	      // Use d-register to hold partial xval.
   9597 
   9598 	      if (val8 != clobber_val)
   9599 		{
   9600 		  // Load partial xval to QI clobber reg and memoize for later.
   9601 		  gcc_assert (REG_P (op[2]));
   9602 		  avr_asm_len ("ldi %2, %1", op, plen, 1);
   9603 		  clobber_val = val8;
   9604 		}
   9605 
   9606 	      avr_asm_len (i == 0
   9607 			   ? "sub %0, %2"
   9608 			   : "sbc %0, %2", op, plen, 1);
   9609 	    }
   9610 	}
   9611     } // Loop bytes.
   9612 
   9613   return "";
   9614 }
   9615 
   9616 
   9617 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
   9618    time constant XOP[2]:
   9619 
   9620       XOP[0] = XOP[0] <op> XOP[2]
   9621 
   9622    and return "".  If PLEN == NULL, print assembler instructions to perform the
   9623    operation; otherwise, set *PLEN to the length of the instruction sequence
   9624    (in words) printed with PLEN == NULL.  XOP[3] is either an 8-bit clobber
   9625    register or SCRATCH if no clobber register is needed for the operation.
   9626    INSN is an INSN_P or a pattern of an insn.  */
   9627 
   9628 const char *
   9629 avr_out_bitop (rtx insn, rtx *xop, int *plen)
   9630 {
   9631   /* CODE and MODE of the operation.  */
   9632   rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
   9633   enum rtx_code code = GET_CODE (SET_SRC (xpattern));
   9634   machine_mode mode = GET_MODE (xop[0]);
   9635 
   9636   /* Number of bytes to operate on.  */
   9637   int n_bytes = GET_MODE_SIZE (mode);
   9638 
   9639   /* Value of T-flag (0 or 1) or -1 if unknow.  */
   9640   int set_t = -1;
   9641 
   9642   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
   9643   int clobber_val = -1;
   9644 
   9645   /* op[0]: 8-bit destination register
   9646      op[1]: 8-bit const int
   9647      op[2]: 8-bit clobber register, SCRATCH or NULL_RTX.
   9648      op[3]: 8-bit register containing 0xff or NULL_RTX  */
   9649   rtx op[4];
   9650 
   9651   op[2] = QImode == mode ? NULL_RTX : xop[3];
   9652   op[3] = NULL_RTX;
   9653 
   9654   if (plen)
   9655     *plen = 0;
   9656 
   9657   for (int i = 0; i < n_bytes; i++)
   9658     {
   9659       /* We operate byte-wise on the destination.  */
   9660       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
   9661       rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
   9662 
   9663       /* 8-bit value to operate with this byte. */
   9664       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
   9665 
   9666       /* Number of bits set in the current byte of the constant.  */
   9667       int pop8 = popcount_hwi (val8);
   9668 
   9669       /* Registers R16..R31 can operate with immediate.  */
   9670       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
   9671 
   9672       op[0] = reg8;
   9673       op[1] = GEN_INT (val8);
   9674 
   9675       switch (code)
   9676 	{
   9677 	case IOR:
   9678 
   9679 	  if (pop8 == 0)
   9680 	    continue;
   9681 	  else if (ld_reg_p)
   9682 	    avr_asm_len ("ori %0,%1", op, plen, 1);
   9683 	  else if (pop8 == 1)
   9684 	    {
   9685 	      if (set_t != 1)
   9686 		avr_asm_len ("set", op, plen, 1);
   9687 	      set_t = 1;
   9688 
   9689 	      op[1] = GEN_INT (exact_log2 (val8));
   9690 	      avr_asm_len ("bld %0,%1", op, plen, 1);
   9691 	    }
   9692 	  else if (pop8 == 8)
   9693 	    {
   9694 	      if (op[3] != NULL_RTX)
   9695 		avr_asm_len ("mov %0,%3", op, plen, 1);
   9696 	      else
   9697 		avr_asm_len ("clr %0" CR_TAB
   9698 			     "dec %0", op, plen, 2);
   9699 
   9700 	      op[3] = op[0];
   9701 	    }
   9702 	  else
   9703 	    {
   9704 	      if (clobber_val != (int) val8)
   9705 		avr_asm_len ("ldi %2,%1", op, plen, 1);
   9706 	      clobber_val = (int) val8;
   9707 
   9708 	      avr_asm_len ("or %0,%2", op, plen, 1);
   9709 	    }
   9710 
   9711 	  continue; /* IOR */
   9712 
   9713 	case AND:
   9714 
   9715 	  if (pop8 == 8)
   9716 	    continue;
   9717 	  else if (pop8 == 0)
   9718 	    avr_asm_len ("clr %0", op, plen, 1);
   9719 	  else if (ld_reg_p)
   9720 	    avr_asm_len ("andi %0,%1", op, plen, 1);
   9721 	  else if (pop8 == 7)
   9722 	    {
   9723 	      if (set_t != 0)
   9724 		avr_asm_len ("clt", op, plen, 1);
   9725 	      set_t = 0;
   9726 
   9727 	      op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
   9728 	      avr_asm_len ("bld %0,%1", op, plen, 1);
   9729 	    }
   9730 	  else
   9731 	    {
   9732 	      if (clobber_val != (int) val8)
   9733 		avr_asm_len ("ldi %2,%1", op, plen, 1);
   9734 	      clobber_val = (int) val8;
   9735 
   9736 	      avr_asm_len ("and %0,%2", op, plen, 1);
   9737 	    }
   9738 
   9739 	  continue; /* AND */
   9740 
   9741 	case XOR:
   9742 
   9743 	  if (pop8 == 0)
   9744 	    continue;
   9745 	  else if (pop8 == 8)
   9746 	    avr_asm_len ("com %0", op, plen, 1);
   9747 	  else if (ld_reg_p && val8 == (1 << 7))
   9748 	    avr_asm_len ("subi %0,%1", op, plen, 1);
   9749 	  else
   9750 	    {
   9751 	      if (clobber_val != (int) val8)
   9752 		avr_asm_len ("ldi %2,%1", op, plen, 1);
   9753 	      clobber_val = (int) val8;
   9754 
   9755 	      avr_asm_len ("eor %0,%2", op, plen, 1);
   9756 	    }
   9757 
   9758 	  continue; /* XOR */
   9759 
   9760 	default:
   9761 	  /* Unknown rtx_code */
   9762 	  gcc_unreachable();
   9763 	}
   9764     } /* for all sub-bytes */
   9765 
   9766   return "";
   9767 }
   9768 
   9769 
   9770 /* Output sign extension from XOP[1] to XOP[0] and return "".
   9771    If PLEN == NULL, print assembler instructions to perform the operation;
   9772    otherwise, set *PLEN to the length of the instruction sequence (in words)
   9773    as printed with PLEN == NULL.  */
   9774 
   9775 const char *
   9776 avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen)
   9777 {
   9778   // Size in bytes of source resp. destination operand.
   9779   unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1]));
   9780   unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0]));
   9781   rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1];
   9782 
   9783   if (plen)
   9784     *plen = 0;
   9785 
   9786   // Copy destination to source
   9787 
   9788   if (REGNO (xop[0]) != REGNO (xop[1]))
   9789     {
   9790       gcc_assert (n_src <= 2);
   9791 
   9792       if (n_src == 2)
   9793 	avr_asm_len (AVR_HAVE_MOVW
   9794 		     ? "movw %0,%1"
   9795 		     : "mov %B0,%B1", xop, plen, 1);
   9796       if (n_src == 1 || !AVR_HAVE_MOVW)
   9797 	avr_asm_len ("mov %A0,%A1", xop, plen, 1);
   9798     }
   9799 
   9800   // Set Carry to the sign bit MSB.7...
   9801 
   9802   if (REGNO (xop[0]) == REGNO (xop[1])
   9803       || !reg_unused_after (insn, r_msb))
   9804     {
   9805       avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1);
   9806       r_msb = tmp_reg_rtx;
   9807     }
   9808 
   9809   avr_asm_len ("lsl %0", &r_msb, plen, 1);
   9810 
   9811   // ...and propagate it to all the new sign bits
   9812 
   9813   for (unsigned n = n_src; n < n_dest; n++)
   9814     avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1);
   9815 
   9816   return "";
   9817 }
   9818 
   9819 
   9820 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
   9821    PLEN != NULL: Set *PLEN to the length of that sequence.
   9822    Return "".  */
   9823 
   9824 const char *
   9825 avr_out_addto_sp (rtx *op, int *plen)
   9826 {
   9827   int pc_len = AVR_2_BYTE_PC ? 2 : 3;
   9828   int addend = INTVAL (op[0]);
   9829 
   9830   if (plen)
   9831     *plen = 0;
   9832 
   9833   if (addend < 0)
   9834     {
   9835       if (flag_verbose_asm || flag_print_asm_name)
   9836 	avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
   9837 
   9838       while (addend <= -pc_len)
   9839 	{
   9840 	  addend += pc_len;
   9841 	  avr_asm_len ("rcall .", op, plen, 1);
   9842 	}
   9843 
   9844       while (addend++ < 0)
   9845 	avr_asm_len ("push __tmp_reg__", op, plen, 1);
   9846     }
   9847   else if (addend > 0)
   9848     {
   9849       if (flag_verbose_asm || flag_print_asm_name)
   9850 	avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
   9851 
   9852       while (addend-- > 0)
   9853 	avr_asm_len ("pop __tmp_reg__", op, plen, 1);
   9854     }
   9855 
   9856   return "";
   9857 }
   9858 
   9859 
   9860 /* Output instructions to insert an inverted bit into OP[0]: $0.$1 = ~$2.$3.
   9861    If PLEN = NULL then output the respective instruction sequence which
   9862    is a combination of BST / BLD and some instruction(s) to invert the bit.
   9863    If PLEN != NULL then store the length of the sequence (in words) in *PLEN.
   9864    Return "".  */
   9865 
   9866 const char *
   9867 avr_out_insert_notbit (rtx_insn *insn, rtx op[], int *plen)
   9868 {
   9869   if (INTVAL (op[1]) == 7
   9870       && test_hard_reg_class (LD_REGS, op[0]))
   9871     {
   9872       /* If the inserted bit number is 7 and we have a d-reg, then invert
   9873 	 the bit after the insertion by means of SUBI *,0x80.  */
   9874 
   9875       if (INTVAL (op[3]) == 7
   9876 	  && REGNO (op[0]) == REGNO (op[2]))
   9877 	{
   9878 	  avr_asm_len ("subi %0,0x80", op, plen, -1);
   9879 	}
   9880       else
   9881 	{
   9882 	  avr_asm_len ("bst %2,%3" CR_TAB
   9883 		       "bld %0,%1" CR_TAB
   9884 		       "subi %0,0x80", op, plen, -3);
   9885 	}
   9886     }
   9887   else if (test_hard_reg_class (LD_REGS, op[0])
   9888 	   && (INTVAL (op[1]) != INTVAL (op[3])
   9889 	       || !reg_overlap_mentioned_p (op[0], op[2])))
   9890     {
   9891       /* If the destination bit is in a d-reg we can jump depending
   9892 	 on the source bit and use ANDI / ORI.  This just applies if we
   9893 	 have not an early-clobber situation with the bit.  */
   9894 
   9895       avr_asm_len ("andi %0,~(1<<%1)" CR_TAB
   9896 		   "sbrs %2,%3"       CR_TAB
   9897 		   "ori %0,1<<%1", op, plen, -3);
   9898     }
   9899   else
   9900     {
   9901       /* Otherwise, invert the bit by means of COM before we store it with
   9902 	 BST and then undo the COM if needed.  */
   9903 
   9904       avr_asm_len ("com %2" CR_TAB
   9905 		   "bst %2,%3", op, plen, -2);
   9906 
   9907       if (!reg_unused_after (insn, op[2])
   9908 	  // A simple 'reg_unused_after' is not enough because that function
   9909 	  // assumes that the destination register is overwritten completely
   9910 	  // and hence is in order for our purpose.  This is not the case
   9911 	  // with BLD which just changes one bit of the destination.
   9912 	  || reg_overlap_mentioned_p (op[0], op[2]))
   9913 	{
   9914 	  /* Undo the COM from above.  */
   9915 	  avr_asm_len ("com %2", op, plen, 1);
   9916 	}
   9917 
   9918       avr_asm_len ("bld %0,%1", op, plen, 1);
   9919     }
   9920 
   9921   return "";
   9922 }
   9923 
   9924 
   9925 /* Output instructions for  XOP[0] = (XOP[1] <Shift> XOP[2]) & XOP[3]  where
   9926    -  XOP[0] and XOP[1] have the same mode which is one of: QI, HI, PSI, SI.
   9927    -  XOP[3] is an exact const_int power of 2.
   9928    -  XOP[2] and XOP[3] are const_int.
   9929    -  <Shift> is any of: ASHIFT, LSHIFTRT, ASHIFTRT.
   9930    -  The result depends on XOP[1].
   9931    or  XOP[0] = XOP[1] & XOP[2]  where
   9932    -  XOP[0] and XOP[1] have the same mode which is one of: HI, PSI, SI.
   9933    -  XOP[2] is an exact const_int power of 2.
   9934    Returns "".
   9935    PLEN != 0: Set *PLEN to the code length in words.  Don't output anything.
   9936    PLEN == 0: Output instructions.  */
   9937 
   9938 const char*
   9939 avr_out_insv (rtx_insn *insn, rtx xop[], int *plen)
   9940 {
   9941   machine_mode mode = GET_MODE (xop[0]);
   9942   int n_bytes = GET_MODE_SIZE (mode);
   9943   rtx xsrc = SET_SRC (single_set (insn));
   9944 
   9945   gcc_assert (AND == GET_CODE (xsrc));
   9946 
   9947   rtx xop2 = xop[2];
   9948   rtx xop3 = xop[3];
   9949 
   9950   if (REG_P (XEXP (xsrc, 0)))
   9951     {
   9952       // This function can also handle AND with an exact power of 2,
   9953       // which can be regarded as a XOP[1] shift with offset 0.
   9954       rtx xshift = gen_rtx_ASHIFT (mode, xop[1], const0_rtx);
   9955       xsrc = gen_rtx_AND (mode, xshift, xop[2]);
   9956       xop3 = xop[2];
   9957       xop2 = const0_rtx;
   9958     }
   9959 
   9960   // Any of ASHIFT, LSHIFTRT, ASHIFTRT.
   9961   enum rtx_code code = GET_CODE (XEXP (xsrc, 0));
   9962   int shift = code == ASHIFT ? INTVAL (xop2) : -INTVAL (xop2);
   9963 
   9964   // Determines the position of the output bit.
   9965   unsigned mask = GET_MODE_MASK (mode) & INTVAL (xop3);
   9966 
   9967   // Position of the output / input bit, respectively.
   9968   int obit = exact_log2 (mask);
   9969   int ibit = obit - shift;
   9970 
   9971   gcc_assert (IN_RANGE (obit, 0, GET_MODE_BITSIZE (mode) - 1));
   9972   gcc_assert (IN_RANGE (ibit, 0, GET_MODE_BITSIZE (mode) - 1));
   9973 
   9974   // In the remainder, use the sub-bytes that hold the bits.
   9975   rtx op[4] =
   9976     {
   9977       // Output
   9978       simplify_gen_subreg (QImode, xop[0], mode, obit / 8),
   9979       GEN_INT (obit & 7),
   9980       // Input
   9981       simplify_gen_subreg (QImode, xop[1], mode, ibit / 8),
   9982       GEN_INT (ibit & 7)
   9983     };
   9984   obit &= 7;
   9985   ibit &= 7;
   9986 
   9987   // The length of the default sequence at the end of this function.
   9988   // We only emit anything other than the default when we find a sequence
   9989   // that is strictly shorter than the default sequence; which is:
   9990   // BST + <CLR-result-bytes> + BLD.
   9991   const int len0 = 2 + n_bytes - (n_bytes == 4 && AVR_HAVE_MOVW);
   9992 
   9993   // Finding something shorter than the default sequence implies that there
   9994   // must be at most 2 instructions that deal with the bytes containing the
   9995   // relevant bits.  In addition, we need  N_BYTES - 1  instructions to clear
   9996   // the remaining result bytes.
   9997 
   9998   const int n_clr = n_bytes - 1;
   9999   bool clr_p = false;
   10000   bool andi_p = false;
   10001 
   10002   if (plen)
   10003     *plen = 0;
   10004 
   10005   if (REGNO (op[0]) == REGNO (op[2])
   10006       // Output reg allows ANDI.
   10007       && test_hard_reg_class (LD_REGS, op[0]))
   10008     {
   10009       if (1 + n_clr < len0
   10010 	  // Same byte and bit: A single ANDI will do.
   10011 	  && obit == ibit)
   10012 	{
   10013 	  clr_p = andi_p = true;
   10014 	}
   10015       else if (2 + n_clr < len0
   10016 	       // |obit - ibit| = 4:  SWAP + ANDI will do.
   10017 	       && (obit == ibit + 4 || obit == ibit - 4))
   10018 	{
   10019 	  avr_asm_len ("swap %0", op, plen, 1);
   10020 	  clr_p = andi_p = true;
   10021 	}
   10022       else if (2 + n_clr < len0
   10023 	       // LSL + ANDI will do.
   10024 	       && obit == ibit + 1)
   10025 	{
   10026 	  avr_asm_len ("lsl %0", op, plen, 1);
   10027 	  clr_p = andi_p = true;
   10028 	}
   10029       else if (2 + n_clr < len0
   10030 	       // LSR + ANDI will do.
   10031 	       && obit == ibit - 1)
   10032 	{
   10033 	  avr_asm_len ("lsr %0", op, plen, 1);
   10034 	  clr_p = andi_p = true;
   10035 	}
   10036     }
   10037 
   10038   if (REGNO (op[0]) != REGNO (op[2])
   10039       && obit == ibit)
   10040     {
   10041       if (2 + n_clr < len0
   10042 	  // Same bit but different byte: MOV + ANDI will do.
   10043 	  && test_hard_reg_class (LD_REGS, op[0]))
   10044 	{
   10045 	  avr_asm_len ("mov %0,%2", op, plen, 1);
   10046 	  clr_p = andi_p = true;
   10047 	}
   10048       else if (2 + n_clr < len0
   10049 	       // Same bit but different byte:  We can use ANDI + MOV,
   10050 	       // but only if the input byte is LD_REGS and unused after.
   10051 	       && test_hard_reg_class (LD_REGS, op[2])
   10052 	       && reg_unused_after (insn, op[2]))
   10053 	{
   10054 	  avr_asm_len ("andi %2,1<<%3"  CR_TAB
   10055 		       "mov %0,%2", op, plen, 2);
   10056 	  clr_p = true;
   10057 	}
   10058     }
   10059 
   10060   // Output remaining instructions of the shorter sequence.
   10061 
   10062   if (andi_p)
   10063     avr_asm_len ("andi %0,1<<%1", op, plen, 1);
   10064 
   10065   if (clr_p)
   10066     {
   10067       for (int b = 0; b < n_bytes; ++b)
   10068 	{
   10069 	  rtx byte = simplify_gen_subreg (QImode, xop[0], mode, b);
   10070 	  if (REGNO (byte) != REGNO (op[0]))
   10071 	    avr_asm_len ("clr %0", &byte, plen, 1);
   10072 	}
   10073 
   10074       // CLR_P means we found a shorter sequence, so we are done now.
   10075       return "";
   10076     }
   10077 
   10078   // No shorter sequence found, just emit  BST, CLR*, BLD  sequence.
   10079 
   10080   avr_asm_len ("bst %2,%3", op, plen, -1);
   10081 
   10082   if (n_bytes == 4 && AVR_HAVE_MOVW)
   10083     avr_asm_len ("clr %A0"   CR_TAB
   10084 		 "clr %B0"   CR_TAB
   10085 		 "movw %C0,%A0", xop, plen, 3);
   10086   else
   10087     for (int b = 0; b < n_bytes; ++b)
   10088       {
   10089 	rtx byte = simplify_gen_subreg (QImode, xop[0], mode, b);
   10090 	avr_asm_len ("clr %0", &byte, plen, 1);
   10091       }
   10092 
   10093   return avr_asm_len ("bld %0,%1", op, plen, 1);
   10094 }
   10095 
   10096 
   10097 /* Output instructions to extract a bit to 8-bit register XOP[0].
   10098    The input XOP[1] is a register or an 8-bit MEM in the lower I/O range.
   10099    XOP[2] is the const_int bit position.  Return "".
   10100 
   10101    PLEN != 0: Set *PLEN to the code length in words.  Don't output anything.
   10102    PLEN == 0: Output instructions.  */
   10103 
   10104 const char *
   10105 avr_out_extr (rtx_insn *insn, rtx xop[], int *plen)
   10106 {
   10107   rtx dest = xop[0];
   10108   rtx src = xop[1];
   10109   int bit = INTVAL (xop[2]);
   10110 
   10111   if (GET_MODE (src) != QImode)
   10112     {
   10113       src = xop[1] = simplify_gen_subreg (QImode, src, GET_MODE (src), bit / 8);
   10114       bit %= 8;
   10115       xop[2] = GEN_INT (bit);
   10116     }
   10117 
   10118   if (MEM_P (src))
   10119     {
   10120       xop[1] = XEXP (src, 0); // address
   10121       gcc_assert (low_io_address_operand (xop[1], Pmode));
   10122 
   10123       return avr_asm_len ("clr %0"      CR_TAB
   10124 			  "sbic %i1,%2" CR_TAB
   10125 			  "inc %0", xop, plen, -3);
   10126     }
   10127 
   10128   gcc_assert (REG_P (src));
   10129 
   10130   bool ld_dest_p = test_hard_reg_class (LD_REGS, dest);
   10131   bool ld_src_p = test_hard_reg_class (LD_REGS, src);
   10132 
   10133   if (ld_dest_p
   10134       && REGNO (src) == REGNO (dest))
   10135     {
   10136       if (bit == 0)
   10137 	return avr_asm_len ("andi %0,1", xop, plen, -1);
   10138       if (bit == 1)
   10139 	return avr_asm_len ("lsr %0" CR_TAB
   10140 			    "andi %0,1", xop, plen, -2);
   10141       if (bit == 4)
   10142 	return avr_asm_len ("swap %0" CR_TAB
   10143 			    "andi %0,1", xop, plen, -2);
   10144     }
   10145 
   10146   if (bit == 0
   10147       && REGNO (src) != REGNO (dest))
   10148   {
   10149     if (ld_dest_p)
   10150       return avr_asm_len ("mov %0,%1" CR_TAB
   10151 			  "andi %0,1", xop, plen, -2);
   10152     if (ld_src_p
   10153 	&& reg_unused_after (insn, src))
   10154       return avr_asm_len ("andi %1,1" CR_TAB
   10155 			  "mov %0,%1", xop, plen, -2);
   10156   }
   10157 
   10158   return avr_asm_len ("bst %1,%2" CR_TAB
   10159 		      "clr %0"    CR_TAB
   10160 		      "bld %0,0", xop, plen, -3);
   10161 }
   10162 
   10163 
   10164 /* Output instructions to extract a negated bit to 8-bit register XOP[0].
   10165    The input XOP[1] is an 8-bit register or MEM in the lower I/O range.
   10166    XOP[2] is the const_int bit position.  Return "".
   10167 
   10168    PLEN != 0: Set *PLEN to the code length in words.  Don't output anything.
   10169    PLEN == 0: Output instructions.  */
   10170 
   10171 const char *
   10172 avr_out_extr_not (rtx_insn * /* insn */, rtx xop[], int *plen)
   10173 {
   10174   rtx dest = xop[0];
   10175   rtx src = xop[1];
   10176   int bit = INTVAL (xop[2]);
   10177 
   10178   if (MEM_P (src))
   10179     {
   10180       xop[1] = XEXP (src, 0); // address
   10181       gcc_assert (low_io_address_operand (xop[1], Pmode));
   10182 
   10183       return avr_asm_len ("clr %0"      CR_TAB
   10184 			  "sbis %i1,%2" CR_TAB
   10185 			  "inc %0", xop, plen, -3);
   10186     }
   10187 
   10188   gcc_assert (REG_P (src));
   10189 
   10190   bool ld_src_p = test_hard_reg_class (LD_REGS, src);
   10191 
   10192   if (ld_src_p
   10193       && REGNO (src) == REGNO (dest))
   10194     {
   10195       if (bit == 0)
   10196 	return avr_asm_len ("inc %0" CR_TAB
   10197 			    "andi %0,1", xop, plen, -2);
   10198       if (bit == 1)
   10199 	return avr_asm_len ("lsr %0" CR_TAB
   10200 			    "inc %0" CR_TAB
   10201 			    "andi %0,1", xop, plen, -3);
   10202       if (bit == 4)
   10203 	return avr_asm_len ("swap %0" CR_TAB
   10204 			    "inc %0"  CR_TAB
   10205 			    "andi %0,1", xop, plen, -3);
   10206     }
   10207 
   10208   if (bit == 7
   10209       && ld_src_p)
   10210     return avr_asm_len ("cpi %1,0x80" CR_TAB
   10211 			"sbc %0,%0"   CR_TAB
   10212 			"neg %0", xop, plen, -3);
   10213 
   10214   if (REGNO (src) != REGNO (dest))
   10215     return avr_asm_len ("clr %0"     CR_TAB
   10216 			"sbrs %1,%2" CR_TAB
   10217 			"inc %0", xop, plen, -3);
   10218 
   10219   return avr_asm_len ("clr __tmp_reg__" CR_TAB
   10220 		      "sbrs %1,%2"      CR_TAB
   10221 		      "inc __tmp_reg__" CR_TAB
   10222 		      "mov %0,__tmp_reg__", xop, plen, -4);
   10223 }
   10224 
   10225 
   10226 /* Outputs instructions needed for fixed point type conversion.
   10227    This includes converting between any fixed point type, as well
   10228    as converting to any integer type.  Conversion between integer
   10229    types is not supported.
   10230 
   10231    Converting signed fractional types requires a bit shift if converting
   10232    to or from any unsigned fractional type because the decimal place is
   10233    shifted by 1 bit.  When the destination is a signed fractional, the sign
   10234    is stored in either the carry or T bit.  */
   10235 
   10236 const char *
   10237 avr_out_fract (rtx_insn *insn, rtx operands[], bool intsigned, int *plen)
   10238 {
   10239   rtx xop[6];
   10240   RTX_CODE shift = UNKNOWN;
   10241   bool sign_in_carry = false;
   10242   bool msb_in_carry = false;
   10243   bool lsb_in_tmp_reg = false;
   10244   bool lsb_in_carry = false;
   10245   bool frac_rounded = false;
   10246   const char *code_ashift = "lsl %0";
   10247 
   10248 
   10249 #define MAY_CLOBBER(RR)                                                 \
   10250   /* Shorthand used below.  */                                          \
   10251   ((sign_bytes                                                          \
   10252     && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb))  \
   10253    || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb))		\
   10254    || (reg_unused_after (insn, all_regs_rtx[RR])                        \
   10255        && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
   10256 
   10257   struct
   10258   {
   10259     /* bytes       : Length of operand in bytes.
   10260        ibyte       : Length of integral part in bytes.
   10261        fbyte, fbit : Length of fractional part in bytes, bits.  */
   10262 
   10263     bool sbit;
   10264     unsigned fbit, bytes, ibyte, fbyte;
   10265     unsigned regno, regno_msb;
   10266   } dest, src, *val[2] = { &dest, &src };
   10267 
   10268   if (plen)
   10269     *plen = 0;
   10270 
   10271   /* Step 0:  Determine information on source and destination operand we
   10272      ======   will need in the remainder.  */
   10273 
   10274   for (size_t i = 0; i < ARRAY_SIZE (val); i++)
   10275     {
   10276       machine_mode mode;
   10277 
   10278       xop[i] = operands[i];
   10279 
   10280       mode = GET_MODE (xop[i]);
   10281 
   10282       val[i]->bytes = GET_MODE_SIZE (mode);
   10283       val[i]->regno = REGNO (xop[i]);
   10284       val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
   10285 
   10286       if (SCALAR_INT_MODE_P (mode))
   10287 	{
   10288 	  val[i]->sbit = intsigned;
   10289 	  val[i]->fbit = 0;
   10290 	}
   10291       else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
   10292 	{
   10293 	  val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
   10294 	  val[i]->fbit = GET_MODE_FBIT (mode);
   10295 	}
   10296       else
   10297 	fatal_insn ("unsupported fixed-point conversion", insn);
   10298 
   10299       val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
   10300       val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
   10301     }
   10302 
   10303   // Byte offset of the decimal point taking into account different place
   10304   // of the decimal point in input and output and different register numbers
   10305   // of input and output.
   10306   int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
   10307 
   10308   // Number of destination bytes that will come from sign / zero extension.
   10309   int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
   10310 
   10311   // Number of bytes at the low end to be filled with zeros.
   10312   int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
   10313 
   10314   // Do we have a 16-Bit register that is cleared?
   10315   rtx clrw = NULL_RTX;
   10316 
   10317   bool sign_extend = src.sbit && sign_bytes;
   10318 
   10319   if (dest.fbit % 8 == 0 && src.fbit % 8 == 7)
   10320     shift = ASHIFT;
   10321   else if (dest.fbit % 8 == 7 && src.fbit % 8 == 0)
   10322     shift = ASHIFTRT;
   10323   else if (dest.fbit % 8 == src.fbit % 8)
   10324     shift = UNKNOWN;
   10325   else
   10326     gcc_unreachable();
   10327 
   10328   /* If we need to round the fraction part, we might need to save/round it
   10329      before clobbering any of it in Step 1.  Also, we might want to do
   10330      the rounding now to make use of LD_REGS.  */
   10331   if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
   10332       && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
   10333       && !TARGET_FRACT_CONV_TRUNC)
   10334     {
   10335       bool overlap
   10336 	= (src.regno <=
   10337 	   (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1)
   10338 	   && dest.regno - offset -1 >= dest.regno);
   10339       unsigned s0 = dest.regno - offset -1;
   10340       bool use_src = true;
   10341       unsigned sn;
   10342       unsigned copied_msb = src.regno_msb;
   10343       bool have_carry = false;
   10344 
   10345       if (src.ibyte > dest.ibyte)
   10346 	copied_msb -= src.ibyte - dest.ibyte;
   10347 
   10348       for (sn = s0; sn <= copied_msb; sn++)
   10349 	if (!IN_RANGE (sn, dest.regno, dest.regno_msb)
   10350 	    && !reg_unused_after (insn, all_regs_rtx[sn]))
   10351 	  use_src = false;
   10352       if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0))
   10353 	{
   10354 	  avr_asm_len ("tst %0" CR_TAB "brpl 0f",
   10355 		       &all_regs_rtx[src.regno_msb], plen, 2);
   10356 	  sn = src.regno;
   10357 	  if (sn < s0)
   10358 	    {
   10359 	      if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn))
   10360 		avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1);
   10361 	      else
   10362 		avr_asm_len ("sec" CR_TAB
   10363 			     "cpc %0,__zero_reg__",
   10364 			     &all_regs_rtx[sn], plen, 2);
   10365 	      have_carry = true;
   10366 	    }
   10367 	  while (++sn < s0)
   10368 	    avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
   10369 
   10370 	  avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129",
   10371 		       &all_regs_rtx[s0], plen, 1);
   10372 	  for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
   10373 	    avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1);
   10374 	  avr_asm_len ("\n0:", NULL, plen, 0);
   10375 	  frac_rounded = true;
   10376 	}
   10377       else if (use_src && overlap)
   10378 	{
   10379 	  avr_asm_len ("clr __tmp_reg__" CR_TAB
   10380 		       "sbrc %1,0"       CR_TAB
   10381 		       "dec __tmp_reg__", xop, plen, 1);
   10382 	  sn = src.regno;
   10383 	  if (sn < s0)
   10384 	    {
   10385 	      avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
   10386 	      have_carry = true;
   10387 	    }
   10388 
   10389 	  while (++sn < s0)
   10390 	    avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
   10391 
   10392 	  if (have_carry)
   10393 	    avr_asm_len ("clt"                CR_TAB
   10394 			 "bld __tmp_reg__,7"  CR_TAB
   10395 			 "adc %0,__tmp_reg__",
   10396 			 &all_regs_rtx[s0], plen, 1);
   10397 	  else
   10398 	    avr_asm_len ("lsr __tmp_reg" CR_TAB
   10399 			 "add %0,__tmp_reg__",
   10400 			 &all_regs_rtx[s0], plen, 2);
   10401 	  for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
   10402 	    avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
   10403 	  frac_rounded = true;
   10404 	}
   10405       else if (overlap)
   10406 	{
   10407 	  bool use_src
   10408 	    = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)
   10409 	       && (IN_RANGE (s0, dest.regno, dest.regno_msb)
   10410 		   || reg_unused_after (insn, all_regs_rtx[s0])));
   10411 	  xop[2] = all_regs_rtx[s0];
   10412 	  unsigned sn = src.regno;
   10413 	  if (!use_src || sn == s0)
   10414 	    avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
   10415 	  /* We need to consider to-be-discarded bits
   10416 	     if the value is negative.  */
   10417 	  if (sn < s0)
   10418 	    {
   10419 	      avr_asm_len ("tst %0" CR_TAB
   10420 			   "brpl 0f",
   10421 			   &all_regs_rtx[src.regno_msb], plen, 2);
   10422 	      /* Test to-be-discarded bytes for any nozero bits.
   10423 		 ??? Could use OR or SBIW to test two registers at once.  */
   10424 	      if (sn < s0)
   10425 		avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
   10426 
   10427 	      while (++sn < s0)
   10428 		avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
   10429 	      /* Set bit 0 in __tmp_reg__ if any of the lower bits was set.  */
   10430 	      if (use_src)
   10431 		avr_asm_len ("breq 0f" CR_TAB
   10432 			     "ori %2,1"
   10433 			     "\n0:\t" "mov __tmp_reg__,%2",
   10434 			     xop, plen, 3);
   10435 	      else
   10436 		avr_asm_len ("breq 0f" CR_TAB
   10437 			     "set"     CR_TAB
   10438 			     "bld __tmp_reg__,0\n0:",
   10439 			     xop, plen, 3);
   10440 	    }
   10441 	  lsb_in_tmp_reg = true;
   10442 	}
   10443     }
   10444 
   10445   /* Step 1:  Clear bytes at the low end and copy payload bits from source
   10446      ======   to destination.  */
   10447 
   10448   int step = offset < 0 ? 1 : -1;
   10449   unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
   10450 
   10451   // We cleared at least that number of registers.
   10452   int clr_n = 0;
   10453 
   10454   for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
   10455     {
   10456       // Next regno of destination is needed for MOVW
   10457       unsigned d1 = d0 + step;
   10458 
   10459       // Current and next regno of source
   10460       signed s0 = d0 - offset;
   10461       signed s1 = s0 + step;
   10462 
   10463       // Must current resp. next regno be CLRed?  This applies to the low
   10464       // bytes of the destination that have no associated source bytes.
   10465       bool clr0 = s0 < (signed) src.regno;
   10466       bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
   10467 
   10468       // First gather what code to emit (if any) and additional step to
   10469       // apply if a MOVW is in use.  xop[2] is destination rtx and xop[3]
   10470       // is the source rtx for the current loop iteration.
   10471       const char *code = NULL;
   10472       int stepw = 0;
   10473 
   10474       if (clr0)
   10475 	{
   10476 	  if (AVR_HAVE_MOVW && clr1 && clrw)
   10477 	    {
   10478 	      xop[2] = all_regs_rtx[d0 & ~1];
   10479 	      xop[3] = clrw;
   10480 	      code = "movw %2,%3";
   10481 	      stepw = step;
   10482 	    }
   10483 	  else
   10484 	    {
   10485 	      xop[2] = all_regs_rtx[d0];
   10486 	      code = "clr %2";
   10487 
   10488 	      if (++clr_n >= 2
   10489 		  && !clrw
   10490 		  && d0 % 2 == (step > 0))
   10491 		{
   10492 		  clrw = all_regs_rtx[d0 & ~1];
   10493 		}
   10494 	    }
   10495 	}
   10496       else if (offset && s0 <= (signed) src.regno_msb)
   10497 	{
   10498 	  int movw = AVR_HAVE_MOVW && offset % 2 == 0
   10499 	    && d0 % 2 == (offset > 0)
   10500 	    && d1 <= dest.regno_msb && d1 >= dest.regno
   10501 	    && s1 <= (signed) src.regno_msb  && s1 >= (signed) src.regno;
   10502 
   10503 	  xop[2] = all_regs_rtx[d0 & ~movw];
   10504 	  xop[3] = all_regs_rtx[s0 & ~movw];
   10505 	  code = movw ? "movw %2,%3" : "mov %2,%3";
   10506 	  stepw = step * movw;
   10507 	}
   10508 
   10509       if (code)
   10510 	{
   10511 	  if (sign_extend && shift != ASHIFT && !sign_in_carry
   10512 	      && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
   10513 	    {
   10514 	      /* We are going to override the sign bit.  If we sign-extend,
   10515 		 store the sign in the Carry flag.  This is not needed if
   10516 		 the destination will be ASHIFT in the remainder because
   10517 		 the ASHIFT will set Carry without extra instruction.  */
   10518 
   10519 	      avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
   10520 	      sign_in_carry = true;
   10521 	    }
   10522 
   10523 	  unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
   10524 
   10525 	  if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
   10526 	      && src.ibyte > dest.ibyte
   10527 	      && (d0 == src_msb || d0 + stepw == src_msb))
   10528 	    {
   10529 	      /* We are going to override the MSB.  If we shift right,
   10530 		 store the MSB in the Carry flag.  This is only needed if
   10531 		 we don't sign-extend becaue with sign-extension the MSB
   10532 		 (the sign) will be produced by the sign extension.  */
   10533 
   10534 	      avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
   10535 	      msb_in_carry = true;
   10536 	    }
   10537 
   10538 	  unsigned src_lsb = dest.regno - offset -1;
   10539 
   10540 	  if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
   10541 	      && !lsb_in_tmp_reg
   10542 	      && (d0 == src_lsb || d0 + stepw == src_lsb))
   10543 	    {
   10544 	      /* We are going to override the new LSB; store it into carry.  */
   10545 
   10546 	      avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
   10547 	      code_ashift = "rol %0";
   10548 	      lsb_in_carry = true;
   10549 	    }
   10550 
   10551 	  avr_asm_len (code, xop, plen, 1);
   10552 	  d0 += stepw;
   10553 	}
   10554     }
   10555 
   10556   /* Step 2:  Shift destination left by 1 bit position.  This might be needed
   10557      ======   for signed input and unsigned output.  */
   10558 
   10559   if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
   10560     {
   10561       unsigned s0 = dest.regno - offset -1;
   10562 
   10563       /* n1169 4.1.4 says:
   10564 	 "Conversions from a fixed-point to an integer type round toward zero."
   10565 	 Hence, converting a fract type to integer only gives a non-zero result
   10566 	 for -1.  */
   10567       if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
   10568 	  && SCALAR_FRACT_MODE_P (GET_MODE (xop[1]))
   10569 	  && !TARGET_FRACT_CONV_TRUNC)
   10570 	{
   10571 	  gcc_assert (s0 == src.regno_msb);
   10572 	  /* Check if the input is -1.  We do that by checking if negating
   10573 	     the input causes an integer overflow.  */
   10574 	  unsigned sn = src.regno;
   10575 	  avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
   10576 	  while (sn <= s0)
   10577 	    avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
   10578 
   10579 	  /* Overflow goes with set carry.  Clear carry otherwise.  */
   10580 	  avr_asm_len ("brvs 0f" CR_TAB
   10581 		       "clc\n0:", NULL, plen, 2);
   10582 	}
   10583       /* Likewise, when converting from accumulator types to integer, we
   10584 	 need to round up negative values.  */
   10585       else if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
   10586 	       && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
   10587 	       && !TARGET_FRACT_CONV_TRUNC
   10588 	       && !frac_rounded)
   10589 	{
   10590 	  bool have_carry = false;
   10591 
   10592 	  xop[2] = all_regs_rtx[s0];
   10593 	  if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0))
   10594 	    avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
   10595 	  avr_asm_len ("tst %0" CR_TAB "brpl 0f",
   10596 		       &all_regs_rtx[src.regno_msb], plen, 2);
   10597 	  if (!lsb_in_tmp_reg)
   10598 	    {
   10599 	      unsigned sn = src.regno;
   10600 	      if (sn < s0)
   10601 		{
   10602 		  avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn],
   10603 			       plen, 1);
   10604 		  have_carry = true;
   10605 		}
   10606 	      while (++sn < s0)
   10607 		avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1);
   10608 	      lsb_in_tmp_reg = !MAY_CLOBBER (s0);
   10609 	    }
   10610 	  /* Add in C and the rounding value 127.  */
   10611 	  /* If the destination msb is a sign byte, and in LD_REGS,
   10612 	     grab it as a temporary.  */
   10613 	  if (sign_bytes
   10614 	      && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS],
   10615 				    dest.regno_msb))
   10616 	    {
   10617 	      xop[3] = all_regs_rtx[dest.regno_msb];
   10618 	      avr_asm_len ("ldi %3,127", xop, plen, 1);
   10619 	      avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3"
   10620 			    : have_carry ? "adc %2,%3"
   10621 			    : lsb_in_tmp_reg ? "add __tmp_reg__,%3"
   10622 			    : "add %2,%3"),
   10623 			   xop, plen, 1);
   10624 	    }
   10625 	  else
   10626 	    {
   10627 	      /* Fall back to use __zero_reg__ as a temporary.  */
   10628 	      avr_asm_len ("dec __zero_reg__", NULL, plen, 1);
   10629 	      if (have_carry)
   10630 		avr_asm_len ("clt" CR_TAB
   10631 			     "bld __zero_reg__,7", NULL, plen, 2);
   10632 	      else
   10633 		avr_asm_len ("lsr __zero_reg__", NULL, plen, 1);
   10634 	      avr_asm_len (have_carry && lsb_in_tmp_reg
   10635 			   ? "adc __tmp_reg__,__zero_reg__"
   10636 			   : have_carry ? "adc %2,__zero_reg__"
   10637 			   : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__"
   10638 			   : "add %2,__zero_reg__",
   10639 			   xop, plen, 1);
   10640 	      avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1);
   10641 	    }
   10642 
   10643 	  for (d0 = dest.regno + zero_bytes;
   10644 	       d0 <= dest.regno_msb - sign_bytes; d0++)
   10645 	    avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1);
   10646 
   10647 	  avr_asm_len (lsb_in_tmp_reg
   10648 		       ? "\n0:\t" "lsl __tmp_reg__"
   10649 		       : "\n0:\t" "lsl %2",
   10650 		       xop, plen, 1);
   10651 	}
   10652       else if (MAY_CLOBBER (s0))
   10653 	avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
   10654       else
   10655 	avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
   10656 		     "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
   10657 
   10658       code_ashift = "rol %0";
   10659       lsb_in_carry = true;
   10660     }
   10661 
   10662   if (shift == ASHIFT)
   10663     {
   10664       for (d0 = dest.regno + zero_bytes;
   10665 	   d0 <= dest.regno_msb - sign_bytes; d0++)
   10666 	{
   10667 	  avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
   10668 	  code_ashift = "rol %0";
   10669 	}
   10670 
   10671       lsb_in_carry = false;
   10672       sign_in_carry = true;
   10673     }
   10674 
   10675   /* Step 4a:  Store MSB in carry if we don't already have it or will produce
   10676      =======   it in sign-extension below.  */
   10677 
   10678   if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
   10679       && src.ibyte > dest.ibyte)
   10680     {
   10681       unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
   10682 
   10683       if (MAY_CLOBBER (s0))
   10684 	avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
   10685       else
   10686 	avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
   10687 		     "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
   10688 
   10689       msb_in_carry = true;
   10690     }
   10691 
   10692   /* Step 3:  Sign-extend or zero-extend the destination as needed.
   10693      ======   */
   10694 
   10695   if (sign_extend && !sign_in_carry)
   10696     {
   10697       unsigned s0 = src.regno_msb;
   10698 
   10699       if (MAY_CLOBBER (s0))
   10700 	avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
   10701       else
   10702 	avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
   10703 		     "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
   10704 
   10705       sign_in_carry = true;
   10706     }
   10707 
   10708   gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
   10709 
   10710   unsigned copies = 0;
   10711   rtx movw = sign_extend ? NULL_RTX : clrw;
   10712 
   10713   for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
   10714     {
   10715       if (AVR_HAVE_MOVW && movw
   10716 	  && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
   10717 	{
   10718 	  xop[2] = all_regs_rtx[d0];
   10719 	  xop[3] = movw;
   10720 	  avr_asm_len ("movw %2,%3", xop, plen, 1);
   10721 	  d0++;
   10722 	}
   10723       else
   10724 	{
   10725 	  avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
   10726 		       &all_regs_rtx[d0], plen, 1);
   10727 
   10728 	  if (++copies >= 2 && !movw && d0 % 2 == 1)
   10729 	    movw = all_regs_rtx[d0-1];
   10730 	}
   10731     } /* for */
   10732 
   10733 
   10734   /* Step 4:  Right shift the destination.  This might be needed for
   10735      ======   conversions from unsigned to signed.  */
   10736 
   10737   if (shift == ASHIFTRT)
   10738     {
   10739       const char *code_ashiftrt = "lsr %0";
   10740 
   10741       if (sign_extend || msb_in_carry)
   10742 	code_ashiftrt = "ror %0";
   10743 
   10744       if (src.sbit && src.ibyte == dest.ibyte)
   10745 	code_ashiftrt = "asr %0";
   10746 
   10747       for (d0 = dest.regno_msb - sign_bytes;
   10748 	   d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
   10749 	{
   10750 	  avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
   10751 	  code_ashiftrt = "ror %0";
   10752 	}
   10753     }
   10754 
   10755 #undef MAY_CLOBBER
   10756 
   10757   return "";
   10758 }
   10759 
   10760 
   10761 /* Output fixed-point rounding.  XOP[0] = XOP[1] is the operand to round.
   10762    XOP[2] is the rounding point, a CONST_INT.  The function prints the
   10763    instruction sequence if PLEN = NULL and computes the length in words
   10764    of the sequence if PLEN != NULL.  Most of this function deals with
   10765    preparing operands for calls to `avr_out_plus' and `avr_out_bitop'.  */
   10766 
   10767 const char *
   10768 avr_out_round (rtx_insn * /*insn*/, rtx *xop, int *plen)
   10769 {
   10770   scalar_mode mode = as_a <scalar_mode> (GET_MODE (xop[0]));
   10771   scalar_int_mode imode = int_mode_for_mode (mode).require ();
   10772   // The smallest fractional bit not cleared by the rounding is 2^(-RP).
   10773   int fbit = (int) GET_MODE_FBIT (mode);
   10774   double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
   10775   wide_int wi_add = wi::set_bit_in_zero (fbit-1 - INTVAL (xop[2]),
   10776 					 GET_MODE_PRECISION (imode));
   10777   // Lengths of PLUS and AND parts.
   10778   int len_add = 0, *plen_add = plen ? &len_add : NULL;
   10779   int len_and = 0, *plen_and = plen ? &len_and : NULL;
   10780 
   10781   // Add-Saturate  1/2 * 2^(-RP).  Don't print the label "0:" when printing
   10782   // the saturated addition so that we can emit the "rjmp 1f" before the
   10783   // "0:" below.
   10784 
   10785   rtx xadd = const_fixed_from_double_int (i_add, mode);
   10786   rtx xpattern, xsrc, op[4];
   10787 
   10788   xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
   10789     ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
   10790     : gen_rtx_US_PLUS (mode, xop[1], xadd);
   10791   xpattern = gen_rtx_SET (xop[0], xsrc);
   10792 
   10793   op[0] = xop[0];
   10794   op[1] = xop[1];
   10795   op[2] = xadd;
   10796   avr_out_plus (xpattern, op, plen_add, false /* Don't print "0:" */);
   10797 
   10798   avr_asm_len ("rjmp 1f" CR_TAB
   10799 	       "0:", NULL, plen_add, 1);
   10800 
   10801   // Keep  all bits from RP and higher:   ... 2^(-RP)
   10802   // Clear all bits from RP+1 and lower:              2^(-RP-1) ...
   10803   // Rounding point                           ^^^^^^^
   10804   // Added above                                      ^^^^^^^^^
   10805   rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
   10806   rtx xmask = immed_wide_int_const (-wi_add - wi_add, imode);
   10807 
   10808   xpattern = gen_rtx_SET (xreg, gen_rtx_AND (imode, xreg, xmask));
   10809 
   10810   op[0] = xreg;
   10811   op[1] = xreg;
   10812   op[2] = xmask;
   10813   op[3] = gen_rtx_SCRATCH (QImode);
   10814   avr_out_bitop (xpattern, op, plen_and);
   10815   avr_asm_len ("1:", NULL, plen, 0);
   10816 
   10817   if (plen)
   10818     *plen = len_add + len_and;
   10819 
   10820   return "";
   10821 }
   10822 
   10823 
   10824 /* Create RTL split patterns for byte sized rotate expressions.  This
   10825    produces a series of move instructions and considers overlap situations.
   10826    Overlapping non-HImode operands need a scratch register.  */
   10827 
   10828 bool
   10829 avr_rotate_bytes (rtx operands[])
   10830 {
   10831   machine_mode mode = GET_MODE (operands[0]);
   10832   bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
   10833   bool same_reg = rtx_equal_p (operands[0], operands[1]);
   10834   int num = INTVAL (operands[2]);
   10835   rtx scratch = operands[3];
   10836   /* Work out if byte or word move is needed.  Odd byte rotates need QImode.
   10837      Word move if no scratch is needed, otherwise use size of scratch.  */
   10838   machine_mode move_mode = QImode;
   10839 
   10840   if (num & 0xf)
   10841     move_mode = QImode;
   10842   else if ((mode == SImode && !same_reg) || !overlapped)
   10843     move_mode = HImode;
   10844   else
   10845     move_mode = GET_MODE (scratch);
   10846 
   10847   /* Force DI rotate to use QI moves since other DI moves are currently split
   10848      into QI moves so forward propagation works better.  */
   10849   if (mode == DImode)
   10850     move_mode = QImode;
   10851   /* Make scratch smaller if needed.  */
   10852   if (SCRATCH != GET_CODE (scratch)
   10853       && HImode == GET_MODE (scratch)
   10854       && QImode == move_mode)
   10855     scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
   10856 
   10857   int move_size = GET_MODE_SIZE (move_mode);
   10858   /* Number of bytes/words to rotate.  */
   10859   int offset = (num  >> 3) / move_size;
   10860   /* Number of moves needed.  */
   10861   int size = GET_MODE_SIZE (mode) / move_size;
   10862   /* Himode byte swap is special case to avoid a scratch register.  */
   10863   if (mode == HImode && same_reg)
   10864     {
   10865       /* HImode byte swap, using xor.  This is as quick as using scratch.  */
   10866       rtx src, dst;
   10867       src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
   10868       dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
   10869       if (!rtx_equal_p (dst, src))
   10870 	{
   10871 	  emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
   10872 	  emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
   10873 	  emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
   10874 	}
   10875     }
   10876   else
   10877     {
   10878 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode)  */
   10879       /* Create linked list of moves to determine move order.  */
   10880       struct {
   10881 	rtx src, dst;
   10882 	int links;
   10883       } move[MAX_SIZE + 8];
   10884       int blocked, moves;
   10885 
   10886       gcc_assert (size <= MAX_SIZE);
   10887       /* Generate list of subreg moves.  */
   10888       for (int i = 0; i < size; i++)
   10889 	{
   10890 	  int from = i;
   10891 	  int to = (from + offset) % size;
   10892 	  move[i].src = simplify_gen_subreg (move_mode, operands[1],
   10893 					     mode, from * move_size);
   10894 	  move[i].dst = simplify_gen_subreg (move_mode, operands[0],
   10895 					     mode, to * move_size);
   10896 	  move[i].links = -1;
   10897 	}
   10898       /* Mark dependence where a dst of one move is the src of another move.
   10899 	 The first move is a conflict as it must wait until second is
   10900 	 performed.  We ignore moves to self - we catch this later.  */
   10901       if (overlapped)
   10902 	for (int i = 0; i < size; i++)
   10903 	  if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
   10904 	    for (int j = 0; j < size; j++)
   10905 	      if (j != i && rtx_equal_p (move[j].src, move[i].dst))
   10906 		{
   10907 		  /* The dst of move i is the src of move j.  */
   10908 		  move[i].links = j;
   10909 		  break;
   10910 		}
   10911 
   10912       blocked = -1;
   10913       moves = 0;
   10914       /* Go through move list and perform non-conflicting moves.  As each
   10915 	 non-overlapping move is made, it may remove other conflicts
   10916 	 so the process is repeated until no conflicts remain.  */
   10917       do
   10918 	{
   10919 	  blocked = -1;
   10920 	  moves = 0;
   10921 	  /* Emit move where dst is not also a src or we have used that
   10922 	     src already.  */
   10923 	  for (int i = 0; i < size; i++)
   10924 	    if (move[i].src != NULL_RTX)
   10925 	      {
   10926 		if (move[i].links == -1
   10927 		    || move[move[i].links].src == NULL_RTX)
   10928 		  {
   10929 		    moves++;
   10930 		    /* Ignore NOP moves to self.  */
   10931 		    if (!rtx_equal_p (move[i].dst, move[i].src))
   10932 		      emit_move_insn (move[i].dst, move[i].src);
   10933 
   10934 		    /* Remove  conflict from list.  */
   10935 		    move[i].src = NULL_RTX;
   10936 		  }
   10937 		else
   10938 		  blocked = i;
   10939 	      }
   10940 
   10941 	  /* Check for deadlock. This is when no moves occurred and we have
   10942 	     at least one blocked move.  */
   10943 	  if (moves == 0 && blocked != -1)
   10944 	    {
   10945 	      /* Need to use scratch register to break deadlock.
   10946 		 Add move to put dst of blocked move into scratch.
   10947 		 When this move occurs, it will break chain deadlock.
   10948 		 The scratch register is substituted for real move.  */
   10949 
   10950 	      gcc_assert (SCRATCH != GET_CODE (scratch));
   10951 
   10952 	      move[size].src = move[blocked].dst;
   10953 	      move[size].dst =  scratch;
   10954 	      /* Scratch move is never blocked.  */
   10955 	      move[size].links = -1;
   10956 	      /* Make sure we have valid link.  */
   10957 	      gcc_assert (move[blocked].links != -1);
   10958 	      /* Replace src of  blocking move with scratch reg.  */
   10959 	      move[move[blocked].links].src = scratch;
   10960 	      /* Make dependent on scratch move occurring.  */
   10961 	      move[blocked].links = size;
   10962 	      size=size+1;
   10963 	    }
   10964 	}
   10965       while (blocked != -1);
   10966     }
   10967   return true;
   10968 }
   10969 
   10970 
   10971 /* Worker function for `ADJUST_INSN_LENGTH'.  */
   10972 /* Modifies the length assigned to instruction INSN
   10973    LEN is the initially computed length of the insn.  */
   10974 
   10975 int
   10976 avr_adjust_insn_length (rtx_insn *insn, int len)
   10977 {
   10978   rtx *op = recog_data.operand;
   10979 
   10980   /* As we pretend jump tables in .text, fix branch offsets crossing jump
   10981      tables now.  */
   10982 
   10983   if (JUMP_TABLE_DATA_P (insn))
   10984     return 0;
   10985 
   10986   /* Some complex insns don't need length adjustment and therefore
   10987      the length need not/must not be adjusted for these insns.
   10988      It is easier to state this in an insn attribute "adjust_len" than
   10989      to clutter up code here...  */
   10990 
   10991   if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) == -1)
   10992     {
   10993       return len;
   10994     }
   10995 
   10996   /* Read from insn attribute "adjust_len" if/how length is to be adjusted.  */
   10997 
   10998   enum attr_adjust_len adjust_len = get_attr_adjust_len (insn);
   10999 
   11000   if (adjust_len == ADJUST_LEN_NO)
   11001     {
   11002       /* Nothing to adjust: The length from attribute "length" is fine.
   11003 	 This is the default.  */
   11004 
   11005       return len;
   11006     }
   11007 
   11008   /* Extract insn's operands.  */
   11009 
   11010   extract_constrain_insn_cached (insn);
   11011 
   11012   /* Dispatch to right function.  */
   11013 
   11014   switch (adjust_len)
   11015     {
   11016     case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
   11017     case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
   11018     case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
   11019 
   11020     case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
   11021     case ADJUST_LEN_EXTR_NOT: avr_out_extr_not (insn, op, &len); break;
   11022     case ADJUST_LEN_EXTR: avr_out_extr (insn, op, &len); break;
   11023     case ADJUST_LEN_INSV: avr_out_insv (insn, op, &len); break;
   11024 
   11025     case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
   11026     case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
   11027 
   11028     case ADJUST_LEN_MOV8:  output_movqi (insn, op, &len); break;
   11029     case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
   11030     case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
   11031     case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
   11032     case ADJUST_LEN_CPYMEM: avr_out_cpymem (insn, op, &len); break;
   11033     case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
   11034     case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break;
   11035 
   11036     case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
   11037     case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
   11038     case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
   11039 
   11040     case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
   11041     case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
   11042     case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
   11043     case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
   11044     case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
   11045     case ADJUST_LEN_CMP_UEXT: avr_out_cmp_ext (op, ZERO_EXTEND, &len); break;
   11046     case ADJUST_LEN_CMP_SEXT: avr_out_cmp_ext (op, SIGN_EXTEND, &len); break;
   11047 
   11048     case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
   11049     case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
   11050     case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
   11051 
   11052     case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
   11053     case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
   11054     case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
   11055 
   11056     case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
   11057     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
   11058     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
   11059 
   11060     case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
   11061     case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
   11062     case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
   11063 
   11064     case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
   11065 
   11066     case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
   11067     case ADJUST_LEN_ADD_SET_ZN: avr_out_plus_set_ZN (op, &len); break;
   11068 
   11069     case ADJUST_LEN_INSV_NOTBIT: avr_out_insert_notbit (insn, op, &len); break;
   11070 
   11071     default:
   11072       gcc_unreachable();
   11073     }
   11074 
   11075   return len;
   11076 }
   11077 
   11078 /* Return nonzero if register REG dead after INSN.  */
   11079 
   11080 int
   11081 reg_unused_after (rtx_insn *insn, rtx reg)
   11082 {
   11083   return (dead_or_set_p (insn, reg)
   11084 	  || (REG_P (reg) && _reg_unused_after (insn, reg, true)));
   11085 }
   11086 
   11087 /* A helper for the previous function.
   11088    Return nonzero if REG is not used after INSN.
   11089    We assume REG is a reload reg, and therefore does
   11090    not live past labels.  It may live past calls or jumps though.  */
   11091 
   11092 bool
   11093 _reg_unused_after (rtx_insn *insn, rtx reg, bool look_at_insn)
   11094 {
   11095   if (look_at_insn)
   11096     {
   11097       /* If the reg is set by this instruction, then it is safe for our
   11098 	 case.  Disregard the case where this is a store to memory, since
   11099 	 we are checking a register used in the store address.  */
   11100       rtx set = single_set (insn);
   11101       if (set && !MEM_P (SET_DEST (set))
   11102 	  && reg_overlap_mentioned_p (reg, SET_DEST (set)))
   11103 	return 1;
   11104     }
   11105 
   11106   while ((insn = NEXT_INSN (insn)))
   11107     {
   11108       rtx set;
   11109       enum rtx_code code = GET_CODE (insn);
   11110 
   11111 #if 0
   11112       /* If this is a label that existed before reload, then the register
   11113 	 if dead here.  However, if this is a label added by reorg, then
   11114 	 the register may still be live here.  We can't tell the difference,
   11115 	 so we just ignore labels completely.  */
   11116       if (code == CODE_LABEL)
   11117 	return 1;
   11118       /* else */
   11119 #endif
   11120 
   11121       if (!INSN_P (insn))
   11122 	continue;
   11123 
   11124       if (code == JUMP_INSN)
   11125 	return 0;
   11126 
   11127       /* If this is a sequence, we must handle them all at once.
   11128 	 We could have for instance a call that sets the target register,
   11129 	 and an insn in a delay slot that uses the register.  In this case,
   11130 	 we must return 0.  */
   11131       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
   11132 	{
   11133 	  rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
   11134 	  int retval = 0;
   11135 
   11136 	  for (int i = 0; i < seq->len (); i++)
   11137 	    {
   11138 	      rtx_insn *this_insn = seq->insn (i);
   11139 	      rtx set = single_set (this_insn);
   11140 
   11141 	      if (CALL_P (this_insn))
   11142 		code = CALL_INSN;
   11143 	      else if (JUMP_P (this_insn))
   11144 		{
   11145 		  if (INSN_ANNULLED_BRANCH_P (this_insn))
   11146 		    return 0;
   11147 		  code = JUMP_INSN;
   11148 		}
   11149 
   11150 	      if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
   11151 		return 0;
   11152 	      if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
   11153 		{
   11154 		  if (!MEM_P (SET_DEST (set)))
   11155 		    retval = 1;
   11156 		  else
   11157 		    return 0;
   11158 		}
   11159 	      if (set == 0
   11160 		  && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
   11161 		return 0;
   11162 	    }
   11163 	  if (retval == 1)
   11164 	    return 1;
   11165 	  else if (code == JUMP_INSN)
   11166 	    return 0;
   11167 	}
   11168 
   11169       if (code == CALL_INSN)
   11170 	{
   11171 	  rtx tem;
   11172 	  for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
   11173 	    if (GET_CODE (XEXP (tem, 0)) == USE
   11174 		&& REG_P (XEXP (XEXP (tem, 0), 0))
   11175 		&& reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
   11176 	      return 0;
   11177 	  if (call_used_or_fixed_reg_p (REGNO (reg)))
   11178 	    return 1;
   11179 	}
   11180 
   11181       set = single_set (insn);
   11182 
   11183       if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
   11184 	return 0;
   11185       if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
   11186 	return !MEM_P (SET_DEST (set));
   11187       if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
   11188 	return 0;
   11189     }
   11190   return 1;
   11191 }
   11192 
   11193 
   11194 /* Implement `TARGET_ASM_INTEGER'.  */
   11195 /* Target hook for assembling integer objects.  The AVR version needs
   11196    special handling for references to certain labels.  */
   11197 
   11198 static bool
   11199 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
   11200 {
   11201   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
   11202       && text_segment_operand (x, VOIDmode))
   11203     {
   11204       fputs ("\t.word\tgs(", asm_out_file);
   11205       output_addr_const (asm_out_file, x);
   11206       fputs (")\n", asm_out_file);
   11207 
   11208       return true;
   11209     }
   11210   else if (GET_MODE (x) == PSImode)
   11211     {
   11212       /* This needs binutils 2.23+, see PR binutils/13503  */
   11213 
   11214       fputs ("\t.byte\tlo8(", asm_out_file);
   11215       output_addr_const (asm_out_file, x);
   11216       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
   11217 
   11218       fputs ("\t.byte\thi8(", asm_out_file);
   11219       output_addr_const (asm_out_file, x);
   11220       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
   11221 
   11222       fputs ("\t.byte\thh8(", asm_out_file);
   11223       output_addr_const (asm_out_file, x);
   11224       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
   11225 
   11226       return true;
   11227     }
   11228   else if (CONST_FIXED_P (x))
   11229     {
   11230       /* varasm fails to handle big fixed modes that don't fit in hwi.  */
   11231 
   11232       for (unsigned n = 0; n < size; n++)
   11233 	{
   11234 	  rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
   11235 	  default_assemble_integer (xn, 1, aligned_p);
   11236 	}
   11237 
   11238       return true;
   11239     }
   11240 
   11241   if (AVR_TINY
   11242       && avr_address_tiny_pm_p (x))
   11243     {
   11244       x = plus_constant (Pmode, x, avr_arch->flash_pm_offset);
   11245     }
   11246 
   11247   return default_assemble_integer (x, size, aligned_p);
   11248 }
   11249 
   11250 /* Implement `TARGET_CLASS_MAX_NREGS'.  Reasons described in comments for
   11251    avr_hard_regno_nregs. */
   11252 
   11253 static unsigned char
   11254 avr_class_max_nregs (reg_class_t rclass, machine_mode mode)
   11255 {
   11256   if (rclass == CC_REG && mode == CCmode)
   11257     return 1;
   11258 
   11259   return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   11260 }
   11261 
   11262 
   11263 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'.  */
   11264 /* Return value is nonzero if pseudos that have been
   11265    assigned to registers of class CLASS would likely be spilled
   11266    because registers of CLASS are needed for spill registers.  */
   11267 
   11268 static bool
   11269 avr_class_likely_spilled_p (reg_class_t c)
   11270 {
   11271   return (c != ALL_REGS
   11272 	  && (AVR_TINY ? 1 : c != ADDW_REGS));
   11273 }
   11274 
   11275 
   11276 /* Valid attributes:
   11277    progmem   -	Put data to program memory.
   11278    signal    -	Make a function to be hardware interrupt.
   11279 		After function prologue interrupts remain disabled.
   11280    interrupt -	Make a function to be hardware interrupt. Before function
   11281 		prologue interrupts are enabled by means of SEI.
   11282    naked     -	Don't generate function prologue/epilogue and RET
   11283 		instruction.  */
   11284 
   11285 /* Handle a "progmem" attribute; arguments as in
   11286    struct attribute_spec.handler.  */
   11287 
   11288 static tree
   11289 avr_handle_progmem_attribute (tree *node, tree name, tree args,
   11290 			      int /*flags*/, bool *no_add_attrs)
   11291 {
   11292   if (DECL_P (*node))
   11293     {
   11294       if (TREE_CODE (*node) == TYPE_DECL)
   11295 	{
   11296 	  /* This is really a decl attribute, not a type attribute,
   11297 	     but try to handle it for GCC 3.0 backwards compatibility.  */
   11298 
   11299 	  tree type = TREE_TYPE (*node);
   11300 	  tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
   11301 	  tree newtype = build_type_attribute_variant (type, attr);
   11302 
   11303 	  TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
   11304 	  TREE_TYPE (*node) = newtype;
   11305 	  *no_add_attrs = true;
   11306 	}
   11307       else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
   11308 	{
   11309 	  *no_add_attrs = false;
   11310 	}
   11311       else
   11312 	{
   11313 	  warning (OPT_Wattributes, "%qE attribute ignored",
   11314 		   name);
   11315 	  *no_add_attrs = true;
   11316 	}
   11317     }
   11318 
   11319   return NULL_TREE;
   11320 }
   11321 
   11322 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
   11323    struct attribute_spec.handler.  */
   11324 
   11325 static tree
   11326 avr_handle_fndecl_attribute (tree *node, tree name, tree /*args*/,
   11327 			     int /*flags*/, bool *no_add_attrs)
   11328 {
   11329   if (TREE_CODE (*node) != FUNCTION_DECL)
   11330     {
   11331       warning (OPT_Wattributes, "%qE attribute only applies to functions",
   11332 	       name);
   11333       *no_add_attrs = true;
   11334     }
   11335 
   11336   return NULL_TREE;
   11337 }
   11338 
   11339 static tree
   11340 avr_handle_fntype_attribute (tree *node, tree name, tree /*args*/,
   11341 			     int /*flags*/, bool *no_add_attrs)
   11342 {
   11343   if (TREE_CODE (*node) != FUNCTION_TYPE)
   11344     {
   11345       warning (OPT_Wattributes, "%qE attribute only applies to functions",
   11346 	       name);
   11347       *no_add_attrs = true;
   11348     }
   11349 
   11350   return NULL_TREE;
   11351 }
   11352 
   11353 static tree
   11354 avr_handle_absdata_attribute (tree *node, tree name, tree /* args */,
   11355 			      int /* flags */, bool *no_add)
   11356 {
   11357   location_t loc = DECL_SOURCE_LOCATION (*node);
   11358 
   11359   if (AVR_TINY)
   11360     {
   11361       if (TREE_CODE (*node) != VAR_DECL
   11362 	  || (!TREE_STATIC (*node) && !DECL_EXTERNAL (*node)))
   11363 	{
   11364 	  warning_at (loc, OPT_Wattributes, "%qE attribute only applies to"
   11365 		      " variables in static storage", name);
   11366 	  *no_add = true;
   11367 	}
   11368     }
   11369   else
   11370     {
   11371       warning_at (loc, OPT_Wattributes, "%qE attribute only supported"
   11372 		  " for reduced Tiny cores", name);
   11373       *no_add = true;
   11374     }
   11375 
   11376   return NULL_TREE;
   11377 }
   11378 
   11379 static tree
   11380 avr_handle_addr_attribute (tree *node, tree name, tree args,
   11381 			   int /*flags*/, bool *no_add)
   11382 {
   11383   bool io_p = startswith (IDENTIFIER_POINTER (name), "io");
   11384   HOST_WIDE_INT io_start = avr_arch->sfr_offset;
   11385   HOST_WIDE_INT io_end = strcmp (IDENTIFIER_POINTER (name), "io_low") == 0
   11386     ? io_start + 0x1f
   11387     : io_start + 0x3f;
   11388   location_t loc = DECL_SOURCE_LOCATION (*node);
   11389 
   11390   if (!VAR_P (*node))
   11391     {
   11392       warning_at (loc, OPT_Wattributes, "%qE attribute only applies to "
   11393 		  "variables", name);
   11394       *no_add = true;
   11395       return NULL_TREE;
   11396     }
   11397 
   11398   if (args != NULL_TREE)
   11399     {
   11400       if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
   11401 	TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
   11402       tree arg = TREE_VALUE (args);
   11403       if (TREE_CODE (arg) != INTEGER_CST)
   11404 	{
   11405 	  warning_at (loc, OPT_Wattributes, "%qE attribute allows only an "
   11406 		      "integer constant argument", name);
   11407 	  *no_add = true;
   11408 	}
   11409       else if (io_p
   11410 	       && (!tree_fits_shwi_p (arg)
   11411 		   || ! IN_RANGE (TREE_INT_CST_LOW (arg), io_start, io_end)))
   11412 	{
   11413 	  warning_at (loc, OPT_Wattributes, "%qE attribute address out of range"
   11414 		      " 0x%x%s0x%x", name, (int) io_start, "...", (int) io_end);
   11415 	  *no_add = true;
   11416 	}
   11417       else
   11418 	{
   11419 	  tree attribs = DECL_ATTRIBUTES (*node);
   11420 	  const char *names[] = { "io", "io_low", "address", NULL };
   11421 	  for (const char **p = names; *p; p++)
   11422 	    {
   11423 	      tree other = lookup_attribute (*p, attribs);
   11424 	      if (other && TREE_VALUE (other))
   11425 		{
   11426 		  warning_at (loc, OPT_Wattributes,
   11427 			      "both %s and %qE attribute provide address",
   11428 			      *p, name);
   11429 		  *no_add = true;
   11430 		  break;
   11431 		}
   11432 	    }
   11433 	}
   11434     }
   11435 
   11436   if (*no_add == false && io_p && !TREE_THIS_VOLATILE (*node))
   11437     warning_at (loc, OPT_Wattributes, "%qE attribute on non-volatile variable",
   11438 		name);
   11439 
   11440   // Optimizers must not draw any conclusions from "static int addr;" etc.
   11441   // because the contents of `addr' are not given by its initializer but
   11442   // by the contents at the address as specified by the attribute.
   11443   if (VAR_P (*node) && ! *no_add)
   11444     TREE_THIS_VOLATILE (*node) = 1;
   11445 
   11446   return NULL_TREE;
   11447 }
   11448 
   11449 rtx
   11450 avr_eval_addr_attrib (rtx x)
   11451 {
   11452   if (SYMBOL_REF_P (x)
   11453       && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_ADDRESS))
   11454     {
   11455       tree decl = SYMBOL_REF_DECL (x);
   11456       tree attr = NULL_TREE;
   11457 
   11458       if (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO)
   11459 	{
   11460 	  attr = lookup_attribute ("io", DECL_ATTRIBUTES (decl));
   11461 	  if (!attr || !TREE_VALUE (attr))
   11462 	    attr = lookup_attribute ("io_low", DECL_ATTRIBUTES (decl));
   11463 	}
   11464       if (!attr || !TREE_VALUE (attr))
   11465 	attr = lookup_attribute ("address", DECL_ATTRIBUTES (decl));
   11466       gcc_assert (attr && TREE_VALUE (attr) && TREE_VALUE (TREE_VALUE (attr)));
   11467       return GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))));
   11468     }
   11469   return x;
   11470 }
   11471 
   11472 
   11473 /* AVR attributes.  */
   11474 TARGET_GNU_ATTRIBUTES (avr_attribute_table,
   11475 {
   11476   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
   11477        affects_type_identity, handler, exclude } */
   11478   { "progmem",   0, 0, false, false, false, false,
   11479     avr_handle_progmem_attribute, NULL },
   11480   { "signal",    0, 0, true,  false, false, false,
   11481     avr_handle_fndecl_attribute, NULL },
   11482   { "interrupt", 0, 0, true,  false, false, false,
   11483     avr_handle_fndecl_attribute, NULL },
   11484   { "no_gccisr", 0, 0, true,  false, false, false,
   11485     avr_handle_fndecl_attribute, NULL },
   11486   { "naked",     0, 0, false, true,  true,  false,
   11487     avr_handle_fntype_attribute, NULL },
   11488   { "OS_task",   0, 0, false, true,  true,  false,
   11489     avr_handle_fntype_attribute, NULL },
   11490   { "OS_main",   0, 0, false, true,  true,  false,
   11491     avr_handle_fntype_attribute, NULL },
   11492   { "io",        0, 1, true, false, false,  false,
   11493     avr_handle_addr_attribute, NULL },
   11494   { "io_low",    0, 1, true, false, false,  false,
   11495     avr_handle_addr_attribute, NULL },
   11496   { "address",   1, 1, true, false, false,  false,
   11497     avr_handle_addr_attribute, NULL },
   11498   { "absdata",   0, 0, true, false, false,  false,
   11499     avr_handle_absdata_attribute, NULL }
   11500 });
   11501 
   11502 
   11503 /* Return true if we support address space AS for the architecture in effect
   11504    and false, otherwise.  If LOC is not UNKNOWN_LOCATION then also issue
   11505    a respective error.  */
   11506 
   11507 bool
   11508 avr_addr_space_supported_p (addr_space_t as, location_t loc)
   11509 {
   11510   if (AVR_TINY)
   11511     {
   11512       if (loc != UNKNOWN_LOCATION)
   11513 	error_at (loc, "address spaces are not supported for reduced "
   11514 		  "Tiny devices");
   11515       return false;
   11516     }
   11517   else if (avr_addrspace[as].segment >= avr_n_flash)
   11518     {
   11519       if (loc != UNKNOWN_LOCATION)
   11520 	error_at (loc, "address space %qs not supported for devices with "
   11521 		  "flash size up to %d KiB", avr_addrspace[as].name,
   11522 		  64 * avr_n_flash);
   11523       return false;
   11524     }
   11525 
   11526   return true;
   11527 }
   11528 
   11529 
   11530 /* Implement `TARGET_ADDR_SPACE_DIAGNOSE_USAGE'.  */
   11531 
   11532 static void
   11533 avr_addr_space_diagnose_usage (addr_space_t as, location_t loc)
   11534 {
   11535   (void) avr_addr_space_supported_p (as, loc);
   11536 }
   11537 
   11538 
   11539 /* Implement `TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID'.  Zero is a valid
   11540    address in all address spaces. Even in ADDR_SPACE_FLASH1 etc..,
   11541    a zero address is valid and means 0x<RAMPZ val>0000, where RAMPZ is
   11542    set to the appropriate segment value. */
   11543 
   11544 static bool
   11545 avr_addr_space_zero_address_valid (addr_space_t)
   11546 {
   11547   return true;
   11548 }
   11549 
   11550 
   11551 /* Look if DECL shall be placed in program memory space by
   11552    means of attribute `progmem' or some address-space qualifier.
   11553    Return non-zero if DECL is data that must end up in Flash and
   11554    zero if the data lives in RAM (.bss, .data, .rodata, ...).
   11555 
   11556    Return 2   if DECL is located in 24-bit flash address-space
   11557    Return 1   if DECL is located in 16-bit flash address-space
   11558    Return -1  if attribute `progmem' occurs in DECL or ATTRIBUTES
   11559    Return 0   otherwise  */
   11560 
   11561 int
   11562 avr_progmem_p (tree decl, tree attributes)
   11563 {
   11564   if (TREE_CODE (decl) != VAR_DECL)
   11565     return 0;
   11566 
   11567   if (avr_decl_memx_p (decl))
   11568     return 2;
   11569 
   11570   if (avr_decl_flash_p (decl))
   11571     return 1;
   11572 
   11573   if (NULL_TREE
   11574       != lookup_attribute ("progmem", attributes))
   11575     return -1;
   11576 
   11577   tree a = decl;
   11578 
   11579   do
   11580     a = TREE_TYPE(a);
   11581   while (TREE_CODE (a) == ARRAY_TYPE);
   11582 
   11583   if (a == error_mark_node)
   11584     return 0;
   11585 
   11586   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
   11587     return -1;
   11588 
   11589   return 0;
   11590 }
   11591 
   11592 
   11593 /* Return true if DECL has attribute `absdata' set.  This function should
   11594    only be used for AVR_TINY.  */
   11595 
   11596 static bool
   11597 avr_decl_absdata_p (tree decl, tree attributes)
   11598 {
   11599   return (VAR_P (decl)
   11600 	  && NULL_TREE != lookup_attribute ("absdata", attributes));
   11601 }
   11602 
   11603 
   11604 /* Scan type TYP for pointer references to address space ASn.
   11605    Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
   11606    the AS are also declared to be CONST.
   11607    Otherwise, return the respective address space, i.e. a value != 0.  */
   11608 
   11609 static addr_space_t
   11610 avr_nonconst_pointer_addrspace (tree typ)
   11611 {
   11612   while (ARRAY_TYPE == TREE_CODE (typ))
   11613     typ = TREE_TYPE (typ);
   11614 
   11615   if (POINTER_TYPE_P (typ))
   11616     {
   11617       tree target = TREE_TYPE (typ);
   11618 
   11619       /* Pointer to function: Test the function's return type.  */
   11620 
   11621       if (FUNCTION_TYPE == TREE_CODE (target))
   11622 	return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
   11623 
   11624       /* "Ordinary" pointers... */
   11625 
   11626       while (TREE_CODE (target) == ARRAY_TYPE)
   11627 	target = TREE_TYPE (target);
   11628 
   11629       /* Pointers to non-generic address space must be const.  */
   11630 
   11631       addr_space_t as = TYPE_ADDR_SPACE (target);
   11632 
   11633       if (!ADDR_SPACE_GENERIC_P (as)
   11634 	  && !TYPE_READONLY (target)
   11635 	  && avr_addr_space_supported_p (as))
   11636 	{
   11637 	  return as;
   11638 	}
   11639 
   11640       /* Scan pointer's target type.  */
   11641 
   11642       return avr_nonconst_pointer_addrspace (target);
   11643     }
   11644 
   11645   return ADDR_SPACE_GENERIC;
   11646 }
   11647 
   11648 
   11649 /* Sanity check NODE so that all pointers targeting non-generic address spaces
   11650    go along with CONST qualifier.  Writing to these address spaces should
   11651    be detected and complained about as early as possible.  */
   11652 
   11653 static bool
   11654 avr_pgm_check_var_decl (tree node)
   11655 {
   11656   const char *reason = NULL;
   11657 
   11658   addr_space_t as = ADDR_SPACE_GENERIC;
   11659 
   11660   gcc_assert (as == 0);
   11661 
   11662   if (avr_log.progmem)
   11663     avr_edump ("%?: %t\n", node);
   11664 
   11665   switch (TREE_CODE (node))
   11666     {
   11667     default:
   11668       break;
   11669 
   11670     case VAR_DECL:
   11671       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
   11672 	reason = _("variable");
   11673       break;
   11674 
   11675     case PARM_DECL:
   11676       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
   11677 	reason = _("function parameter");
   11678       break;
   11679 
   11680     case FIELD_DECL:
   11681       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
   11682 	reason = _("structure field");
   11683       break;
   11684 
   11685     case FUNCTION_DECL:
   11686       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
   11687 	  as)
   11688 	reason = _("return type of function");
   11689       break;
   11690 
   11691     case POINTER_TYPE:
   11692       if (as = avr_nonconst_pointer_addrspace (node), as)
   11693 	reason = _("pointer");
   11694       break;
   11695     }
   11696 
   11697   if (reason)
   11698     {
   11699       if (TYPE_P (node))
   11700 	error ("pointer targeting address space %qs must be const in %qT",
   11701 	       avr_addrspace[as].name, node);
   11702       else
   11703 	error ("pointer targeting address space %qs must be const"
   11704 	       " in %s %q+D",
   11705 	       avr_addrspace[as].name, reason, node);
   11706     }
   11707 
   11708   return reason == NULL;
   11709 }
   11710 
   11711 
   11712 /* Implement `TARGET_INSERT_ATTRIBUTES'.  */
   11713 
   11714 static void
   11715 avr_insert_attributes (tree node, tree *attributes)
   11716 {
   11717   if (VAR_P (node)
   11718       && ! TREE_STATIC (node)
   11719       && ! DECL_EXTERNAL (node))
   11720     {
   11721       const char *names[] = { "io", "io_low", "address", NULL };
   11722       for (const char **p = names; *p; ++p)
   11723 	if (lookup_attribute (*p, *attributes))
   11724 	  error ("variable %q+D with attribute %qs must be located in "
   11725 		 "static storage", node, *p);
   11726     }
   11727 
   11728   avr_pgm_check_var_decl (node);
   11729 
   11730   if (TARGET_MAIN_IS_OS_TASK
   11731       && TREE_CODE (node) == FUNCTION_DECL
   11732       && MAIN_NAME_P (DECL_NAME (node))
   11733       // FIXME:  We'd like to also test `flag_hosted' which is only
   11734       // available in the C-ish fronts, hence no such test for now.
   11735       // Instead, we test the return type of "main" which is not exactly
   11736       // the same but good enough.
   11737       && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (node)))
   11738       && NULL == lookup_attribute ("OS_task", *attributes))
   11739     {
   11740       *attributes = tree_cons (get_identifier ("OS_task"),
   11741 			       NULL, *attributes);
   11742     }
   11743 
   11744   /* Add the section attribute if the variable is in progmem.  */
   11745 
   11746   if (VAR_P (node)
   11747       && (TREE_STATIC (node) || DECL_EXTERNAL (node))
   11748       && avr_progmem_p (node, *attributes))
   11749     {
   11750       tree node0 = node;
   11751 
   11752       /* For C++, we have to peel arrays in order to get correct
   11753 	 determination of readonlyness.  */
   11754 
   11755       do
   11756 	node0 = TREE_TYPE (node0);
   11757       while (TREE_CODE (node0) == ARRAY_TYPE);
   11758 
   11759       if (error_mark_node == node0)
   11760 	return;
   11761 
   11762       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (node));
   11763 
   11764       if (!TYPE_READONLY (node0)
   11765 	  && !TREE_READONLY (node))
   11766 	{
   11767 	  const char *reason = "__attribute__((progmem))";
   11768 
   11769 	  if (!ADDR_SPACE_GENERIC_P (as))
   11770 	    reason = avr_addrspace[as].name;
   11771 
   11772 	  if (avr_log.progmem)
   11773 	    avr_edump ("\n%?: %t\n%t\n", node, node0);
   11774 
   11775 	  error ("variable %q+D must be const in order to be put into"
   11776 		 " read-only section by means of %qs", node, reason);
   11777 	}
   11778     }
   11779 }
   11780 
   11781 #ifdef HAVE_LD_AVR_AVRXMEGA2_FLMAP
   11782 static const bool have_avrxmega2_flmap = true;
   11783 #else
   11784 static const bool have_avrxmega2_flmap = false;
   11785 #endif
   11786 
   11787 #ifdef HAVE_LD_AVR_AVRXMEGA4_FLMAP
   11788 static const bool have_avrxmega4_flmap = true;
   11789 #else
   11790 static const bool have_avrxmega4_flmap = false;
   11791 #endif
   11792 
   11793 #ifdef HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH
   11794 static const bool have_avrxmega3_rodata_in_flash = true;
   11795 #else
   11796 static const bool have_avrxmega3_rodata_in_flash = false;
   11797 #endif
   11798 
   11799 
   11800 static bool
   11801 avr_rodata_in_flash_p ()
   11802 {
   11803   switch (avr_arch_index)
   11804     {
   11805     default:
   11806       break;
   11807 
   11808     case ARCH_AVRTINY:
   11809       return true;
   11810 
   11811     case ARCH_AVRXMEGA3:
   11812       return have_avrxmega3_rodata_in_flash;
   11813 
   11814     case ARCH_AVRXMEGA2:
   11815       return avr_flmap && have_avrxmega2_flmap && avr_rodata_in_ram != 1;
   11816 
   11817     case ARCH_AVRXMEGA4:
   11818       return avr_flmap && have_avrxmega4_flmap && avr_rodata_in_ram != 1;
   11819     }
   11820 
   11821   return false;
   11822 }
   11823 
   11824 
   11825 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'.  */
   11826 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'.  */
   11827 /* Track need of __do_clear_bss.  */
   11828 
   11829 void
   11830 avr_asm_output_aligned_decl_common (FILE *stream, tree /* decl */,
   11831 				    const char *name,
   11832 				    unsigned HOST_WIDE_INT size,
   11833 				    unsigned int align, bool local_p)
   11834 {
   11835   /* __gnu_lto_slim is just a marker for the linker injected by toplev.cc.
   11836      There is no need to trigger __do_clear_bss code for them.  */
   11837 
   11838   if (!startswith (name, "__gnu_lto"))
   11839     avr_need_clear_bss_p = true;
   11840 
   11841   if (local_p)
   11842     ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
   11843   else
   11844     ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
   11845 }
   11846 
   11847 
   11848 /* Implement `ASM_OUTPUT_ALIGNED_BSS'.  */
   11849 
   11850 void
   11851 avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
   11852 				unsigned HOST_WIDE_INT size, int align,
   11853 				void (*default_func)
   11854 				  (FILE *, tree, const char *,
   11855 				   unsigned HOST_WIDE_INT, int))
   11856 {
   11857   if (!startswith (name, "__gnu_lto"))
   11858     avr_need_clear_bss_p = true;
   11859 
   11860   default_func (file, decl, name, size, align);
   11861 }
   11862 
   11863 
   11864 /* Unnamed section callback for data_section
   11865    to track need of __do_copy_data.  */
   11866 
   11867 static void
   11868 avr_output_data_section_asm_op (const char *data)
   11869 {
   11870   avr_need_copy_data_p = true;
   11871 
   11872   /* Dispatch to default.  */
   11873   output_section_asm_op (data);
   11874 }
   11875 
   11876 
   11877 /* Unnamed section callback for bss_section
   11878    to track need of __do_clear_bss.  */
   11879 
   11880 static void
   11881 avr_output_bss_section_asm_op (const char *data)
   11882 {
   11883   avr_need_clear_bss_p = true;
   11884 
   11885   /* Dispatch to default.  */
   11886   output_section_asm_op (data);
   11887 }
   11888 
   11889 
   11890 /* Unnamed section callback for progmem*.data sections.  */
   11891 
   11892 static void
   11893 avr_output_progmem_section_asm_op (const char *data)
   11894 {
   11895   fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n", data);
   11896 }
   11897 
   11898 
   11899 /* A noswitch section callback to output symbol definitions for
   11900    attributes "io", "io_low" and "address".  */
   11901 
   11902 static bool
   11903 avr_output_addr_attrib (tree decl, const char *name,
   11904 			unsigned HOST_WIDE_INT /* size */,
   11905 			unsigned HOST_WIDE_INT /* align */)
   11906 {
   11907   gcc_assert (DECL_RTL_SET_P (decl));
   11908 
   11909   FILE *stream = asm_out_file;
   11910   bool local_p = ! DECL_WEAK (decl) && ! TREE_PUBLIC (decl);
   11911   rtx symbol, mem = DECL_RTL (decl);
   11912 
   11913   if (mem != NULL_RTX && MEM_P (mem)
   11914       && SYMBOL_REF_P ((symbol = XEXP (mem, 0)))
   11915       && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
   11916     {
   11917       if (! local_p)
   11918 	{
   11919 	  fprintf (stream, "\t%s\t", DECL_WEAK (decl) ? ".weak" : ".globl");
   11920 	  assemble_name (stream, name);
   11921 	  fprintf (stream, "\n");
   11922 	}
   11923 
   11924       if (SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS)
   11925 	{
   11926 	  assemble_name (stream, name);
   11927 	  fprintf (stream, " = %ld\n",
   11928 		   (long) INTVAL (avr_eval_addr_attrib (symbol)));
   11929 	}
   11930       else if (local_p)
   11931 	{
   11932 	  const char *names[] = { "io", "io_low", "address", NULL };
   11933 	  for (const char **p = names; *p; ++p)
   11934 	    if (lookup_attribute (*p, DECL_ATTRIBUTES (decl)))
   11935 	      {
   11936 		error ("static attribute %qs declaration for %q+D needs an "
   11937 		       "address", *p, decl);
   11938 		break;
   11939 	      }
   11940 	}
   11941 
   11942       return true;
   11943     }
   11944 
   11945   gcc_unreachable();
   11946 
   11947   return false;
   11948 }
   11949 
   11950 
   11951 /* Implement `TARGET_ASM_INIT_SECTIONS'.  */
   11952 
   11953 static void
   11954 avr_asm_init_sections (void)
   11955 {
   11956   /* Override section callbacks to keep track of `avr_need_clear_bss_p',
   11957      `avr_need_copy_data_p' and `avr_has_rodata_p'.
   11958      Track also .rodata for the case when .rodata is located in RAM.  */
   11959 
   11960   if (! avr_rodata_in_flash_p ())
   11961     readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
   11962   data_section->unnamed.callback = avr_output_data_section_asm_op;
   11963   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
   11964   tls_comm_section->noswitch.callback = avr_output_addr_attrib;
   11965 }
   11966 
   11967 
   11968 /* Implement `TARGET_ASM_NAMED_SECTION'.  */
   11969 /* Track need of __do_clear_bss, __do_copy_data for named sections.  */
   11970 
   11971 static void
   11972 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
   11973 {
   11974   if (flags & AVR_SECTION_PROGMEM
   11975       // Only use section .progmem*.data if there is no attribute section.
   11976       && ! (decl
   11977 	    && DECL_SECTION_NAME (decl)
   11978 	    && symtab_node::get (decl)
   11979 	    && ! symtab_node::get (decl)->implicit_section))
   11980     {
   11981       addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
   11982       const char *old_prefix = ".rodata";
   11983       const char *new_prefix = avr_addrspace[as].section_name;
   11984 
   11985       if (startswith (name, old_prefix))
   11986 	{
   11987 	  const char *sname = ACONCAT ((new_prefix,
   11988 					name + strlen (old_prefix), NULL));
   11989 	  default_elf_asm_named_section (sname, flags, decl);
   11990 	  return;
   11991 	}
   11992 
   11993       default_elf_asm_named_section (new_prefix, flags, decl);
   11994       return;
   11995     }
   11996 
   11997   if (!avr_need_copy_data_p)
   11998     avr_need_copy_data_p = (startswith (name, ".data")
   11999 			    || startswith (name, ".gnu.linkonce.d"));
   12000 
   12001   if (!avr_has_rodata_p)
   12002     avr_has_rodata_p = (startswith (name, ".rodata")
   12003 			|| startswith (name, ".gnu.linkonce.r"));
   12004 
   12005   if (!avr_need_clear_bss_p)
   12006     avr_need_clear_bss_p = startswith (name, ".bss");
   12007 
   12008   default_elf_asm_named_section (name, flags, decl);
   12009 }
   12010 
   12011 
   12012 /* Implement `TARGET_SECTION_TYPE_FLAGS'.  */
   12013 
   12014 static unsigned int
   12015 avr_section_type_flags (tree decl, const char *name, int reloc)
   12016 {
   12017   unsigned int flags = default_section_type_flags (decl, name, reloc);
   12018 
   12019   if (startswith (name, ".noinit"))
   12020     {
   12021       if (decl && VAR_P (decl)
   12022 	  && DECL_INITIAL (decl) == NULL_TREE)
   12023 	flags |= SECTION_BSS;  /* @nobits */
   12024       else
   12025 	warning (0, "only uninitialized variables can be placed in the "
   12026 		 "%<.noinit%> section");
   12027     }
   12028 
   12029   if (decl && DECL_P (decl)
   12030       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
   12031     {
   12032       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
   12033 
   12034       /* Attribute progmem puts data in generic address space.
   12035 	 Set section flags as if it was in __flash to get the right
   12036 	 section prefix in the remainder.  */
   12037 
   12038       if (ADDR_SPACE_GENERIC_P (as))
   12039 	as = ADDR_SPACE_FLASH;
   12040 
   12041       flags |= as * SECTION_MACH_DEP;
   12042       flags &= ~SECTION_WRITE;
   12043       flags &= ~SECTION_BSS;
   12044       flags &= ~SECTION_NOTYPE;
   12045     }
   12046 
   12047   return flags;
   12048 }
   12049 
   12050 
   12051 /* A helper for the next function.  NODE is a decl that is associated with
   12052    a symbol.  Return TRUE if the respective object may be accessed by LDS.
   12053    There might still be other reasons for why LDS is not appropriate.
   12054    This function is only appropriate for AVR_TINY.  */
   12055 
   12056 static bool
   12057 avr_decl_maybe_lds_p (tree node)
   12058 {
   12059   if (!node
   12060       || TREE_CODE (node) != VAR_DECL
   12061       || DECL_SECTION_NAME (node) != NULL)
   12062     return false;
   12063 
   12064   /* Don't use LDS for objects that go to .rodata.  The current default
   12065      linker description file still locates .rodata in RAM, but this is not
   12066      a must.  A better linker script would just keep .rodata in flash and
   12067      add an offset of 0x4000 to the VMA.  Hence avoid LDS for such data.  */
   12068 
   12069   if (TREE_READONLY (node))
   12070     return false;
   12071 
   12072   // C++ requires peeling arrays.
   12073 
   12074   do
   12075     node = TREE_TYPE (node);
   12076   while (ARRAY_TYPE == TREE_CODE (node));
   12077 
   12078   return (node != error_mark_node
   12079 	  && !TYPE_READONLY (node));
   12080 }
   12081 
   12082 
   12083 /* Implement `TARGET_ENCODE_SECTION_INFO'.  */
   12084 
   12085 static void
   12086 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
   12087 {
   12088   tree addr_attr = NULL_TREE;
   12089 
   12090   /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
   12091      readily available, see PR34734.  So we postpone the warning
   12092      about uninitialized data in program memory section until here.  */
   12093 
   12094   if (new_decl_p
   12095       && decl && DECL_P (decl)
   12096       && !DECL_EXTERNAL (decl)
   12097       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
   12098     {
   12099       if (!TREE_READONLY (decl))
   12100 	{
   12101 	  // This might happen with C++ if stuff needs constructing.
   12102 	  error ("variable %q+D with dynamic initialization put "
   12103 		 "into program memory area", decl);
   12104 	}
   12105       else if (NULL_TREE == DECL_INITIAL (decl))
   12106 	{
   12107 	  // Don't warn for (implicit) aliases like in PR80462.
   12108 	  tree asmname = DECL_ASSEMBLER_NAME (decl);
   12109 	  varpool_node *node = varpool_node::get_for_asmname (asmname);
   12110 	  bool alias_p = node && node->alias;
   12111 
   12112 	  if (!alias_p)
   12113 	    warning (OPT_Wuninitialized, "uninitialized variable %q+D put "
   12114 		     "into program memory area", decl);
   12115 	}
   12116     }
   12117 
   12118   default_encode_section_info (decl, rtl, new_decl_p);
   12119 
   12120   if (decl && DECL_P (decl)
   12121       && TREE_CODE (decl) != FUNCTION_DECL
   12122       && MEM_P (rtl)
   12123       && SYMBOL_REF_P (XEXP (rtl, 0)))
   12124     {
   12125       rtx sym = XEXP (rtl, 0);
   12126       tree type = TREE_TYPE (decl);
   12127       tree attr = DECL_ATTRIBUTES (decl);
   12128       if (type == error_mark_node)
   12129 	return;
   12130 
   12131       addr_space_t as = TYPE_ADDR_SPACE (type);
   12132 
   12133       /* PSTR strings are in generic space but located in flash:
   12134 	 patch address space.  */
   12135 
   12136       if (!AVR_TINY && avr_progmem_p (decl, attr) == -1)
   12137 	as = ADDR_SPACE_FLASH;
   12138 
   12139       AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
   12140 
   12141       tree io_low_attr = lookup_attribute ("io_low", attr);
   12142       tree io_attr = lookup_attribute ("io", attr);
   12143       tree address_attr = lookup_attribute ("address", attr);
   12144 
   12145       if (io_low_attr
   12146 	  && TREE_VALUE (io_low_attr) && TREE_VALUE (TREE_VALUE (io_low_attr)))
   12147 	addr_attr = io_low_attr;
   12148       else if (io_attr
   12149 	       && TREE_VALUE (io_attr) && TREE_VALUE (TREE_VALUE (io_attr)))
   12150 	addr_attr = io_attr;
   12151       else
   12152 	addr_attr = address_attr;
   12153 
   12154       if (io_low_attr
   12155 	  || (io_attr && addr_attr
   12156 	      && low_io_address_operand
   12157 		  (GEN_INT (TREE_INT_CST_LOW
   12158 			    (TREE_VALUE (TREE_VALUE (addr_attr)))), QImode)))
   12159 	SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO_LOW;
   12160       if (io_attr || io_low_attr)
   12161 	SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO;
   12162       /* If we have an (io) address attribute specification, but the variable
   12163 	 is external, treat the address as only a tentative definition
   12164 	 to be used to determine if an io port is in the lower range, but
   12165 	 don't use the exact value for constant propagation.  */
   12166       if (addr_attr && !DECL_EXTERNAL (decl))
   12167 	SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS;
   12168 
   12169       if (io_attr || io_low_attr || address_attr)
   12170 	{
   12171 	  if (DECL_INITIAL (decl))
   12172 	    {
   12173 	      /* Initializers are not yet parsed in TARGET_INSERT_ATTRIBUTES,
   12174 		 hence deny initializers now.  The values of symbols with an
   12175 		 address attribute are determined by the attribute, not by
   12176 		 some initializer.  */
   12177 
   12178 	      error ("variable %q+D with attribute %qs must not have an "
   12179 		     "initializer", decl,
   12180 		     io_low_attr ? "io_low" : io_attr ? "io" : "address");
   12181 	    }
   12182 	  else
   12183 	    {
   12184 	      /* PR112952: The only way to output a variable declaration in a
   12185 		 custom manner is by means of a noswitch section callback.
   12186 		 There are only three noswitch sections: comm_section,
   12187 		 lcomm_section and tls_comm_section.  And there is no way to
   12188 		 wire a custom noswitch section to a decl.  As lcomm_section
   12189 		 is bypassed with -fdata-sections -fno-common, there is no
   12190 		 other way than making use of tls_comm_section.  As we are
   12191 		 using that section anyway, also use it in the public case.  */
   12192 
   12193 	      DECL_COMMON (decl) = 1;
   12194 	      set_decl_section_name (decl, (const char *) nullptr);
   12195 	      set_decl_tls_model (decl, (tls_model) 2);
   12196 	    }
   12197 	}
   12198     }
   12199 
   12200   if (AVR_TINY
   12201       && decl
   12202       && VAR_P (decl)
   12203       && MEM_P (rtl)
   12204       && SYMBOL_REF_P (XEXP (rtl, 0)))
   12205     {
   12206       rtx sym = XEXP (rtl, 0);
   12207       bool progmem_p = avr_progmem_p (decl, DECL_ATTRIBUTES (decl)) == -1;
   12208 
   12209       if (progmem_p)
   12210 	{
   12211 	  // Tag symbols for addition of 0x4000 (avr_arch->flash_pm_offset).
   12212 	  SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM;
   12213 	}
   12214 
   12215       if (avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl))
   12216 	  || (TARGET_ABSDATA
   12217 	      && !progmem_p
   12218 	      && !addr_attr
   12219 	      && avr_decl_maybe_lds_p (decl))
   12220 	  || (addr_attr
   12221 	      // If addr_attr is non-null, it has an argument.  Peek into it.
   12222 	      && TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (addr_attr))) < 0xc0))
   12223 	{
   12224 	  // May be accessed by LDS / STS.
   12225 	  SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_ABSDATA;
   12226 	}
   12227 
   12228       if (progmem_p
   12229 	  && avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl)))
   12230 	{
   12231 	  error ("%q+D has incompatible attributes %qs and %qs",
   12232 		 decl, "progmem", "absdata");
   12233 	}
   12234     }
   12235 }
   12236 
   12237 
   12238 /* Implement `TARGET_ASM_SELECT_SECTION' */
   12239 
   12240 static section *
   12241 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
   12242 {
   12243   section *sect = default_elf_select_section (decl, reloc, align);
   12244 
   12245   if (decl && DECL_P (decl)
   12246       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
   12247     {
   12248       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
   12249 
   12250       /* __progmem__ goes in generic space but shall be allocated to
   12251 	 .progmem.data  */
   12252 
   12253       if (ADDR_SPACE_GENERIC_P (as))
   12254 	as = ADDR_SPACE_FLASH;
   12255 
   12256       if (sect->common.flags & SECTION_NAMED)
   12257 	{
   12258 	  const char *name = sect->named.name;
   12259 	  const char *old_prefix = ".rodata";
   12260 	  const char *new_prefix = avr_addrspace[as].section_name;
   12261 
   12262 	  if (startswith (name, old_prefix))
   12263 	    {
   12264 	      const char *sname = ACONCAT ((new_prefix,
   12265 					    name + strlen (old_prefix), NULL));
   12266 	      return get_section (sname,
   12267 				  sect->common.flags & ~SECTION_DECLARED,
   12268 				  sect->named.decl);
   12269 	    }
   12270 	}
   12271 
   12272       if (!progmem_section[as])
   12273 	{
   12274 	  progmem_section[as]
   12275 	    = get_unnamed_section (0, avr_output_progmem_section_asm_op,
   12276 				   avr_addrspace[as].section_name);
   12277 	}
   12278 
   12279       return progmem_section[as];
   12280     }
   12281 
   12282   return sect;
   12283 }
   12284 
   12285 /* Implement `TARGET_ASM_FILE_START'.  */
   12286 /* Outputs some text at the start of each assembler file.  */
   12287 
   12288 static void
   12289 avr_file_start (void)
   12290 {
   12291   int sfr_offset = avr_arch->sfr_offset;
   12292 
   12293   if (avr_arch->asm_only)
   12294     error ("architecture %qs supported for assembler only", avr_mmcu);
   12295 
   12296   default_file_start ();
   12297 
   12298   /* Print I/O addresses of some SFRs used with IN and OUT.  */
   12299 
   12300   if (AVR_HAVE_SPH)
   12301     fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
   12302 
   12303   fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
   12304   fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
   12305   if (AVR_HAVE_RAMPZ)
   12306     fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
   12307   if (AVR_HAVE_RAMPY)
   12308     fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
   12309   if (AVR_HAVE_RAMPX)
   12310     fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
   12311   if (AVR_HAVE_RAMPD)
   12312     fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
   12313   if (AVR_XMEGA || AVR_TINY)
   12314     fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
   12315   fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO);
   12316   fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO);
   12317 }
   12318 
   12319 
   12320 /* Implement `TARGET_ASM_FILE_END'.  */
   12321 /* Outputs to the stdio stream FILE some
   12322    appropriate text to go at the end of an assembler file.  */
   12323 
   12324 static void
   12325 avr_file_end (void)
   12326 {
   12327   /* Output these only if there is anything in the
   12328      .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
   12329      input section(s) - some code size can be saved by not
   12330      linking in the initialization code from libgcc if resp.
   12331      sections are empty, see PR18145.  */
   12332 
   12333   if (avr_need_copy_data_p
   12334       || (avr_has_rodata_p && ! avr_rodata_in_flash_p ()))
   12335     fputs (".global __do_copy_data\n", asm_out_file);
   12336 
   12337   if (avr_need_clear_bss_p)
   12338     fputs (".global __do_clear_bss\n", asm_out_file);
   12339 }
   12340 
   12341 
   12342 /* Worker function for `ADJUST_REG_ALLOC_ORDER'.  */
   12343 /* Choose the order in which to allocate hard registers for
   12344    pseudo-registers local to a basic block.
   12345 
   12346    Store the desired register order in the array `reg_alloc_order'.
   12347    Element 0 should be the register to allocate first; element 1, the
   12348    next register; and so on.  */
   12349 
   12350 void
   12351 avr_adjust_reg_alloc_order (void)
   12352 {
   12353   static const int order_0[] =
   12354     {
   12355       24, 25,
   12356       18, 19, 20, 21, 22, 23,
   12357       30, 31,
   12358       26, 27, 28, 29,
   12359       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
   12360       0, 1,
   12361       32, 33, 34, 35
   12362     };
   12363   static const int tiny_order_0[] = {
   12364     20, 21,
   12365     22, 23,
   12366     24, 25,
   12367     30, 31,
   12368     26, 27,
   12369     28, 29,
   12370     19, 18,
   12371     16, 17,
   12372     32, 33, 34, 35,
   12373     15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
   12374   };
   12375   static const int order_1[] =
   12376     {
   12377       18, 19, 20, 21, 22, 23, 24, 25,
   12378       30, 31,
   12379       26, 27, 28, 29,
   12380       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
   12381       0, 1,
   12382       32, 33, 34, 35
   12383     };
   12384   static const int tiny_order_1[] = {
   12385     22, 23,
   12386     24, 25,
   12387     30, 31,
   12388     26, 27,
   12389     28, 29,
   12390     21, 20, 19, 18,
   12391     16, 17,
   12392     32, 33, 34, 35,
   12393     15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
   12394   };
   12395   static const int order_2[] =
   12396     {
   12397       25, 24, 23, 22, 21, 20, 19, 18,
   12398       30, 31,
   12399       26, 27, 28, 29,
   12400       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
   12401       1, 0,
   12402       32, 33, 34, 35
   12403     };
   12404 
   12405   /* Select specific register allocation order.
   12406      Tiny Core (ATtiny4/5/9/10/20/40) devices have only 16 registers,
   12407      so different allocation order should be used.  */
   12408 
   12409   const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1)
   12410 		      : TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_0 : order_2)
   12411 		      : (AVR_TINY ? tiny_order_0 : order_0));
   12412 
   12413   for (size_t i = 0; i < ARRAY_SIZE (order_0); ++i)
   12414     reg_alloc_order[i] = order[i];
   12415 }
   12416 
   12417 
   12418 /* Implement `TARGET_REGISTER_MOVE_COST' */
   12419 
   12420 static int
   12421 avr_register_move_cost (machine_mode /*mode*/, reg_class_t from, reg_class_t to)
   12422 {
   12423   return (from == STACK_REG ? 6
   12424 	  : to == STACK_REG ? 12
   12425 	  : 2);
   12426 }
   12427 
   12428 
   12429 /* Implement `TARGET_MEMORY_MOVE_COST' */
   12430 
   12431 static int
   12432 avr_memory_move_cost (machine_mode mode, reg_class_t /*rclass*/, bool /*in*/)
   12433 {
   12434   return (mode == QImode ? 2
   12435 	  : mode == HImode ? 4
   12436 	  : mode == SImode ? 8
   12437 	  : mode == SFmode ? 8
   12438 	  : 16);
   12439 }
   12440 
   12441 
   12442 /* Cost for mul highpart.  X is a LSHIFTRT, i.e. the outer TRUNCATE is
   12443    already stripped off.  */
   12444 
   12445 static int
   12446 avr_mul_highpart_cost (rtx x, int)
   12447 {
   12448   if (AVR_HAVE_MUL
   12449       && LSHIFTRT == GET_CODE (x)
   12450       && MULT == GET_CODE (XEXP (x, 0))
   12451       && CONST_INT_P (XEXP (x, 1)))
   12452     {
   12453       // This is the wider mode.
   12454       machine_mode mode = GET_MODE (x);
   12455 
   12456       // The middle-end might still have PR81444, i.e. it is calling the cost
   12457       // functions with strange modes.  Fix this now by also considering
   12458       // PSImode (should actually be SImode instead).
   12459       if (HImode == mode || PSImode == mode || SImode == mode)
   12460 	{
   12461 	  return COSTS_N_INSNS (2);
   12462 	}
   12463     }
   12464 
   12465   return 10000;
   12466 }
   12467 
   12468 
   12469 /* Return the expected cost of a conditional branch like
   12470    (set (pc)
   12471 	(if_then_else (X)
   12472 		      (label_ref *)
   12473 		      (pc)))
   12474    where X is some comparison operator.  */
   12475 
   12476 static int
   12477 avr_cbranch_cost (rtx x)
   12478 {
   12479   bool difficult_p = difficult_comparison_operator (x, VOIDmode);
   12480 
   12481   if (reload_completed)
   12482     {
   12483       // After reload, we basically just have plain branches.
   12484       return COSTS_N_INSNS (1 + difficult_p);
   12485     }
   12486 
   12487   rtx xreg = XEXP (x, 0);
   12488   rtx xval = XEXP (x, 1);
   12489   machine_mode mode = GET_MODE (xreg);
   12490   if (mode == VOIDmode)
   12491     mode = GET_MODE (xval);
   12492   int size = GET_MODE_SIZE (mode);
   12493 
   12494   if (GET_CODE (xreg) == ZERO_EXTEND
   12495       || GET_CODE (xval) == ZERO_EXTEND)
   12496     {
   12497       // *cbranch<HISI:mode>.<code><QIPSI:mode>.0/1, code = zero_extend.
   12498       return COSTS_N_INSNS (size + 1);
   12499     }
   12500 
   12501   if (GET_CODE (xreg) == SIGN_EXTEND
   12502       || GET_CODE (xval) == SIGN_EXTEND)
   12503     {
   12504       // *cbranch<HISI:mode>.<code><QIPSI:mode>.0/1, code = sign_extend.
   12505       // Make it a bit cheaper than it actually is (less reg pressure).
   12506       return COSTS_N_INSNS (size + 1 + 1);
   12507     }
   12508 
   12509   if (GET_CODE (xreg) == ZERO_EXTRACT
   12510       && XEXP (xreg, 1) == const1_rtx)
   12511     {
   12512       // Branch on a single bit, with an additional edge due to less
   12513       // register pressure.
   12514       return (int) COSTS_N_INSNS (1.5);
   12515     }
   12516 
   12517   bool reg_p = register_operand (xreg, mode);
   12518   bool reg_or_0_p = reg_or_0_operand (xval, mode);
   12519 
   12520   return COSTS_N_INSNS (size
   12521 			// For the branch
   12522 			+ 1 + difficult_p
   12523 			// Combine might propagate constants other than zero
   12524 			// into the 2nd operand.  Make that more expensive.
   12525 			+ 1 * (!reg_p || !reg_or_0_p));
   12526 }
   12527 
   12528 
   12529 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
   12530    cost of an RTX operand given its context.  X is the rtx of the
   12531    operand, MODE is its mode, and OUTER is the rtx_code of this
   12532    operand's parent operator.  */
   12533 
   12534 static int
   12535 avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer,
   12536 		      int opno, bool speed)
   12537 {
   12538   enum rtx_code code = GET_CODE (x);
   12539 
   12540   switch (code)
   12541     {
   12542     case REG:
   12543     case SUBREG:
   12544       return 0;
   12545 
   12546     case CONST_INT:
   12547     case CONST_FIXED:
   12548     case CONST_DOUBLE:
   12549       return COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12550 
   12551     default:
   12552       break;
   12553     }
   12554 
   12555   int total = 0;
   12556   avr_rtx_costs (x, mode, outer, opno, &total, speed);
   12557   return total;
   12558 }
   12559 
   12560 /* Worker function for AVR backend's rtx_cost function.
   12561    X is rtx expression whose cost is to be calculated.
   12562    Return true if the complete cost has been computed.
   12563    Return false if subexpressions should be scanned.
   12564    In either case, *TOTAL contains the cost result.  */
   12565 
   12566 static bool
   12567 avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
   12568 		 int /*opno*/, int *total, bool speed)
   12569 {
   12570   enum rtx_code code = GET_CODE (x);
   12571   HOST_WIDE_INT val;
   12572 
   12573   switch (code)
   12574     {
   12575     case CONST_INT:
   12576     case CONST_FIXED:
   12577     case CONST_DOUBLE:
   12578     case SYMBOL_REF:
   12579     case CONST:
   12580     case LABEL_REF:
   12581       /* Immediate constants are as cheap as registers.  */
   12582       *total = 0;
   12583       return true;
   12584 
   12585     case MEM:
   12586       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12587       return true;
   12588 
   12589     case NEG:
   12590       switch (mode)
   12591 	{
   12592 	case E_QImode:
   12593 	case E_SFmode:
   12594 	  *total = COSTS_N_INSNS (1);
   12595 	  break;
   12596 
   12597 	case E_HImode:
   12598 	case E_PSImode:
   12599 	case E_SImode:
   12600 	  *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
   12601 	  break;
   12602 
   12603 	default:
   12604 	  return false;
   12605 	}
   12606       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   12607       return true;
   12608 
   12609     case ABS:
   12610       switch (mode)
   12611 	{
   12612 	case E_QImode:
   12613 	case E_SFmode:
   12614 	  *total = COSTS_N_INSNS (1);
   12615 	  break;
   12616 
   12617 	default:
   12618 	  return false;
   12619 	}
   12620       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   12621       return true;
   12622 
   12623     case NOT:
   12624       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12625       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   12626       return true;
   12627 
   12628     case ZERO_EXTEND:
   12629       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
   12630 			      - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
   12631       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
   12632 				      code, 0, speed);
   12633       return true;
   12634 
   12635     case SIGN_EXTEND:
   12636       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
   12637 			      - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
   12638       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
   12639 				      code, 0, speed);
   12640       return true;
   12641 
   12642     case PLUS:
   12643       // uint16_t += 2 * uint8_t;
   12644       if (mode == HImode
   12645 	  && GET_CODE (XEXP (x, 0)) == ASHIFT
   12646 	  && REG_P (XEXP (x, 1))
   12647 	  && XEXP (XEXP (x, 0), 1) == const1_rtx
   12648 	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND)
   12649 	{
   12650 	  *total = COSTS_N_INSNS (4);
   12651 	  return true;
   12652 	}
   12653 
   12654       // *usum_widenqihi
   12655       if (mode == HImode
   12656 	  && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
   12657 	  && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
   12658 	{
   12659 	  *total = COSTS_N_INSNS (3);
   12660 	  return true;
   12661 	}
   12662 
   12663       if (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
   12664 	  && REG_P (XEXP (x, 1)))
   12665 	{
   12666 	  *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12667 	  return true;
   12668 	}
   12669       if (REG_P (XEXP (x, 0))
   12670 	  && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
   12671 	{
   12672 	  *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12673 	  return true;
   12674 	}
   12675 
   12676       switch (mode)
   12677 	{
   12678 	case E_QImode:
   12679 	  if (AVR_HAVE_MUL
   12680 	      && MULT == GET_CODE (XEXP (x, 0))
   12681 	      && register_operand (XEXP (x, 1), QImode))
   12682 	    {
   12683 	      /* multiply-add */
   12684 	      *total = COSTS_N_INSNS (speed ? 4 : 3);
   12685 	      /* multiply-add with constant: will be split and load constant. */
   12686 	      if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
   12687 		*total = COSTS_N_INSNS (1) + *total;
   12688 	      return true;
   12689 	    }
   12690 	  *total = COSTS_N_INSNS (1);
   12691 	  if (!CONST_INT_P (XEXP (x, 1)))
   12692 	    *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   12693 	  break;
   12694 
   12695 	case E_HImode:
   12696 	  if (AVR_HAVE_MUL
   12697 	      && (MULT == GET_CODE (XEXP (x, 0))
   12698 		  || ASHIFT == GET_CODE (XEXP (x, 0)))
   12699 	      && register_operand (XEXP (x, 1), HImode)
   12700 	      && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
   12701 		  || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
   12702 	    {
   12703 	      /* multiply-add */
   12704 	      *total = COSTS_N_INSNS (speed ? 5 : 4);
   12705 	      /* multiply-add with constant: will be split and load constant. */
   12706 	      if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
   12707 		*total = COSTS_N_INSNS (1) + *total;
   12708 	      return true;
   12709 	    }
   12710 	  if (!CONST_INT_P (XEXP (x, 1)))
   12711 	    {
   12712 	      *total = COSTS_N_INSNS (2);
   12713 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   12714 					      speed);
   12715 	    }
   12716 	  else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63))
   12717 	    *total = COSTS_N_INSNS (1);
   12718 	  else
   12719 	    *total = COSTS_N_INSNS (2);
   12720 	  break;
   12721 
   12722 	case E_PSImode:
   12723 	  if (!CONST_INT_P (XEXP (x, 1)))
   12724 	    {
   12725 	      *total = COSTS_N_INSNS (3);
   12726 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   12727 					      speed);
   12728 	    }
   12729 	  else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63))
   12730 	    *total = COSTS_N_INSNS (2);
   12731 	  else
   12732 	    *total = COSTS_N_INSNS (3);
   12733 	  break;
   12734 
   12735 	case E_SImode:
   12736 	  if (!CONST_INT_P (XEXP (x, 1)))
   12737 	    {
   12738 	      *total = COSTS_N_INSNS (4);
   12739 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   12740 					      speed);
   12741 	    }
   12742 	  else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63))
   12743 	    *total = COSTS_N_INSNS (1);
   12744 	  else
   12745 	    *total = COSTS_N_INSNS (4);
   12746 	  break;
   12747 
   12748 	default:
   12749 	  return false;
   12750 	}
   12751       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   12752       return true;
   12753 
   12754     case MINUS:
   12755       // *udiff_widenqihi
   12756       if (mode == HImode
   12757 	  && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
   12758 	  && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
   12759 	{
   12760 	  *total = COSTS_N_INSNS (2);
   12761 	  return true;
   12762 	}
   12763       // *sub<mode>3_zero_extend1
   12764       if (REG_P (XEXP (x, 0))
   12765 	  && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
   12766 	{
   12767 	  *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12768 	  return true;
   12769 	}
   12770       // *sub<mode>3.sign_extend2
   12771       if (REG_P (XEXP (x, 0))
   12772 	  && GET_CODE (XEXP (x, 1)) == SIGN_EXTEND)
   12773 	{
   12774 	  *total = COSTS_N_INSNS (2 + GET_MODE_SIZE (mode));
   12775 	  return true;
   12776 	}
   12777 
   12778       if (AVR_HAVE_MUL
   12779 	  && QImode == mode
   12780 	  && register_operand (XEXP (x, 0), QImode)
   12781 	  && MULT == GET_CODE (XEXP (x, 1)))
   12782 	{
   12783 	  /* multiply-sub */
   12784 	  *total = COSTS_N_INSNS (speed ? 4 : 3);
   12785 	  /* multiply-sub with constant: will be split and load constant. */
   12786 	  if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
   12787 	    *total = COSTS_N_INSNS (1) + *total;
   12788 	  return true;
   12789 	}
   12790       if (AVR_HAVE_MUL
   12791 	  && HImode == mode
   12792 	  && register_operand (XEXP (x, 0), HImode)
   12793 	  && (MULT == GET_CODE (XEXP (x, 1))
   12794 	      || ASHIFT == GET_CODE (XEXP (x, 1)))
   12795 	  && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
   12796 	      || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
   12797 	{
   12798 	  /* multiply-sub */
   12799 	  *total = COSTS_N_INSNS (speed ? 5 : 4);
   12800 	  /* multiply-sub with constant: will be split and load constant. */
   12801 	  if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
   12802 	    *total = COSTS_N_INSNS (1) + *total;
   12803 	  return true;
   12804 	}
   12805       /* FALLTHRU */
   12806     case AND:
   12807     case IOR:
   12808       if (IOR == code
   12809 	  && HImode == mode
   12810 	  && ASHIFT == GET_CODE (XEXP (x, 0)))
   12811 	{
   12812 	  *total = COSTS_N_INSNS (2);
   12813 	  // Just a rough estimate.  If we see no sign- or zero-extend,
   12814 	  // then increase the cost a little bit.
   12815 	  if (REG_P (XEXP (XEXP (x, 0), 0)))
   12816 	    *total += COSTS_N_INSNS (1);
   12817 	  if (REG_P (XEXP (x, 1)))
   12818 	    *total += COSTS_N_INSNS (1);
   12819 	  return true;
   12820 	}
   12821       if (IOR == code
   12822 	  && AND == GET_CODE (XEXP (x, 0))
   12823 	  && AND == GET_CODE (XEXP (x, 1))
   12824 	  && single_zero_operand (XEXP (XEXP (x, 0), 1), mode))
   12825 	{
   12826 	  // Open-coded bit transfer.
   12827 	  *total = COSTS_N_INSNS (2);
   12828 	  return true;
   12829 	}
   12830       if (AND == code
   12831 	  && single_one_operand (XEXP (x, 1), mode)
   12832 	  && (ASHIFT == GET_CODE (XEXP (x, 0))
   12833 	      || ASHIFTRT == GET_CODE (XEXP (x, 0))
   12834 	      || LSHIFTRT == GET_CODE (XEXP (x, 0))))
   12835 	{
   12836 	  // "*insv.any_shift.<mode>
   12837 	  *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode));
   12838 	  return true;
   12839 	}
   12840       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12841       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   12842       if (!CONST_INT_P (XEXP (x, 1)))
   12843 	*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   12844       return true;
   12845 
   12846     case XOR:
   12847       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12848       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   12849       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   12850       return true;
   12851 
   12852     case MULT:
   12853       switch (mode)
   12854 	{
   12855 	case E_QImode:
   12856 	  if (AVR_HAVE_MUL)
   12857 	    *total = COSTS_N_INSNS (!speed ? 3 : 4);
   12858 	  else if (!speed)
   12859 	    *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
   12860 	  else
   12861 	    return false;
   12862 	  break;
   12863 
   12864 	case E_HImode:
   12865 	  if (AVR_HAVE_MUL)
   12866 	    {
   12867 	      rtx op0 = XEXP (x, 0);
   12868 	      rtx op1 = XEXP (x, 1);
   12869 	      enum rtx_code code0 = GET_CODE (op0);
   12870 	      enum rtx_code code1 = GET_CODE (op1);
   12871 	      bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
   12872 	      bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
   12873 
   12874 	      if (ex0
   12875 		  && (u8_operand (op1, HImode)
   12876 		      || s8_operand (op1, HImode)))
   12877 		{
   12878 		  *total = COSTS_N_INSNS (!speed ? 4 : 6);
   12879 		  return true;
   12880 		}
   12881 	      if (ex0
   12882 		  && register_operand (op1, HImode))
   12883 		{
   12884 		  *total = COSTS_N_INSNS (!speed ? 5 : 8);
   12885 		  return true;
   12886 		}
   12887 	      else if (ex0 || ex1)
   12888 		{
   12889 		  *total = COSTS_N_INSNS (!speed ? 3 : 5);
   12890 		  return true;
   12891 		}
   12892 	      else if (register_operand (op0, HImode)
   12893 		       && (u8_operand (op1, HImode)
   12894 			   || s8_operand (op1, HImode)))
   12895 		{
   12896 		  *total = COSTS_N_INSNS (!speed ? 6 : 9);
   12897 		  return true;
   12898 		}
   12899 	      else
   12900 		*total = COSTS_N_INSNS (!speed ? 7 : 10);
   12901 	    }
   12902 	  else if (!speed)
   12903 	    *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
   12904 	  else
   12905 	    return false;
   12906 	  break;
   12907 
   12908 	case E_PSImode:
   12909 	  if (!speed)
   12910 	    *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
   12911 	  else
   12912 	    *total = 10;
   12913 	  break;
   12914 
   12915 	case E_SImode:
   12916 	case E_DImode:
   12917 	  if (AVR_HAVE_MUL)
   12918 	    {
   12919 	      if (!speed)
   12920 		{
   12921 		  /* Add some additional costs besides CALL like moves etc.  */
   12922 
   12923 		  *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
   12924 		}
   12925 	      else
   12926 		{
   12927 		  /* Just a rough estimate.  Even with -O2 we don't want bulky
   12928 		     code expanded inline.  */
   12929 
   12930 		  *total = COSTS_N_INSNS (25);
   12931 		}
   12932 	    }
   12933 	  else
   12934 	    {
   12935 	      if (speed)
   12936 		*total = COSTS_N_INSNS (300);
   12937 	      else
   12938 		/* Add some additional costs besides CALL like moves etc.  */
   12939 		*total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
   12940 	    }
   12941 
   12942 	  if (mode == DImode)
   12943 	    *total *= 2;
   12944 
   12945 	  return true;
   12946 
   12947 	default:
   12948 	  return false;
   12949 	}
   12950       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   12951       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   12952       return true;
   12953 
   12954     case DIV:
   12955     case MOD:
   12956     case UDIV:
   12957     case UMOD:
   12958       if (!speed)
   12959 	*total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
   12960       else
   12961 	*total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
   12962       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   12963       /* For div/mod with const-int divisor we have at least the cost of
   12964 	 loading the divisor. */
   12965       if (CONST_INT_P (XEXP (x, 1)))
   12966 	*total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
   12967       /* Add some overall penaly for clobbering and moving around registers */
   12968       *total += COSTS_N_INSNS (2);
   12969       return true;
   12970 
   12971     case ROTATE:
   12972       switch (mode)
   12973 	{
   12974 	case E_QImode:
   12975 	  if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
   12976 	    *total = COSTS_N_INSNS (1);
   12977 
   12978 	  break;
   12979 
   12980 	case E_HImode:
   12981 	  if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
   12982 	    *total = COSTS_N_INSNS (3);
   12983 
   12984 	  break;
   12985 
   12986 	case E_SImode:
   12987 	  if (CONST_INT_P (XEXP (x, 1)))
   12988 	    switch (INTVAL (XEXP (x, 1)))
   12989 	      {
   12990 	      case 8:
   12991 	      case 24:
   12992 		*total = COSTS_N_INSNS (5);
   12993 		break;
   12994 	      case 16:
   12995 		*total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
   12996 		break;
   12997 	      }
   12998 	  break;
   12999 
   13000 	default:
   13001 	  return false;
   13002 	}
   13003       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   13004       return true;
   13005 
   13006     case ASHIFT:
   13007       switch (mode)
   13008 	{
   13009 	case E_QImode:
   13010 	  if (!CONST_INT_P (XEXP (x, 1)))
   13011 	    {
   13012 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
   13013 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13014 					      speed);
   13015 	    }
   13016 	  else
   13017 	    {
   13018 	      val = INTVAL (XEXP (x, 1));
   13019 	      if (val == 7)
   13020 		*total = COSTS_N_INSNS (3);
   13021 	      else if (val >= 0 && val <= 7)
   13022 		*total = COSTS_N_INSNS (val);
   13023 	      else
   13024 		*total = COSTS_N_INSNS (1);
   13025 	    }
   13026 	  break;
   13027 
   13028 	case E_HImode:
   13029 	  if (AVR_HAVE_MUL)
   13030 	    {
   13031 	      if (const_2_to_7_operand (XEXP (x, 1), HImode)
   13032 		  && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
   13033 		      || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
   13034 		{
   13035 		  *total = COSTS_N_INSNS (!speed ? 4 : 6);
   13036 		  return true;
   13037 		}
   13038 	    }
   13039 
   13040 	  if (const1_rtx == (XEXP (x, 1))
   13041 	      && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
   13042 	    {
   13043 	      *total = COSTS_N_INSNS (2);
   13044 	      return true;
   13045 	    }
   13046 
   13047 	  if (!CONST_INT_P (XEXP (x, 1)))
   13048 	    {
   13049 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
   13050 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13051 					      speed);
   13052 	    }
   13053 	  else
   13054 	    switch (INTVAL (XEXP (x, 1)))
   13055 	      {
   13056 	      case 0:
   13057 		*total = 0;
   13058 		break;
   13059 	      case 1:
   13060 	      case 8:
   13061 		*total = COSTS_N_INSNS (2);
   13062 		break;
   13063 	      case 9:
   13064 		*total = COSTS_N_INSNS (3);
   13065 		break;
   13066 	      case 2:
   13067 	      case 3:
   13068 	      case 10:
   13069 	      case 15:
   13070 		*total = COSTS_N_INSNS (4);
   13071 		break;
   13072 	      case 7:
   13073 	      case 11:
   13074 	      case 12:
   13075 		*total = COSTS_N_INSNS (5);
   13076 		break;
   13077 	      case 4:
   13078 		*total = COSTS_N_INSNS (!speed ? 5 : 8);
   13079 		break;
   13080 	      case 6:
   13081 		*total = COSTS_N_INSNS (!speed ? 5 : 9);
   13082 		break;
   13083 	      case 5:
   13084 		*total = COSTS_N_INSNS (!speed ? 5 : 10);
   13085 		break;
   13086 	      default:
   13087 		*total = COSTS_N_INSNS (!speed ? 5 : 41);
   13088 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13089 						speed);
   13090 	      }
   13091 	  break;
   13092 
   13093 	case E_PSImode:
   13094 	  if (!CONST_INT_P (XEXP (x, 1)))
   13095 	    {
   13096 	      *total = COSTS_N_INSNS (!speed ? 6 : 73);
   13097 	    }
   13098 	  else
   13099 	    switch (INTVAL (XEXP (x, 1)))
   13100 	      {
   13101 	      case 0:
   13102 		*total = 0;
   13103 		break;
   13104 	      case 1:
   13105 	      case 8:
   13106 	      case 16:
   13107 		*total = COSTS_N_INSNS (3);
   13108 		break;
   13109 	      case 23:
   13110 		*total = COSTS_N_INSNS (5);
   13111 		break;
   13112 	      default:
   13113 		*total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
   13114 		break;
   13115 	      }
   13116 	  break;
   13117 
   13118 	case E_SImode:
   13119 	  if (!CONST_INT_P (XEXP (x, 1)))
   13120 	    {
   13121 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
   13122 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13123 					      speed);
   13124 	    }
   13125 	  else
   13126 	    switch (INTVAL (XEXP (x, 1)))
   13127 	      {
   13128 	      case 0:
   13129 		*total = 0;
   13130 		break;
   13131 	      case 24:
   13132 		*total = COSTS_N_INSNS (3);
   13133 		break;
   13134 	      case 1:
   13135 	      case 8:
   13136 	      case 16:
   13137 		*total = COSTS_N_INSNS (4);
   13138 		break;
   13139 	      case 31:
   13140 		*total = COSTS_N_INSNS (6);
   13141 		break;
   13142 	      case 2:
   13143 		*total = COSTS_N_INSNS (!speed ? 7 : 8);
   13144 		break;
   13145 	      default:
   13146 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
   13147 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13148 						speed);
   13149 	      }
   13150 	  break;
   13151 
   13152 	default:
   13153 	  return false;
   13154 	}
   13155       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   13156       return true;
   13157 
   13158     case ASHIFTRT:
   13159       switch (mode)
   13160 	{
   13161 	case E_QImode:
   13162 	  if (!CONST_INT_P (XEXP (x, 1)))
   13163 	    {
   13164 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
   13165 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13166 					      speed);
   13167 	    }
   13168 	  else
   13169 	    {
   13170 	      val = INTVAL (XEXP (x, 1));
   13171 	      if (val == 6)
   13172 		*total = COSTS_N_INSNS (4);
   13173 	      else if (val == 7)
   13174 		*total = COSTS_N_INSNS (2);
   13175 	      else if (val >= 0 && val <= 7)
   13176 		*total = COSTS_N_INSNS (val);
   13177 	      else
   13178 		*total = COSTS_N_INSNS (1);
   13179 	    }
   13180 	  break;
   13181 
   13182 	case E_HImode:
   13183 	  if (!CONST_INT_P (XEXP (x, 1)))
   13184 	    {
   13185 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
   13186 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13187 					      speed);
   13188 	    }
   13189 	  else
   13190 	    switch (INTVAL (XEXP (x, 1)))
   13191 	      {
   13192 	      case 0:
   13193 		*total = 0;
   13194 		break;
   13195 	      case 1:
   13196 		*total = COSTS_N_INSNS (2);
   13197 		break;
   13198 	      case 15:
   13199 		*total = COSTS_N_INSNS (3);
   13200 		break;
   13201 	      case 2:
   13202 	      case 7:
   13203 	      case 8:
   13204 	      case 9:
   13205 		*total = COSTS_N_INSNS (4);
   13206 		break;
   13207 	      case 10:
   13208 	      case 14:
   13209 		*total = COSTS_N_INSNS (5);
   13210 		break;
   13211 	      case 11:
   13212 		*total = COSTS_N_INSNS (!speed ? 5 : 6);
   13213 		break;
   13214 	      case 12:
   13215 		*total = COSTS_N_INSNS (!speed ? 5 : 7);
   13216 		break;
   13217 	      case 6:
   13218 	      case 13:
   13219 		*total = COSTS_N_INSNS (!speed ? 5 : 8);
   13220 		break;
   13221 	      default:
   13222 		*total = COSTS_N_INSNS (!speed ? 5 : 41);
   13223 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13224 						speed);
   13225 	      }
   13226 	  break;
   13227 
   13228 	case E_PSImode:
   13229 	  if (!CONST_INT_P (XEXP (x, 1)))
   13230 	    {
   13231 	      *total = COSTS_N_INSNS (!speed ? 6 : 73);
   13232 	    }
   13233 	  else
   13234 	    switch (INTVAL (XEXP (x, 1)))
   13235 	      {
   13236 	      case 0:
   13237 		*total = 0;
   13238 		break;
   13239 	      case 1:
   13240 		*total = COSTS_N_INSNS (3);
   13241 		break;
   13242 	      case 16:
   13243 	      case 8:
   13244 		*total = COSTS_N_INSNS (5);
   13245 		break;
   13246 	      case 23:
   13247 		*total = COSTS_N_INSNS (4);
   13248 		break;
   13249 	      default:
   13250 		*total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
   13251 		break;
   13252 	      }
   13253 	  break;
   13254 
   13255 	case E_SImode:
   13256 	  if (!CONST_INT_P (XEXP (x, 1)))
   13257 	    {
   13258 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
   13259 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13260 					      speed);
   13261 	    }
   13262 	  else
   13263 	    switch (INTVAL (XEXP (x, 1)))
   13264 	      {
   13265 	      case 0:
   13266 		*total = 0;
   13267 		break;
   13268 	      case 1:
   13269 		*total = COSTS_N_INSNS (4);
   13270 		break;
   13271 	      case 8:
   13272 	      case 16:
   13273 	      case 24:
   13274 		*total = COSTS_N_INSNS (6);
   13275 		break;
   13276 	      case 2:
   13277 		*total = COSTS_N_INSNS (!speed ? 7 : 8);
   13278 		break;
   13279 	      case 31:
   13280 		*total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
   13281 		break;
   13282 	      default:
   13283 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
   13284 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13285 						speed);
   13286 	      }
   13287 	  break;
   13288 
   13289 	default:
   13290 	  return false;
   13291 	}
   13292       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   13293       return true;
   13294 
   13295     case LSHIFTRT:
   13296       if (outer_code == TRUNCATE)
   13297 	{
   13298 	  *total = avr_mul_highpart_cost (x, speed);
   13299 	  return true;
   13300 	}
   13301 
   13302       switch (mode)
   13303 	{
   13304 	case E_QImode:
   13305 	  if (!CONST_INT_P (XEXP (x, 1)))
   13306 	    {
   13307 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
   13308 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13309 					      speed);
   13310 	    }
   13311 	  else
   13312 	    {
   13313 	      val = INTVAL (XEXP (x, 1));
   13314 	      if (val == 7)
   13315 		*total = COSTS_N_INSNS (3);
   13316 	      else if (val >= 0 && val <= 7)
   13317 		*total = COSTS_N_INSNS (val);
   13318 	      else
   13319 		*total = COSTS_N_INSNS (1);
   13320 	    }
   13321 	  break;
   13322 
   13323 	case E_HImode:
   13324 	  if (!CONST_INT_P (XEXP (x, 1)))
   13325 	    {
   13326 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
   13327 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13328 					      speed);
   13329 	    }
   13330 	  else
   13331 	    switch (INTVAL (XEXP (x, 1)))
   13332 	      {
   13333 	      case 0:
   13334 		*total = 0;
   13335 		break;
   13336 	      case 1:
   13337 	      case 8:
   13338 		*total = COSTS_N_INSNS (2);
   13339 		break;
   13340 	      case 9:
   13341 		*total = COSTS_N_INSNS (3);
   13342 		break;
   13343 	      case 2:
   13344 	      case 10:
   13345 	      case 15:
   13346 		*total = COSTS_N_INSNS (4);
   13347 		break;
   13348 	      case 7:
   13349 	      case 11:
   13350 		*total = COSTS_N_INSNS (5);
   13351 		break;
   13352 	      case 3:
   13353 	      case 12:
   13354 	      case 13:
   13355 	      case 14:
   13356 		*total = COSTS_N_INSNS (!speed ? 5 : 6);
   13357 		break;
   13358 	      case 4:
   13359 		*total = COSTS_N_INSNS (!speed ? 5 : 7);
   13360 		break;
   13361 	      case 5:
   13362 	      case 6:
   13363 		*total = COSTS_N_INSNS (!speed ? 5 : 9);
   13364 		break;
   13365 	      default:
   13366 		*total = COSTS_N_INSNS (!speed ? 5 : 41);
   13367 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13368 						speed);
   13369 	      }
   13370 	  break;
   13371 
   13372 	case E_PSImode:
   13373 	  if (!CONST_INT_P (XEXP (x, 1)))
   13374 	    {
   13375 	      *total = COSTS_N_INSNS (!speed ? 6 : 73);
   13376 	    }
   13377 	  else
   13378 	    switch (INTVAL (XEXP (x, 1)))
   13379 	      {
   13380 	      case 0:
   13381 		*total = 0;
   13382 		break;
   13383 	      case 1:
   13384 	      case 8:
   13385 	      case 16:
   13386 		*total = COSTS_N_INSNS (3);
   13387 		break;
   13388 	      case 23:
   13389 		*total = COSTS_N_INSNS (5);
   13390 		break;
   13391 	      default:
   13392 		*total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
   13393 		break;
   13394 	      }
   13395 	  break;
   13396 
   13397 	case E_SImode:
   13398 	  if (!CONST_INT_P (XEXP (x, 1)))
   13399 	    {
   13400 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
   13401 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13402 					      speed);
   13403 	    }
   13404 	  else
   13405 	    switch (INTVAL (XEXP (x, 1)))
   13406 	      {
   13407 	      case 0:
   13408 		*total = 0;
   13409 		break;
   13410 	      case 1:
   13411 		*total = COSTS_N_INSNS (4);
   13412 		break;
   13413 	      case 2:
   13414 		*total = COSTS_N_INSNS (!speed ? 7 : 8);
   13415 		break;
   13416 	      case 8:
   13417 	      case 16:
   13418 	      case 24:
   13419 		*total = COSTS_N_INSNS (4);
   13420 		break;
   13421 	      case 31:
   13422 		*total = COSTS_N_INSNS (6);
   13423 		break;
   13424 	      default:
   13425 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
   13426 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
   13427 						speed);
   13428 	      }
   13429 	  break;
   13430 
   13431 	default:
   13432 	  return false;
   13433 	}
   13434       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   13435       return true;
   13436 
   13437     case COMPARE:
   13438       switch (GET_MODE (XEXP (x, 0)))
   13439 	{
   13440 	case E_QImode:
   13441 	  *total = COSTS_N_INSNS (1);
   13442 	  if (!CONST_INT_P (XEXP (x, 1)))
   13443 	    *total += avr_operand_rtx_cost (XEXP (x, 1), QImode, code,
   13444 					    1, speed);
   13445 	  break;
   13446 
   13447 	case E_HImode:
   13448 	  *total = COSTS_N_INSNS (2);
   13449 	  if (!CONST_INT_P (XEXP (x, 1)))
   13450 	    *total += avr_operand_rtx_cost (XEXP (x, 1), HImode, code,
   13451 					    1, speed);
   13452 	  else if (INTVAL (XEXP (x, 1)) != 0)
   13453 	    *total += COSTS_N_INSNS (1);
   13454 	  break;
   13455 
   13456 	case E_PSImode:
   13457 	  *total = COSTS_N_INSNS (3);
   13458 	  if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
   13459 	    *total += COSTS_N_INSNS (2);
   13460 	  break;
   13461 
   13462 	case E_SImode:
   13463 	  *total = COSTS_N_INSNS (4);
   13464 	  if (!CONST_INT_P (XEXP (x, 1)))
   13465 	    *total += avr_operand_rtx_cost (XEXP (x, 1), SImode, code,
   13466 					    1, speed);
   13467 	  else if (INTVAL (XEXP (x, 1)) != 0)
   13468 	    *total += COSTS_N_INSNS (3);
   13469 	  break;
   13470 
   13471 	default:
   13472 	  return false;
   13473 	}
   13474       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
   13475 				      code, 0, speed);
   13476       return true;
   13477 
   13478     case TRUNCATE:
   13479       if (LSHIFTRT == GET_CODE (XEXP (x, 0)))
   13480 	{
   13481 	  *total = avr_mul_highpart_cost (XEXP (x, 0), speed);
   13482 	  return true;
   13483 	}
   13484       break;
   13485 
   13486     case IF_THEN_ELSE:
   13487       if (outer_code == SET
   13488 	  && XEXP (x, 2) == pc_rtx
   13489 	  && ordered_comparison_operator (XEXP (x, 0), VOIDmode))
   13490 	{
   13491 	  *total = avr_cbranch_cost (XEXP (x, 0));
   13492 	  return true;
   13493 	}
   13494 
   13495     default:
   13496       break;
   13497     }
   13498   return false;
   13499 }
   13500 
   13501 
   13502 /* Implement `TARGET_RTX_COSTS'.  */
   13503 
   13504 static bool
   13505 avr_rtx_costs (rtx x, machine_mode mode, int outer_code,
   13506 	       int opno, int *total, bool speed)
   13507 {
   13508   bool done = avr_rtx_costs_1 (x, mode, outer_code, opno, total, speed);
   13509 
   13510   if (avr_log.rtx_costs)
   13511     {
   13512       avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
   13513 		 done, speed ? "speed" : "size", *total, outer_code, x);
   13514     }
   13515 
   13516   return done;
   13517 }
   13518 
   13519 
   13520 /* Implement `TARGET_INSN_COST'.  */
   13521 /* For some insns, it is not enough to look at the cost of the SET_SRC.
   13522    In that case, have a look at the entire insn, e.g. during insn combine.  */
   13523 
   13524 static int
   13525 avr_insn_cost (rtx_insn *insn, bool speed)
   13526 {
   13527   const int unknown_cost = -1;
   13528   int cost = unknown_cost;
   13529 
   13530   rtx set = single_set (insn);
   13531 
   13532   if (set
   13533       && ZERO_EXTRACT == GET_CODE (SET_DEST (set)))
   13534     {
   13535       // Try find anything that would flip the extracted bit.
   13536       bool not_bit_p = false;
   13537 
   13538       subrtx_iterator::array_type array;
   13539       FOR_EACH_SUBRTX (iter, array, SET_SRC (set), NONCONST)
   13540 	{
   13541 	  enum rtx_code code = GET_CODE (*iter);
   13542 	  not_bit_p |= code == NOT || code == XOR || code == GE;
   13543 	}
   13544 
   13545       // Don't go too deep into the analysis.  In almost all cases,
   13546       // using BLD/BST is the best we can do for single-bit moves,
   13547       // even considering CSE.
   13548       cost = COSTS_N_INSNS (2 + not_bit_p);
   13549     }
   13550 
   13551   if (cost != unknown_cost)
   13552     {
   13553       if (avr_log.rtx_costs)
   13554 	avr_edump ("\n%? (%s) insn_cost=%d\n%r\n",
   13555 		   speed ? "speed" : "size", cost, insn);
   13556       return cost;
   13557     }
   13558 
   13559   // Resort to what rtlanal.cc::insn_cost() implements as a default
   13560   // when targetm.insn_cost() is not implemented.
   13561 
   13562   return pattern_cost (PATTERN (insn), speed);
   13563 }
   13564 
   13565 
   13566 /* Implement `TARGET_ADDRESS_COST'.  */
   13567 
   13568 static int
   13569 avr_address_cost (rtx x, machine_mode mode, addr_space_t /*as*/,
   13570 		  bool /*speed*/)
   13571 {
   13572   int cost = 4;
   13573 
   13574   if (GET_CODE (x) == PLUS
   13575       && CONST_INT_P (XEXP (x, 1))
   13576       && (REG_P (XEXP (x, 0))
   13577 	  || SUBREG_P (XEXP (x, 0))))
   13578     {
   13579       if (INTVAL (XEXP (x, 1)) > MAX_LD_OFFSET(mode))
   13580 	cost = 18;
   13581     }
   13582   else if (CONSTANT_ADDRESS_P (x))
   13583     {
   13584       if (io_address_operand (x, QImode))
   13585 	cost = 2;
   13586 
   13587       if (AVR_TINY
   13588 	  && avr_address_tiny_absdata_p (x, QImode))
   13589 	cost = 2;
   13590     }
   13591 
   13592   if (avr_log.address_cost)
   13593     avr_edump ("\n%?: %d = %r\n", cost, x);
   13594 
   13595   return cost;
   13596 }
   13597 
   13598 /* Test for extra memory constraint 'Q'.
   13599    It's a memory address based on Y or Z pointer with valid displacement.  */
   13600 
   13601 int
   13602 extra_constraint_Q (rtx x)
   13603 {
   13604   int ok = 0;
   13605   rtx plus = XEXP (x, 0);
   13606 
   13607   if (GET_CODE (plus) == PLUS
   13608       && REG_P (XEXP (plus, 0))
   13609       && CONST_INT_P (XEXP (plus, 1))
   13610       && (INTVAL (XEXP (plus, 1))
   13611 	  <= MAX_LD_OFFSET (GET_MODE (x))))
   13612     {
   13613       rtx xx = XEXP (plus, 0);
   13614       int regno = REGNO (xx);
   13615 
   13616       ok = (/* allocate pseudos */
   13617 	    regno >= FIRST_PSEUDO_REGISTER
   13618 	    /* strictly check */
   13619 	    || regno == REG_Z || regno == REG_Y
   13620 	    /* XXX frame & arg pointer checks */
   13621 	    || xx == frame_pointer_rtx
   13622 	    || xx == arg_pointer_rtx);
   13623 
   13624       if (avr_log.constraints)
   13625 	avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
   13626 		   ok, reload_completed, reload_in_progress, x);
   13627     }
   13628 
   13629   return ok;
   13630 }
   13631 
   13632 /* Convert condition code CONDITION to the valid AVR condition code.  */
   13633 
   13634 RTX_CODE
   13635 avr_normalize_condition (RTX_CODE condition)
   13636 {
   13637   switch (condition)
   13638     {
   13639     case GT:
   13640       return GE;
   13641     case GTU:
   13642       return GEU;
   13643     case LE:
   13644       return LT;
   13645     case LEU:
   13646       return LTU;
   13647     default:
   13648       gcc_unreachable ();
   13649     }
   13650 }
   13651 
   13652 
   13653 /* Returns register number for function return value.*/
   13654 
   13655 static inline unsigned int
   13656 avr_ret_register (void)
   13657 {
   13658   return REG_24;
   13659 }
   13660 
   13661 
   13662 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'.  */
   13663 
   13664 static bool
   13665 avr_function_value_regno_p (const unsigned int regno)
   13666 {
   13667   return regno == avr_ret_register ();
   13668 }
   13669 
   13670 
   13671 /* Implement `TARGET_LIBCALL_VALUE'.  */
   13672 /* Create an RTX representing the place where a
   13673    library function returns a value of mode MODE.  */
   13674 
   13675 static rtx
   13676 avr_libcall_value (machine_mode mode, const_rtx /*func*/)
   13677 {
   13678   int offs = GET_MODE_SIZE (mode);
   13679 
   13680   if (offs <= 4)
   13681     offs = (offs + 1) & ~1;
   13682 
   13683   return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
   13684 }
   13685 
   13686 
   13687 /* Implement `TARGET_FUNCTION_VALUE'.  */
   13688 /* Create an RTX representing the place where a
   13689    function returns a value of data type VALTYPE.  */
   13690 
   13691 static rtx
   13692 avr_function_value (const_tree type, const_tree /*fn_decl_or_type*/,
   13693 		    bool /*outgoing*/)
   13694 {
   13695   if (TYPE_MODE (type) != BLKmode)
   13696     return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
   13697 
   13698   unsigned int offs = int_size_in_bytes (type);
   13699   if (offs < 2)
   13700     offs = 2;
   13701   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
   13702     offs = GET_MODE_SIZE (SImode);
   13703   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
   13704     offs = GET_MODE_SIZE (DImode);
   13705 
   13706   return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
   13707 }
   13708 
   13709 int
   13710 test_hard_reg_class (enum reg_class rclass, rtx x)
   13711 {
   13712   int regno = true_regnum (x);
   13713   if (regno < 0)
   13714     return 0;
   13715 
   13716   if (TEST_HARD_REG_CLASS (rclass, regno))
   13717     return 1;
   13718 
   13719   return 0;
   13720 }
   13721 
   13722 
   13723 /* Helper for jump_over_one_insn_p:  Test if INSN is a 2-word instruction
   13724    and thus is suitable to be skipped by CPSE, SBRC, etc.  */
   13725 
   13726 static bool
   13727 avr_2word_insn_p (rtx_insn *insn)
   13728 {
   13729   if (TARGET_SKIP_BUG || !insn || get_attr_length (insn) != 2)
   13730     {
   13731       return false;
   13732     }
   13733 
   13734   switch (INSN_CODE (insn))
   13735     {
   13736     default:
   13737       return false;
   13738 
   13739     case CODE_FOR_movqi_insn:
   13740     case CODE_FOR_movuqq_insn:
   13741     case CODE_FOR_movqq_insn:
   13742       {
   13743 	rtx set  = single_set (insn);
   13744 	rtx src  = SET_SRC (set);
   13745 	rtx dest = SET_DEST (set);
   13746 
   13747 	/* Factor out LDS and STS from movqi_insn.  */
   13748 
   13749 	if (MEM_P (dest)
   13750 	    && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
   13751 	  {
   13752 	    return CONSTANT_ADDRESS_P (XEXP (dest, 0));
   13753 	  }
   13754 	else if (REG_P (dest)
   13755 		 && MEM_P (src))
   13756 	  {
   13757 	    return CONSTANT_ADDRESS_P (XEXP (src, 0));
   13758 	  }
   13759 
   13760 	return false;
   13761       }
   13762 
   13763     case CODE_FOR_call_insn:
   13764     case CODE_FOR_call_value_insn:
   13765       return true;
   13766     }
   13767 }
   13768 
   13769 
   13770 int
   13771 jump_over_one_insn_p (rtx_insn *insn, rtx dest)
   13772 {
   13773   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
   13774 		      ? XEXP (dest, 0)
   13775 		      : dest);
   13776   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
   13777   int dest_addr = INSN_ADDRESSES (uid);
   13778   int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
   13779 
   13780   return (jump_offset == 1
   13781 	  || (jump_offset == 2
   13782 	      && avr_2word_insn_p (next_active_insn (insn))));
   13783 }
   13784 
   13785 
   13786 /* Implement `TARGET_HARD_REGNO_NREGS'.  CCmode is four units for historical
   13787    reasons. If this hook is not defined, TARGET_HARD_REGNO_NREGS
   13788    reports that CCmode requires four registers.
   13789    Define this hook to allow CCmode to fit in a single REG_CC. For
   13790    other modes and regs, return the number of words in mode (i.e whatever
   13791    the default implementation of the hook returned). */
   13792 
   13793 static unsigned int
   13794 avr_hard_regno_nregs (unsigned int regno, machine_mode mode)
   13795 {
   13796   if (regno == REG_CC && mode == CCmode)
   13797     return 1;
   13798 
   13799   return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   13800 }
   13801 
   13802 
   13803 /* Implement `TARGET_HARD_REGNO_MODE_OK'.  On the enhanced core, anything
   13804    larger than 1 byte must start in even numbered register for "movw" to
   13805    work (this way we don't have to check for odd registers everywhere).  */
   13806 
   13807 static bool
   13808 avr_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
   13809 {
   13810   if (regno == REG_CC)
   13811     return mode == CCmode;
   13812 
   13813   /* NOTE: 8-bit values must not be disallowed for R28 or R29.
   13814 	Disallowing QI et al. in these regs might lead to code like
   13815 	    (set (subreg:QI (reg:HI 28) n) ...)
   13816 	which will result in wrong code because reload does not
   13817 	handle SUBREGs of hard regsisters like this.
   13818 	This could be fixed in reload.  However, it appears
   13819 	that fixing reload is not wanted by reload people.  */
   13820 
   13821   /* Any GENERAL_REGS register can hold 8-bit values.  */
   13822 
   13823   if (GET_MODE_SIZE (mode) == 1)
   13824     return true;
   13825 
   13826   /* FIXME: Ideally, the following test is not needed.
   13827 	However, it turned out that it can reduce the number
   13828 	of spill fails.  AVR and it's poor endowment with
   13829 	address registers is extreme stress test for reload.  */
   13830 
   13831   if (GET_MODE_SIZE (mode) >= 4
   13832       && regno >= REG_X)
   13833     return false;
   13834 
   13835   /* All modes larger than 8 bits should start in an even register.  */
   13836 
   13837   return !(regno & 1);
   13838 }
   13839 
   13840 
   13841 /* Implement `TARGET_HARD_REGNO_CALL_PART_CLOBBERED'.  */
   13842 
   13843 static bool
   13844 avr_hard_regno_call_part_clobbered (unsigned, unsigned regno,
   13845 				    machine_mode mode)
   13846 {
   13847   /* FIXME: This hook gets called with MODE:REGNO combinations that don't
   13848 	represent valid hard registers like, e.g. HI:29.  Returning TRUE
   13849 	for such registers can lead to performance degradation as mentioned
   13850 	in PR53595.  Thus, report invalid hard registers as FALSE.  */
   13851 
   13852   if (!avr_hard_regno_mode_ok (regno, mode))
   13853     return 0;
   13854 
   13855   /* Return true if any of the following boundaries is crossed:
   13856      17/18 or 19/20 (if AVR_TINY), 27/28 and 29/30.  */
   13857 
   13858   return ((regno <= LAST_CALLEE_SAVED_REG
   13859 	   && regno + GET_MODE_SIZE (mode) > 1 + LAST_CALLEE_SAVED_REG)
   13860 	  || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
   13861 	  || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
   13862 }
   13863 
   13864 
   13865 /* Implement `MODE_CODE_BASE_REG_CLASS'.  */
   13866 
   13867 enum reg_class
   13868 avr_mode_code_base_reg_class (machine_mode /*mode*/, addr_space_t as,
   13869 			      RTX_CODE outer_code, RTX_CODE /*index_code*/)
   13870 {
   13871   if (!ADDR_SPACE_GENERIC_P (as))
   13872     {
   13873       return POINTER_Z_REGS;
   13874     }
   13875 
   13876   if (AVR_TINY)
   13877     // We allow all offsets for all pointer regs.  Pass .avr-fuse-add
   13878     // will rectify it (register allocation cannot do it).
   13879     return POINTER_REGS;
   13880 
   13881   if (!avr_strict_X)
   13882     return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
   13883 
   13884   return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
   13885 }
   13886 
   13887 
   13888 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'.  */
   13889 
   13890 bool
   13891 avr_regno_mode_code_ok_for_base_p (int regno, machine_mode /*mode*/,
   13892 				   addr_space_t as, RTX_CODE outer_code,
   13893 				   RTX_CODE /*index_code*/)
   13894 {
   13895   bool ok = false;
   13896 
   13897   if (!ADDR_SPACE_GENERIC_P (as))
   13898     {
   13899       if (regno < FIRST_PSEUDO_REGISTER
   13900 	  && regno == REG_Z)
   13901 	{
   13902 	  return true;
   13903 	}
   13904 
   13905       if (reg_renumber)
   13906 	{
   13907 	  regno = reg_renumber[regno];
   13908 
   13909 	  if (regno == REG_Z)
   13910 	    {
   13911 	      return true;
   13912 	    }
   13913 	}
   13914 
   13915       return false;
   13916     }
   13917 
   13918   if (regno < FIRST_PSEUDO_REGISTER
   13919       && (regno == REG_X
   13920 	  || regno == REG_Y
   13921 	  || regno == REG_Z
   13922 	  || regno == ARG_POINTER_REGNUM))
   13923     {
   13924       ok = true;
   13925     }
   13926   else if (reg_renumber)
   13927     {
   13928       regno = reg_renumber[regno];
   13929 
   13930       if (regno == REG_X
   13931 	  || regno == REG_Y
   13932 	  || regno == REG_Z
   13933 	  || regno == ARG_POINTER_REGNUM)
   13934 	{
   13935 	  ok = true;
   13936 	}
   13937     }
   13938 
   13939   if (avr_strict_X
   13940       // On Reduced Tiny, all registers are equal in that they do not
   13941       // support PLUS addressing; respective addresses will be fake,
   13942       // even for the frame pointer.  They must be handled in the
   13943       // printers by add-store-sub sequences -- or may be split after
   13944       // reload by `avr_split_tiny_move'.
   13945       && ! AVR_TINY
   13946       && PLUS == outer_code
   13947       && regno == REG_X)
   13948     {
   13949       ok = false;
   13950     }
   13951 
   13952   return ok;
   13953 }
   13954 
   13955 
   13956 /* A helper for `output_reload_insisf' and `output_reload_inhi'.  */
   13957 /* Set 32-bit register OP[0] to compile-time constant OP[1].
   13958    CLOBBER_REG is a QI clobber register or NULL_RTX.
   13959    LEN == NULL: output instructions.
   13960    LEN != NULL: set *LEN to the length of the instruction sequence
   13961 		(in words) printed with LEN = NULL.
   13962    If CLEAR_P is true, OP[0] had been cleard to Zero already.
   13963    If CLEAR_P is false, nothing is known about OP[0].
   13964 
   13965    The effect on cc0 is as follows:
   13966 
   13967    Load 0 to any register except ZERO_REG : NONE
   13968    Load ld register with any value        : NONE
   13969    Anything else:                         : CLOBBER  */
   13970 
   13971 static void
   13972 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
   13973 {
   13974   rtx src = op[1];
   13975   rtx dest = op[0];
   13976   rtx xval, xdest[4];
   13977   int ival[4];
   13978   int clobber_val = 1234;
   13979   bool cooked_clobber_p = false;
   13980   bool set_p = false;
   13981   machine_mode mode = GET_MODE (dest);
   13982   int n_bytes = GET_MODE_SIZE (mode);
   13983 
   13984   gcc_assert (REG_P (dest)
   13985 	      && CONSTANT_P (src));
   13986 
   13987   if (len)
   13988     *len = 0;
   13989 
   13990   /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
   13991      but has some subregs that are in LD_REGS.  Use the MSB (REG:QI 17).  */
   13992 
   13993   if (REGNO (dest) < REG_16
   13994       && REGNO (dest) + GET_MODE_SIZE (mode) > REG_16)
   13995     {
   13996       clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
   13997     }
   13998 
   13999   /* We might need a clobber reg but don't have one.  Look at the value to
   14000      be loaded more closely.  A clobber is only needed if it is a symbol
   14001      or contains a byte that is neither 0, -1 or a power of 2.  */
   14002 
   14003   if (NULL_RTX == clobber_reg
   14004       && !test_hard_reg_class (LD_REGS, dest)
   14005       && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
   14006 	  || !avr_popcount_each_byte (src, n_bytes,
   14007 				      (1 << 0) | (1 << 1) | (1 << 8))))
   14008     {
   14009       /* We have no clobber register but need one.  Cook one up.
   14010 	 That's cheaper than loading from constant pool.  */
   14011 
   14012       cooked_clobber_p = true;
   14013       clobber_reg = all_regs_rtx[REG_Z + 1];
   14014       avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
   14015     }
   14016 
   14017   /* Now start filling DEST from LSB to MSB.  */
   14018 
   14019   for (int n = 0; n < n_bytes; n++)
   14020     {
   14021       bool done_byte = false;
   14022       rtx xop[3];
   14023 
   14024       /* Crop the n-th destination byte.  */
   14025 
   14026       xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
   14027       int ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
   14028 
   14029       if (!CONST_INT_P (src)
   14030 	  && !CONST_FIXED_P (src)
   14031 	  && !CONST_DOUBLE_P (src))
   14032 	{
   14033 	  static const char *const asm_code[][2] =
   14034 	    {
   14035 	      { "ldi %2,lo8(%1)"  CR_TAB "mov %0,%2",    "ldi %0,lo8(%1)"  },
   14036 	      { "ldi %2,hi8(%1)"  CR_TAB "mov %0,%2",    "ldi %0,hi8(%1)"  },
   14037 	      { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2",    "ldi %0,hlo8(%1)" },
   14038 	      { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2",    "ldi %0,hhi8(%1)" }
   14039 	    };
   14040 
   14041 	  xop[0] = xdest[n];
   14042 	  xop[1] = src;
   14043 	  xop[2] = clobber_reg;
   14044 
   14045 	  avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
   14046 
   14047 	  continue;
   14048 	}
   14049 
   14050       /* Crop the n-th source byte.  */
   14051 
   14052       xval = simplify_gen_subreg (QImode, src, mode, n);
   14053       ival[n] = INTVAL (xval);
   14054 
   14055       /* Look if we can reuse the low word by means of MOVW.  */
   14056 
   14057       if (n == 2
   14058 	  && n_bytes >= 4
   14059 	  && AVR_HAVE_MOVW)
   14060 	{
   14061 	  rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
   14062 	  rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
   14063 
   14064 	  if (INTVAL (lo16) == INTVAL (hi16))
   14065 	    {
   14066 	      if (INTVAL (lo16) != 0 || !clear_p)
   14067 		avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
   14068 
   14069 	      break;
   14070 	    }
   14071 	}
   14072 
   14073       /* Don't use CLR so that cc0 is set as expected.  */
   14074 
   14075       if (ival[n] == 0)
   14076 	{
   14077 	  if (!clear_p)
   14078 	    avr_asm_len (ldreg_p ? "ldi %0,0"
   14079 			 : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
   14080 			 : "mov %0,__zero_reg__",
   14081 			 &xdest[n], len, 1);
   14082 	  continue;
   14083 	}
   14084 
   14085       if (clobber_val == ival[n]
   14086 	  && REGNO (clobber_reg) == REGNO (xdest[n]))
   14087 	{
   14088 	  continue;
   14089 	}
   14090 
   14091       /* LD_REGS can use LDI to move a constant value */
   14092 
   14093       if (ldreg_p)
   14094 	{
   14095 	  xop[0] = xdest[n];
   14096 	  xop[1] = xval;
   14097 	  avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
   14098 	  continue;
   14099 	}
   14100 
   14101       /* Try to reuse value already loaded in some lower byte. */
   14102 
   14103       for (int j = 0; j < n; j++)
   14104 	if (ival[j] == ival[n])
   14105 	  {
   14106 	    xop[0] = xdest[n];
   14107 	    xop[1] = xdest[j];
   14108 
   14109 	    avr_asm_len ("mov %0,%1", xop, len, 1);
   14110 	    done_byte = true;
   14111 	    break;
   14112 	  }
   14113 
   14114       if (done_byte)
   14115 	continue;
   14116 
   14117       /* Need no clobber reg for -1: Use CLR/DEC */
   14118 
   14119       if (ival[n] == -1)
   14120 	{
   14121 	  if (!clear_p)
   14122 	    avr_asm_len ("clr %0", &xdest[n], len, 1);
   14123 
   14124 	  avr_asm_len ("dec %0", &xdest[n], len, 1);
   14125 	  continue;
   14126 	}
   14127       else if (ival[n] == 1)
   14128 	{
   14129 	  if (!clear_p)
   14130 	    avr_asm_len ("clr %0", &xdest[n], len, 1);
   14131 
   14132 	  avr_asm_len ("inc %0", &xdest[n], len, 1);
   14133 	  continue;
   14134 	}
   14135 
   14136       /* Use T flag or INC to manage powers of 2 if we have
   14137 	 no clobber reg.  */
   14138 
   14139       if (NULL_RTX == clobber_reg
   14140 	  && single_one_operand (xval, QImode))
   14141 	{
   14142 	  xop[0] = xdest[n];
   14143 	  xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
   14144 
   14145 	  gcc_assert (constm1_rtx != xop[1]);
   14146 
   14147 	  if (!set_p)
   14148 	    {
   14149 	      set_p = true;
   14150 	      avr_asm_len ("set", xop, len, 1);
   14151 	    }
   14152 
   14153 	  if (!clear_p)
   14154 	    avr_asm_len ("clr %0", xop, len, 1);
   14155 
   14156 	  avr_asm_len ("bld %0,%1", xop, len, 1);
   14157 	  continue;
   14158 	}
   14159 
   14160       /* We actually need the LD_REGS clobber reg.  */
   14161 
   14162       gcc_assert (NULL_RTX != clobber_reg);
   14163 
   14164       xop[0] = xdest[n];
   14165       xop[1] = xval;
   14166       xop[2] = clobber_reg;
   14167       clobber_val = ival[n];
   14168 
   14169       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
   14170 		   "mov %0,%2", xop, len, 2);
   14171     }
   14172 
   14173   /* If we cooked up a clobber reg above, restore it.  */
   14174 
   14175   if (cooked_clobber_p)
   14176     {
   14177       avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
   14178     }
   14179 }
   14180 
   14181 
   14182 /* Reload the constant OP[1] into the HI register OP[0].
   14183    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
   14184    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
   14185    need a clobber reg or have to cook one up.
   14186 
   14187    PLEN == NULL: Output instructions.
   14188    PLEN != NULL: Output nothing.  Set *PLEN to number of words occupied
   14189 		 by the insns printed.
   14190 
   14191    Return "".  */
   14192 
   14193 const char *
   14194 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
   14195 {
   14196   output_reload_in_const (op, clobber_reg, plen, false);
   14197   return "";
   14198 }
   14199 
   14200 
   14201 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
   14202    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
   14203    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
   14204    need a clobber reg or have to cook one up.
   14205 
   14206    LEN == NULL: Output instructions.
   14207 
   14208    LEN != NULL: Output nothing.  Set *LEN to number of words occupied
   14209 		by the insns printed.
   14210 
   14211    Return "".  */
   14212 
   14213 const char *
   14214 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
   14215 {
   14216   if (AVR_HAVE_MOVW
   14217       && !test_hard_reg_class (LD_REGS, op[0])
   14218       && (CONST_INT_P (op[1])
   14219 	  || CONST_FIXED_P (op[1])
   14220 	  || CONST_DOUBLE_P (op[1])))
   14221     {
   14222       /* In some cases it is better to clear the destination beforehand, e.g.
   14223 
   14224 	     CLR R2   CLR R3   MOVW R4,R2   INC R2
   14225 
   14226 	 is shorther than
   14227 
   14228 	     CLR R2   INC R2   CLR  R3      CLR R4   CLR R5
   14229 
   14230 	 We find it too tedious to work that out in the print function.
   14231 	 Instead, we call the print function twice to get the lengths of
   14232 	 both methods and use the shortest one.  */
   14233 
   14234       int len_clr, len_noclr;
   14235       output_reload_in_const (op, clobber_reg, &len_clr, true);
   14236       output_reload_in_const (op, clobber_reg, &len_noclr, false);
   14237 
   14238       if (len_noclr - len_clr == 4)
   14239 	{
   14240 	  /* Default needs 4 CLR instructions: clear register beforehand.  */
   14241 
   14242 	  avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
   14243 		       "mov %B0,__zero_reg__" CR_TAB
   14244 		       "movw %C0,%A0", &op[0], len, 3);
   14245 
   14246 	  output_reload_in_const (op, clobber_reg, len, true);
   14247 
   14248 	  if (len)
   14249 	    *len += 3;
   14250 
   14251 	  return "";
   14252 	}
   14253     }
   14254 
   14255   /* Default: destination not pre-cleared.  */
   14256 
   14257   output_reload_in_const (op, clobber_reg, len, false);
   14258   return "";
   14259 }
   14260 
   14261 const char *
   14262 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
   14263 {
   14264   output_reload_in_const (op, clobber_reg, len, false);
   14265   return "";
   14266 }
   14267 
   14268 
   14269 /* Worker function for `ASM_OUTPUT_ADDR_VEC'.  */
   14270 /* Emit jump tables out-of-line so that branches crossing the table
   14271    get shorter offsets.  If we have JUMP + CALL, then put the tables
   14272    in a dedicated non-.text section so that CALLs get better chance to
   14273    be relaxed to RCALLs.
   14274 
   14275    We emit the tables by hand because `function_rodata_section' does not
   14276    work as expected, cf. PR71151, and we do *NOT* want the table to be
   14277    in .rodata, hence setting JUMP_TABLES_IN_TEXT_SECTION = 0 is of limited
   14278    use; and setting it to 1 attributes table lengths to branch offsets...
   14279    Moreover, fincal.c keeps switching section before each table entry
   14280    which we find too fragile as to rely on section caching.  */
   14281 
   14282 void
   14283 avr_output_addr_vec (rtx_insn *labl, rtx table)
   14284 {
   14285   FILE *stream = asm_out_file;
   14286 
   14287   app_disable();
   14288 
   14289   // Switch to appropriate (sub)section.
   14290 
   14291   if (DECL_SECTION_NAME (current_function_decl)
   14292       && symtab_node::get (current_function_decl)
   14293       && ! symtab_node::get (current_function_decl)->implicit_section)
   14294     {
   14295       // .subsection will emit the code after the function and in the
   14296       // section as chosen by the user.
   14297 
   14298       switch_to_section (current_function_section ());
   14299       fprintf (stream, "\t.subsection\t1\n");
   14300     }
   14301   else
   14302     {
   14303       // Since PR63223 there is no restriction where to put the table; it
   14304       // may even reside above 128 KiB.  We put it in a section as high as
   14305       // possible and avoid progmem in order not to waste flash <= 64 KiB.
   14306 
   14307       const char *sec_name = ".jumptables.gcc";
   14308 
   14309       // The table belongs to its host function, therefore use fine
   14310       // grained sections so that, if that function is removed by
   14311       // --gc-sections, the child table(s) may also be removed.  */
   14312 
   14313       tree asm_name = DECL_ASSEMBLER_NAME (current_function_decl);
   14314       const char *fname = IDENTIFIER_POINTER (asm_name);
   14315       fname = targetm.strip_name_encoding (fname);
   14316       sec_name = ACONCAT ((sec_name, ".", fname, NULL));
   14317 
   14318       fprintf (stream, "\t.section\t%s,\"%s\",@progbits\n", sec_name,
   14319 	       AVR_HAVE_JMP_CALL ? "a" : "ax");
   14320     }
   14321 
   14322   // Output the label that preceeds the table.
   14323 
   14324   ASM_OUTPUT_ALIGN (stream, 1);
   14325   targetm.asm_out.internal_label (stream, "L", CODE_LABEL_NUMBER (labl));
   14326 
   14327   // Output the table's content.
   14328 
   14329   int vlen = XVECLEN (table, 0);
   14330 
   14331   for (int idx = 0; idx < vlen; idx++)
   14332     {
   14333       int value = CODE_LABEL_NUMBER (XEXP (XVECEXP (table, 0, idx), 0));
   14334 
   14335       if (AVR_HAVE_JMP_CALL)
   14336 	fprintf (stream, "\t.word gs(.L%d)\n", value);
   14337       else
   14338 	fprintf (stream, "\trjmp .L%d\n", value);
   14339     }
   14340 
   14341   // Switch back to original section.  As we clobbered the section above,
   14342   // forget the current section before switching back.
   14343 
   14344   in_section = NULL;
   14345   switch_to_section (current_function_section ());
   14346 }
   14347 
   14348 
   14349 /* Implement `TARGET_CONDITIONAL_REGISTER_USAGE'.  */
   14350 
   14351 static void
   14352 avr_conditional_register_usage (void)
   14353 {
   14354   if (AVR_TINY)
   14355     {
   14356       const int tiny_reg_alloc_order[] = {
   14357 	24, 25,
   14358 	22, 23,
   14359 	30, 31,
   14360 	26, 27,
   14361 	28, 29,
   14362 	21, 20, 19, 18,
   14363 	16, 17,
   14364 	32, 33, 34, 35,
   14365 	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
   14366       };
   14367 
   14368       /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
   14369 	 - R0-R15 are not available in Tiny Core devices
   14370 	 - R16 and R17 are fixed registers.  */
   14371 
   14372       for (size_t i = REG_0; i <= REG_17;  i++)
   14373 	{
   14374 	  fixed_regs[i] = 1;
   14375 	  call_used_regs[i] = 1;
   14376 	}
   14377 
   14378       /* Set R18 to R21 as callee saved registers
   14379 	 - R18, R19, R20 and R21 are the callee saved registers in
   14380 	   Tiny Core devices  */
   14381 
   14382       for (size_t i = REG_18; i <= LAST_CALLEE_SAVED_REG; i++)
   14383 	{
   14384 	  call_used_regs[i] = 0;
   14385 	}
   14386 
   14387       /* Update register allocation order for Tiny Core devices */
   14388 
   14389       for (size_t i = 0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++)
   14390 	{
   14391 	  reg_alloc_order[i] = tiny_reg_alloc_order[i];
   14392 	}
   14393 
   14394       CLEAR_HARD_REG_SET (reg_class_contents[(int) NO_LD_REGS]);
   14395     }
   14396 }
   14397 
   14398 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'.  */
   14399 /* Returns true if SCRATCH are safe to be allocated as a scratch
   14400    registers (for a define_peephole2) in the current function.  */
   14401 
   14402 static bool
   14403 avr_hard_regno_scratch_ok (unsigned int regno)
   14404 {
   14405   /* Interrupt functions can only use registers that have already been saved
   14406      by the prologue, even if they would normally be call-clobbered.  */
   14407 
   14408   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
   14409       && !df_regs_ever_live_p (regno))
   14410     return false;
   14411 
   14412   /* Don't allow hard registers that might be part of the frame pointer.
   14413      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
   14414      and don't care for a frame pointer that spans more than one register.  */
   14415 
   14416   if ((!reload_completed || frame_pointer_needed)
   14417       && (regno == REG_Y || regno == REG_Y + 1))
   14418     {
   14419       return false;
   14420     }
   14421 
   14422   return true;
   14423 }
   14424 
   14425 
   14426 /* Worker function for `HARD_REGNO_RENAME_OK'.  */
   14427 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
   14428 
   14429 int
   14430 avr_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
   14431 {
   14432   /* Interrupt functions can only use registers that have already been
   14433      saved by the prologue, even if they would normally be
   14434      call-clobbered.  */
   14435 
   14436   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
   14437       && !df_regs_ever_live_p (new_reg))
   14438     return 0;
   14439 
   14440   /* Don't allow hard registers that might be part of the frame pointer.
   14441      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
   14442      and don't care for a frame pointer that spans more than one register.  */
   14443 
   14444   if ((!reload_completed || frame_pointer_needed)
   14445       && (old_reg == REG_Y || old_reg == REG_Y + 1
   14446 	  || new_reg == REG_Y || new_reg == REG_Y + 1))
   14447     {
   14448       return 0;
   14449     }
   14450 
   14451   return 1;
   14452 }
   14453 
   14454 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
   14455    or memory location in the I/O space (QImode only).
   14456 
   14457    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
   14458    Operand 1: register operand to test, or CONST_INT memory address.
   14459    Operand 2: bit number.
   14460    Operand 3: label to jump to if the test is true.  */
   14461 
   14462 const char *
   14463 avr_out_sbxx_branch (rtx_insn *insn, rtx operands[])
   14464 {
   14465   enum rtx_code comp = GET_CODE (operands[0]);
   14466   bool long_jump = get_attr_length (insn) >= 4;
   14467   bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
   14468 
   14469   // PR116953: jump_over_one_insn_p may call extract on the next insn,
   14470   // clobbering recog_data.operand.  Thus, restore recog_data.
   14471   extract_constrain_insn_cached (insn);
   14472 
   14473   if (comp == GE)
   14474     comp = EQ;
   14475   else if (comp == LT)
   14476     comp = NE;
   14477 
   14478   if (reverse)
   14479     comp = reverse_condition (comp);
   14480 
   14481   switch (GET_CODE (operands[1]))
   14482     {
   14483     default:
   14484       gcc_unreachable();
   14485 
   14486     case CONST_INT:
   14487     case CONST:
   14488     case SYMBOL_REF:
   14489 
   14490       if (low_io_address_operand (operands[1], QImode))
   14491 	{
   14492 	  if (comp == EQ)
   14493 	    output_asm_insn ("sbis %i1,%2", operands);
   14494 	  else
   14495 	    output_asm_insn ("sbic %i1,%2", operands);
   14496 	}
   14497       else
   14498 	{
   14499 	  gcc_assert (io_address_operand (operands[1], QImode));
   14500 	  output_asm_insn ("in __tmp_reg__,%i1", operands);
   14501 	  if (comp == EQ)
   14502 	    output_asm_insn ("sbrs __tmp_reg__,%2", operands);
   14503 	  else
   14504 	    output_asm_insn ("sbrc __tmp_reg__,%2", operands);
   14505 	}
   14506 
   14507       break; /* CONST_INT */
   14508 
   14509     case REG:
   14510 
   14511       if (comp == EQ)
   14512 	output_asm_insn ("sbrs %T1%T2", operands);
   14513       else
   14514 	output_asm_insn ("sbrc %T1%T2", operands);
   14515 
   14516       break; /* REG */
   14517     } /* switch */
   14518 
   14519   if (long_jump)
   14520     return ("rjmp .+4" CR_TAB
   14521 	    "jmp %x3");
   14522 
   14523   if (!reverse)
   14524     return "rjmp %x3";
   14525 
   14526   return "";
   14527 }
   14528 
   14529 
   14530 /* Worker function for `TARGET_ASM_CONSTRUCTOR'.  */
   14531 
   14532 static void
   14533 avr_asm_out_ctor (rtx symbol, int priority)
   14534 {
   14535   fputs ("\t.global __do_global_ctors\n", asm_out_file);
   14536   default_ctor_section_asm_out_constructor (symbol, priority);
   14537 }
   14538 
   14539 
   14540 /* Worker function for `TARGET_ASM_DESTRUCTOR'.  */
   14541 
   14542 static void
   14543 avr_asm_out_dtor (rtx symbol, int priority)
   14544 {
   14545   fputs ("\t.global __do_global_dtors\n", asm_out_file);
   14546   default_dtor_section_asm_out_destructor (symbol, priority);
   14547 }
   14548 
   14549 
   14550 /* Implement `TARGET_RETURN_IN_MEMORY'.  */
   14551 
   14552 static bool
   14553 avr_return_in_memory (const_tree type, const_tree /*fntype*/)
   14554 {
   14555   HOST_WIDE_INT size = int_size_in_bytes (type);
   14556   HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
   14557 
   14558   /* In avr, there are 8 return registers. But, for Tiny Core
   14559      (ATtiny4/5/9/10/20/40) devices, only 4 registers are available.
   14560      Return true if size is unknown or greater than the limit.  */
   14561 
   14562   if (size == -1 || size > ret_size_limit)
   14563     {
   14564       return true;
   14565     }
   14566   else
   14567     {
   14568       return false;
   14569     }
   14570 }
   14571 
   14572 
   14573 /* Implement `CASE_VALUES_THRESHOLD'.  */
   14574 /* Supply the default for --param case-values-threshold=0  */
   14575 
   14576 static unsigned int
   14577 avr_case_values_threshold (void)
   14578 {
   14579   /* The exact break-even point between a jump table and an if-else tree
   14580      depends on several factors not available here like, e.g. if 8-bit
   14581      comparisons can be used in the if-else tree or not, on the
   14582      range of the case values, if the case value can be reused, on the
   14583      register allocation, etc.  '7' appears to be a good choice.  */
   14584 
   14585   return 7;
   14586 }
   14587 
   14588 
   14589 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'.  */
   14590 
   14591 static scalar_int_mode
   14592 avr_addr_space_address_mode (addr_space_t as)
   14593 {
   14594   return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
   14595 }
   14596 
   14597 
   14598 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'.  */
   14599 
   14600 static scalar_int_mode
   14601 avr_addr_space_pointer_mode (addr_space_t as)
   14602 {
   14603   return avr_addr_space_address_mode (as);
   14604 }
   14605 
   14606 
   14607 /* Helper for following function.  */
   14608 
   14609 static bool
   14610 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
   14611 {
   14612   gcc_assert (REG_P (reg));
   14613 
   14614   if (strict)
   14615     {
   14616       return REGNO (reg) == REG_Z;
   14617     }
   14618 
   14619   /* Avoid combine to propagate hard regs.  */
   14620 
   14621   if (can_create_pseudo_p()
   14622       && REGNO (reg) < REG_Z)
   14623     {
   14624       return false;
   14625     }
   14626 
   14627   return true;
   14628 }
   14629 
   14630 
   14631 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'.  */
   14632 
   14633 static bool
   14634 avr_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict,
   14635 				     addr_space_t as, code_helper = ERROR_MARK)
   14636 {
   14637   bool ok = false;
   14638 
   14639   switch (as)
   14640     {
   14641     default:
   14642       gcc_unreachable();
   14643 
   14644     case ADDR_SPACE_GENERIC:
   14645       return avr_legitimate_address_p (mode, x, strict);
   14646 
   14647     case ADDR_SPACE_FLASH:
   14648     case ADDR_SPACE_FLASH1:
   14649     case ADDR_SPACE_FLASH2:
   14650     case ADDR_SPACE_FLASH3:
   14651     case ADDR_SPACE_FLASH4:
   14652     case ADDR_SPACE_FLASH5:
   14653 
   14654       switch (GET_CODE (x))
   14655 	{
   14656 	case REG:
   14657 	  ok = avr_reg_ok_for_pgm_addr (x, strict);
   14658 	  break;
   14659 
   14660 	case POST_INC:
   14661 	  ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
   14662 	  break;
   14663 
   14664 	default:
   14665 	  break;
   14666 	}
   14667 
   14668       break; /* FLASH */
   14669 
   14670     case ADDR_SPACE_MEMX:
   14671       if (REG_P (x))
   14672 	ok = (!strict
   14673 	      && can_create_pseudo_p());
   14674 
   14675       if (LO_SUM == GET_CODE (x))
   14676 	{
   14677 	  rtx hi = XEXP (x, 0);
   14678 	  rtx lo = XEXP (x, 1);
   14679 
   14680 	  ok = (REG_P (hi)
   14681 		&& (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
   14682 		&& REG_P (lo)
   14683 		&& REGNO (lo) == REG_Z);
   14684 	}
   14685 
   14686       break; /* MEMX */
   14687     }
   14688 
   14689   if (avr_log.legitimate_address_p)
   14690     {
   14691       avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
   14692 		 "reload_completed=%d reload_in_progress=%d %s:",
   14693 		 ok, mode, strict, reload_completed, reload_in_progress,
   14694 		 reg_renumber ? "(reg_renumber)" : "");
   14695 
   14696       if (GET_CODE (x) == PLUS
   14697 	  && REG_P (XEXP (x, 0))
   14698 	  && CONST_INT_P (XEXP (x, 1))
   14699 	  && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
   14700 	  && reg_renumber)
   14701 	{
   14702 	  avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
   14703 		     true_regnum (XEXP (x, 0)));
   14704 	}
   14705 
   14706       avr_edump ("\n%r\n", x);
   14707     }
   14708 
   14709   return ok;
   14710 }
   14711 
   14712 
   14713 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'.  */
   14714 
   14715 static rtx
   14716 avr_addr_space_legitimize_address (rtx x, rtx old_x,
   14717 				   machine_mode mode, addr_space_t as)
   14718 {
   14719   if (ADDR_SPACE_GENERIC_P (as))
   14720     return avr_legitimize_address (x, old_x, mode);
   14721 
   14722   if (avr_log.legitimize_address)
   14723     {
   14724       avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
   14725     }
   14726 
   14727   return old_x;
   14728 }
   14729 
   14730 
   14731 /* Implement `TARGET_ADDR_SPACE_CONVERT'.  */
   14732 
   14733 static rtx
   14734 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
   14735 {
   14736   addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
   14737   addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
   14738 
   14739   if (avr_log.progmem)
   14740     avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
   14741 	       src, type_from, type_to);
   14742 
   14743   /* Up-casting from 16-bit to 24-bit pointer.  */
   14744 
   14745   if (as_from != ADDR_SPACE_MEMX
   14746       && as_to == ADDR_SPACE_MEMX)
   14747     {
   14748       rtx sym = src;
   14749       rtx reg = gen_reg_rtx (PSImode);
   14750 
   14751       while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
   14752 	sym = XEXP (sym, 0);
   14753 
   14754       /* Look at symbol flags:  avr_encode_section_info set the flags
   14755 	 also if attribute progmem was seen so that we get the right
   14756 	 promotion for, e.g. PSTR-like strings that reside in generic space
   14757 	 but are located in flash.  In that case we patch the incoming
   14758 	 address space.  */
   14759 
   14760       if (SYMBOL_REF_P (sym)
   14761 	  && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
   14762 	{
   14763 	  as_from = ADDR_SPACE_FLASH;
   14764 	}
   14765 
   14766       /* Linearize memory: RAM has bit 23 set.  */
   14767 
   14768       int msb = ADDR_SPACE_GENERIC_P (as_from)
   14769 	? 0x80
   14770 	: avr_addrspace[as_from].segment;
   14771 
   14772       src = force_reg (Pmode, src);
   14773 
   14774       emit_insn (msb == 0
   14775 		 ? gen_zero_extendhipsi2 (reg, src)
   14776 		 : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
   14777 
   14778       return reg;
   14779     }
   14780 
   14781   /* Down-casting from 24-bit to 16-bit throws away the high byte.  */
   14782 
   14783   if (as_from == ADDR_SPACE_MEMX
   14784       && as_to != ADDR_SPACE_MEMX)
   14785     {
   14786       rtx new_src = gen_reg_rtx (Pmode);
   14787 
   14788       src = force_reg (PSImode, src);
   14789 
   14790       emit_move_insn (new_src,
   14791 		      simplify_gen_subreg (Pmode, src, PSImode, 0));
   14792       return new_src;
   14793     }
   14794 
   14795   return src;
   14796 }
   14797 
   14798 
   14799 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'.  */
   14800 
   14801 static bool
   14802 avr_addr_space_subset_p (addr_space_t /*subset*/, addr_space_t /*superset*/)
   14803 {
   14804   /* Allow any kind of pointer mess.  */
   14805 
   14806   return true;
   14807 }
   14808 
   14809 
   14810 /* Implement `TARGET_CONVERT_TO_TYPE'.  */
   14811 
   14812 static tree
   14813 avr_convert_to_type (tree type, tree expr)
   14814 {
   14815   /* Print a diagnose for pointer conversion that changes the address
   14816      space of the pointer target to a non-enclosing address space,
   14817      provided -Waddr-space-convert is on.
   14818 
   14819      FIXME: Filter out cases where the target object is known to
   14820 	    be located in the right memory, like in
   14821 
   14822 		(const __flash*) PSTR ("text")
   14823 
   14824 	    Also try to distinguish between explicit casts requested by
   14825 	    the user and implicit casts like
   14826 
   14827 		void f (const __flash char*);
   14828 
   14829 		void g (const char *p)
   14830 		{
   14831 		    f ((const __flash*) p);
   14832 		}
   14833 
   14834 	    under the assumption that an explicit casts means that the user
   14835 	    knows what he is doing, e.g. interface with PSTR or old style
   14836 	    code with progmem and pgm_read_xxx.
   14837   */
   14838 
   14839   if (avr_warn_addr_space_convert
   14840       && expr != error_mark_node
   14841       && POINTER_TYPE_P (type)
   14842       && POINTER_TYPE_P (TREE_TYPE (expr)))
   14843     {
   14844       addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
   14845       addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
   14846 
   14847       if (avr_log.progmem)
   14848 	avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
   14849 
   14850       if (as_new != ADDR_SPACE_MEMX
   14851 	  && as_new != as_old)
   14852 	{
   14853 	  location_t loc = EXPR_LOCATION (expr);
   14854 	  const char *name_old = avr_addrspace[as_old].name;
   14855 	  const char *name_new = avr_addrspace[as_new].name;
   14856 
   14857 	  warning (OPT_Waddr_space_convert,
   14858 		   "conversion from address space %qs to address space %qs",
   14859 		   ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
   14860 		   ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
   14861 
   14862 	  return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
   14863 	}
   14864     }
   14865 
   14866   return NULL_TREE;
   14867 }
   14868 
   14869 
   14870 /* Implement `TARGET_LEGITIMATE_COMBINED_INSN'.  */
   14871 /* PR78883: Filter out paradoxical SUBREGs of MEM which are not handled
   14872    properly by following passes.  As INSN_SCHEDULING is off and hence
   14873    general_operand accepts such expressions, ditch them now.  */
   14874 
   14875 static bool
   14876 avr_legitimate_combined_insn (rtx_insn *insn)
   14877 {
   14878   subrtx_iterator::array_type array;
   14879 
   14880   FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
   14881     {
   14882       const_rtx op = *iter;
   14883 
   14884       if (SUBREG_P (op)
   14885 	  && MEM_P (SUBREG_REG (op))
   14886 	  && (GET_MODE_SIZE (GET_MODE (op))
   14887 	      > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
   14888 	{
   14889 	  return false;
   14890 	}
   14891     }
   14892 
   14893   return true;
   14894 }
   14895 
   14896 
   14897 /* PR63633: The middle-end might come up with hard regs as input operands.
   14898 
   14899    RMASK is a bit mask representing a subset of hard registers R0...R31:
   14900    Rn is an element of that set iff bit n of RMASK is set.
   14901    OPMASK describes a subset of OP[]:  If bit n of OPMASK is 1 then
   14902    OP[n] has to be fixed; otherwise OP[n] is left alone.
   14903 
   14904    For each element of OPMASK which is a hard register overlapping RMASK,
   14905    replace OP[n] with a newly created pseudo register
   14906 
   14907    HREG == 0:  Also emit a move insn that copies the contents of that
   14908 	       hard register into the new pseudo.
   14909 
   14910    HREG != 0:  Also set HREG[n] to the hard register.  */
   14911 
   14912 static void
   14913 avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask)
   14914 {
   14915   for (; opmask; opmask >>= 1, op++)
   14916     {
   14917       rtx reg = *op;
   14918 
   14919       if (hreg)
   14920 	*hreg = NULL_RTX;
   14921 
   14922       if ((opmask & 1)
   14923 	  && REG_P (reg)
   14924 	  && REGNO (reg) < FIRST_PSEUDO_REGISTER
   14925 	  // This hard-reg overlaps other prohibited hard regs?
   14926 	  && (rmask & regmask (GET_MODE (reg), REGNO (reg))))
   14927 	{
   14928 	  *op = gen_reg_rtx (GET_MODE (reg));
   14929 	  if (hreg == NULL)
   14930 	    emit_move_insn (*op, reg);
   14931 	  else
   14932 	    *hreg = reg;
   14933 	}
   14934 
   14935       if (hreg)
   14936 	hreg++;
   14937     }
   14938 }
   14939 
   14940 
   14941 void
   14942 avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask)
   14943 {
   14944   avr_fix_operands (op, NULL, opmask, rmask);
   14945 }
   14946 
   14947 
   14948 /* Helper for the function below:  If bit n of MASK is set and
   14949    HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n].
   14950    Otherwise do nothing for that n.  Return TRUE.  */
   14951 
   14952 static bool
   14953 avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask)
   14954 {
   14955   for (; mask; mask >>= 1, op++, hreg++)
   14956     if ((mask & 1)
   14957 	&& *hreg)
   14958       emit_move_insn (*hreg, *op);
   14959 
   14960   return true;
   14961 }
   14962 
   14963 
   14964 /* PR63633: The middle-end might come up with hard regs as output operands.
   14965 
   14966    GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[].
   14967    RMASK is a bit mask representing a subset of hard registers R0...R31:
   14968    Rn is an element of that set iff bit n of RMASK is set.
   14969    OPMASK describes a subset of OP[]:  If bit n of OPMASK is 1 then
   14970    OP[n] has to be fixed; otherwise OP[n] is left alone.
   14971 
   14972    Emit the insn sequence as generated by GEN() with all elements of OPMASK
   14973    which are hard registers overlapping RMASK replaced by newly created
   14974    pseudo registers.  After the sequence has been emitted, emit insns that
   14975    move the contents of respective pseudos to their hard regs.  */
   14976 
   14977 bool
   14978 avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
   14979 		       unsigned opmask, unsigned rmask)
   14980 {
   14981   const int n = 3;
   14982   rtx hreg[n];
   14983 
   14984   /* It is letigimate for GEN to call this function, and in order not to
   14985      get self-recursive we use the following static kludge.  This is the
   14986      only way not to duplicate all expanders and to avoid ugly and
   14987      hard-to-maintain C-code instead of the much more appreciated RTL
   14988      representation as supplied by define_expand.  */
   14989   static bool lock = false;
   14990 
   14991   gcc_assert (opmask < (1u << n));
   14992 
   14993   if (lock)
   14994     return false;
   14995 
   14996   avr_fix_operands (op, hreg, opmask, rmask);
   14997 
   14998   lock = true;
   14999   emit_insn (gen (op[0], op[1], op[2]));
   15000   lock = false;
   15001 
   15002   return avr_move_fixed_operands (op, hreg, opmask);
   15003 }
   15004 
   15005 
   15006 /* Worker function for cpymemhi expander.
   15007    XOP[0]  Destination as MEM:BLK
   15008    XOP[1]  Source      "     "
   15009    XOP[2]  # Bytes to copy
   15010 
   15011    Return TRUE  if the expansion is accomplished.
   15012    Return FALSE if the operand compination is not supported.  */
   15013 
   15014 bool
   15015 avr_emit_cpymemhi (rtx *xop)
   15016 {
   15017   machine_mode loop_mode;
   15018   addr_space_t as = MEM_ADDR_SPACE (xop[1]);
   15019   rtx loop_reg, addr1, insn;
   15020   rtx a_hi8 = NULL_RTX;
   15021 
   15022   if (avr_mem_flash_p (xop[0]))
   15023     return false;
   15024 
   15025   if (!CONST_INT_P (xop[2]))
   15026     return false;
   15027 
   15028   HOST_WIDE_INT count = INTVAL (xop[2]);
   15029   if (count <= 0)
   15030     return false;
   15031 
   15032   rtx a_src  = XEXP (xop[1], 0);
   15033   rtx a_dest = XEXP (xop[0], 0);
   15034 
   15035   if (PSImode == GET_MODE (a_src))
   15036     {
   15037       gcc_assert (as == ADDR_SPACE_MEMX);
   15038 
   15039       loop_mode = (count < 0x100) ? QImode : HImode;
   15040       loop_reg = gen_rtx_REG (loop_mode, 24);
   15041       emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
   15042 
   15043       addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
   15044       a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
   15045     }
   15046   else
   15047     {
   15048       int segment = avr_addrspace[as].segment;
   15049 
   15050       if (segment
   15051 	  && avr_n_flash > 1)
   15052 	{
   15053 	  a_hi8 = GEN_INT (segment);
   15054 	  emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
   15055 	}
   15056       else if (!ADDR_SPACE_GENERIC_P (as))
   15057 	{
   15058 	  as = ADDR_SPACE_FLASH;
   15059 	}
   15060 
   15061       addr1 = a_src;
   15062 
   15063       loop_mode = (count <= 0x100) ? QImode : HImode;
   15064       loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
   15065     }
   15066 
   15067   rtx xas = GEN_INT (as);
   15068 
   15069   /* FIXME: Register allocator might come up with spill fails if it is left
   15070 	on its own.  Thus, we allocate the pointer registers by hand:
   15071 	Z = source address
   15072 	X = destination address  */
   15073 
   15074   emit_move_insn (lpm_addr_reg_rtx, addr1);
   15075   emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
   15076 
   15077   /* FIXME: Register allocator does a bad job and might spill address
   15078 	register(s) inside the loop leading to additional move instruction
   15079 	to/from stack which could clobber tmp_reg.  Thus, do *not* emit
   15080 	load and store as separate insns.  Instead, we perform the copy
   15081 	by means of one monolithic insn.  */
   15082 
   15083   gcc_assert (TMP_REGNO == LPM_REGNO);
   15084 
   15085   if (as != ADDR_SPACE_MEMX)
   15086     {
   15087       /* Load instruction ([E]LPM or LD) is known at compile time:
   15088 	 Do the copy-loop inline.  */
   15089 
   15090       rtx (*fun) (rtx, rtx, rtx)
   15091 	= QImode == loop_mode ? gen_cpymem_qi : gen_cpymem_hi;
   15092 
   15093       insn = fun (xas, loop_reg, loop_reg);
   15094     }
   15095   else
   15096     {
   15097       rtx (*fun) (rtx, rtx)
   15098 	= QImode == loop_mode ? gen_cpymemx_qi : gen_cpymemx_hi;
   15099 
   15100       emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
   15101 
   15102       insn = fun (xas, GEN_INT (avr_addr.rampz));
   15103     }
   15104 
   15105   set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
   15106   emit_insn (insn);
   15107 
   15108   return true;
   15109 }
   15110 
   15111 
   15112 /* Print assembler for cpymem_qi, cpymem_hi insns...
   15113        $0     : Address Space
   15114        $1, $2 : Loop register
   15115        Z      : Source address
   15116        X      : Destination address
   15117 */
   15118 
   15119 const char *
   15120 avr_out_cpymem (rtx_insn * /*insn*/, rtx *op, int *plen)
   15121 {
   15122   addr_space_t as = (addr_space_t) INTVAL (op[0]);
   15123   machine_mode loop_mode = GET_MODE (op[1]);
   15124   bool sbiw_p = avr_adiw_reg_p (op[1]);
   15125   rtx xop[3] = { op[0], op[1], tmp_reg_rtx };
   15126 
   15127   if (plen)
   15128     *plen = 0;
   15129 
   15130   /* Loop label */
   15131 
   15132   avr_asm_len ("0:", xop, plen, 0);
   15133 
   15134   /* Load with post-increment */
   15135 
   15136   switch (as)
   15137     {
   15138     default:
   15139       gcc_unreachable();
   15140 
   15141     case ADDR_SPACE_GENERIC:
   15142 
   15143       avr_asm_len ("ld %2,Z+", xop, plen, 1);
   15144       break;
   15145 
   15146     case ADDR_SPACE_FLASH:
   15147 
   15148       if (AVR_HAVE_LPMX)
   15149 	avr_asm_len ("lpm %2,Z+", xop, plen, 1);
   15150       else
   15151 	avr_asm_len ("lpm" CR_TAB
   15152 		     "adiw r30,1", xop, plen, 2);
   15153       break;
   15154 
   15155     case ADDR_SPACE_FLASH1:
   15156     case ADDR_SPACE_FLASH2:
   15157     case ADDR_SPACE_FLASH3:
   15158     case ADDR_SPACE_FLASH4:
   15159     case ADDR_SPACE_FLASH5:
   15160 
   15161       if (AVR_HAVE_ELPMX)
   15162 	avr_asm_len ("elpm %2,Z+", xop, plen, 1);
   15163       else
   15164 	avr_asm_len ("elpm" CR_TAB
   15165 		     "adiw r30,1", xop, plen, 2);
   15166       break;
   15167     }
   15168 
   15169   /* Store with post-increment */
   15170 
   15171   avr_asm_len ("st X+,%2", xop, plen, 1);
   15172 
   15173   /* Decrement loop-counter and set Z-flag */
   15174 
   15175   if (QImode == loop_mode)
   15176     {
   15177       avr_asm_len ("dec %1", xop, plen, 1);
   15178     }
   15179   else if (sbiw_p)
   15180     {
   15181       avr_asm_len ("sbiw %1,1", xop, plen, 1);
   15182     }
   15183   else
   15184     {
   15185       avr_asm_len ("subi %A1,1" CR_TAB
   15186 		   "sbci %B1,0", xop, plen, 2);
   15187     }
   15188 
   15189   /* Loop until zero */
   15190 
   15191   return avr_asm_len ("brne 0b", xop, plen, 1);
   15192 }
   15193 
   15194 
   15195 
   15196 /* Helper for __builtin_avr_delay_cycles */
   15198 
   15199 static rtx
   15200 avr_mem_clobber (void)
   15201 {
   15202   rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
   15203   MEM_VOLATILE_P (mem) = 1;
   15204   return mem;
   15205 }
   15206 
   15207 static void
   15208 avr_expand_delay_cycles (rtx operands0)
   15209 {
   15210   unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
   15211   unsigned HOST_WIDE_INT cycles_used;
   15212   unsigned HOST_WIDE_INT loop_count;
   15213 
   15214   if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
   15215     {
   15216       loop_count = ((cycles - 9) / 6) + 1;
   15217       cycles_used = ((loop_count - 1) * 6) + 9;
   15218       emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
   15219 				     avr_mem_clobber()));
   15220       cycles -= cycles_used;
   15221     }
   15222 
   15223   if (IN_RANGE (cycles, 262145, 83886081))
   15224     {
   15225       loop_count = ((cycles - 7) / 5) + 1;
   15226       if (loop_count > 0xFFFFFF)
   15227 	loop_count = 0xFFFFFF;
   15228       cycles_used = ((loop_count - 1) * 5) + 7;
   15229       emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
   15230 				     avr_mem_clobber()));
   15231       cycles -= cycles_used;
   15232     }
   15233 
   15234   if (IN_RANGE (cycles, 768, 262144))
   15235     {
   15236       loop_count = ((cycles - 5) / 4) + 1;
   15237       if (loop_count > 0xFFFF)
   15238 	loop_count = 0xFFFF;
   15239       cycles_used = ((loop_count - 1) * 4) + 5;
   15240       emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
   15241 				     avr_mem_clobber()));
   15242       cycles -= cycles_used;
   15243     }
   15244 
   15245   if (IN_RANGE (cycles, 6, 767))
   15246     {
   15247       loop_count = cycles / 3;
   15248       if (loop_count > 255)
   15249 	loop_count = 255;
   15250       cycles_used = loop_count * 3;
   15251       emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
   15252 				     avr_mem_clobber()));
   15253       cycles -= cycles_used;
   15254     }
   15255 
   15256   while (cycles >= 2)
   15257     {
   15258       emit_insn (gen_nopv (GEN_INT (2)));
   15259       cycles -= 2;
   15260     }
   15261 
   15262   if (cycles == 1)
   15263     {
   15264       emit_insn (gen_nopv (GEN_INT (1)));
   15265       cycles--;
   15266     }
   15267 }
   15268 
   15269 
   15270 static void
   15271 avr_expand_nops (rtx operands0)
   15272 {
   15273   unsigned HOST_WIDE_INT n_nops = UINTVAL (operands0) & GET_MODE_MASK (HImode);
   15274 
   15275   while (n_nops--)
   15276     {
   15277       emit_insn (gen_nopv (const1_rtx));
   15278     }
   15279 }
   15280 
   15281 
   15282 /* Compute the image of x under f, i.e. perform   x --> f(x)    */
   15283 
   15284 static int
   15285 avr_map (unsigned int f, int x)
   15286 {
   15287   return x < 8 ? (f >> (4 * x)) & 0xf : 0;
   15288 }
   15289 
   15290 
   15291 /* Return some metrics of map A.  */
   15292 
   15293 enum
   15294   {
   15295     /* Number of fixed points in { 0 ... 7 } */
   15296     MAP_FIXED_0_7,
   15297 
   15298     /* Size of preimage of non-fixed points in { 0 ... 7 } */
   15299     MAP_NONFIXED_0_7,
   15300 
   15301     /* Mask representing the fixed points in { 0 ... 7 } */
   15302     MAP_MASK_FIXED_0_7,
   15303 
   15304     /* Size of the preimage of { 0 ... 7 } */
   15305     MAP_PREIMAGE_0_7,
   15306 
   15307     /* Mask that represents the preimage of { f } */
   15308     MAP_MASK_PREIMAGE_F
   15309   };
   15310 
   15311 static unsigned
   15312 avr_map_metric (unsigned int a, int mode)
   15313 {
   15314   unsigned metric = 0;
   15315 
   15316   for (unsigned i = 0; i < 8; i++)
   15317     {
   15318       unsigned ai = avr_map (a, i);
   15319 
   15320       if (mode == MAP_FIXED_0_7)
   15321 	metric += ai == i;
   15322       else if (mode == MAP_NONFIXED_0_7)
   15323 	metric += ai < 8 && ai != i;
   15324       else if (mode == MAP_MASK_FIXED_0_7)
   15325 	metric |= ((unsigned) (ai == i)) << i;
   15326       else if (mode == MAP_PREIMAGE_0_7)
   15327 	metric += ai < 8;
   15328       else if (mode == MAP_MASK_PREIMAGE_F)
   15329 	metric |= ((unsigned) (ai == 0xf)) << i;
   15330       else
   15331 	gcc_unreachable();
   15332     }
   15333 
   15334   return metric;
   15335 }
   15336 
   15337 
   15338 /* Return true if IVAL has a 0xf in its hexadecimal representation
   15339    and false, otherwise.  Only nibbles 0..7 are taken into account.
   15340    Used as constraint helper for C0f and Cxf.  */
   15341 
   15342 bool
   15343 avr_has_nibble_0xf (rtx ival)
   15344 {
   15345   unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode);
   15346   return avr_map_metric (map, MAP_MASK_PREIMAGE_F) != 0;
   15347 }
   15348 
   15349 
   15350 /* We have a set of bits that are mapped by a function F.
   15351    Try to decompose F by means of a second function G so that
   15352 
   15353       F = F o G^-1 o G
   15354 
   15355    and
   15356 
   15357       cost (F o G^-1) + cost (G)  <  cost (F)
   15358 
   15359    Example:  Suppose builtin insert_bits supplies us with the map
   15360    F = 0x3210ffff.  Instead of doing 4 bit insertions to get the high
   15361    nibble of the result, we can just as well rotate the bits before inserting
   15362    them and use the map 0x7654ffff which is cheaper than the original map.
   15363    For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff.  */
   15364 
   15365 typedef struct
   15366 {
   15367   /* tree code of binary function G */
   15368   enum tree_code code;
   15369 
   15370   /* The constant second argument of G */
   15371   int arg;
   15372 
   15373   /* G^-1, the inverse of G (*, arg) */
   15374   unsigned ginv;
   15375 
   15376   /* The cost of applying G (*, arg) */
   15377   int cost;
   15378 
   15379   /* The composition F o G^-1 (*, arg) for some function F */
   15380   unsigned int map;
   15381 
   15382   /* For debug purpose only */
   15383   const char *str;
   15384 } avr_map_op_t;
   15385 
   15386 static const avr_map_op_t avr_map_op[] =
   15387   {
   15388     { LROTATE_EXPR, 0, 0x76543210, 0, 0, "id" },
   15389     { LROTATE_EXPR, 1, 0x07654321, 2, 0, "<<<" },
   15390     { LROTATE_EXPR, 2, 0x10765432, 4, 0, "<<<" },
   15391     { LROTATE_EXPR, 3, 0x21076543, 4, 0, "<<<" },
   15392     { LROTATE_EXPR, 4, 0x32107654, 1, 0, "<<<" },
   15393     { LROTATE_EXPR, 5, 0x43210765, 3, 0, "<<<" },
   15394     { LROTATE_EXPR, 6, 0x54321076, 5, 0, "<<<" },
   15395     { LROTATE_EXPR, 7, 0x65432107, 3, 0, "<<<" },
   15396     { RSHIFT_EXPR, 1, 0x6543210c, 1, 0, ">>" },
   15397     { RSHIFT_EXPR, 1, 0x7543210c, 1, 0, ">>" },
   15398     { RSHIFT_EXPR, 2, 0x543210cc, 2, 0, ">>" },
   15399     { RSHIFT_EXPR, 2, 0x643210cc, 2, 0, ">>" },
   15400     { RSHIFT_EXPR, 2, 0x743210cc, 2, 0, ">>" },
   15401     { LSHIFT_EXPR, 1, 0xc7654321, 1, 0, "<<" },
   15402     { LSHIFT_EXPR, 2, 0xcc765432, 2, 0, "<<" }
   15403   };
   15404 
   15405 
   15406 /* Try to decompose F as F = (F o G^-1) o G as described above.
   15407    The result is a struct representing F o G^-1 and G.
   15408    If result.cost < 0 then such a decomposition does not exist.  */
   15409 
   15410 static avr_map_op_t
   15411 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p)
   15412 {
   15413   bool val_used_p = avr_map_metric (f, MAP_MASK_PREIMAGE_F) != 0;
   15414   avr_map_op_t f_ginv = *g;
   15415   unsigned int ginv = g->ginv;
   15416 
   15417   f_ginv.cost = -1;
   15418 
   15419   /* Step 1:  Computing F o G^-1  */
   15420 
   15421   for (int i = 7; i >= 0; i--)
   15422     {
   15423       int x = avr_map (f, i);
   15424 
   15425       if (x <= 7)
   15426 	{
   15427 	  x = avr_map (ginv, x);
   15428 
   15429 	  /* The bit is no element of the image of G: no avail (cost = -1)  */
   15430 
   15431 	  if (x > 7)
   15432 	    return f_ginv;
   15433 	}
   15434 
   15435       f_ginv.map = (f_ginv.map << 4) + x;
   15436     }
   15437 
   15438   /* Step 2:  Compute the cost of the operations.
   15439      The overall cost of doing an operation prior to the insertion is
   15440       the cost of the insertion plus the cost of the operation.  */
   15441 
   15442   /* Step 2a:  Compute cost of F o G^-1  */
   15443 
   15444   if (avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7) == 0)
   15445     /* The mapping consists only of fixed points and can be folded
   15446        to AND/OR logic in the remainder.  Reasonable cost is 3. */
   15447     f_ginv.cost = 2 + (val_used_p && !val_const_p);
   15448   else
   15449     {
   15450       rtx xop[4];
   15451 
   15452       /* Get the cost of the insn by calling the output worker with some
   15453 	 fake values.  Mimic effect of reloading xop[3]: Unused operands
   15454 	 are mapped to 0 and used operands are reloaded to xop[0].  */
   15455 
   15456       xop[0] = all_regs_rtx[REG_24];
   15457       xop[1] = gen_int_mode (f_ginv.map, SImode);
   15458       xop[2] = all_regs_rtx[REG_25];
   15459       xop[3] = val_used_p ? xop[0] : const0_rtx;
   15460 
   15461       avr_out_insert_bits (xop, &f_ginv.cost);
   15462 
   15463       f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
   15464     }
   15465 
   15466   /* Step 2b:  Add cost of G  */
   15467 
   15468   f_ginv.cost += g->cost;
   15469 
   15470   if (avr_log.builtin)
   15471     avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
   15472 
   15473   return f_ginv;
   15474 }
   15475 
   15476 
   15477 /* Insert bits from XOP[1] into XOP[0] according to MAP.
   15478    XOP[0] and XOP[1] don't overlap.
   15479    If FIXP_P = true:  Move all bits according to MAP using BLD/BST sequences.
   15480    If FIXP_P = false: Just move the bit if its position in the destination
   15481    is different to its source position.  */
   15482 
   15483 static void
   15484 avr_move_bits (rtx *xop, unsigned int map, bool fixp_p, int *plen)
   15485 {
   15486   /* T-flag contains this bit of the source, i.e. of XOP[1]  */
   15487   int t_bit_src = -1;
   15488 
   15489   /* We order the operations according to the requested source bit b.  */
   15490 
   15491   for (int b = 0; b < 8; b++)
   15492     for (int bit_dest = 0; bit_dest < 8; bit_dest++)
   15493       {
   15494 	int bit_src = avr_map (map, bit_dest);
   15495 
   15496 	if (b != bit_src
   15497 	    || bit_src >= 8
   15498 	    /* Same position: No need to copy as requested by FIXP_P.  */
   15499 	    || (bit_dest == bit_src && !fixp_p))
   15500 	  continue;
   15501 
   15502 	if (t_bit_src != bit_src)
   15503 	  {
   15504 	    /* Source bit is not yet in T: Store it to T.  */
   15505 
   15506 	    t_bit_src = bit_src;
   15507 
   15508 	    xop[3] = GEN_INT (bit_src);
   15509 	    avr_asm_len ("bst %T1%T3", xop, plen, 1);
   15510 	  }
   15511 
   15512 	/* Load destination bit with T.  */
   15513 
   15514 	xop[3] = GEN_INT (bit_dest);
   15515 	avr_asm_len ("bld %T0%T3", xop, plen, 1);
   15516       }
   15517 }
   15518 
   15519 
   15520 /* PLEN == 0: Print assembler code for `insert_bits'.
   15521    PLEN != 0: Compute code length in bytes.
   15522 
   15523    OP[0]:  Result
   15524    OP[1]:  The mapping composed of nibbles. If nibble no. N is
   15525 	   0:   Bit N of result is copied from bit OP[2].0
   15526 	   ...  ...
   15527 	   7:   Bit N of result is copied from bit OP[2].7
   15528 	   0xf: Bit N of result is copied from bit OP[3].N
   15529    OP[2]:  Bits to be inserted
   15530    OP[3]:  Target value  */
   15531 
   15532 const char *
   15533 avr_out_insert_bits (rtx *op, int *plen)
   15534 {
   15535   unsigned int map = UINTVAL (op[1]) & GET_MODE_MASK (SImode);
   15536   bool fixp_p = true;
   15537   rtx xop[4];
   15538 
   15539   xop[0] = op[0];
   15540   xop[1] = op[2];
   15541   xop[2] = op[3];
   15542 
   15543   gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
   15544 
   15545   if (plen)
   15546     *plen = 0;
   15547   else if (flag_print_asm_name)
   15548     fprintf (asm_out_file, ASM_COMMENT_START "map = 0x%08x\n", map);
   15549 
   15550   /* If MAP has fixed points it might be better to initialize the result
   15551      with the bits to be inserted instead of moving all bits by hand.  */
   15552 
   15553   unsigned mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
   15554 
   15555   if (REGNO (xop[0]) == REGNO (xop[1]))
   15556     {
   15557       /* Avoid early-clobber conflicts */
   15558 
   15559       avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
   15560       xop[1] = tmp_reg_rtx;
   15561       fixp_p = false;
   15562     }
   15563 
   15564   if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
   15565     {
   15566       /* XOP[2] is used and reloaded to XOP[0] already */
   15567 
   15568       int n_fix = 0, n_nofix = 0;
   15569 
   15570       gcc_assert (REG_P (xop[2]));
   15571 
   15572       /* Get the code size of the bit insertions; once with all bits
   15573 	 moved and once with fixed points omitted.  */
   15574 
   15575       avr_move_bits (xop, map, true, &n_fix);
   15576       avr_move_bits (xop, map, false, &n_nofix);
   15577 
   15578       if (fixp_p && n_fix - n_nofix > 3)
   15579 	{
   15580 	  xop[3] = gen_int_mode (~mask_fixed, QImode);
   15581 
   15582 	  avr_asm_len ("eor %0,%1"   CR_TAB
   15583 		       "andi %0,%3"  CR_TAB
   15584 		       "eor %0,%1", xop, plen, 3);
   15585 	  fixp_p = false;
   15586 	}
   15587     }
   15588   else
   15589     {
   15590       /* XOP[2] is unused */
   15591 
   15592       if (fixp_p && mask_fixed)
   15593 	{
   15594 	  avr_asm_len ("mov %0,%1", xop, plen, 1);
   15595 	  fixp_p = false;
   15596 	}
   15597     }
   15598 
   15599   /* Move/insert remaining bits.  */
   15600 
   15601   avr_move_bits (xop, map, fixp_p, plen);
   15602 
   15603   return "";
   15604 }
   15605 
   15606 
   15607 /* IDs for all the AVR builtins.  */
   15608 
   15609 enum avr_builtin_id
   15610   {
   15611 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)  \
   15612     AVR_BUILTIN_ ## NAME,
   15613 #include "builtins.def"
   15614 #undef DEF_BUILTIN
   15615 
   15616     AVR_BUILTIN_COUNT
   15617   };
   15618 
   15619 struct GTY(()) avr_builtin_description
   15620 {
   15621   enum insn_code icode;
   15622   int n_args;
   15623   tree fndecl;
   15624 };
   15625 
   15626 
   15627 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
   15628    that a built-in's ID can be used to access the built-in by means of
   15629    avr_bdesc[ID]  */
   15630 
   15631 static GTY(()) struct avr_builtin_description
   15632 avr_bdesc[AVR_BUILTIN_COUNT] =
   15633   {
   15634 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME)         \
   15635     { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
   15636 #include "builtins.def"
   15637 #undef DEF_BUILTIN
   15638   };
   15639 
   15640 
   15641 /* Implement `TARGET_BUILTIN_DECL'.  */
   15642 
   15643 static tree
   15644 avr_builtin_decl (unsigned id, bool /*initialize_p*/)
   15645 {
   15646   if (id < AVR_BUILTIN_COUNT)
   15647     return avr_bdesc[id].fndecl;
   15648 
   15649   return error_mark_node;
   15650 }
   15651 
   15652 
   15653 static void
   15654 avr_init_builtin_int24 (void)
   15655 {
   15656   for (int i = 0; i < NUM_INT_N_ENTS; ++i)
   15657     if (int_n_data[i].bitsize == 24)
   15658       {
   15659 	tree uint24_type = int_n_trees[i].unsigned_type;
   15660 	lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
   15661 	break;
   15662       }
   15663 }
   15664 
   15665 
   15666 /* Implement `TARGET_INIT_BUILTINS' */
   15667 /* Set up all builtin functions for this target.  */
   15668 
   15669 static void
   15670 avr_init_builtins (void)
   15671 {
   15672   tree void_ftype_void
   15673     = build_function_type_list (void_type_node, NULL_TREE);
   15674   tree uintQI_ftype_uintQI
   15675     = build_function_type_list (unsigned_intQI_type_node,
   15676 				unsigned_intQI_type_node,
   15677 				NULL_TREE);
   15678   tree uintHI_ftype_uintQI_uintQI
   15679     = build_function_type_list (unsigned_intHI_type_node,
   15680 				unsigned_intQI_type_node,
   15681 				unsigned_intQI_type_node,
   15682 				NULL_TREE);
   15683   tree intHI_ftype_intQI_intQI
   15684     = build_function_type_list (intHI_type_node,
   15685 				intQI_type_node,
   15686 				intQI_type_node,
   15687 				NULL_TREE);
   15688   tree intHI_ftype_intQI_uintQI
   15689     = build_function_type_list (intHI_type_node,
   15690 				intQI_type_node,
   15691 				unsigned_intQI_type_node,
   15692 				NULL_TREE);
   15693   tree void_ftype_uintSI
   15694     = build_function_type_list (void_type_node,
   15695 				unsigned_intSI_type_node,
   15696 				NULL_TREE);
   15697 
   15698   tree uintQI_ftype_uintSI_uintQI_uintQI
   15699     = build_function_type_list (unsigned_intQI_type_node,
   15700 				unsigned_intSI_type_node,
   15701 				unsigned_intQI_type_node,
   15702 				unsigned_intQI_type_node,
   15703 				NULL_TREE);
   15704 
   15705   tree const_memx_void_node
   15706     = build_qualified_type (void_type_node,
   15707 			    TYPE_QUAL_CONST
   15708 			    | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
   15709 
   15710   tree const_memx_ptr_type_node
   15711     = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
   15712 
   15713   tree intQI_ftype_const_memx_ptr
   15714     = build_function_type_list (intQI_type_node,
   15715 				const_memx_ptr_type_node,
   15716 				NULL);
   15717 
   15718 #define ITYP(T)                                                         \
   15719   lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
   15720 
   15721 #define FX_FTYPE_FX(fx)                                                 \
   15722   tree fx##r_ftype_##fx##r                                              \
   15723     = build_function_type_list (node_##fx##r, node_##fx##r, NULL);      \
   15724   tree fx##k_ftype_##fx##k                                              \
   15725     = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
   15726 
   15727 #define FX_FTYPE_FX_INT(fx)                                             \
   15728   tree fx##r_ftype_##fx##r_int                                          \
   15729     = build_function_type_list (node_##fx##r, node_##fx##r,             \
   15730                                 integer_type_node, NULL);               \
   15731   tree fx##k_ftype_##fx##k_int                                          \
   15732     = build_function_type_list (node_##fx##k, node_##fx##k,             \
   15733                                 integer_type_node, NULL)
   15734 
   15735 #define INT_FTYPE_FX(fx)                                                \
   15736   tree int_ftype_##fx##r                                                \
   15737     = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
   15738   tree int_ftype_##fx##k                                                \
   15739     = build_function_type_list (integer_type_node, node_##fx##k, NULL)
   15740 
   15741 #define INTX_FTYPE_FX(fx)                                               \
   15742   tree int##fx##r_ftype_##fx##r                                         \
   15743     = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
   15744   tree int##fx##k_ftype_##fx##k                                         \
   15745     = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
   15746 
   15747 #define FX_FTYPE_INTX(fx)                                               \
   15748   tree fx##r_ftype_int##fx##r                                           \
   15749     = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
   15750   tree fx##k_ftype_int##fx##k                                           \
   15751     = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
   15752 
   15753   tree node_hr = short_fract_type_node;
   15754   tree node_nr = fract_type_node;
   15755   tree node_lr = long_fract_type_node;
   15756   tree node_llr = long_long_fract_type_node;
   15757 
   15758   tree node_uhr = unsigned_short_fract_type_node;
   15759   tree node_unr = unsigned_fract_type_node;
   15760   tree node_ulr = unsigned_long_fract_type_node;
   15761   tree node_ullr = unsigned_long_long_fract_type_node;
   15762 
   15763   tree node_hk = short_accum_type_node;
   15764   tree node_nk = accum_type_node;
   15765   tree node_lk = long_accum_type_node;
   15766   tree node_llk = long_long_accum_type_node;
   15767 
   15768   tree node_uhk = unsigned_short_accum_type_node;
   15769   tree node_unk = unsigned_accum_type_node;
   15770   tree node_ulk = unsigned_long_accum_type_node;
   15771   tree node_ullk = unsigned_long_long_accum_type_node;
   15772 
   15773 
   15774   /* For absfx builtins.  */
   15775 
   15776   FX_FTYPE_FX (h);
   15777   FX_FTYPE_FX (n);
   15778   FX_FTYPE_FX (l);
   15779   FX_FTYPE_FX (ll);
   15780 
   15781   /* For roundfx builtins.  */
   15782 
   15783   FX_FTYPE_FX_INT (h);
   15784   FX_FTYPE_FX_INT (n);
   15785   FX_FTYPE_FX_INT (l);
   15786   FX_FTYPE_FX_INT (ll);
   15787 
   15788   FX_FTYPE_FX_INT (uh);
   15789   FX_FTYPE_FX_INT (un);
   15790   FX_FTYPE_FX_INT (ul);
   15791   FX_FTYPE_FX_INT (ull);
   15792 
   15793   /* For countlsfx builtins.  */
   15794 
   15795   INT_FTYPE_FX (h);
   15796   INT_FTYPE_FX (n);
   15797   INT_FTYPE_FX (l);
   15798   INT_FTYPE_FX (ll);
   15799 
   15800   INT_FTYPE_FX (uh);
   15801   INT_FTYPE_FX (un);
   15802   INT_FTYPE_FX (ul);
   15803   INT_FTYPE_FX (ull);
   15804 
   15805   /* For bitsfx builtins.  */
   15806 
   15807   INTX_FTYPE_FX (h);
   15808   INTX_FTYPE_FX (n);
   15809   INTX_FTYPE_FX (l);
   15810   INTX_FTYPE_FX (ll);
   15811 
   15812   INTX_FTYPE_FX (uh);
   15813   INTX_FTYPE_FX (un);
   15814   INTX_FTYPE_FX (ul);
   15815   INTX_FTYPE_FX (ull);
   15816 
   15817   /* For fxbits builtins.  */
   15818 
   15819   FX_FTYPE_INTX (h);
   15820   FX_FTYPE_INTX (n);
   15821   FX_FTYPE_INTX (l);
   15822   FX_FTYPE_INTX (ll);
   15823 
   15824   FX_FTYPE_INTX (uh);
   15825   FX_FTYPE_INTX (un);
   15826   FX_FTYPE_INTX (ul);
   15827   FX_FTYPE_INTX (ull);
   15828 
   15829 
   15830 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)                  \
   15831   {                                                                     \
   15832     int id = AVR_BUILTIN_ ## NAME;                                      \
   15833     const char *Name = "__builtin_avr_" #NAME;                          \
   15834     char *name = (char *) alloca (1 + strlen (Name));                   \
   15835                                                                         \
   15836     gcc_assert (id < AVR_BUILTIN_COUNT);                                \
   15837     avr_bdesc[id].fndecl                                                \
   15838       = add_builtin_function (avr_tolower (name, Name), TYPE, id,       \
   15839 			      BUILT_IN_MD, LIBNAME, NULL_TREE);         \
   15840   }
   15841 #include "builtins.def"
   15842 #undef DEF_BUILTIN
   15843 
   15844   avr_init_builtin_int24 ();
   15845 }
   15846 
   15847 
   15848 /* Subroutine of avr_expand_builtin to expand vanilla builtins
   15849    with non-void result and 1 ... 3 arguments.  */
   15850 
   15851 static rtx
   15852 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
   15853 {
   15854   rtx pat, xop[3];
   15855   int n_args = call_expr_nargs (exp);
   15856   machine_mode tmode = insn_data[icode].operand[0].mode;
   15857 
   15858   gcc_assert (n_args >= 1 && n_args <= 3);
   15859 
   15860   if (target == NULL_RTX
   15861       || GET_MODE (target) != tmode
   15862       || !insn_data[icode].operand[0].predicate (target, tmode))
   15863     {
   15864       target = gen_reg_rtx (tmode);
   15865     }
   15866 
   15867   for (int n = 0; n < n_args; n++)
   15868     {
   15869       tree arg = CALL_EXPR_ARG (exp, n);
   15870       rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
   15871       machine_mode opmode = GET_MODE (op);
   15872       machine_mode mode = insn_data[icode].operand[n + 1].mode;
   15873 
   15874       if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
   15875 	{
   15876 	  opmode = HImode;
   15877 	  op = gen_lowpart (HImode, op);
   15878 	}
   15879 
   15880       /* In case the insn wants input operands in modes different from
   15881 	 the result, abort.  */
   15882 
   15883       gcc_assert (opmode == mode || opmode == VOIDmode);
   15884 
   15885       if (!insn_data[icode].operand[n + 1].predicate (op, mode))
   15886 	op = copy_to_mode_reg (mode, op);
   15887 
   15888       xop[n] = op;
   15889     }
   15890 
   15891   switch (n_args)
   15892     {
   15893     case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
   15894     case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
   15895     case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
   15896 
   15897     default:
   15898       gcc_unreachable();
   15899     }
   15900 
   15901   if (pat == NULL_RTX)
   15902     return NULL_RTX;
   15903 
   15904   emit_insn (pat);
   15905 
   15906   return target;
   15907 }
   15908 
   15909 
   15910 /* Implement `TARGET_EXPAND_BUILTIN'.  */
   15911 /* Expand an expression EXP that calls a built-in function,
   15912    with result going to TARGET if that's convenient
   15913    (and in mode MODE if that's convenient).
   15914    SUBTARGET may be used as the target for computing one of EXP's operands.
   15915    IGNORE is nonzero if the value is to be ignored.  */
   15916 
   15917 static rtx
   15918 avr_expand_builtin (tree exp, rtx target, rtx /*subtarget*/,
   15919 		    machine_mode mode, int ignore)
   15920 {
   15921   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   15922   const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   15923   unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
   15924   const struct avr_builtin_description *d = &avr_bdesc[id];
   15925   tree arg0;
   15926   rtx op0;
   15927 
   15928   gcc_assert (id < AVR_BUILTIN_COUNT);
   15929 
   15930   switch (id)
   15931     {
   15932     case AVR_BUILTIN_NOP:
   15933       emit_insn (gen_nopv (GEN_INT (1)));
   15934       return 0;
   15935 
   15936     case AVR_BUILTIN_DELAY_CYCLES:
   15937       {
   15938 	arg0 = CALL_EXPR_ARG (exp, 0);
   15939 	op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
   15940 
   15941 	if (!CONST_INT_P (op0))
   15942 	  error ("%s expects a compile time integer constant", bname);
   15943 	else
   15944 	  avr_expand_delay_cycles (op0);
   15945 
   15946 	return NULL_RTX;
   15947       }
   15948 
   15949     case AVR_BUILTIN_NOPS:
   15950       {
   15951 	arg0 = CALL_EXPR_ARG (exp, 0);
   15952 	op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
   15953 
   15954 	if (!CONST_INT_P (op0))
   15955 	  error ("%s expects a compile time integer constant", bname);
   15956 	else
   15957 	  avr_expand_nops (op0);
   15958 
   15959 	return NULL_RTX;
   15960       }
   15961 
   15962     case AVR_BUILTIN_INSERT_BITS:
   15963       {
   15964 	arg0 = CALL_EXPR_ARG (exp, 0);
   15965 	op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
   15966 
   15967 	if (!CONST_INT_P (op0))
   15968 	  {
   15969 	    error ("%s expects a compile time long integer constant"
   15970 		   " as first argument", bname);
   15971 	    return target;
   15972 	  }
   15973 
   15974 	break;
   15975       }
   15976 
   15977     case AVR_BUILTIN_ROUNDHR:   case AVR_BUILTIN_ROUNDUHR:
   15978     case AVR_BUILTIN_ROUNDR:    case AVR_BUILTIN_ROUNDUR:
   15979     case AVR_BUILTIN_ROUNDLR:   case AVR_BUILTIN_ROUNDULR:
   15980     case AVR_BUILTIN_ROUNDLLR:  case AVR_BUILTIN_ROUNDULLR:
   15981 
   15982     case AVR_BUILTIN_ROUNDHK:   case AVR_BUILTIN_ROUNDUHK:
   15983     case AVR_BUILTIN_ROUNDK:    case AVR_BUILTIN_ROUNDUK:
   15984     case AVR_BUILTIN_ROUNDLK:   case AVR_BUILTIN_ROUNDULK:
   15985     case AVR_BUILTIN_ROUNDLLK:  case AVR_BUILTIN_ROUNDULLK:
   15986 
   15987       /* Warn about odd rounding.  Rounding points >= FBIT will have
   15988 	 no effect.  */
   15989 
   15990       if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
   15991 	break;
   15992 
   15993       int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
   15994 
   15995       if (rbit >= (int) GET_MODE_FBIT (mode))
   15996 	{
   15997 	  warning (OPT_Wextra, "rounding to %d bits has no effect for "
   15998 		   "fixed-point value with %d fractional bits",
   15999 		   rbit, GET_MODE_FBIT (mode));
   16000 
   16001 	  return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
   16002 			      EXPAND_NORMAL);
   16003 	}
   16004       else if (rbit <= - (int) GET_MODE_IBIT (mode))
   16005 	{
   16006 	  warning (0, "rounding result will always be 0");
   16007 	  return CONST0_RTX (mode);
   16008 	}
   16009 
   16010       /* The rounding points RP satisfies now:  -IBIT < RP < FBIT.
   16011 
   16012 	 TR 18037 only specifies results for  RP > 0.  However, the
   16013 	 remaining cases of  -IBIT < RP <= 0  can easily be supported
   16014 	 without any additional overhead.  */
   16015 
   16016       break; /* round */
   16017     }
   16018 
   16019   /* No fold found and no insn:  Call support function from libgcc.  */
   16020 
   16021   if (d->icode == CODE_FOR_nothing
   16022       && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
   16023     {
   16024       return expand_call (exp, target, ignore);
   16025     }
   16026 
   16027   /* No special treatment needed: vanilla expand.  */
   16028 
   16029   gcc_assert (d->icode != CODE_FOR_nothing);
   16030   gcc_assert (d->n_args == call_expr_nargs (exp));
   16031 
   16032   if (d->n_args == 0)
   16033     {
   16034       emit_insn ((GEN_FCN (d->icode)) (target));
   16035       return NULL_RTX;
   16036     }
   16037 
   16038   return avr_default_expand_builtin (d->icode, exp, target);
   16039 }
   16040 
   16041 
   16042 /* Helper for `avr_fold_builtin' that folds  absfx (FIXED_CST).  */
   16043 
   16044 static tree
   16045 avr_fold_absfx (tree tval)
   16046 {
   16047   if (FIXED_CST != TREE_CODE (tval))
   16048     return NULL_TREE;
   16049 
   16050   /* Our fixed-points have no padding:  Use double_int payload directly.  */
   16051 
   16052   FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
   16053   unsigned int bits = GET_MODE_BITSIZE (fval.mode);
   16054   double_int ival = fval.data.sext (bits);
   16055 
   16056   if (!ival.is_negative())
   16057     return tval;
   16058 
   16059   /* ISO/IEC TR 18037, 7.18a.6.2:  The absfx functions are saturating.  */
   16060 
   16061   fval.data = (ival == double_int::min_value (bits, false).sext (bits))
   16062     ? double_int::max_value (bits, false)
   16063     : -ival;
   16064 
   16065   return build_fixed (TREE_TYPE (tval), fval);
   16066 }
   16067 
   16068 
   16069 /* Implement `TARGET_FOLD_BUILTIN'.  */
   16070 
   16071 static tree
   16072 avr_fold_builtin (tree fndecl, int /*n_args*/, tree *arg, bool /*ignore*/)
   16073 {
   16074   unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   16075   tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
   16076 
   16077   if (!optimize)
   16078     return NULL_TREE;
   16079 
   16080   switch (fcode)
   16081     {
   16082     default:
   16083       break;
   16084 
   16085     case AVR_BUILTIN_SWAP:
   16086       {
   16087 	return fold_build2 (LROTATE_EXPR, val_type, arg[0],
   16088 			    build_int_cst (val_type, 4));
   16089       }
   16090 
   16091     case AVR_BUILTIN_ABSHR:
   16092     case AVR_BUILTIN_ABSR:
   16093     case AVR_BUILTIN_ABSLR:
   16094     case AVR_BUILTIN_ABSLLR:
   16095 
   16096     case AVR_BUILTIN_ABSHK:
   16097     case AVR_BUILTIN_ABSK:
   16098     case AVR_BUILTIN_ABSLK:
   16099     case AVR_BUILTIN_ABSLLK:
   16100       /* GCC is not good with folding ABS for fixed-point.  Do it by hand.  */
   16101 
   16102       return avr_fold_absfx (arg[0]);
   16103 
   16104     case AVR_BUILTIN_BITSHR:    case AVR_BUILTIN_HRBITS:
   16105     case AVR_BUILTIN_BITSHK:    case AVR_BUILTIN_HKBITS:
   16106     case AVR_BUILTIN_BITSUHR:   case AVR_BUILTIN_UHRBITS:
   16107     case AVR_BUILTIN_BITSUHK:   case AVR_BUILTIN_UHKBITS:
   16108 
   16109     case AVR_BUILTIN_BITSR:     case AVR_BUILTIN_RBITS:
   16110     case AVR_BUILTIN_BITSK:     case AVR_BUILTIN_KBITS:
   16111     case AVR_BUILTIN_BITSUR:    case AVR_BUILTIN_URBITS:
   16112     case AVR_BUILTIN_BITSUK:    case AVR_BUILTIN_UKBITS:
   16113 
   16114     case AVR_BUILTIN_BITSLR:    case AVR_BUILTIN_LRBITS:
   16115     case AVR_BUILTIN_BITSLK:    case AVR_BUILTIN_LKBITS:
   16116     case AVR_BUILTIN_BITSULR:   case AVR_BUILTIN_ULRBITS:
   16117     case AVR_BUILTIN_BITSULK:   case AVR_BUILTIN_ULKBITS:
   16118 
   16119     case AVR_BUILTIN_BITSLLR:   case AVR_BUILTIN_LLRBITS:
   16120     case AVR_BUILTIN_BITSLLK:   case AVR_BUILTIN_LLKBITS:
   16121     case AVR_BUILTIN_BITSULLR:  case AVR_BUILTIN_ULLRBITS:
   16122     case AVR_BUILTIN_BITSULLK:  case AVR_BUILTIN_ULLKBITS:
   16123 
   16124       gcc_assert (TYPE_PRECISION (val_type)
   16125 		  == TYPE_PRECISION (TREE_TYPE (arg[0])));
   16126 
   16127       return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
   16128 
   16129     case AVR_BUILTIN_INSERT_BITS:
   16130       {
   16131 	tree tbits = arg[1];
   16132 	tree tval = arg[2];
   16133 	tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
   16134 	bool changed = false;
   16135 	avr_map_op_t best_g;
   16136 
   16137 	if (TREE_CODE (arg[0]) != INTEGER_CST)
   16138 	  {
   16139 	    /* No constant as first argument: Don't fold this and run into
   16140 	       error in avr_expand_builtin.  */
   16141 
   16142 	    break;
   16143 	  }
   16144 
   16145 	tree tmap = wide_int_to_tree (map_type, wi::to_wide (arg[0]));
   16146 	unsigned int map = TREE_INT_CST_LOW (tmap);
   16147 
   16148 	if (TREE_CODE (tval) != INTEGER_CST
   16149 	    && avr_map_metric (map, MAP_MASK_PREIMAGE_F) == 0)
   16150 	  {
   16151 	    /* There are no F in the map, i.e. 3rd operand is unused.
   16152 	       Replace that argument with some constant to render
   16153 	       respective input unused.  */
   16154 
   16155 	    tval = build_int_cst (val_type, 0);
   16156 	    changed = true;
   16157 	  }
   16158 
   16159 	if (TREE_CODE (tbits) != INTEGER_CST
   16160 	    && avr_map_metric (map, MAP_PREIMAGE_0_7) == 0)
   16161 	  {
   16162 	    /* Similar for the bits to be inserted. If they are unused,
   16163 	       we can just as well pass 0.  */
   16164 
   16165 	    tbits = build_int_cst (val_type, 0);
   16166 	  }
   16167 
   16168 	if (TREE_CODE (tbits) == INTEGER_CST)
   16169 	  {
   16170 	    /* Inserting bits known at compile time is easy and can be
   16171 	       performed by AND and OR with appropriate masks.  */
   16172 
   16173 	    int bits = TREE_INT_CST_LOW (tbits);
   16174 	    int mask_ior = 0, mask_and = 0xff;
   16175 
   16176 	    for (size_t i = 0; i < 8; i++)
   16177 	      {
   16178 		int mi = avr_map (map, i);
   16179 
   16180 		if (mi < 8)
   16181 		  {
   16182 		    if (bits & (1 << mi))     mask_ior |=  (1 << i);
   16183 		    else		      mask_and &= ~(1 << i);
   16184 		  }
   16185 	      }
   16186 
   16187 	    tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
   16188 				build_int_cst (val_type, mask_ior));
   16189 	    return fold_build2 (BIT_AND_EXPR, val_type, tval,
   16190 				build_int_cst (val_type, mask_and));
   16191 	  }
   16192 
   16193 	if (changed)
   16194 	  return build_call_expr (fndecl, 3, tmap, tbits, tval);
   16195 
   16196 	/* If bits don't change their position, we can use vanilla logic
   16197 	   to merge the two arguments...  */
   16198 
   16199 	if (avr_map_metric (map, MAP_NONFIXED_0_7) == 0
   16200 	    // ...except when we are copying just one bit. In that
   16201 	    // case, BLD/BST is better than XOR/AND/XOR, see PR90622.
   16202 	    && avr_map_metric (map, MAP_FIXED_0_7) != 1)
   16203 	  {
   16204 	    int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
   16205 	    tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
   16206 
   16207 	    tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
   16208 	    tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
   16209 	    return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
   16210 	  }
   16211 
   16212 	/* Try to decomposing map to reduce overall cost.  */
   16213 
   16214 	if (avr_log.builtin)
   16215 	  avr_edump ("\n%?: %x\n%?: ROL cost: ", map);
   16216 
   16217 	best_g = avr_map_op[0];
   16218 	best_g.cost = 1000;
   16219 
   16220 	for (size_t i = 0; i < ARRAY_SIZE (avr_map_op); i++)
   16221 	  {
   16222 	    avr_map_op_t g
   16223 	      = avr_map_decompose (map, avr_map_op + i,
   16224 				   TREE_CODE (tval) == INTEGER_CST);
   16225 
   16226 	    if (g.cost >= 0 && g.cost < best_g.cost)
   16227 	      best_g = g;
   16228 	  }
   16229 
   16230 	if (avr_log.builtin)
   16231 	  avr_edump ("\n");
   16232 
   16233 	if (best_g.arg == 0)
   16234 	  /* No optimization found */
   16235 	  break;
   16236 
   16237 	/* Apply operation G to the 2nd argument.  */
   16238 
   16239 	if (avr_log.builtin)
   16240 	  avr_edump ("%?: using OP(%s%d, %x) cost %d\n",
   16241 		     best_g.str, best_g.arg, best_g.map, best_g.cost);
   16242 
   16243 	/* Do right-shifts arithmetically: They copy the MSB instead of
   16244 	   shifting in a non-usable value (0) as with logic right-shift.  */
   16245 
   16246 	tbits = fold_convert (signed_char_type_node, tbits);
   16247 	tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
   16248 			     build_int_cst (val_type, best_g.arg));
   16249 	tbits = fold_convert (val_type, tbits);
   16250 
   16251 	/* Use map o G^-1 instead of original map to undo the effect of G.  */
   16252 
   16253 	tmap = wide_int_to_tree (map_type, best_g.map);
   16254 
   16255 	return build_call_expr (fndecl, 3, tmap, tbits, tval);
   16256       } /* AVR_BUILTIN_INSERT_BITS */
   16257     }
   16258 
   16259   return NULL_TREE;
   16260 }
   16261 
   16262 
   16263 /* Implement `TARGET_MD_ASM_ADJUST'.  */
   16264 /* Prepend to CLOBBERS hard registers that are automatically clobbered
   16265    for an asm. We do this for CC_REGNUM to maintain source compatibility
   16266    with the original cc0-based compiler.  */
   16267 
   16268 static rtx_insn *
   16269 avr_md_asm_adjust (vec<rtx> &/*outputs*/, vec<rtx> &/*inputs*/,
   16270 		   vec<machine_mode> & /*input_modes*/,
   16271 		   vec<const char *> &/*constraints*/,
   16272 		   vec<rtx> &/*uses*/,
   16273 		   vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
   16274 		   location_t /*loc*/)
   16275 {
   16276   clobbers.safe_push (cc_reg_rtx);
   16277   SET_HARD_REG_BIT (clobbered_regs, REG_CC);
   16278   return NULL;
   16279 }
   16280 
   16281 
   16282 /* Worker function for `FLOAT_LIB_COMPARE_RETURNS_BOOL'.  */
   16283 
   16284 bool
   16285 avr_float_lib_compare_returns_bool (machine_mode mode, enum rtx_code)
   16286 {
   16287   if (mode == DFmode)
   16288     {
   16289 #if WITH_DOUBLE_COMPARISON == 2
   16290       return true;
   16291 #endif
   16292     }
   16293 
   16294   // This is the GCC default and also what AVR-LibC implements.
   16295   return false;
   16296 }
   16297 
   16298 
   16299 
   16301 /* Initialize the GCC target structure.  */
   16302 
   16303 #undef  TARGET_ASM_ALIGNED_HI_OP
   16304 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
   16305 #undef  TARGET_ASM_ALIGNED_SI_OP
   16306 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
   16307 #undef  TARGET_ASM_UNALIGNED_HI_OP
   16308 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
   16309 #undef  TARGET_ASM_UNALIGNED_SI_OP
   16310 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
   16311 #undef  TARGET_ASM_INTEGER
   16312 #define TARGET_ASM_INTEGER avr_assemble_integer
   16313 #undef  TARGET_ASM_FILE_START
   16314 #define TARGET_ASM_FILE_START avr_file_start
   16315 #undef  TARGET_ASM_FILE_END
   16316 #define TARGET_ASM_FILE_END avr_file_end
   16317 
   16318 #undef  TARGET_ASM_FUNCTION_END_PROLOGUE
   16319 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
   16320 #undef  TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
   16321 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
   16322 
   16323 #undef  TARGET_FUNCTION_VALUE
   16324 #define TARGET_FUNCTION_VALUE avr_function_value
   16325 #undef  TARGET_LIBCALL_VALUE
   16326 #define TARGET_LIBCALL_VALUE avr_libcall_value
   16327 #undef  TARGET_FUNCTION_VALUE_REGNO_P
   16328 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
   16329 
   16330 #undef  TARGET_ATTRIBUTE_TABLE
   16331 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
   16332 #undef  TARGET_INSERT_ATTRIBUTES
   16333 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
   16334 #undef  TARGET_SECTION_TYPE_FLAGS
   16335 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
   16336 
   16337 #undef  TARGET_ASM_NAMED_SECTION
   16338 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
   16339 #undef  TARGET_ASM_INIT_SECTIONS
   16340 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
   16341 #undef  TARGET_ENCODE_SECTION_INFO
   16342 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
   16343 #undef  TARGET_ASM_SELECT_SECTION
   16344 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
   16345 
   16346 #undef  TARGET_ASM_FINAL_POSTSCAN_INSN
   16347 #define TARGET_ASM_FINAL_POSTSCAN_INSN avr_asm_final_postscan_insn
   16348 
   16349 #undef  TARGET_INSN_COST
   16350 #define TARGET_INSN_COST avr_insn_cost
   16351 #undef  TARGET_REGISTER_MOVE_COST
   16352 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
   16353 #undef  TARGET_MEMORY_MOVE_COST
   16354 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
   16355 #undef  TARGET_RTX_COSTS
   16356 #define TARGET_RTX_COSTS avr_rtx_costs
   16357 #undef  TARGET_ADDRESS_COST
   16358 #define TARGET_ADDRESS_COST avr_address_cost
   16359 #undef  TARGET_FUNCTION_ARG
   16360 #define TARGET_FUNCTION_ARG avr_function_arg
   16361 #undef  TARGET_FUNCTION_ARG_ADVANCE
   16362 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
   16363 
   16364 #undef  TARGET_SET_CURRENT_FUNCTION
   16365 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
   16366 
   16367 #undef  TARGET_RETURN_IN_MEMORY
   16368 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
   16369 
   16370 #undef  TARGET_STRICT_ARGUMENT_NAMING
   16371 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
   16372 
   16373 #undef TARGET_CONDITIONAL_REGISTER_USAGE
   16374 #define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage
   16375 
   16376 #undef TARGET_HARD_REGNO_NREGS
   16377 #define TARGET_HARD_REGNO_NREGS avr_hard_regno_nregs
   16378 
   16379 #undef  TARGET_HARD_REGNO_MODE_OK
   16380 #define TARGET_HARD_REGNO_MODE_OK avr_hard_regno_mode_ok
   16381 #undef  TARGET_HARD_REGNO_SCRATCH_OK
   16382 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
   16383 #undef  TARGET_HARD_REGNO_CALL_PART_CLOBBERED
   16384 #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
   16385   avr_hard_regno_call_part_clobbered
   16386 
   16387 #undef  TARGET_CASE_VALUES_THRESHOLD
   16388 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
   16389 
   16390 #undef  TARGET_FRAME_POINTER_REQUIRED
   16391 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
   16392 #undef  TARGET_CAN_ELIMINATE
   16393 #define TARGET_CAN_ELIMINATE avr_can_eliminate
   16394 
   16395 #undef  TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
   16396 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
   16397 
   16398 #undef TARGET_WARN_FUNC_RETURN
   16399 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
   16400 
   16401 #undef  TARGET_CLASS_LIKELY_SPILLED_P
   16402 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
   16403 
   16404 #undef  TARGET_CLASS_MAX_NREGS
   16405 #define TARGET_CLASS_MAX_NREGS avr_class_max_nregs
   16406 
   16407 #undef  TARGET_OPTION_OVERRIDE
   16408 #define TARGET_OPTION_OVERRIDE avr_option_override
   16409 
   16410 #undef  TARGET_CANNOT_MODIFY_JUMPS_P
   16411 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
   16412 
   16413 #undef  TARGET_FUNCTION_OK_FOR_SIBCALL
   16414 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
   16415 
   16416 #undef  TARGET_INIT_BUILTINS
   16417 #define TARGET_INIT_BUILTINS avr_init_builtins
   16418 
   16419 #undef  TARGET_BUILTIN_DECL
   16420 #define TARGET_BUILTIN_DECL avr_builtin_decl
   16421 
   16422 #undef  TARGET_EXPAND_BUILTIN
   16423 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
   16424 
   16425 #undef  TARGET_FOLD_BUILTIN
   16426 #define TARGET_FOLD_BUILTIN avr_fold_builtin
   16427 
   16428 #undef  TARGET_SCALAR_MODE_SUPPORTED_P
   16429 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
   16430 
   16431 #undef  TARGET_BUILD_BUILTIN_VA_LIST
   16432 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
   16433 
   16434 #undef  TARGET_FIXED_POINT_SUPPORTED_P
   16435 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
   16436 
   16437 #undef  TARGET_CONVERT_TO_TYPE
   16438 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
   16439 
   16440 #undef TARGET_LRA_P
   16441 #define TARGET_LRA_P hook_bool_void_false
   16442 
   16443 #undef  TARGET_ADDR_SPACE_SUBSET_P
   16444 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
   16445 
   16446 #undef  TARGET_ADDR_SPACE_CONVERT
   16447 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
   16448 
   16449 #undef  TARGET_ADDR_SPACE_ADDRESS_MODE
   16450 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
   16451 
   16452 #undef  TARGET_ADDR_SPACE_POINTER_MODE
   16453 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
   16454 
   16455 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
   16456 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P  \
   16457   avr_addr_space_legitimate_address_p
   16458 
   16459 #undef  TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
   16460 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
   16461 
   16462 #undef  TARGET_ADDR_SPACE_DIAGNOSE_USAGE
   16463 #define TARGET_ADDR_SPACE_DIAGNOSE_USAGE avr_addr_space_diagnose_usage
   16464 
   16465 #undef  TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
   16466 #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID avr_addr_space_zero_address_valid
   16467 
   16468 #undef  TARGET_MODE_DEPENDENT_ADDRESS_P
   16469 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
   16470 
   16471 #undef  TARGET_PRINT_OPERAND
   16472 #define TARGET_PRINT_OPERAND avr_print_operand
   16473 #undef  TARGET_PRINT_OPERAND_ADDRESS
   16474 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
   16475 #undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
   16476 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
   16477 
   16478 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
   16479 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
   16480   avr_use_by_pieces_infrastructure_p
   16481 
   16482 #undef  TARGET_LEGITIMATE_COMBINED_INSN
   16483 #define TARGET_LEGITIMATE_COMBINED_INSN avr_legitimate_combined_insn
   16484 
   16485 #undef  TARGET_STARTING_FRAME_OFFSET
   16486 #define TARGET_STARTING_FRAME_OFFSET avr_starting_frame_offset
   16487 
   16488 #undef  TARGET_MD_ASM_ADJUST
   16489 #define TARGET_MD_ASM_ADJUST avr_md_asm_adjust
   16490 
   16491 #undef  TARGET_CAN_INLINE_P
   16492 #define TARGET_CAN_INLINE_P avr_can_inline_p
   16493 
   16494 #undef  TARGET_CANONICALIZE_COMPARISON
   16495 #define TARGET_CANONICALIZE_COMPARISON avr_canonicalize_comparison
   16496 
   16497 /* According to the opening comment in PR86772, the following applies:
   16498   "If the port does not (and never will in the future) need to mitigate
   16499    against unsafe speculation."  */
   16500 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
   16501 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
   16502 
   16503 struct gcc_target targetm = TARGET_INITIALIZER;
   16504 
   16505 
   16506 #include "gt-avr.h"
   16508