]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/avr/avr.c
gen-mul-tables.cc: Adjust include files.
[thirdparty/gcc.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2 Copyright (C) 1998-2015 Free Software Foundation, Inc.
3 Contributed by Denis Chertykov (chertykov@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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "c-family/c-common.h"
28 #include "cfghooks.h"
29 #include "df.h"
30 #include "tm_p.h"
31 #include "optabs.h"
32 #include "regs.h"
33 #include "emit-rtl.h"
34 #include "recog.h"
35 #include "conditions.h"
36 #include "insn-attr.h"
37 #include "reload.h"
38 #include "varasm.h"
39 #include "calls.h"
40 #include "stor-layout.h"
41 #include "output.h"
42 #include "explow.h"
43 #include "expr.h"
44 #include "langhooks.h"
45 #include "cfgrtl.h"
46 #include "builtins.h"
47 #include "context.h"
48 #include "tree-pass.h"
49
50 /* This file should be included last. */
51 #include "target-def.h"
52
53 /* Maximal allowed offset for an address in the LD command */
54 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
55
56 /* Return true if STR starts with PREFIX and false, otherwise. */
57 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
58
59 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
60 address space where data is to be located.
61 As the only non-generic address spaces are all located in flash,
62 this can be used to test if data shall go into some .progmem* section.
63 This must be the rightmost field of machine dependent section flags. */
64 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
65
66 /* Similar 4-bit region for SYMBOL_REF_FLAGS. */
67 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
68
69 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
70 Set address-space AS in SYMBOL_REF_FLAGS of SYM */
71 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS) \
72 do { \
73 SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM; \
74 SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP; \
75 } while (0)
76
77 /* Read address-space from SYMBOL_REF_FLAGS of SYM */
78 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM) \
79 ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM) \
80 / SYMBOL_FLAG_MACH_DEP)
81
82 #define TINY_ADIW(REG1, REG2, I) \
83 "subi " #REG1 ",lo8(-(" #I "))" CR_TAB \
84 "sbci " #REG2 ",hi8(-(" #I "))"
85
86 #define TINY_SBIW(REG1, REG2, I) \
87 "subi " #REG1 ",lo8((" #I "))" CR_TAB \
88 "sbci " #REG2 ",hi8((" #I "))"
89
90 #define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
91 #define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
92
93 /* Known address spaces. The order must be the same as in the respective
94 enum from avr.h (or designated initialized must be used). */
95 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
96 {
97 { ADDR_SPACE_RAM, 0, 2, "", 0, NULL },
98 { ADDR_SPACE_FLASH, 1, 2, "__flash", 0, ".progmem.data" },
99 { ADDR_SPACE_FLASH1, 1, 2, "__flash1", 1, ".progmem1.data" },
100 { ADDR_SPACE_FLASH2, 1, 2, "__flash2", 2, ".progmem2.data" },
101 { ADDR_SPACE_FLASH3, 1, 2, "__flash3", 3, ".progmem3.data" },
102 { ADDR_SPACE_FLASH4, 1, 2, "__flash4", 4, ".progmem4.data" },
103 { ADDR_SPACE_FLASH5, 1, 2, "__flash5", 5, ".progmem5.data" },
104 { ADDR_SPACE_MEMX, 1, 3, "__memx", 0, ".progmemx.data" },
105 };
106
107
108 /* Holding RAM addresses of some SFRs used by the compiler and that
109 are unique over all devices in an architecture like 'avr4'. */
110
111 typedef struct
112 {
113 /* SREG: The processor status */
114 int sreg;
115
116 /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
117 int ccp;
118 int rampd;
119 int rampx;
120 int rampy;
121
122 /* RAMPZ: The high byte of 24-bit address used with ELPM */
123 int rampz;
124
125 /* SP: The stack pointer and its low and high byte */
126 int sp_l;
127 int sp_h;
128 } avr_addr_t;
129
130 static avr_addr_t avr_addr;
131
132
133 /* Prototypes for local helper functions. */
134
135 static const char* out_movqi_r_mr (rtx_insn *, rtx[], int*);
136 static const char* out_movhi_r_mr (rtx_insn *, rtx[], int*);
137 static const char* out_movsi_r_mr (rtx_insn *, rtx[], int*);
138 static const char* out_movqi_mr_r (rtx_insn *, rtx[], int*);
139 static const char* out_movhi_mr_r (rtx_insn *, rtx[], int*);
140 static const char* out_movsi_mr_r (rtx_insn *, rtx[], int*);
141
142 static int get_sequence_length (rtx_insn *insns);
143 static int sequent_regs_live (void);
144 static const char *ptrreg_to_str (int);
145 static const char *cond_string (enum rtx_code);
146 static int avr_num_arg_regs (machine_mode, const_tree);
147 static int avr_operand_rtx_cost (rtx, machine_mode, enum rtx_code,
148 int, bool);
149 static void output_reload_in_const (rtx*, rtx, int*, bool);
150 static struct machine_function * avr_init_machine_status (void);
151
152
153 /* Prototypes for hook implementors if needed before their implementation. */
154
155 static bool avr_rtx_costs (rtx, machine_mode, int, int, int*, bool);
156
157
158 /* Allocate registers from r25 to r8 for parameters for function calls. */
159 #define FIRST_CUM_REG 26
160
161 /* Last call saved register */
162 #define LAST_CALLEE_SAVED_REG (AVR_TINY ? 19 : 17)
163
164 /* Implicit target register of LPM instruction (R0) */
165 extern GTY(()) rtx lpm_reg_rtx;
166 rtx lpm_reg_rtx;
167
168 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
169 extern GTY(()) rtx lpm_addr_reg_rtx;
170 rtx lpm_addr_reg_rtx;
171
172 /* Temporary register RTX (reg:QI TMP_REGNO) */
173 extern GTY(()) rtx tmp_reg_rtx;
174 rtx tmp_reg_rtx;
175
176 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
177 extern GTY(()) rtx zero_reg_rtx;
178 rtx zero_reg_rtx;
179
180 /* RTXs for all general purpose registers as QImode */
181 extern GTY(()) rtx all_regs_rtx[32];
182 rtx all_regs_rtx[32];
183
184 /* SREG, the processor status */
185 extern GTY(()) rtx sreg_rtx;
186 rtx sreg_rtx;
187
188 /* RAMP* special function registers */
189 extern GTY(()) rtx rampd_rtx;
190 extern GTY(()) rtx rampx_rtx;
191 extern GTY(()) rtx rampy_rtx;
192 extern GTY(()) rtx rampz_rtx;
193 rtx rampd_rtx;
194 rtx rampx_rtx;
195 rtx rampy_rtx;
196 rtx rampz_rtx;
197
198 /* RTX containing the strings "" and "e", respectively */
199 static GTY(()) rtx xstring_empty;
200 static GTY(()) rtx xstring_e;
201
202 /* Current architecture. */
203 const avr_arch_t *avr_arch;
204
205 /* Section to put switch tables in. */
206 static GTY(()) section *progmem_swtable_section;
207
208 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
209 or to address space __flash* or __memx. Only used as singletons inside
210 avr_asm_select_section, but it must not be local there because of GTY. */
211 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
212
213 /* Condition for insns/expanders from avr-dimode.md. */
214 bool avr_have_dimode = true;
215
216 /* To track if code will use .bss and/or .data. */
217 bool avr_need_clear_bss_p = false;
218 bool avr_need_copy_data_p = false;
219
220 \f
221 /* Transform UP into lowercase and write the result to LO.
222 You must provide enough space for LO. Return LO. */
223
224 static char*
225 avr_tolower (char *lo, const char *up)
226 {
227 char *lo0 = lo;
228
229 for (; *up; up++, lo++)
230 *lo = TOLOWER (*up);
231
232 *lo = '\0';
233
234 return lo0;
235 }
236
237
238 /* Custom function to count number of set bits. */
239
240 static inline int
241 avr_popcount (unsigned int val)
242 {
243 int pop = 0;
244
245 while (val)
246 {
247 val &= val-1;
248 pop++;
249 }
250
251 return pop;
252 }
253
254
255 /* Constraint helper function. XVAL is a CONST_INT or a CONST_DOUBLE.
256 Return true if the least significant N_BYTES bytes of XVAL all have a
257 popcount in POP_MASK and false, otherwise. POP_MASK represents a subset
258 of integers which contains an integer N iff bit N of POP_MASK is set. */
259
260 bool
261 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
262 {
263 int i;
264
265 machine_mode mode = GET_MODE (xval);
266
267 if (VOIDmode == mode)
268 mode = SImode;
269
270 for (i = 0; i < n_bytes; i++)
271 {
272 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
273 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
274
275 if (0 == (pop_mask & (1 << avr_popcount (val8))))
276 return false;
277 }
278
279 return true;
280 }
281
282
283 /* Access some RTX as INT_MODE. If X is a CONST_FIXED we can get
284 the bit representation of X by "casting" it to CONST_INT. */
285
286 rtx
287 avr_to_int_mode (rtx x)
288 {
289 machine_mode mode = GET_MODE (x);
290
291 return VOIDmode == mode
292 ? x
293 : simplify_gen_subreg (int_mode_for_mode (mode), x, mode, 0);
294 }
295
296
297 static const pass_data avr_pass_data_recompute_notes =
298 {
299 RTL_PASS, // type
300 "", // name (will be patched)
301 OPTGROUP_NONE, // optinfo_flags
302 TV_DF_SCAN, // tv_id
303 0, // properties_required
304 0, // properties_provided
305 0, // properties_destroyed
306 0, // todo_flags_start
307 TODO_df_finish | TODO_df_verify // todo_flags_finish
308 };
309
310
311 class avr_pass_recompute_notes : public rtl_opt_pass
312 {
313 public:
314 avr_pass_recompute_notes (gcc::context *ctxt, const char *name)
315 : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt)
316 {
317 this->name = name;
318 }
319
320 virtual unsigned int execute (function*)
321 {
322 df_note_add_problem ();
323 df_analyze ();
324
325 return 0;
326 }
327 }; // avr_pass_recompute_notes
328
329
330 static void
331 avr_register_passes (void)
332 {
333 /* This avr-specific pass (re)computes insn notes, in particular REG_DEAD
334 notes which are used by `avr.c::reg_unused_after' and branch offset
335 computations. These notes must be correct, i.e. there must be no
336 dangling REG_DEAD notes; otherwise wrong code might result, cf. PR64331.
337
338 DF needs (correct) CFG, hence right before free_cfg is the last
339 opportunity to rectify notes. */
340
341 register_pass (new avr_pass_recompute_notes (g, "avr-notes-free-cfg"),
342 PASS_POS_INSERT_BEFORE, "*free_cfg", 1);
343 }
344
345
346 /* Set `avr_arch' as specified by `-mmcu='.
347 Return true on success. */
348
349 static bool
350 avr_set_core_architecture (void)
351 {
352 /* Search for mcu core architecture. */
353
354 if (!avr_mmcu)
355 avr_mmcu = AVR_MMCU_DEFAULT;
356
357 avr_arch = &avr_arch_types[0];
358
359 for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++)
360 {
361 if (NULL == mcu->name)
362 {
363 /* Reached the end of `avr_mcu_types'. This should actually never
364 happen as options are provided by device-specs. It could be a
365 typo in a device-specs or calling the compiler proper directly
366 with -mmcu=<device>. */
367
368 error ("unknown core architecture %qs specified with %qs",
369 avr_mmcu, "-mmcu=");
370 avr_inform_core_architectures ();
371 break;
372 }
373 else if (0 == strcmp (mcu->name, avr_mmcu)
374 // Is this a proper architecture ?
375 && NULL == mcu->macro)
376 {
377 avr_arch = &avr_arch_types[mcu->arch_id];
378 if (avr_n_flash < 0)
379 avr_n_flash = mcu->n_flash;
380
381 return true;
382 }
383 }
384
385 return false;
386 }
387
388
389 /* Implement `TARGET_OPTION_OVERRIDE'. */
390
391 static void
392 avr_option_override (void)
393 {
394 /* Disable -fdelete-null-pointer-checks option for AVR target.
395 This option compiler assumes that dereferencing of a null pointer
396 would halt the program. For AVR this assumption is not true and
397 programs can safely dereference null pointers. Changes made by this
398 option may not work properly for AVR. So disable this option. */
399
400 flag_delete_null_pointer_checks = 0;
401
402 /* caller-save.c looks for call-clobbered hard registers that are assigned
403 to pseudos that cross calls and tries so save-restore them around calls
404 in order to reduce the number of stack slots needed.
405
406 This might lead to situations where reload is no more able to cope
407 with the challenge of AVR's very few address registers and fails to
408 perform the requested spills. */
409
410 if (avr_strict_X)
411 flag_caller_saves = 0;
412
413 /* Unwind tables currently require a frame pointer for correctness,
414 see toplev.c:process_options(). */
415
416 if ((flag_unwind_tables
417 || flag_non_call_exceptions
418 || flag_asynchronous_unwind_tables)
419 && !ACCUMULATE_OUTGOING_ARGS)
420 {
421 flag_omit_frame_pointer = 0;
422 }
423
424 if (flag_pic == 1)
425 warning (OPT_fpic, "-fpic is not supported");
426 if (flag_pic == 2)
427 warning (OPT_fPIC, "-fPIC is not supported");
428 if (flag_pie == 1)
429 warning (OPT_fpie, "-fpie is not supported");
430 if (flag_pie == 2)
431 warning (OPT_fPIE, "-fPIE is not supported");
432
433 if (!avr_set_core_architecture())
434 return;
435
436 /* RAM addresses of some SFRs common to all devices in respective arch. */
437
438 /* SREG: Status Register containing flags like I (global IRQ) */
439 avr_addr.sreg = 0x3F + avr_arch->sfr_offset;
440
441 /* RAMPZ: Address' high part when loading via ELPM */
442 avr_addr.rampz = 0x3B + avr_arch->sfr_offset;
443
444 avr_addr.rampy = 0x3A + avr_arch->sfr_offset;
445 avr_addr.rampx = 0x39 + avr_arch->sfr_offset;
446 avr_addr.rampd = 0x38 + avr_arch->sfr_offset;
447 avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset;
448
449 /* SP: Stack Pointer (SP_H:SP_L) */
450 avr_addr.sp_l = 0x3D + avr_arch->sfr_offset;
451 avr_addr.sp_h = avr_addr.sp_l + 1;
452
453 init_machine_status = avr_init_machine_status;
454
455 avr_log_set_avr_log();
456
457 /* Register some avr-specific pass(es). There is no canonical place for
458 pass registration. This function is convenient. */
459
460 avr_register_passes ();
461 }
462
463 /* Function to set up the backend function structure. */
464
465 static struct machine_function *
466 avr_init_machine_status (void)
467 {
468 return ggc_cleared_alloc<machine_function> ();
469 }
470
471
472 /* Implement `INIT_EXPANDERS'. */
473 /* The function works like a singleton. */
474
475 void
476 avr_init_expanders (void)
477 {
478 int regno;
479
480 for (regno = 0; regno < 32; regno ++)
481 all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
482
483 lpm_reg_rtx = all_regs_rtx[LPM_REGNO];
484 tmp_reg_rtx = all_regs_rtx[AVR_TMP_REGNO];
485 zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
486
487 lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
488
489 sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
490 rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
491 rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
492 rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
493 rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
494
495 xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
496 xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
497
498 /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
499 to be present */
500 if (AVR_TINY)
501 avr_have_dimode = false;
502 }
503
504
505 /* Implement `REGNO_REG_CLASS'. */
506 /* Return register class for register R. */
507
508 enum reg_class
509 avr_regno_reg_class (int r)
510 {
511 static const enum reg_class reg_class_tab[] =
512 {
513 R0_REG,
514 /* r1 - r15 */
515 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
516 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
517 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
518 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
519 /* r16 - r23 */
520 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
521 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
522 /* r24, r25 */
523 ADDW_REGS, ADDW_REGS,
524 /* X: r26, 27 */
525 POINTER_X_REGS, POINTER_X_REGS,
526 /* Y: r28, r29 */
527 POINTER_Y_REGS, POINTER_Y_REGS,
528 /* Z: r30, r31 */
529 POINTER_Z_REGS, POINTER_Z_REGS,
530 /* SP: SPL, SPH */
531 STACK_REG, STACK_REG
532 };
533
534 if (r <= 33)
535 return reg_class_tab[r];
536
537 return ALL_REGS;
538 }
539
540
541 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'. */
542
543 static bool
544 avr_scalar_mode_supported_p (machine_mode mode)
545 {
546 if (ALL_FIXED_POINT_MODE_P (mode))
547 return true;
548
549 if (PSImode == mode)
550 return true;
551
552 return default_scalar_mode_supported_p (mode);
553 }
554
555
556 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise. */
557
558 static bool
559 avr_decl_flash_p (tree decl)
560 {
561 if (TREE_CODE (decl) != VAR_DECL
562 || TREE_TYPE (decl) == error_mark_node)
563 {
564 return false;
565 }
566
567 return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
568 }
569
570
571 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash
572 address space and FALSE, otherwise. */
573
574 static bool
575 avr_decl_memx_p (tree decl)
576 {
577 if (TREE_CODE (decl) != VAR_DECL
578 || TREE_TYPE (decl) == error_mark_node)
579 {
580 return false;
581 }
582
583 return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
584 }
585
586
587 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise. */
588
589 bool
590 avr_mem_flash_p (rtx x)
591 {
592 return (MEM_P (x)
593 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
594 }
595
596
597 /* Return TRUE if X is a MEM rtx located in the 24-bit flash
598 address space and FALSE, otherwise. */
599
600 bool
601 avr_mem_memx_p (rtx x)
602 {
603 return (MEM_P (x)
604 && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
605 }
606
607
608 /* A helper for the subsequent function attribute used to dig for
609 attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
610
611 static inline int
612 avr_lookup_function_attribute1 (const_tree func, const char *name)
613 {
614 if (FUNCTION_DECL == TREE_CODE (func))
615 {
616 if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
617 {
618 return true;
619 }
620
621 func = TREE_TYPE (func);
622 }
623
624 gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
625 || TREE_CODE (func) == METHOD_TYPE);
626
627 return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
628 }
629
630 /* Return nonzero if FUNC is a naked function. */
631
632 static int
633 avr_naked_function_p (tree func)
634 {
635 return avr_lookup_function_attribute1 (func, "naked");
636 }
637
638 /* Return nonzero if FUNC is an interrupt function as specified
639 by the "interrupt" attribute. */
640
641 static int
642 avr_interrupt_function_p (tree func)
643 {
644 return avr_lookup_function_attribute1 (func, "interrupt");
645 }
646
647 /* Return nonzero if FUNC is a signal function as specified
648 by the "signal" attribute. */
649
650 static int
651 avr_signal_function_p (tree func)
652 {
653 return avr_lookup_function_attribute1 (func, "signal");
654 }
655
656 /* Return nonzero if FUNC is an OS_task function. */
657
658 static int
659 avr_OS_task_function_p (tree func)
660 {
661 return avr_lookup_function_attribute1 (func, "OS_task");
662 }
663
664 /* Return nonzero if FUNC is an OS_main function. */
665
666 static int
667 avr_OS_main_function_p (tree func)
668 {
669 return avr_lookup_function_attribute1 (func, "OS_main");
670 }
671
672
673 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */
674 /* Sanity cheching for above function attributes. */
675
676 static void
677 avr_set_current_function (tree decl)
678 {
679 location_t loc;
680 const char *isr;
681
682 if (decl == NULL_TREE
683 || current_function_decl == NULL_TREE
684 || current_function_decl == error_mark_node
685 || ! cfun->machine
686 || cfun->machine->attributes_checked_p)
687 return;
688
689 loc = DECL_SOURCE_LOCATION (decl);
690
691 cfun->machine->is_naked = avr_naked_function_p (decl);
692 cfun->machine->is_signal = avr_signal_function_p (decl);
693 cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
694 cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
695 cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
696
697 isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
698
699 /* Too much attributes make no sense as they request conflicting features. */
700
701 if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
702 + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
703 error_at (loc, "function attributes %qs, %qs and %qs are mutually"
704 " exclusive", "OS_task", "OS_main", isr);
705
706 /* 'naked' will hide effects of 'OS_task' and 'OS_main'. */
707
708 if (cfun->machine->is_naked
709 && (cfun->machine->is_OS_task || cfun->machine->is_OS_main))
710 warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
711 " no effect on %qs function", "OS_task", "OS_main", "naked");
712
713 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
714 {
715 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
716 tree ret = TREE_TYPE (TREE_TYPE (decl));
717 const char *name;
718
719 name = DECL_ASSEMBLER_NAME_SET_P (decl)
720 ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
721 : IDENTIFIER_POINTER (DECL_NAME (decl));
722
723 /* Skip a leading '*' that might still prefix the assembler name,
724 e.g. in non-LTO runs. */
725
726 name = default_strip_name_encoding (name);
727
728 /* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet
729 using this when it switched from SIGNAL and INTERRUPT to ISR. */
730
731 if (cfun->machine->is_interrupt)
732 cfun->machine->is_signal = 0;
733
734 /* Interrupt handlers must be void __vector (void) functions. */
735
736 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
737 error_at (loc, "%qs function cannot have arguments", isr);
738
739 if (TREE_CODE (ret) != VOID_TYPE)
740 error_at (loc, "%qs function cannot return a value", isr);
741
742 /* If the function has the 'signal' or 'interrupt' attribute, ensure
743 that the name of the function is "__vector_NN" so as to catch
744 when the user misspells the vector name. */
745
746 if (!STR_PREFIX_P (name, "__vector"))
747 warning_at (loc, 0, "%qs appears to be a misspelled %s handler",
748 name, isr);
749 }
750
751 /* Don't print the above diagnostics more than once. */
752
753 cfun->machine->attributes_checked_p = 1;
754 }
755
756
757 /* Implement `ACCUMULATE_OUTGOING_ARGS'. */
758
759 int
760 avr_accumulate_outgoing_args (void)
761 {
762 if (!cfun)
763 return TARGET_ACCUMULATE_OUTGOING_ARGS;
764
765 /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
766 what offset is correct. In some cases it is relative to
767 virtual_outgoing_args_rtx and in others it is relative to
768 virtual_stack_vars_rtx. For example code see
769 gcc.c-torture/execute/built-in-setjmp.c
770 gcc.c-torture/execute/builtins/sprintf-chk.c */
771
772 return (TARGET_ACCUMULATE_OUTGOING_ARGS
773 && !(cfun->calls_setjmp
774 || cfun->has_nonlocal_label));
775 }
776
777
778 /* Report contribution of accumulated outgoing arguments to stack size. */
779
780 static inline int
781 avr_outgoing_args_size (void)
782 {
783 return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
784 }
785
786
787 /* Implement `STARTING_FRAME_OFFSET'. */
788 /* This is the offset from the frame pointer register to the first stack slot
789 that contains a variable living in the frame. */
790
791 int
792 avr_starting_frame_offset (void)
793 {
794 return 1 + avr_outgoing_args_size ();
795 }
796
797
798 /* Return the number of hard registers to push/pop in the prologue/epilogue
799 of the current function, and optionally store these registers in SET. */
800
801 static int
802 avr_regs_to_save (HARD_REG_SET *set)
803 {
804 int reg, count;
805 int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
806
807 if (set)
808 CLEAR_HARD_REG_SET (*set);
809 count = 0;
810
811 /* No need to save any registers if the function never returns or
812 has the "OS_task" or "OS_main" attribute. */
813
814 if (TREE_THIS_VOLATILE (current_function_decl)
815 || cfun->machine->is_OS_task
816 || cfun->machine->is_OS_main)
817 return 0;
818
819 for (reg = 0; reg < 32; reg++)
820 {
821 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
822 any global register variables. */
823
824 if (fixed_regs[reg])
825 continue;
826
827 if ((int_or_sig_p && !crtl->is_leaf && call_used_regs[reg])
828 || (df_regs_ever_live_p (reg)
829 && (int_or_sig_p || !call_used_regs[reg])
830 /* Don't record frame pointer registers here. They are treated
831 indivitually in prologue. */
832 && !(frame_pointer_needed
833 && (reg == REG_Y || reg == (REG_Y+1)))))
834 {
835 if (set)
836 SET_HARD_REG_BIT (*set, reg);
837 count++;
838 }
839 }
840 return count;
841 }
842
843
844 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
845
846 static bool
847 avr_allocate_stack_slots_for_args (void)
848 {
849 return !cfun->machine->is_naked;
850 }
851
852
853 /* Return true if register FROM can be eliminated via register TO. */
854
855 static bool
856 avr_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
857 {
858 return ((frame_pointer_needed && to == FRAME_POINTER_REGNUM)
859 || !frame_pointer_needed);
860 }
861
862
863 /* Implement `TARGET_WARN_FUNC_RETURN'. */
864
865 static bool
866 avr_warn_func_return (tree decl)
867 {
868 /* Naked functions are implemented entirely in assembly, including the
869 return sequence, so suppress warnings about this. */
870
871 return !avr_naked_function_p (decl);
872 }
873
874 /* Compute offset between arg_pointer and frame_pointer. */
875
876 int
877 avr_initial_elimination_offset (int from, int to)
878 {
879 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
880 return 0;
881 else
882 {
883 int offset = frame_pointer_needed ? 2 : 0;
884 int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
885
886 offset += avr_regs_to_save (NULL);
887 return (get_frame_size () + avr_outgoing_args_size()
888 + avr_pc_size + 1 + offset);
889 }
890 }
891
892
893 /* Helper for the function below. */
894
895 static void
896 avr_adjust_type_node (tree *node, machine_mode mode, int sat_p)
897 {
898 *node = make_node (FIXED_POINT_TYPE);
899 TYPE_SATURATING (*node) = sat_p;
900 TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
901 TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
902 TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
903 TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
904 TYPE_ALIGN (*node) = 8;
905 SET_TYPE_MODE (*node, mode);
906
907 layout_type (*node);
908 }
909
910
911 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'. */
912
913 static tree
914 avr_build_builtin_va_list (void)
915 {
916 /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
917 This is more appropriate for the 8-bit machine AVR than 128-bit modes.
918 The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
919 which is auto-generated by genmodes, but the compiler assigns [U]DAmode
920 to the long long accum modes instead of the desired [U]TAmode.
921
922 Fix this now, right after node setup in tree.c:build_common_tree_nodes().
923 This must run before c-cppbuiltin.c:builtin_define_fixed_point_constants()
924 which built-in defines macros like __ULLACCUM_FBIT__ that are used by
925 libgcc to detect IBIT and FBIT. */
926
927 avr_adjust_type_node (&ta_type_node, TAmode, 0);
928 avr_adjust_type_node (&uta_type_node, UTAmode, 0);
929 avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
930 avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
931
932 unsigned_long_long_accum_type_node = uta_type_node;
933 long_long_accum_type_node = ta_type_node;
934 sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
935 sat_long_long_accum_type_node = sat_ta_type_node;
936
937 /* Dispatch to the default handler. */
938
939 return std_build_builtin_va_list ();
940 }
941
942
943 /* Implement `TARGET_BUILTIN_SETJMP_FRAME_VALUE'. */
944 /* Actual start of frame is virtual_stack_vars_rtx this is offset from
945 frame pointer by +STARTING_FRAME_OFFSET.
946 Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
947 avoids creating add/sub of offset in nonlocal goto and setjmp. */
948
949 static rtx
950 avr_builtin_setjmp_frame_value (void)
951 {
952 rtx xval = gen_reg_rtx (Pmode);
953 emit_insn (gen_subhi3 (xval, virtual_stack_vars_rtx,
954 gen_int_mode (STARTING_FRAME_OFFSET, Pmode)));
955 return xval;
956 }
957
958
959 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
960 This is return address of function. */
961
962 rtx
963 avr_return_addr_rtx (int count, rtx tem)
964 {
965 rtx r;
966
967 /* Can only return this function's return address. Others not supported. */
968 if (count)
969 return NULL;
970
971 if (AVR_3_BYTE_PC)
972 {
973 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
974 warning (0, "%<builtin_return_address%> contains only 2 bytes"
975 " of address");
976 }
977 else
978 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
979
980 r = gen_rtx_PLUS (Pmode, tem, r);
981 r = gen_frame_mem (Pmode, memory_address (Pmode, r));
982 r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
983 return r;
984 }
985
986 /* Return 1 if the function epilogue is just a single "ret". */
987
988 int
989 avr_simple_epilogue (void)
990 {
991 return (! frame_pointer_needed
992 && get_frame_size () == 0
993 && avr_outgoing_args_size() == 0
994 && avr_regs_to_save (NULL) == 0
995 && ! cfun->machine->is_interrupt
996 && ! cfun->machine->is_signal
997 && ! cfun->machine->is_naked
998 && ! TREE_THIS_VOLATILE (current_function_decl));
999 }
1000
1001 /* This function checks sequence of live registers. */
1002
1003 static int
1004 sequent_regs_live (void)
1005 {
1006 int reg;
1007 int live_seq = 0;
1008 int cur_seq = 0;
1009
1010 for (reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
1011 {
1012 if (fixed_regs[reg])
1013 {
1014 /* Don't recognize sequences that contain global register
1015 variables. */
1016
1017 if (live_seq != 0)
1018 return 0;
1019 else
1020 continue;
1021 }
1022
1023 if (!call_used_regs[reg])
1024 {
1025 if (df_regs_ever_live_p (reg))
1026 {
1027 ++live_seq;
1028 ++cur_seq;
1029 }
1030 else
1031 cur_seq = 0;
1032 }
1033 }
1034
1035 if (!frame_pointer_needed)
1036 {
1037 if (df_regs_ever_live_p (REG_Y))
1038 {
1039 ++live_seq;
1040 ++cur_seq;
1041 }
1042 else
1043 cur_seq = 0;
1044
1045 if (df_regs_ever_live_p (REG_Y+1))
1046 {
1047 ++live_seq;
1048 ++cur_seq;
1049 }
1050 else
1051 cur_seq = 0;
1052 }
1053 else
1054 {
1055 cur_seq += 2;
1056 live_seq += 2;
1057 }
1058 return (cur_seq == live_seq) ? live_seq : 0;
1059 }
1060
1061 /* Obtain the length sequence of insns. */
1062
1063 int
1064 get_sequence_length (rtx_insn *insns)
1065 {
1066 rtx_insn *insn;
1067 int length;
1068
1069 for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
1070 length += get_attr_length (insn);
1071
1072 return length;
1073 }
1074
1075
1076 /* Implement `INCOMING_RETURN_ADDR_RTX'. */
1077
1078 rtx
1079 avr_incoming_return_addr_rtx (void)
1080 {
1081 /* The return address is at the top of the stack. Note that the push
1082 was via post-decrement, which means the actual address is off by one. */
1083 return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
1084 }
1085
1086 /* Helper for expand_prologue. Emit a push of a byte register. */
1087
1088 static void
1089 emit_push_byte (unsigned regno, bool frame_related_p)
1090 {
1091 rtx mem, reg;
1092 rtx_insn *insn;
1093
1094 mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
1095 mem = gen_frame_mem (QImode, mem);
1096 reg = gen_rtx_REG (QImode, regno);
1097
1098 insn = emit_insn (gen_rtx_SET (mem, reg));
1099 if (frame_related_p)
1100 RTX_FRAME_RELATED_P (insn) = 1;
1101
1102 cfun->machine->stack_usage++;
1103 }
1104
1105
1106 /* Helper for expand_prologue. Emit a push of a SFR via tmp_reg.
1107 SFR is a MEM representing the memory location of the SFR.
1108 If CLR_P then clear the SFR after the push using zero_reg. */
1109
1110 static void
1111 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
1112 {
1113 rtx_insn *insn;
1114
1115 gcc_assert (MEM_P (sfr));
1116
1117 /* IN __tmp_reg__, IO(SFR) */
1118 insn = emit_move_insn (tmp_reg_rtx, sfr);
1119 if (frame_related_p)
1120 RTX_FRAME_RELATED_P (insn) = 1;
1121
1122 /* PUSH __tmp_reg__ */
1123 emit_push_byte (AVR_TMP_REGNO, frame_related_p);
1124
1125 if (clr_p)
1126 {
1127 /* OUT IO(SFR), __zero_reg__ */
1128 insn = emit_move_insn (sfr, const0_rtx);
1129 if (frame_related_p)
1130 RTX_FRAME_RELATED_P (insn) = 1;
1131 }
1132 }
1133
1134 static void
1135 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
1136 {
1137 rtx_insn *insn;
1138 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1139 int live_seq = sequent_regs_live ();
1140
1141 HOST_WIDE_INT size_max
1142 = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
1143
1144 bool minimize = (TARGET_CALL_PROLOGUES
1145 && size < size_max
1146 && live_seq
1147 && !isr_p
1148 && !cfun->machine->is_OS_task
1149 && !cfun->machine->is_OS_main
1150 && !AVR_TINY);
1151
1152 if (minimize
1153 && (frame_pointer_needed
1154 || avr_outgoing_args_size() > 8
1155 || (AVR_2_BYTE_PC && live_seq > 6)
1156 || live_seq > 7))
1157 {
1158 rtx pattern;
1159 int first_reg, reg, offset;
1160
1161 emit_move_insn (gen_rtx_REG (HImode, REG_X),
1162 gen_int_mode (size, HImode));
1163
1164 pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
1165 gen_int_mode (live_seq+size, HImode));
1166 insn = emit_insn (pattern);
1167 RTX_FRAME_RELATED_P (insn) = 1;
1168
1169 /* Describe the effect of the unspec_volatile call to prologue_saves.
1170 Note that this formulation assumes that add_reg_note pushes the
1171 notes to the front. Thus we build them in the reverse order of
1172 how we want dwarf2out to process them. */
1173
1174 /* The function does always set frame_pointer_rtx, but whether that
1175 is going to be permanent in the function is frame_pointer_needed. */
1176
1177 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1178 gen_rtx_SET ((frame_pointer_needed
1179 ? frame_pointer_rtx
1180 : stack_pointer_rtx),
1181 plus_constant (Pmode, stack_pointer_rtx,
1182 -(size + live_seq))));
1183
1184 /* Note that live_seq always contains r28+r29, but the other
1185 registers to be saved are all below 18. */
1186
1187 first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
1188
1189 for (reg = 29, offset = -live_seq + 1;
1190 reg >= first_reg;
1191 reg = (reg == 28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
1192 {
1193 rtx m, r;
1194
1195 m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
1196 offset));
1197 r = gen_rtx_REG (QImode, reg);
1198 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (m, r));
1199 }
1200
1201 cfun->machine->stack_usage += size + live_seq;
1202 }
1203 else /* !minimize */
1204 {
1205 int reg;
1206
1207 for (reg = 0; reg < 32; ++reg)
1208 if (TEST_HARD_REG_BIT (set, reg))
1209 emit_push_byte (reg, true);
1210
1211 if (frame_pointer_needed
1212 && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
1213 {
1214 /* Push frame pointer. Always be consistent about the
1215 ordering of pushes -- epilogue_restores expects the
1216 register pair to be pushed low byte first. */
1217
1218 emit_push_byte (REG_Y, true);
1219 emit_push_byte (REG_Y + 1, true);
1220 }
1221
1222 if (frame_pointer_needed
1223 && size == 0)
1224 {
1225 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1226 RTX_FRAME_RELATED_P (insn) = 1;
1227 }
1228
1229 if (size != 0)
1230 {
1231 /* Creating a frame can be done by direct manipulation of the
1232 stack or via the frame pointer. These two methods are:
1233 fp = sp
1234 fp -= size
1235 sp = fp
1236 or
1237 sp -= size
1238 fp = sp (*)
1239 the optimum method depends on function type, stack and
1240 frame size. To avoid a complex logic, both methods are
1241 tested and shortest is selected.
1242
1243 There is also the case where SIZE != 0 and no frame pointer is
1244 needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1245 In that case, insn (*) is not needed in that case.
1246 We use the X register as scratch. This is save because in X
1247 is call-clobbered.
1248 In an interrupt routine, the case of SIZE != 0 together with
1249 !frame_pointer_needed can only occur if the function is not a
1250 leaf function and thus X has already been saved. */
1251
1252 int irq_state = -1;
1253 HOST_WIDE_INT size_cfa = size, neg_size;
1254 rtx_insn *fp_plus_insns;
1255 rtx fp, my_fp;
1256
1257 gcc_assert (frame_pointer_needed
1258 || !isr_p
1259 || !crtl->is_leaf);
1260
1261 fp = my_fp = (frame_pointer_needed
1262 ? frame_pointer_rtx
1263 : gen_rtx_REG (Pmode, REG_X));
1264
1265 if (AVR_HAVE_8BIT_SP)
1266 {
1267 /* The high byte (r29) does not change:
1268 Prefer SUBI (1 cycle) over SBIW (2 cycles, same size). */
1269
1270 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1271 }
1272
1273 /* Cut down size and avoid size = 0 so that we don't run
1274 into ICE like PR52488 in the remainder. */
1275
1276 if (size > size_max)
1277 {
1278 /* Don't error so that insane code from newlib still compiles
1279 and does not break building newlib. As PR51345 is implemented
1280 now, there are multilib variants with -msp8.
1281
1282 If user wants sanity checks he can use -Wstack-usage=
1283 or similar options.
1284
1285 For CFA we emit the original, non-saturated size so that
1286 the generic machinery is aware of the real stack usage and
1287 will print the above diagnostic as expected. */
1288
1289 size = size_max;
1290 }
1291
1292 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1293 neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
1294
1295 /************ Method 1: Adjust frame pointer ************/
1296
1297 start_sequence ();
1298
1299 /* Normally, the dwarf2out frame-related-expr interpreter does
1300 not expect to have the CFA change once the frame pointer is
1301 set up. Thus, we avoid marking the move insn below and
1302 instead indicate that the entire operation is complete after
1303 the frame pointer subtraction is done. */
1304
1305 insn = emit_move_insn (fp, stack_pointer_rtx);
1306 if (frame_pointer_needed)
1307 {
1308 RTX_FRAME_RELATED_P (insn) = 1;
1309 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1310 gen_rtx_SET (fp, stack_pointer_rtx));
1311 }
1312
1313 insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
1314 my_fp, neg_size));
1315
1316 if (frame_pointer_needed)
1317 {
1318 RTX_FRAME_RELATED_P (insn) = 1;
1319 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1320 gen_rtx_SET (fp, plus_constant (Pmode, fp,
1321 -size_cfa)));
1322 }
1323
1324 /* Copy to stack pointer. Note that since we've already
1325 changed the CFA to the frame pointer this operation
1326 need not be annotated if frame pointer is needed.
1327 Always move through unspec, see PR50063.
1328 For meaning of irq_state see movhi_sp_r insn. */
1329
1330 if (cfun->machine->is_interrupt)
1331 irq_state = 1;
1332
1333 if (TARGET_NO_INTERRUPTS
1334 || cfun->machine->is_signal
1335 || cfun->machine->is_OS_main)
1336 irq_state = 0;
1337
1338 if (AVR_HAVE_8BIT_SP)
1339 irq_state = 2;
1340
1341 insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1342 fp, GEN_INT (irq_state)));
1343 if (!frame_pointer_needed)
1344 {
1345 RTX_FRAME_RELATED_P (insn) = 1;
1346 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1347 gen_rtx_SET (stack_pointer_rtx,
1348 plus_constant (Pmode,
1349 stack_pointer_rtx,
1350 -size_cfa)));
1351 }
1352
1353 fp_plus_insns = get_insns ();
1354 end_sequence ();
1355
1356 /************ Method 2: Adjust Stack pointer ************/
1357
1358 /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1359 can only handle specific offsets. */
1360
1361 if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1362 {
1363 rtx_insn *sp_plus_insns;
1364
1365 start_sequence ();
1366
1367 insn = emit_move_insn (stack_pointer_rtx,
1368 plus_constant (Pmode, stack_pointer_rtx,
1369 -size));
1370 RTX_FRAME_RELATED_P (insn) = 1;
1371 add_reg_note (insn, REG_CFA_ADJUST_CFA,
1372 gen_rtx_SET (stack_pointer_rtx,
1373 plus_constant (Pmode,
1374 stack_pointer_rtx,
1375 -size_cfa)));
1376 if (frame_pointer_needed)
1377 {
1378 insn = emit_move_insn (fp, stack_pointer_rtx);
1379 RTX_FRAME_RELATED_P (insn) = 1;
1380 }
1381
1382 sp_plus_insns = get_insns ();
1383 end_sequence ();
1384
1385 /************ Use shortest method ************/
1386
1387 emit_insn (get_sequence_length (sp_plus_insns)
1388 < get_sequence_length (fp_plus_insns)
1389 ? sp_plus_insns
1390 : fp_plus_insns);
1391 }
1392 else
1393 {
1394 emit_insn (fp_plus_insns);
1395 }
1396
1397 cfun->machine->stack_usage += size_cfa;
1398 } /* !minimize && size != 0 */
1399 } /* !minimize */
1400 }
1401
1402
1403 /* Output function prologue. */
1404
1405 void
1406 avr_expand_prologue (void)
1407 {
1408 HARD_REG_SET set;
1409 HOST_WIDE_INT size;
1410
1411 size = get_frame_size() + avr_outgoing_args_size();
1412
1413 cfun->machine->stack_usage = 0;
1414
1415 /* Prologue: naked. */
1416 if (cfun->machine->is_naked)
1417 {
1418 return;
1419 }
1420
1421 avr_regs_to_save (&set);
1422
1423 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1424 {
1425 /* Enable interrupts. */
1426 if (cfun->machine->is_interrupt)
1427 emit_insn (gen_enable_interrupt ());
1428
1429 /* Push zero reg. */
1430 emit_push_byte (AVR_ZERO_REGNO, true);
1431
1432 /* Push tmp reg. */
1433 emit_push_byte (AVR_TMP_REGNO, true);
1434
1435 /* Push SREG. */
1436 /* ??? There's no dwarf2 column reserved for SREG. */
1437 emit_push_sfr (sreg_rtx, false, false /* clr */);
1438
1439 /* Clear zero reg. */
1440 emit_move_insn (zero_reg_rtx, const0_rtx);
1441
1442 /* Prevent any attempt to delete the setting of ZERO_REG! */
1443 emit_use (zero_reg_rtx);
1444
1445 /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
1446 ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z. */
1447
1448 if (AVR_HAVE_RAMPD)
1449 emit_push_sfr (rampd_rtx, false /* frame-related */, true /* clr */);
1450
1451 if (AVR_HAVE_RAMPX
1452 && TEST_HARD_REG_BIT (set, REG_X)
1453 && TEST_HARD_REG_BIT (set, REG_X + 1))
1454 {
1455 emit_push_sfr (rampx_rtx, false /* frame-related */, true /* clr */);
1456 }
1457
1458 if (AVR_HAVE_RAMPY
1459 && (frame_pointer_needed
1460 || (TEST_HARD_REG_BIT (set, REG_Y)
1461 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1462 {
1463 emit_push_sfr (rampy_rtx, false /* frame-related */, true /* clr */);
1464 }
1465
1466 if (AVR_HAVE_RAMPZ
1467 && TEST_HARD_REG_BIT (set, REG_Z)
1468 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1469 {
1470 emit_push_sfr (rampz_rtx, false /* frame-related */, AVR_HAVE_RAMPD);
1471 }
1472 } /* is_interrupt is_signal */
1473
1474 avr_prologue_setup_frame (size, set);
1475
1476 if (flag_stack_usage_info)
1477 current_function_static_stack_size = cfun->machine->stack_usage;
1478 }
1479
1480
1481 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'. */
1482 /* Output summary at end of function prologue. */
1483
1484 static void
1485 avr_asm_function_end_prologue (FILE *file)
1486 {
1487 if (cfun->machine->is_naked)
1488 {
1489 fputs ("/* prologue: naked */\n", file);
1490 }
1491 else
1492 {
1493 if (cfun->machine->is_interrupt)
1494 {
1495 fputs ("/* prologue: Interrupt */\n", file);
1496 }
1497 else if (cfun->machine->is_signal)
1498 {
1499 fputs ("/* prologue: Signal */\n", file);
1500 }
1501 else
1502 fputs ("/* prologue: function */\n", file);
1503 }
1504
1505 if (ACCUMULATE_OUTGOING_ARGS)
1506 fprintf (file, "/* outgoing args size = %d */\n",
1507 avr_outgoing_args_size());
1508
1509 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1510 get_frame_size());
1511 fprintf (file, "/* stack size = %d */\n",
1512 cfun->machine->stack_usage);
1513 /* Create symbol stack offset here so all functions have it. Add 1 to stack
1514 usage for offset so that SP + .L__stack_offset = return address. */
1515 fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1516 }
1517
1518
1519 /* Implement `EPILOGUE_USES'. */
1520
1521 int
1522 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1523 {
1524 if (reload_completed
1525 && cfun->machine
1526 && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1527 return 1;
1528 return 0;
1529 }
1530
1531 /* Helper for avr_expand_epilogue. Emit a pop of a byte register. */
1532
1533 static void
1534 emit_pop_byte (unsigned regno)
1535 {
1536 rtx mem, reg;
1537
1538 mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1539 mem = gen_frame_mem (QImode, mem);
1540 reg = gen_rtx_REG (QImode, regno);
1541
1542 emit_insn (gen_rtx_SET (reg, mem));
1543 }
1544
1545 /* Output RTL epilogue. */
1546
1547 void
1548 avr_expand_epilogue (bool sibcall_p)
1549 {
1550 int reg;
1551 int live_seq;
1552 HARD_REG_SET set;
1553 int minimize;
1554 HOST_WIDE_INT size;
1555 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1556
1557 size = get_frame_size() + avr_outgoing_args_size();
1558
1559 /* epilogue: naked */
1560 if (cfun->machine->is_naked)
1561 {
1562 gcc_assert (!sibcall_p);
1563
1564 emit_jump_insn (gen_return ());
1565 return;
1566 }
1567
1568 avr_regs_to_save (&set);
1569 live_seq = sequent_regs_live ();
1570
1571 minimize = (TARGET_CALL_PROLOGUES
1572 && live_seq
1573 && !isr_p
1574 && !cfun->machine->is_OS_task
1575 && !cfun->machine->is_OS_main
1576 && !AVR_TINY);
1577
1578 if (minimize
1579 && (live_seq > 4
1580 || frame_pointer_needed
1581 || size))
1582 {
1583 /* Get rid of frame. */
1584
1585 if (!frame_pointer_needed)
1586 {
1587 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1588 }
1589
1590 if (size)
1591 {
1592 emit_move_insn (frame_pointer_rtx,
1593 plus_constant (Pmode, frame_pointer_rtx, size));
1594 }
1595
1596 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1597 return;
1598 }
1599
1600 if (size)
1601 {
1602 /* Try two methods to adjust stack and select shortest. */
1603
1604 int irq_state = -1;
1605 rtx fp, my_fp;
1606 rtx_insn *fp_plus_insns;
1607 HOST_WIDE_INT size_max;
1608
1609 gcc_assert (frame_pointer_needed
1610 || !isr_p
1611 || !crtl->is_leaf);
1612
1613 fp = my_fp = (frame_pointer_needed
1614 ? frame_pointer_rtx
1615 : gen_rtx_REG (Pmode, REG_X));
1616
1617 if (AVR_HAVE_8BIT_SP)
1618 {
1619 /* The high byte (r29) does not change:
1620 Prefer SUBI (1 cycle) over SBIW (2 cycles). */
1621
1622 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1623 }
1624
1625 /* For rationale see comment in prologue generation. */
1626
1627 size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
1628 if (size > size_max)
1629 size = size_max;
1630 size = trunc_int_for_mode (size, GET_MODE (my_fp));
1631
1632 /********** Method 1: Adjust fp register **********/
1633
1634 start_sequence ();
1635
1636 if (!frame_pointer_needed)
1637 emit_move_insn (fp, stack_pointer_rtx);
1638
1639 emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
1640
1641 /* Copy to stack pointer. */
1642
1643 if (TARGET_NO_INTERRUPTS)
1644 irq_state = 0;
1645
1646 if (AVR_HAVE_8BIT_SP)
1647 irq_state = 2;
1648
1649 emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
1650 GEN_INT (irq_state)));
1651
1652 fp_plus_insns = get_insns ();
1653 end_sequence ();
1654
1655 /********** Method 2: Adjust Stack pointer **********/
1656
1657 if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1658 {
1659 rtx_insn *sp_plus_insns;
1660
1661 start_sequence ();
1662
1663 emit_move_insn (stack_pointer_rtx,
1664 plus_constant (Pmode, stack_pointer_rtx, size));
1665
1666 sp_plus_insns = get_insns ();
1667 end_sequence ();
1668
1669 /************ Use shortest method ************/
1670
1671 emit_insn (get_sequence_length (sp_plus_insns)
1672 < get_sequence_length (fp_plus_insns)
1673 ? sp_plus_insns
1674 : fp_plus_insns);
1675 }
1676 else
1677 emit_insn (fp_plus_insns);
1678 } /* size != 0 */
1679
1680 if (frame_pointer_needed
1681 && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1682 {
1683 /* Restore previous frame_pointer. See avr_expand_prologue for
1684 rationale for not using pophi. */
1685
1686 emit_pop_byte (REG_Y + 1);
1687 emit_pop_byte (REG_Y);
1688 }
1689
1690 /* Restore used registers. */
1691
1692 for (reg = 31; reg >= 0; --reg)
1693 if (TEST_HARD_REG_BIT (set, reg))
1694 emit_pop_byte (reg);
1695
1696 if (isr_p)
1697 {
1698 /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
1699 The conditions to restore them must be tha same as in prologue. */
1700
1701 if (AVR_HAVE_RAMPZ
1702 && TEST_HARD_REG_BIT (set, REG_Z)
1703 && TEST_HARD_REG_BIT (set, REG_Z + 1))
1704 {
1705 emit_pop_byte (TMP_REGNO);
1706 emit_move_insn (rampz_rtx, tmp_reg_rtx);
1707 }
1708
1709 if (AVR_HAVE_RAMPY
1710 && (frame_pointer_needed
1711 || (TEST_HARD_REG_BIT (set, REG_Y)
1712 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1713 {
1714 emit_pop_byte (TMP_REGNO);
1715 emit_move_insn (rampy_rtx, tmp_reg_rtx);
1716 }
1717
1718 if (AVR_HAVE_RAMPX
1719 && TEST_HARD_REG_BIT (set, REG_X)
1720 && TEST_HARD_REG_BIT (set, REG_X + 1))
1721 {
1722 emit_pop_byte (TMP_REGNO);
1723 emit_move_insn (rampx_rtx, tmp_reg_rtx);
1724 }
1725
1726 if (AVR_HAVE_RAMPD)
1727 {
1728 emit_pop_byte (TMP_REGNO);
1729 emit_move_insn (rampd_rtx, tmp_reg_rtx);
1730 }
1731
1732 /* Restore SREG using tmp_reg as scratch. */
1733
1734 emit_pop_byte (AVR_TMP_REGNO);
1735 emit_move_insn (sreg_rtx, tmp_reg_rtx);
1736
1737 /* Restore tmp REG. */
1738 emit_pop_byte (AVR_TMP_REGNO);
1739
1740 /* Restore zero REG. */
1741 emit_pop_byte (AVR_ZERO_REGNO);
1742 }
1743
1744 if (!sibcall_p)
1745 emit_jump_insn (gen_return ());
1746 }
1747
1748
1749 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'. */
1750
1751 static void
1752 avr_asm_function_begin_epilogue (FILE *file)
1753 {
1754 fprintf (file, "/* epilogue start */\n");
1755 }
1756
1757
1758 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'. */
1759
1760 static bool
1761 avr_cannot_modify_jumps_p (void)
1762 {
1763
1764 /* Naked Functions must not have any instructions after
1765 their epilogue, see PR42240 */
1766
1767 if (reload_completed
1768 && cfun->machine
1769 && cfun->machine->is_naked)
1770 {
1771 return true;
1772 }
1773
1774 return false;
1775 }
1776
1777
1778 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'. */
1779
1780 static bool
1781 avr_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED, addr_space_t as)
1782 {
1783 /* FIXME: Non-generic addresses are not mode-dependent in themselves.
1784 This hook just serves to hack around PR rtl-optimization/52543 by
1785 claiming that non-generic addresses were mode-dependent so that
1786 lower-subreg.c will skip these addresses. lower-subreg.c sets up fake
1787 RTXes to probe SET and MEM costs and assumes that MEM is always in the
1788 generic address space which is not true. */
1789
1790 return !ADDR_SPACE_GENERIC_P (as);
1791 }
1792
1793
1794 /* Helper function for `avr_legitimate_address_p'. */
1795
1796 static inline bool
1797 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1798 RTX_CODE outer_code, bool strict)
1799 {
1800 return (REG_P (reg)
1801 && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1802 as, outer_code, UNKNOWN)
1803 || (!strict
1804 && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1805 }
1806
1807
1808 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1809 machine for a memory operand of mode MODE. */
1810
1811 static bool
1812 avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
1813 {
1814 bool ok = CONSTANT_ADDRESS_P (x);
1815
1816 switch (GET_CODE (x))
1817 {
1818 case REG:
1819 ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1820 MEM, strict);
1821
1822 if (strict
1823 && GET_MODE_SIZE (mode) > 4
1824 && REG_X == REGNO (x))
1825 {
1826 ok = false;
1827 }
1828 break;
1829
1830 case POST_INC:
1831 case PRE_DEC:
1832 ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1833 GET_CODE (x), strict);
1834 break;
1835
1836 case PLUS:
1837 {
1838 rtx reg = XEXP (x, 0);
1839 rtx op1 = XEXP (x, 1);
1840
1841 if (REG_P (reg)
1842 && CONST_INT_P (op1)
1843 && INTVAL (op1) >= 0)
1844 {
1845 bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1846
1847 if (fit)
1848 {
1849 ok = (! strict
1850 || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1851 PLUS, strict));
1852
1853 if (reg == frame_pointer_rtx
1854 || reg == arg_pointer_rtx)
1855 {
1856 ok = true;
1857 }
1858 }
1859 else if (frame_pointer_needed
1860 && reg == frame_pointer_rtx)
1861 {
1862 ok = true;
1863 }
1864 }
1865 }
1866 break;
1867
1868 default:
1869 break;
1870 }
1871
1872 if (AVR_TINY
1873 && CONSTANT_ADDRESS_P (x))
1874 {
1875 /* avrtiny's load / store instructions only cover addresses 0..0xbf:
1876 IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf. */
1877
1878 ok = (CONST_INT_P (x)
1879 && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode)));
1880 }
1881
1882 if (avr_log.legitimate_address_p)
1883 {
1884 avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1885 "reload_completed=%d reload_in_progress=%d %s:",
1886 ok, mode, strict, reload_completed, reload_in_progress,
1887 reg_renumber ? "(reg_renumber)" : "");
1888
1889 if (GET_CODE (x) == PLUS
1890 && REG_P (XEXP (x, 0))
1891 && CONST_INT_P (XEXP (x, 1))
1892 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1893 && reg_renumber)
1894 {
1895 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1896 true_regnum (XEXP (x, 0)));
1897 }
1898
1899 avr_edump ("\n%r\n", x);
1900 }
1901
1902 return ok;
1903 }
1904
1905
1906 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1907 now only a helper for avr_addr_space_legitimize_address. */
1908 /* Attempts to replace X with a valid
1909 memory address for an operand of mode MODE */
1910
1911 static rtx
1912 avr_legitimize_address (rtx x, rtx oldx, machine_mode mode)
1913 {
1914 bool big_offset_p = false;
1915
1916 x = oldx;
1917
1918 if (GET_CODE (oldx) == PLUS
1919 && REG_P (XEXP (oldx, 0)))
1920 {
1921 if (REG_P (XEXP (oldx, 1)))
1922 x = force_reg (GET_MODE (oldx), oldx);
1923 else if (CONST_INT_P (XEXP (oldx, 1)))
1924 {
1925 int offs = INTVAL (XEXP (oldx, 1));
1926 if (frame_pointer_rtx != XEXP (oldx, 0)
1927 && offs > MAX_LD_OFFSET (mode))
1928 {
1929 big_offset_p = true;
1930 x = force_reg (GET_MODE (oldx), oldx);
1931 }
1932 }
1933 }
1934
1935 if (avr_log.legitimize_address)
1936 {
1937 avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1938
1939 if (x != oldx)
1940 avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1941 }
1942
1943 return x;
1944 }
1945
1946
1947 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */
1948 /* This will allow register R26/27 to be used where it is no worse than normal
1949 base pointers R28/29 or R30/31. For example, if base offset is greater
1950 than 63 bytes or for R++ or --R addressing. */
1951
1952 rtx
1953 avr_legitimize_reload_address (rtx *px, machine_mode mode,
1954 int opnum, int type, int addr_type,
1955 int ind_levels ATTRIBUTE_UNUSED,
1956 rtx (*mk_memloc)(rtx,int))
1957 {
1958 rtx x = *px;
1959
1960 if (avr_log.legitimize_reload_address)
1961 avr_edump ("\n%?:%m %r\n", mode, x);
1962
1963 if (1 && (GET_CODE (x) == POST_INC
1964 || GET_CODE (x) == PRE_DEC))
1965 {
1966 push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1967 POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1968 opnum, RELOAD_OTHER);
1969
1970 if (avr_log.legitimize_reload_address)
1971 avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1972 POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1973
1974 return x;
1975 }
1976
1977 if (GET_CODE (x) == PLUS
1978 && REG_P (XEXP (x, 0))
1979 && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1980 && CONST_INT_P (XEXP (x, 1))
1981 && INTVAL (XEXP (x, 1)) >= 1)
1982 {
1983 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1984
1985 if (fit)
1986 {
1987 if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1988 {
1989 int regno = REGNO (XEXP (x, 0));
1990 rtx mem = mk_memloc (x, regno);
1991
1992 push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
1993 POINTER_REGS, Pmode, VOIDmode, 0, 0,
1994 1, (enum reload_type) addr_type);
1995
1996 if (avr_log.legitimize_reload_address)
1997 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1998 POINTER_REGS, XEXP (mem, 0), NULL_RTX);
1999
2000 push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
2001 BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
2002 opnum, (enum reload_type) type);
2003
2004 if (avr_log.legitimize_reload_address)
2005 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
2006 BASE_POINTER_REGS, mem, NULL_RTX);
2007
2008 return x;
2009 }
2010 }
2011 else if (! (frame_pointer_needed
2012 && XEXP (x, 0) == frame_pointer_rtx))
2013 {
2014 push_reload (x, NULL_RTX, px, NULL,
2015 POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
2016 opnum, (enum reload_type) type);
2017
2018 if (avr_log.legitimize_reload_address)
2019 avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
2020 POINTER_REGS, x, NULL_RTX);
2021
2022 return x;
2023 }
2024 }
2025
2026 return NULL_RTX;
2027 }
2028
2029
2030 /* Implement `TARGET_SECONDARY_RELOAD' */
2031
2032 static reg_class_t
2033 avr_secondary_reload (bool in_p, rtx x,
2034 reg_class_t reload_class ATTRIBUTE_UNUSED,
2035 machine_mode mode, secondary_reload_info *sri)
2036 {
2037 if (in_p
2038 && MEM_P (x)
2039 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
2040 && ADDR_SPACE_MEMX != MEM_ADDR_SPACE (x))
2041 {
2042 /* For the non-generic 16-bit spaces we need a d-class scratch. */
2043
2044 switch (mode)
2045 {
2046 default:
2047 gcc_unreachable();
2048
2049 case QImode: sri->icode = CODE_FOR_reload_inqi; break;
2050 case QQmode: sri->icode = CODE_FOR_reload_inqq; break;
2051 case UQQmode: sri->icode = CODE_FOR_reload_inuqq; break;
2052
2053 case HImode: sri->icode = CODE_FOR_reload_inhi; break;
2054 case HQmode: sri->icode = CODE_FOR_reload_inhq; break;
2055 case HAmode: sri->icode = CODE_FOR_reload_inha; break;
2056 case UHQmode: sri->icode = CODE_FOR_reload_inuhq; break;
2057 case UHAmode: sri->icode = CODE_FOR_reload_inuha; break;
2058
2059 case PSImode: sri->icode = CODE_FOR_reload_inpsi; break;
2060
2061 case SImode: sri->icode = CODE_FOR_reload_insi; break;
2062 case SFmode: sri->icode = CODE_FOR_reload_insf; break;
2063 case SQmode: sri->icode = CODE_FOR_reload_insq; break;
2064 case SAmode: sri->icode = CODE_FOR_reload_insa; break;
2065 case USQmode: sri->icode = CODE_FOR_reload_inusq; break;
2066 case USAmode: sri->icode = CODE_FOR_reload_inusa; break;
2067 }
2068 }
2069
2070 return NO_REGS;
2071 }
2072
2073
2074 /* Helper function to print assembler resp. track instruction
2075 sequence lengths. Always return "".
2076
2077 If PLEN == NULL:
2078 Output assembler code from template TPL with operands supplied
2079 by OPERANDS. This is just forwarding to output_asm_insn.
2080
2081 If PLEN != NULL:
2082 If N_WORDS >= 0 Add N_WORDS to *PLEN.
2083 If N_WORDS < 0 Set *PLEN to -N_WORDS.
2084 Don't output anything.
2085 */
2086
2087 static const char*
2088 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
2089 {
2090 if (NULL == plen)
2091 {
2092 output_asm_insn (tpl, operands);
2093 }
2094 else
2095 {
2096 if (n_words < 0)
2097 *plen = -n_words;
2098 else
2099 *plen += n_words;
2100 }
2101
2102 return "";
2103 }
2104
2105
2106 /* Return a pointer register name as a string. */
2107
2108 static const char*
2109 ptrreg_to_str (int regno)
2110 {
2111 switch (regno)
2112 {
2113 case REG_X: return "X";
2114 case REG_Y: return "Y";
2115 case REG_Z: return "Z";
2116 default:
2117 output_operand_lossage ("address operand requires constraint for"
2118 " X, Y, or Z register");
2119 }
2120 return NULL;
2121 }
2122
2123 /* Return the condition name as a string.
2124 Used in conditional jump constructing */
2125
2126 static const char*
2127 cond_string (enum rtx_code code)
2128 {
2129 switch (code)
2130 {
2131 case NE:
2132 return "ne";
2133 case EQ:
2134 return "eq";
2135 case GE:
2136 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2137 return "pl";
2138 else
2139 return "ge";
2140 case LT:
2141 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2142 return "mi";
2143 else
2144 return "lt";
2145 case GEU:
2146 return "sh";
2147 case LTU:
2148 return "lo";
2149 default:
2150 gcc_unreachable ();
2151 }
2152
2153 return "";
2154 }
2155
2156
2157 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'. */
2158 /* Output ADDR to FILE as address. */
2159
2160 static void
2161 avr_print_operand_address (FILE *file, rtx addr)
2162 {
2163 switch (GET_CODE (addr))
2164 {
2165 case REG:
2166 fprintf (file, ptrreg_to_str (REGNO (addr)));
2167 break;
2168
2169 case PRE_DEC:
2170 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2171 break;
2172
2173 case POST_INC:
2174 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2175 break;
2176
2177 default:
2178 if (CONSTANT_ADDRESS_P (addr)
2179 && text_segment_operand (addr, VOIDmode))
2180 {
2181 rtx x = addr;
2182 if (GET_CODE (x) == CONST)
2183 x = XEXP (x, 0);
2184 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
2185 {
2186 /* Assembler gs() will implant word address. Make offset
2187 a byte offset inside gs() for assembler. This is
2188 needed because the more logical (constant+gs(sym)) is not
2189 accepted by gas. For 128K and smaller devices this is ok.
2190 For large devices it will create a trampoline to offset
2191 from symbol which may not be what the user really wanted. */
2192
2193 fprintf (file, "gs(");
2194 output_addr_const (file, XEXP (x,0));
2195 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
2196 2 * INTVAL (XEXP (x, 1)));
2197 if (AVR_3_BYTE_PC)
2198 if (warning (0, "pointer offset from symbol maybe incorrect"))
2199 {
2200 output_addr_const (stderr, addr);
2201 fprintf(stderr,"\n");
2202 }
2203 }
2204 else
2205 {
2206 fprintf (file, "gs(");
2207 output_addr_const (file, addr);
2208 fprintf (file, ")");
2209 }
2210 }
2211 else
2212 output_addr_const (file, addr);
2213 }
2214 }
2215
2216
2217 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'. */
2218
2219 static bool
2220 avr_print_operand_punct_valid_p (unsigned char code)
2221 {
2222 return code == '~' || code == '!';
2223 }
2224
2225
2226 /* Implement `TARGET_PRINT_OPERAND'. */
2227 /* Output X as assembler operand to file FILE.
2228 For a description of supported %-codes, see top of avr.md. */
2229
2230 static void
2231 avr_print_operand (FILE *file, rtx x, int code)
2232 {
2233 int abcd = 0, ef = 0, ij = 0;
2234
2235 if (code >= 'A' && code <= 'D')
2236 abcd = code - 'A';
2237 else if (code == 'E' || code == 'F')
2238 ef = code - 'E';
2239 else if (code == 'I' || code == 'J')
2240 ij = code - 'I';
2241
2242 if (code == '~')
2243 {
2244 if (!AVR_HAVE_JMP_CALL)
2245 fputc ('r', file);
2246 }
2247 else if (code == '!')
2248 {
2249 if (AVR_HAVE_EIJMP_EICALL)
2250 fputc ('e', file);
2251 }
2252 else if (code == 't'
2253 || code == 'T')
2254 {
2255 static int t_regno = -1;
2256 static int t_nbits = -1;
2257
2258 if (REG_P (x) && t_regno < 0 && code == 'T')
2259 {
2260 t_regno = REGNO (x);
2261 t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
2262 }
2263 else if (CONST_INT_P (x) && t_regno >= 0
2264 && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
2265 {
2266 int bpos = INTVAL (x);
2267
2268 fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
2269 if (code == 'T')
2270 fprintf (file, ",%d", bpos % 8);
2271
2272 t_regno = -1;
2273 }
2274 else
2275 fatal_insn ("operands to %T/%t must be reg + const_int:", x);
2276 }
2277 else if (code == 'E' || code == 'F')
2278 {
2279 rtx op = XEXP(x, 0);
2280 fprintf (file, reg_names[REGNO (op) + ef]);
2281 }
2282 else if (code == 'I' || code == 'J')
2283 {
2284 rtx op = XEXP(XEXP(x, 0), 0);
2285 fprintf (file, reg_names[REGNO (op) + ij]);
2286 }
2287 else if (REG_P (x))
2288 {
2289 if (x == zero_reg_rtx)
2290 fprintf (file, "__zero_reg__");
2291 else if (code == 'r' && REGNO (x) < 32)
2292 fprintf (file, "%d", (int) REGNO (x));
2293 else
2294 fprintf (file, reg_names[REGNO (x) + abcd]);
2295 }
2296 else if (CONST_INT_P (x))
2297 {
2298 HOST_WIDE_INT ival = INTVAL (x);
2299
2300 if ('i' != code)
2301 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
2302 else if (low_io_address_operand (x, VOIDmode)
2303 || high_io_address_operand (x, VOIDmode))
2304 {
2305 if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
2306 fprintf (file, "__RAMPZ__");
2307 else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
2308 fprintf (file, "__RAMPY__");
2309 else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
2310 fprintf (file, "__RAMPX__");
2311 else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
2312 fprintf (file, "__RAMPD__");
2313 else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
2314 fprintf (file, "__CCP__");
2315 else if (ival == avr_addr.sreg) fprintf (file, "__SREG__");
2316 else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__");
2317 else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__");
2318 else
2319 {
2320 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
2321 ival - avr_arch->sfr_offset);
2322 }
2323 }
2324 else
2325 fatal_insn ("bad address, not an I/O address:", x);
2326 }
2327 else if (MEM_P (x))
2328 {
2329 rtx addr = XEXP (x, 0);
2330
2331 if (code == 'm')
2332 {
2333 if (!CONSTANT_P (addr))
2334 fatal_insn ("bad address, not a constant:", addr);
2335 /* Assembler template with m-code is data - not progmem section */
2336 if (text_segment_operand (addr, VOIDmode))
2337 if (warning (0, "accessing data memory with"
2338 " program memory address"))
2339 {
2340 output_addr_const (stderr, addr);
2341 fprintf(stderr,"\n");
2342 }
2343 output_addr_const (file, addr);
2344 }
2345 else if (code == 'i')
2346 {
2347 avr_print_operand (file, addr, 'i');
2348 }
2349 else if (code == 'o')
2350 {
2351 if (GET_CODE (addr) != PLUS)
2352 fatal_insn ("bad address, not (reg+disp):", addr);
2353
2354 avr_print_operand (file, XEXP (addr, 1), 0);
2355 }
2356 else if (code == 'b')
2357 {
2358 if (GET_CODE (addr) != PLUS)
2359 fatal_insn ("bad address, not (reg+disp):", addr);
2360
2361 avr_print_operand_address (file, XEXP (addr, 0));
2362 }
2363 else if (code == 'p' || code == 'r')
2364 {
2365 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
2366 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
2367
2368 if (code == 'p')
2369 avr_print_operand_address (file, XEXP (addr, 0)); /* X, Y, Z */
2370 else
2371 avr_print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
2372 }
2373 else if (GET_CODE (addr) == PLUS)
2374 {
2375 avr_print_operand_address (file, XEXP (addr,0));
2376 if (REGNO (XEXP (addr, 0)) == REG_X)
2377 fatal_insn ("internal compiler error. Bad address:"
2378 ,addr);
2379 fputc ('+', file);
2380 avr_print_operand (file, XEXP (addr,1), code);
2381 }
2382 else
2383 avr_print_operand_address (file, addr);
2384 }
2385 else if (code == 'i')
2386 {
2387 if (GET_CODE (x) == SYMBOL_REF && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO))
2388 avr_print_operand_address
2389 (file, plus_constant (HImode, x, -avr_arch->sfr_offset));
2390 else
2391 fatal_insn ("bad address, not an I/O address:", x);
2392 }
2393 else if (code == 'x')
2394 {
2395 /* Constant progmem address - like used in jmp or call */
2396 if (0 == text_segment_operand (x, VOIDmode))
2397 if (warning (0, "accessing program memory"
2398 " with data memory address"))
2399 {
2400 output_addr_const (stderr, x);
2401 fprintf(stderr,"\n");
2402 }
2403 /* Use normal symbol for direct address no linker trampoline needed */
2404 output_addr_const (file, x);
2405 }
2406 else if (CONST_FIXED_P (x))
2407 {
2408 HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
2409 if (code != 0)
2410 output_operand_lossage ("Unsupported code '%c' for fixed-point:",
2411 code);
2412 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
2413 }
2414 else if (GET_CODE (x) == CONST_DOUBLE)
2415 {
2416 long val;
2417 if (GET_MODE (x) != SFmode)
2418 fatal_insn ("internal compiler error. Unknown mode:", x);
2419 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
2420 fprintf (file, "0x%lx", val);
2421 }
2422 else if (GET_CODE (x) == CONST_STRING)
2423 fputs (XSTR (x, 0), file);
2424 else if (code == 'j')
2425 fputs (cond_string (GET_CODE (x)), file);
2426 else if (code == 'k')
2427 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
2428 else
2429 avr_print_operand_address (file, x);
2430 }
2431
2432
2433 /* Worker function for `NOTICE_UPDATE_CC'. */
2434 /* Update the condition code in the INSN. */
2435
2436 void
2437 avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx_insn *insn)
2438 {
2439 rtx set;
2440 enum attr_cc cc = get_attr_cc (insn);
2441
2442 switch (cc)
2443 {
2444 default:
2445 break;
2446
2447 case CC_PLUS:
2448 case CC_LDI:
2449 {
2450 rtx *op = recog_data.operand;
2451 int len_dummy, icc;
2452
2453 /* Extract insn's operands. */
2454 extract_constrain_insn_cached (insn);
2455
2456 switch (cc)
2457 {
2458 default:
2459 gcc_unreachable();
2460
2461 case CC_PLUS:
2462 avr_out_plus (insn, op, &len_dummy, &icc);
2463 cc = (enum attr_cc) icc;
2464 break;
2465
2466 case CC_LDI:
2467
2468 cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
2469 && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
2470 /* Loading zero-reg with 0 uses CLR and thus clobbers cc0. */
2471 ? CC_CLOBBER
2472 /* Any other "r,rL" combination does not alter cc0. */
2473 : CC_NONE;
2474
2475 break;
2476 } /* inner switch */
2477
2478 break;
2479 }
2480 } /* outer swicth */
2481
2482 switch (cc)
2483 {
2484 default:
2485 /* Special values like CC_OUT_PLUS from above have been
2486 mapped to "standard" CC_* values so we never come here. */
2487
2488 gcc_unreachable();
2489 break;
2490
2491 case CC_NONE:
2492 /* Insn does not affect CC at all. */
2493 break;
2494
2495 case CC_SET_N:
2496 CC_STATUS_INIT;
2497 break;
2498
2499 case CC_SET_ZN:
2500 set = single_set (insn);
2501 CC_STATUS_INIT;
2502 if (set)
2503 {
2504 cc_status.flags |= CC_NO_OVERFLOW;
2505 cc_status.value1 = SET_DEST (set);
2506 }
2507 break;
2508
2509 case CC_SET_VZN:
2510 /* Insn like INC, DEC, NEG that set Z,N,V. We currently don't make use
2511 of this combination, cf. also PR61055. */
2512 CC_STATUS_INIT;
2513 break;
2514
2515 case CC_SET_CZN:
2516 /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2517 The V flag may or may not be known but that's ok because
2518 alter_cond will change tests to use EQ/NE. */
2519 set = single_set (insn);
2520 CC_STATUS_INIT;
2521 if (set)
2522 {
2523 cc_status.value1 = SET_DEST (set);
2524 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2525 }
2526 break;
2527
2528 case CC_COMPARE:
2529 set = single_set (insn);
2530 CC_STATUS_INIT;
2531 if (set)
2532 cc_status.value1 = SET_SRC (set);
2533 break;
2534
2535 case CC_CLOBBER:
2536 /* Insn doesn't leave CC in a usable state. */
2537 CC_STATUS_INIT;
2538 break;
2539 }
2540 }
2541
2542 /* Choose mode for jump insn:
2543 1 - relative jump in range -63 <= x <= 62 ;
2544 2 - relative jump in range -2046 <= x <= 2045 ;
2545 3 - absolute jump (only for ATmega[16]03). */
2546
2547 int
2548 avr_jump_mode (rtx x, rtx_insn *insn)
2549 {
2550 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2551 ? XEXP (x, 0) : x));
2552 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2553 int jump_distance = cur_addr - dest_addr;
2554
2555 if (-63 <= jump_distance && jump_distance <= 62)
2556 return 1;
2557 else if (-2046 <= jump_distance && jump_distance <= 2045)
2558 return 2;
2559 else if (AVR_HAVE_JMP_CALL)
2560 return 3;
2561
2562 return 2;
2563 }
2564
2565 /* Return an AVR condition jump commands.
2566 X is a comparison RTX.
2567 LEN is a number returned by avr_jump_mode function.
2568 If REVERSE nonzero then condition code in X must be reversed. */
2569
2570 const char*
2571 ret_cond_branch (rtx x, int len, int reverse)
2572 {
2573 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2574
2575 switch (cond)
2576 {
2577 case GT:
2578 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2579 return (len == 1 ? ("breq .+2" CR_TAB
2580 "brpl %0") :
2581 len == 2 ? ("breq .+4" CR_TAB
2582 "brmi .+2" CR_TAB
2583 "rjmp %0") :
2584 ("breq .+6" CR_TAB
2585 "brmi .+4" CR_TAB
2586 "jmp %0"));
2587
2588 else
2589 return (len == 1 ? ("breq .+2" CR_TAB
2590 "brge %0") :
2591 len == 2 ? ("breq .+4" CR_TAB
2592 "brlt .+2" CR_TAB
2593 "rjmp %0") :
2594 ("breq .+6" CR_TAB
2595 "brlt .+4" CR_TAB
2596 "jmp %0"));
2597 case GTU:
2598 return (len == 1 ? ("breq .+2" CR_TAB
2599 "brsh %0") :
2600 len == 2 ? ("breq .+4" CR_TAB
2601 "brlo .+2" CR_TAB
2602 "rjmp %0") :
2603 ("breq .+6" CR_TAB
2604 "brlo .+4" CR_TAB
2605 "jmp %0"));
2606 case LE:
2607 if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2608 return (len == 1 ? ("breq %0" CR_TAB
2609 "brmi %0") :
2610 len == 2 ? ("breq .+2" CR_TAB
2611 "brpl .+2" CR_TAB
2612 "rjmp %0") :
2613 ("breq .+2" CR_TAB
2614 "brpl .+4" CR_TAB
2615 "jmp %0"));
2616 else
2617 return (len == 1 ? ("breq %0" CR_TAB
2618 "brlt %0") :
2619 len == 2 ? ("breq .+2" CR_TAB
2620 "brge .+2" CR_TAB
2621 "rjmp %0") :
2622 ("breq .+2" CR_TAB
2623 "brge .+4" CR_TAB
2624 "jmp %0"));
2625 case LEU:
2626 return (len == 1 ? ("breq %0" CR_TAB
2627 "brlo %0") :
2628 len == 2 ? ("breq .+2" CR_TAB
2629 "brsh .+2" CR_TAB
2630 "rjmp %0") :
2631 ("breq .+2" CR_TAB
2632 "brsh .+4" CR_TAB
2633 "jmp %0"));
2634 default:
2635 if (reverse)
2636 {
2637 switch (len)
2638 {
2639 case 1:
2640 return "br%k1 %0";
2641 case 2:
2642 return ("br%j1 .+2" CR_TAB
2643 "rjmp %0");
2644 default:
2645 return ("br%j1 .+4" CR_TAB
2646 "jmp %0");
2647 }
2648 }
2649 else
2650 {
2651 switch (len)
2652 {
2653 case 1:
2654 return "br%j1 %0";
2655 case 2:
2656 return ("br%k1 .+2" CR_TAB
2657 "rjmp %0");
2658 default:
2659 return ("br%k1 .+4" CR_TAB
2660 "jmp %0");
2661 }
2662 }
2663 }
2664 return "";
2665 }
2666
2667
2668 /* Worker function for `FINAL_PRESCAN_INSN'. */
2669 /* Output insn cost for next insn. */
2670
2671 void
2672 avr_final_prescan_insn (rtx_insn *insn, rtx *operand ATTRIBUTE_UNUSED,
2673 int num_operands ATTRIBUTE_UNUSED)
2674 {
2675 if (avr_log.rtx_costs)
2676 {
2677 rtx set = single_set (insn);
2678
2679 if (set)
2680 fprintf (asm_out_file, "/* DEBUG: cost = %d. */\n",
2681 set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)),
2682 optimize_insn_for_speed_p ()));
2683 else
2684 fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d. */\n",
2685 rtx_cost (PATTERN (insn), VOIDmode, INSN, 0,
2686 optimize_insn_for_speed_p()));
2687 }
2688 }
2689
2690 /* Return 0 if undefined, 1 if always true or always false. */
2691
2692 int
2693 avr_simplify_comparison_p (machine_mode mode, RTX_CODE op, rtx x)
2694 {
2695 unsigned int max = (mode == QImode ? 0xff :
2696 mode == HImode ? 0xffff :
2697 mode == PSImode ? 0xffffff :
2698 mode == SImode ? 0xffffffff : 0);
2699 if (max && op && CONST_INT_P (x))
2700 {
2701 if (unsigned_condition (op) != op)
2702 max >>= 1;
2703
2704 if (max != (INTVAL (x) & max)
2705 && INTVAL (x) != 0xff)
2706 return 1;
2707 }
2708 return 0;
2709 }
2710
2711
2712 /* Worker function for `FUNCTION_ARG_REGNO_P'. */
2713 /* Returns nonzero if REGNO is the number of a hard
2714 register in which function arguments are sometimes passed. */
2715
2716 int
2717 avr_function_arg_regno_p(int r)
2718 {
2719 return (AVR_TINY ? r >= 20 && r <= 25 : r >= 8 && r <= 25);
2720 }
2721
2722
2723 /* Worker function for `INIT_CUMULATIVE_ARGS'. */
2724 /* Initializing the variable cum for the state at the beginning
2725 of the argument list. */
2726
2727 void
2728 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2729 tree fndecl ATTRIBUTE_UNUSED)
2730 {
2731 cum->nregs = AVR_TINY ? 6 : 18;
2732 cum->regno = FIRST_CUM_REG;
2733 if (!libname && stdarg_p (fntype))
2734 cum->nregs = 0;
2735
2736 /* Assume the calle may be tail called */
2737
2738 cfun->machine->sibcall_fails = 0;
2739 }
2740
2741 /* Returns the number of registers to allocate for a function argument. */
2742
2743 static int
2744 avr_num_arg_regs (machine_mode mode, const_tree type)
2745 {
2746 int size;
2747
2748 if (mode == BLKmode)
2749 size = int_size_in_bytes (type);
2750 else
2751 size = GET_MODE_SIZE (mode);
2752
2753 /* Align all function arguments to start in even-numbered registers.
2754 Odd-sized arguments leave holes above them. */
2755
2756 return (size + 1) & ~1;
2757 }
2758
2759
2760 /* Implement `TARGET_FUNCTION_ARG'. */
2761 /* Controls whether a function argument is passed
2762 in a register, and which register. */
2763
2764 static rtx
2765 avr_function_arg (cumulative_args_t cum_v, machine_mode mode,
2766 const_tree type, bool named ATTRIBUTE_UNUSED)
2767 {
2768 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2769 int bytes = avr_num_arg_regs (mode, type);
2770
2771 if (cum->nregs && bytes <= cum->nregs)
2772 return gen_rtx_REG (mode, cum->regno - bytes);
2773
2774 return NULL_RTX;
2775 }
2776
2777
2778 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'. */
2779 /* Update the summarizer variable CUM to advance past an argument
2780 in the argument list. */
2781
2782 static void
2783 avr_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2784 const_tree type, bool named ATTRIBUTE_UNUSED)
2785 {
2786 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2787 int bytes = avr_num_arg_regs (mode, type);
2788
2789 cum->nregs -= bytes;
2790 cum->regno -= bytes;
2791
2792 /* A parameter is being passed in a call-saved register. As the original
2793 contents of these regs has to be restored before leaving the function,
2794 a function must not pass arguments in call-saved regs in order to get
2795 tail-called. */
2796
2797 if (cum->regno >= 8
2798 && cum->nregs >= 0
2799 && !call_used_regs[cum->regno])
2800 {
2801 /* FIXME: We ship info on failing tail-call in struct machine_function.
2802 This uses internals of calls.c:expand_call() and the way args_so_far
2803 is used. targetm.function_ok_for_sibcall() needs to be extended to
2804 pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
2805 dependent so that such an extension is not wanted. */
2806
2807 cfun->machine->sibcall_fails = 1;
2808 }
2809
2810 /* Test if all registers needed by the ABI are actually available. If the
2811 user has fixed a GPR needed to pass an argument, an (implicit) function
2812 call will clobber that fixed register. See PR45099 for an example. */
2813
2814 if (cum->regno >= 8
2815 && cum->nregs >= 0)
2816 {
2817 int regno;
2818
2819 for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2820 if (fixed_regs[regno])
2821 warning (0, "fixed register %s used to pass parameter to function",
2822 reg_names[regno]);
2823 }
2824
2825 if (cum->nregs <= 0)
2826 {
2827 cum->nregs = 0;
2828 cum->regno = FIRST_CUM_REG;
2829 }
2830 }
2831
2832 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2833 /* Decide whether we can make a sibling call to a function. DECL is the
2834 declaration of the function being targeted by the call and EXP is the
2835 CALL_EXPR representing the call. */
2836
2837 static bool
2838 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2839 {
2840 tree fntype_callee;
2841
2842 /* Tail-calling must fail if callee-saved regs are used to pass
2843 function args. We must not tail-call when `epilogue_restores'
2844 is used. Unfortunately, we cannot tell at this point if that
2845 actually will happen or not, and we cannot step back from
2846 tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
2847
2848 if (cfun->machine->sibcall_fails
2849 || TARGET_CALL_PROLOGUES)
2850 {
2851 return false;
2852 }
2853
2854 fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2855
2856 if (decl_callee)
2857 {
2858 decl_callee = TREE_TYPE (decl_callee);
2859 }
2860 else
2861 {
2862 decl_callee = fntype_callee;
2863
2864 while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2865 && METHOD_TYPE != TREE_CODE (decl_callee))
2866 {
2867 decl_callee = TREE_TYPE (decl_callee);
2868 }
2869 }
2870
2871 /* Ensure that caller and callee have compatible epilogues */
2872
2873 if (cfun->machine->is_interrupt
2874 || cfun->machine->is_signal
2875 || cfun->machine->is_naked
2876 || avr_naked_function_p (decl_callee)
2877 /* FIXME: For OS_task and OS_main, this might be over-conservative. */
2878 || (avr_OS_task_function_p (decl_callee)
2879 != cfun->machine->is_OS_task)
2880 || (avr_OS_main_function_p (decl_callee)
2881 != cfun->machine->is_OS_main))
2882 {
2883 return false;
2884 }
2885
2886 return true;
2887 }
2888
2889 /***********************************************************************
2890 Functions for outputting various mov's for a various modes
2891 ************************************************************************/
2892
2893 /* Return true if a value of mode MODE is read from flash by
2894 __load_* function from libgcc. */
2895
2896 bool
2897 avr_load_libgcc_p (rtx op)
2898 {
2899 machine_mode mode = GET_MODE (op);
2900 int n_bytes = GET_MODE_SIZE (mode);
2901
2902 return (n_bytes > 2
2903 && !AVR_HAVE_LPMX
2904 && avr_mem_flash_p (op));
2905 }
2906
2907 /* Return true if a value of mode MODE is read by __xload_* function. */
2908
2909 bool
2910 avr_xload_libgcc_p (machine_mode mode)
2911 {
2912 int n_bytes = GET_MODE_SIZE (mode);
2913
2914 return (n_bytes > 1
2915 || avr_n_flash > 1);
2916 }
2917
2918
2919 /* Fixme: This is a hack because secondary reloads don't works as expected.
2920
2921 Find an unused d-register to be used as scratch in INSN.
2922 EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
2923 is a register, skip all possible return values that overlap EXCLUDE.
2924 The policy for the returned register is similar to that of
2925 `reg_unused_after', i.e. the returned register may overlap the SET_DEST
2926 of INSN.
2927
2928 Return a QImode d-register or NULL_RTX if nothing found. */
2929
2930 static rtx
2931 avr_find_unused_d_reg (rtx_insn *insn, rtx exclude)
2932 {
2933 int regno;
2934 bool isr_p = (avr_interrupt_function_p (current_function_decl)
2935 || avr_signal_function_p (current_function_decl));
2936
2937 for (regno = 16; regno < 32; regno++)
2938 {
2939 rtx reg = all_regs_rtx[regno];
2940
2941 if ((exclude
2942 && reg_overlap_mentioned_p (exclude, reg))
2943 || fixed_regs[regno])
2944 {
2945 continue;
2946 }
2947
2948 /* Try non-live register */
2949
2950 if (!df_regs_ever_live_p (regno)
2951 && (TREE_THIS_VOLATILE (current_function_decl)
2952 || cfun->machine->is_OS_task
2953 || cfun->machine->is_OS_main
2954 || (!isr_p && call_used_regs[regno])))
2955 {
2956 return reg;
2957 }
2958
2959 /* Any live register can be used if it is unused after.
2960 Prologue/epilogue will care for it as needed. */
2961
2962 if (df_regs_ever_live_p (regno)
2963 && reg_unused_after (insn, reg))
2964 {
2965 return reg;
2966 }
2967 }
2968
2969 return NULL_RTX;
2970 }
2971
2972
2973 /* Helper function for the next function in the case where only restricted
2974 version of LPM instruction is available. */
2975
2976 static const char*
2977 avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
2978 {
2979 rtx dest = xop[0];
2980 rtx addr = xop[1];
2981 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2982 int regno_dest;
2983
2984 regno_dest = REGNO (dest);
2985
2986 /* The implicit target register of LPM. */
2987 xop[3] = lpm_reg_rtx;
2988
2989 switch (GET_CODE (addr))
2990 {
2991 default:
2992 gcc_unreachable();
2993
2994 case REG:
2995
2996 gcc_assert (REG_Z == REGNO (addr));
2997
2998 switch (n_bytes)
2999 {
3000 default:
3001 gcc_unreachable();
3002
3003 case 1:
3004 avr_asm_len ("%4lpm", xop, plen, 1);
3005
3006 if (regno_dest != LPM_REGNO)
3007 avr_asm_len ("mov %0,%3", xop, plen, 1);
3008
3009 return "";
3010
3011 case 2:
3012 if (REGNO (dest) == REG_Z)
3013 return avr_asm_len ("%4lpm" CR_TAB
3014 "push %3" CR_TAB
3015 "adiw %2,1" CR_TAB
3016 "%4lpm" CR_TAB
3017 "mov %B0,%3" CR_TAB
3018 "pop %A0", xop, plen, 6);
3019
3020 avr_asm_len ("%4lpm" CR_TAB
3021 "mov %A0,%3" CR_TAB
3022 "adiw %2,1" CR_TAB
3023 "%4lpm" CR_TAB
3024 "mov %B0,%3", xop, plen, 5);
3025
3026 if (!reg_unused_after (insn, addr))
3027 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3028
3029 break; /* 2 */
3030 }
3031
3032 break; /* REG */
3033
3034 case POST_INC:
3035
3036 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3037 && n_bytes <= 4);
3038
3039 if (regno_dest == LPM_REGNO)
3040 avr_asm_len ("%4lpm" CR_TAB
3041 "adiw %2,1", xop, plen, 2);
3042 else
3043 avr_asm_len ("%4lpm" CR_TAB
3044 "mov %A0,%3" CR_TAB
3045 "adiw %2,1", xop, plen, 3);
3046
3047 if (n_bytes >= 2)
3048 avr_asm_len ("%4lpm" CR_TAB
3049 "mov %B0,%3" CR_TAB
3050 "adiw %2,1", xop, plen, 3);
3051
3052 if (n_bytes >= 3)
3053 avr_asm_len ("%4lpm" CR_TAB
3054 "mov %C0,%3" CR_TAB
3055 "adiw %2,1", xop, plen, 3);
3056
3057 if (n_bytes >= 4)
3058 avr_asm_len ("%4lpm" CR_TAB
3059 "mov %D0,%3" CR_TAB
3060 "adiw %2,1", xop, plen, 3);
3061
3062 break; /* POST_INC */
3063
3064 } /* switch CODE (addr) */
3065
3066 return "";
3067 }
3068
3069
3070 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
3071 OP[1] in AS1 to register OP[0].
3072 If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
3073 Return "". */
3074
3075 const char*
3076 avr_out_lpm (rtx_insn *insn, rtx *op, int *plen)
3077 {
3078 rtx xop[7];
3079 rtx dest = op[0];
3080 rtx src = SET_SRC (single_set (insn));
3081 rtx addr;
3082 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
3083 int segment;
3084 RTX_CODE code;
3085 addr_space_t as = MEM_ADDR_SPACE (src);
3086
3087 if (plen)
3088 *plen = 0;
3089
3090 if (MEM_P (dest))
3091 {
3092 warning (0, "writing to address space %qs not supported",
3093 avr_addrspace[MEM_ADDR_SPACE (dest)].name);
3094
3095 return "";
3096 }
3097
3098 addr = XEXP (src, 0);
3099 code = GET_CODE (addr);
3100
3101 gcc_assert (REG_P (dest));
3102 gcc_assert (REG == code || POST_INC == code);
3103
3104 xop[0] = dest;
3105 xop[1] = addr;
3106 xop[2] = lpm_addr_reg_rtx;
3107 xop[4] = xstring_empty;
3108 xop[5] = tmp_reg_rtx;
3109 xop[6] = XEXP (rampz_rtx, 0);
3110
3111 segment = avr_addrspace[as].segment;
3112
3113 /* Set RAMPZ as needed. */
3114
3115 if (segment)
3116 {
3117 xop[4] = GEN_INT (segment);
3118 xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
3119
3120 if (xop[3] != NULL_RTX)
3121 {
3122 avr_asm_len ("ldi %3,%4" CR_TAB
3123 "out %i6,%3", xop, plen, 2);
3124 }
3125 else if (segment == 1)
3126 {
3127 avr_asm_len ("clr %5" CR_TAB
3128 "inc %5" CR_TAB
3129 "out %i6,%5", xop, plen, 3);
3130 }
3131 else
3132 {
3133 avr_asm_len ("mov %5,%2" CR_TAB
3134 "ldi %2,%4" CR_TAB
3135 "out %i6,%2" CR_TAB
3136 "mov %2,%5", xop, plen, 4);
3137 }
3138
3139 xop[4] = xstring_e;
3140
3141 if (!AVR_HAVE_ELPMX)
3142 return avr_out_lpm_no_lpmx (insn, xop, plen);
3143 }
3144 else if (!AVR_HAVE_LPMX)
3145 {
3146 return avr_out_lpm_no_lpmx (insn, xop, plen);
3147 }
3148
3149 /* We have [E]LPMX: Output reading from Flash the comfortable way. */
3150
3151 switch (GET_CODE (addr))
3152 {
3153 default:
3154 gcc_unreachable();
3155
3156 case REG:
3157
3158 gcc_assert (REG_Z == REGNO (addr));
3159
3160 switch (n_bytes)
3161 {
3162 default:
3163 gcc_unreachable();
3164
3165 case 1:
3166 return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
3167
3168 case 2:
3169 if (REGNO (dest) == REG_Z)
3170 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3171 "%4lpm %B0,%a2" CR_TAB
3172 "mov %A0,%5", xop, plen, 3);
3173 else
3174 {
3175 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3176 "%4lpm %B0,%a2", xop, plen, 2);
3177
3178 if (!reg_unused_after (insn, addr))
3179 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3180 }
3181
3182 break; /* 2 */
3183
3184 case 3:
3185
3186 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3187 "%4lpm %B0,%a2+" CR_TAB
3188 "%4lpm %C0,%a2", xop, plen, 3);
3189
3190 if (!reg_unused_after (insn, addr))
3191 avr_asm_len ("sbiw %2,2", xop, plen, 1);
3192
3193 break; /* 3 */
3194
3195 case 4:
3196
3197 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3198 "%4lpm %B0,%a2+", xop, plen, 2);
3199
3200 if (REGNO (dest) == REG_Z - 2)
3201 return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3202 "%4lpm %C0,%a2" CR_TAB
3203 "mov %D0,%5", xop, plen, 3);
3204 else
3205 {
3206 avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
3207 "%4lpm %D0,%a2", xop, plen, 2);
3208
3209 if (!reg_unused_after (insn, addr))
3210 avr_asm_len ("sbiw %2,3", xop, plen, 1);
3211 }
3212
3213 break; /* 4 */
3214 } /* n_bytes */
3215
3216 break; /* REG */
3217
3218 case POST_INC:
3219
3220 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3221 && n_bytes <= 4);
3222
3223 avr_asm_len ("%4lpm %A0,%a2+", xop, plen, 1);
3224 if (n_bytes >= 2) avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
3225 if (n_bytes >= 3) avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
3226 if (n_bytes >= 4) avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
3227
3228 break; /* POST_INC */
3229
3230 } /* switch CODE (addr) */
3231
3232 if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
3233 {
3234 /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM. */
3235
3236 xop[0] = zero_reg_rtx;
3237 avr_asm_len ("out %i6,%0", xop, plen, 1);
3238 }
3239
3240 return "";
3241 }
3242
3243
3244 /* Worker function for xload_8 insn. */
3245
3246 const char*
3247 avr_out_xload (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
3248 {
3249 rtx xop[4];
3250
3251 xop[0] = op[0];
3252 xop[1] = op[1];
3253 xop[2] = lpm_addr_reg_rtx;
3254 xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
3255
3256 avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, -1);
3257
3258 avr_asm_len ("sbrc %1,7" CR_TAB
3259 "ld %3,%a2", xop, plen, 2);
3260
3261 if (REGNO (xop[0]) != REGNO (xop[3]))
3262 avr_asm_len ("mov %0,%3", xop, plen, 1);
3263
3264 return "";
3265 }
3266
3267
3268 const char*
3269 output_movqi (rtx_insn *insn, rtx operands[], int *plen)
3270 {
3271 rtx dest = operands[0];
3272 rtx src = operands[1];
3273
3274 if (avr_mem_flash_p (src)
3275 || avr_mem_flash_p (dest))
3276 {
3277 return avr_out_lpm (insn, operands, plen);
3278 }
3279
3280 gcc_assert (1 == GET_MODE_SIZE (GET_MODE (dest)));
3281
3282 if (REG_P (dest))
3283 {
3284 if (REG_P (src)) /* mov r,r */
3285 {
3286 if (test_hard_reg_class (STACK_REG, dest))
3287 return avr_asm_len ("out %0,%1", operands, plen, -1);
3288 else if (test_hard_reg_class (STACK_REG, src))
3289 return avr_asm_len ("in %0,%1", operands, plen, -1);
3290
3291 return avr_asm_len ("mov %0,%1", operands, plen, -1);
3292 }
3293 else if (CONSTANT_P (src))
3294 {
3295 output_reload_in_const (operands, NULL_RTX, plen, false);
3296 return "";
3297 }
3298 else if (MEM_P (src))
3299 return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
3300 }
3301 else if (MEM_P (dest))
3302 {
3303 rtx xop[2];
3304
3305 xop[0] = dest;
3306 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3307
3308 return out_movqi_mr_r (insn, xop, plen);
3309 }
3310
3311 return "";
3312 }
3313
3314
3315 const char *
3316 output_movhi (rtx_insn *insn, rtx xop[], int *plen)
3317 {
3318 rtx dest = xop[0];
3319 rtx src = xop[1];
3320
3321 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
3322
3323 if (avr_mem_flash_p (src)
3324 || avr_mem_flash_p (dest))
3325 {
3326 return avr_out_lpm (insn, xop, plen);
3327 }
3328
3329 gcc_assert (2 == GET_MODE_SIZE (GET_MODE (dest)));
3330
3331 if (REG_P (dest))
3332 {
3333 if (REG_P (src)) /* mov r,r */
3334 {
3335 if (test_hard_reg_class (STACK_REG, dest))
3336 {
3337 if (AVR_HAVE_8BIT_SP)
3338 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
3339
3340 if (AVR_XMEGA)
3341 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
3342 "out __SP_H__,%B1", xop, plen, -2);
3343
3344 /* Use simple load of SP if no interrupts are used. */
3345
3346 return TARGET_NO_INTERRUPTS
3347 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
3348 "out __SP_L__,%A1", xop, plen, -2)
3349 : avr_asm_len ("in __tmp_reg__,__SREG__" CR_TAB
3350 "cli" CR_TAB
3351 "out __SP_H__,%B1" CR_TAB
3352 "out __SREG__,__tmp_reg__" CR_TAB
3353 "out __SP_L__,%A1", xop, plen, -5);
3354 }
3355 else if (test_hard_reg_class (STACK_REG, src))
3356 {
3357 return !AVR_HAVE_SPH
3358 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
3359 "clr %B0", xop, plen, -2)
3360
3361 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
3362 "in %B0,__SP_H__", xop, plen, -2);
3363 }
3364
3365 return AVR_HAVE_MOVW
3366 ? avr_asm_len ("movw %0,%1", xop, plen, -1)
3367
3368 : avr_asm_len ("mov %A0,%A1" CR_TAB
3369 "mov %B0,%B1", xop, plen, -2);
3370 } /* REG_P (src) */
3371 else if (CONSTANT_P (src))
3372 {
3373 return output_reload_inhi (xop, NULL, plen);
3374 }
3375 else if (MEM_P (src))
3376 {
3377 return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
3378 }
3379 }
3380 else if (MEM_P (dest))
3381 {
3382 rtx xop[2];
3383
3384 xop[0] = dest;
3385 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3386
3387 return out_movhi_mr_r (insn, xop, plen);
3388 }
3389
3390 fatal_insn ("invalid insn:", insn);
3391
3392 return "";
3393 }
3394
3395
3396 /* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
3397
3398 static const char*
3399 avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
3400 {
3401 rtx dest = op[0];
3402 rtx src = op[1];
3403 rtx x = XEXP (src, 0);
3404
3405 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3406 "ld %0,%b1" , op, plen, -3);
3407
3408 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3409 && !reg_unused_after (insn, XEXP (x,0)))
3410 avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
3411
3412 return "";
3413 }
3414
3415 static const char*
3416 out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3417 {
3418 rtx dest = op[0];
3419 rtx src = op[1];
3420 rtx x = XEXP (src, 0);
3421
3422 if (CONSTANT_ADDRESS_P (x))
3423 {
3424 int n_words = AVR_TINY ? 1 : 2;
3425 return optimize > 0 && io_address_operand (x, QImode)
3426 ? avr_asm_len ("in %0,%i1", op, plen, -1)
3427 : avr_asm_len ("lds %0,%m1", op, plen, -n_words);
3428 }
3429
3430 if (GET_CODE (x) == PLUS
3431 && REG_P (XEXP (x, 0))
3432 && CONST_INT_P (XEXP (x, 1)))
3433 {
3434 /* memory access by reg+disp */
3435
3436 int disp = INTVAL (XEXP (x, 1));
3437
3438 if (AVR_TINY)
3439 return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
3440
3441 if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
3442 {
3443 if (REGNO (XEXP (x, 0)) != REG_Y)
3444 fatal_insn ("incorrect insn:",insn);
3445
3446 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3447 return avr_asm_len ("adiw r28,%o1-63" CR_TAB
3448 "ldd %0,Y+63" CR_TAB
3449 "sbiw r28,%o1-63", op, plen, -3);
3450
3451 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3452 "sbci r29,hi8(-%o1)" CR_TAB
3453 "ld %0,Y" CR_TAB
3454 "subi r28,lo8(%o1)" CR_TAB
3455 "sbci r29,hi8(%o1)", op, plen, -5);
3456 }
3457 else if (REGNO (XEXP (x, 0)) == REG_X)
3458 {
3459 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
3460 it but I have this situation with extremal optimizing options. */
3461
3462 avr_asm_len ("adiw r26,%o1" CR_TAB
3463 "ld %0,X", op, plen, -2);
3464
3465 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3466 && !reg_unused_after (insn, XEXP (x,0)))
3467 {
3468 avr_asm_len ("sbiw r26,%o1", op, plen, 1);
3469 }
3470
3471 return "";
3472 }
3473
3474 return avr_asm_len ("ldd %0,%1", op, plen, -1);
3475 }
3476
3477 return avr_asm_len ("ld %0,%1", op, plen, -1);
3478 }
3479
3480
3481 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3482
3483 static const char*
3484 avr_out_movhi_r_mr_reg_no_disp_tiny (rtx op[], int *plen)
3485 {
3486 rtx dest = op[0];
3487 rtx src = op[1];
3488 rtx base = XEXP (src, 0);
3489
3490 int reg_dest = true_regnum (dest);
3491 int reg_base = true_regnum (base);
3492
3493 if (reg_dest == reg_base) /* R = (R) */
3494 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3495 "ld %B0,%1" CR_TAB
3496 "mov %A0,__tmp_reg__", op, plen, -3);
3497
3498 return avr_asm_len ("ld %A0,%1" CR_TAB
3499 TINY_ADIW (%E1, %F1, 1) CR_TAB
3500 "ld %B0,%1" CR_TAB
3501 TINY_SBIW (%E1, %F1, 1), op, plen, -6);
3502 }
3503
3504
3505 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3506
3507 static const char*
3508 avr_out_movhi_r_mr_reg_disp_tiny (rtx op[], int *plen)
3509 {
3510 rtx dest = op[0];
3511 rtx src = op[1];
3512 rtx base = XEXP (src, 0);
3513
3514 int reg_dest = true_regnum (dest);
3515 int reg_base = true_regnum (XEXP (base, 0));
3516
3517 if (reg_base == reg_dest)
3518 {
3519 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3520 "ld __tmp_reg__,%b1+" CR_TAB
3521 "ld %B0,%b1" CR_TAB
3522 "mov %A0,__tmp_reg__", op, plen, -5);
3523 }
3524 else
3525 {
3526 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3527 "ld %A0,%b1+" CR_TAB
3528 "ld %B0,%b1" CR_TAB
3529 TINY_SBIW (%I1, %J1, %o1+1), op, plen, -6);
3530 }
3531 }
3532
3533
3534 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3535
3536 static const char*
3537 avr_out_movhi_r_mr_pre_dec_tiny (rtx_insn *insn, rtx op[], int *plen)
3538 {
3539 int mem_volatile_p = 0;
3540 rtx dest = op[0];
3541 rtx src = op[1];
3542 rtx base = XEXP (src, 0);
3543
3544 /* "volatile" forces reading low byte first, even if less efficient,
3545 for correct operation with 16-bit I/O registers. */
3546 mem_volatile_p = MEM_VOLATILE_P (src);
3547
3548 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3549 fatal_insn ("incorrect insn:", insn);
3550
3551 if (!mem_volatile_p)
3552 return avr_asm_len ("ld %B0,%1" CR_TAB
3553 "ld %A0,%1", op, plen, -2);
3554
3555 return avr_asm_len (TINY_SBIW (%I1, %J1, 2) CR_TAB
3556 "ld %A0,%p1+" CR_TAB
3557 "ld %B0,%p1" CR_TAB
3558 TINY_SBIW (%I1, %J1, 1), op, plen, -6);
3559 }
3560
3561
3562 static const char*
3563 out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3564 {
3565 rtx dest = op[0];
3566 rtx src = op[1];
3567 rtx base = XEXP (src, 0);
3568 int reg_dest = true_regnum (dest);
3569 int reg_base = true_regnum (base);
3570 /* "volatile" forces reading low byte first, even if less efficient,
3571 for correct operation with 16-bit I/O registers. */
3572 int mem_volatile_p = MEM_VOLATILE_P (src);
3573
3574 if (reg_base > 0)
3575 {
3576 if (AVR_TINY)
3577 return avr_out_movhi_r_mr_reg_no_disp_tiny (op, plen);
3578
3579 if (reg_dest == reg_base) /* R = (R) */
3580 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3581 "ld %B0,%1" CR_TAB
3582 "mov %A0,__tmp_reg__", op, plen, -3);
3583
3584 if (reg_base != REG_X)
3585 return avr_asm_len ("ld %A0,%1" CR_TAB
3586 "ldd %B0,%1+1", op, plen, -2);
3587
3588 avr_asm_len ("ld %A0,X+" CR_TAB
3589 "ld %B0,X", op, plen, -2);
3590
3591 if (!reg_unused_after (insn, base))
3592 avr_asm_len ("sbiw r26,1", op, plen, 1);
3593
3594 return "";
3595 }
3596 else if (GET_CODE (base) == PLUS) /* (R + i) */
3597 {
3598 int disp = INTVAL (XEXP (base, 1));
3599 int reg_base = true_regnum (XEXP (base, 0));
3600
3601 if (AVR_TINY)
3602 return avr_out_movhi_r_mr_reg_disp_tiny (op, plen);
3603
3604 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3605 {
3606 if (REGNO (XEXP (base, 0)) != REG_Y)
3607 fatal_insn ("incorrect insn:",insn);
3608
3609 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3610 ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3611 "ldd %A0,Y+62" CR_TAB
3612 "ldd %B0,Y+63" CR_TAB
3613 "sbiw r28,%o1-62", op, plen, -4)
3614
3615 : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3616 "sbci r29,hi8(-%o1)" CR_TAB
3617 "ld %A0,Y" CR_TAB
3618 "ldd %B0,Y+1" CR_TAB
3619 "subi r28,lo8(%o1)" CR_TAB
3620 "sbci r29,hi8(%o1)", op, plen, -6);
3621 }
3622
3623 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3624 it but I have this situation with extremal
3625 optimization options. */
3626
3627 if (reg_base == REG_X)
3628 return reg_base == reg_dest
3629 ? avr_asm_len ("adiw r26,%o1" CR_TAB
3630 "ld __tmp_reg__,X+" CR_TAB
3631 "ld %B0,X" CR_TAB
3632 "mov %A0,__tmp_reg__", op, plen, -4)
3633
3634 : avr_asm_len ("adiw r26,%o1" CR_TAB
3635 "ld %A0,X+" CR_TAB
3636 "ld %B0,X" CR_TAB
3637 "sbiw r26,%o1+1", op, plen, -4);
3638
3639 return reg_base == reg_dest
3640 ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3641 "ldd %B0,%B1" CR_TAB
3642 "mov %A0,__tmp_reg__", op, plen, -3)
3643
3644 : avr_asm_len ("ldd %A0,%A1" CR_TAB
3645 "ldd %B0,%B1", op, plen, -2);
3646 }
3647 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3648 {
3649 if (AVR_TINY)
3650 return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
3651
3652 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3653 fatal_insn ("incorrect insn:", insn);
3654
3655 if (!mem_volatile_p)
3656 return avr_asm_len ("ld %B0,%1" CR_TAB
3657 "ld %A0,%1", op, plen, -2);
3658
3659 return REGNO (XEXP (base, 0)) == REG_X
3660 ? avr_asm_len ("sbiw r26,2" CR_TAB
3661 "ld %A0,X+" CR_TAB
3662 "ld %B0,X" CR_TAB
3663 "sbiw r26,1", op, plen, -4)
3664
3665 : avr_asm_len ("sbiw %r1,2" CR_TAB
3666 "ld %A0,%p1" CR_TAB
3667 "ldd %B0,%p1+1", op, plen, -3);
3668 }
3669 else if (GET_CODE (base) == POST_INC) /* (R++) */
3670 {
3671 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3672 fatal_insn ("incorrect insn:", insn);
3673
3674 return avr_asm_len ("ld %A0,%1" CR_TAB
3675 "ld %B0,%1", op, plen, -2);
3676 }
3677 else if (CONSTANT_ADDRESS_P (base))
3678 {
3679 int n_words = AVR_TINY ? 2 : 4;
3680 return optimize > 0 && io_address_operand (base, HImode)
3681 ? avr_asm_len ("in %A0,%i1" CR_TAB
3682 "in %B0,%i1+1", op, plen, -2)
3683
3684 : avr_asm_len ("lds %A0,%m1" CR_TAB
3685 "lds %B0,%m1+1", op, plen, -n_words);
3686 }
3687
3688 fatal_insn ("unknown move insn:",insn);
3689 return "";
3690 }
3691
3692 static const char*
3693 avr_out_movsi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3694 {
3695 rtx dest = op[0];
3696 rtx src = op[1];
3697 rtx base = XEXP (src, 0);
3698 int reg_dest = true_regnum (dest);
3699 int reg_base = true_regnum (base);
3700
3701 if (reg_dest == reg_base)
3702 {
3703 /* "ld r26,-X" is undefined */
3704 return *l = 9, (TINY_ADIW (%E1, %F1, 3) CR_TAB
3705 "ld %D0,%1" CR_TAB
3706 "ld %C0,-%1" CR_TAB
3707 "ld __tmp_reg__,-%1" CR_TAB
3708 TINY_SBIW (%E1, %F1, 1) CR_TAB
3709 "ld %A0,%1" CR_TAB
3710 "mov %B0,__tmp_reg__");
3711 }
3712 else if (reg_dest == reg_base - 2)
3713 {
3714 return *l = 5, ("ld %A0,%1+" CR_TAB
3715 "ld %B0,%1+" CR_TAB
3716 "ld __tmp_reg__,%1+" CR_TAB
3717 "ld %D0,%1" CR_TAB
3718 "mov %C0,__tmp_reg__");
3719 }
3720 else if (reg_unused_after (insn, base))
3721 {
3722 return *l = 4, ("ld %A0,%1+" CR_TAB
3723 "ld %B0,%1+" CR_TAB
3724 "ld %C0,%1+" CR_TAB
3725 "ld %D0,%1");
3726 }
3727 else
3728 {
3729 return *l = 6, ("ld %A0,%1+" CR_TAB
3730 "ld %B0,%1+" CR_TAB
3731 "ld %C0,%1+" CR_TAB
3732 "ld %D0,%1" CR_TAB
3733 TINY_SBIW (%E1, %F1, 3));
3734 }
3735 }
3736
3737
3738 static const char*
3739 avr_out_movsi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3740 {
3741 rtx dest = op[0];
3742 rtx src = op[1];
3743 rtx base = XEXP (src, 0);
3744 int reg_dest = true_regnum (dest);
3745 int reg_base = true_regnum (XEXP (base, 0));
3746
3747 if (reg_dest == reg_base)
3748 {
3749 /* "ld r26,-X" is undefined */
3750 return *l = 9, (TINY_ADIW (%I1, %J1, %o1+3) CR_TAB
3751 "ld %D0,%b1" CR_TAB
3752 "ld %C0,-%b1" CR_TAB
3753 "ld __tmp_reg__,-%b1" CR_TAB
3754 TINY_SBIW (%I1, %J1, 1) CR_TAB
3755 "ld %A0,%b1" CR_TAB
3756 "mov %B0,__tmp_reg__");
3757 }
3758 else if (reg_dest == reg_base - 2)
3759 {
3760 return *l = 7, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3761 "ld %A0,%b1+" CR_TAB
3762 "ld %B0,%b1+" CR_TAB
3763 "ld __tmp_reg__,%b1+" CR_TAB
3764 "ld %D0,%b1" CR_TAB
3765 "mov %C0,__tmp_reg__");
3766 }
3767 else if (reg_unused_after (insn, XEXP (base, 0)))
3768 {
3769 return *l = 6, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3770 "ld %A0,%b1+" CR_TAB
3771 "ld %B0,%b1+" CR_TAB
3772 "ld %C0,%b1+" CR_TAB
3773 "ld %D0,%b1");
3774 }
3775 else
3776 {
3777 return *l = 8, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3778 "ld %A0,%b1+" CR_TAB
3779 "ld %B0,%b1+" CR_TAB
3780 "ld %C0,%b1+" CR_TAB
3781 "ld %D0,%b1" CR_TAB
3782 TINY_SBIW (%I1, %J1, %o1+3));
3783 }
3784 }
3785
3786 static const char*
3787 out_movsi_r_mr (rtx_insn *insn, rtx op[], int *l)
3788 {
3789 rtx dest = op[0];
3790 rtx src = op[1];
3791 rtx base = XEXP (src, 0);
3792 int reg_dest = true_regnum (dest);
3793 int reg_base = true_regnum (base);
3794 int tmp;
3795
3796 if (!l)
3797 l = &tmp;
3798
3799 if (reg_base > 0)
3800 {
3801 if (AVR_TINY)
3802 return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
3803
3804 if (reg_base == REG_X) /* (R26) */
3805 {
3806 if (reg_dest == REG_X)
3807 /* "ld r26,-X" is undefined */
3808 return *l=7, ("adiw r26,3" CR_TAB
3809 "ld r29,X" CR_TAB
3810 "ld r28,-X" CR_TAB
3811 "ld __tmp_reg__,-X" CR_TAB
3812 "sbiw r26,1" CR_TAB
3813 "ld r26,X" CR_TAB
3814 "mov r27,__tmp_reg__");
3815 else if (reg_dest == REG_X - 2)
3816 return *l=5, ("ld %A0,X+" CR_TAB
3817 "ld %B0,X+" CR_TAB
3818 "ld __tmp_reg__,X+" CR_TAB
3819 "ld %D0,X" CR_TAB
3820 "mov %C0,__tmp_reg__");
3821 else if (reg_unused_after (insn, base))
3822 return *l=4, ("ld %A0,X+" CR_TAB
3823 "ld %B0,X+" CR_TAB
3824 "ld %C0,X+" CR_TAB
3825 "ld %D0,X");
3826 else
3827 return *l=5, ("ld %A0,X+" CR_TAB
3828 "ld %B0,X+" CR_TAB
3829 "ld %C0,X+" CR_TAB
3830 "ld %D0,X" CR_TAB
3831 "sbiw r26,3");
3832 }
3833 else
3834 {
3835 if (reg_dest == reg_base)
3836 return *l=5, ("ldd %D0,%1+3" CR_TAB
3837 "ldd %C0,%1+2" CR_TAB
3838 "ldd __tmp_reg__,%1+1" CR_TAB
3839 "ld %A0,%1" CR_TAB
3840 "mov %B0,__tmp_reg__");
3841 else if (reg_base == reg_dest + 2)
3842 return *l=5, ("ld %A0,%1" CR_TAB
3843 "ldd %B0,%1+1" CR_TAB
3844 "ldd __tmp_reg__,%1+2" CR_TAB
3845 "ldd %D0,%1+3" CR_TAB
3846 "mov %C0,__tmp_reg__");
3847 else
3848 return *l=4, ("ld %A0,%1" CR_TAB
3849 "ldd %B0,%1+1" CR_TAB
3850 "ldd %C0,%1+2" CR_TAB
3851 "ldd %D0,%1+3");
3852 }
3853 }
3854 else if (GET_CODE (base) == PLUS) /* (R + i) */
3855 {
3856 int disp = INTVAL (XEXP (base, 1));
3857
3858 if (AVR_TINY)
3859 return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
3860
3861 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3862 {
3863 if (REGNO (XEXP (base, 0)) != REG_Y)
3864 fatal_insn ("incorrect insn:",insn);
3865
3866 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3867 return *l = 6, ("adiw r28,%o1-60" CR_TAB
3868 "ldd %A0,Y+60" CR_TAB
3869 "ldd %B0,Y+61" CR_TAB
3870 "ldd %C0,Y+62" CR_TAB
3871 "ldd %D0,Y+63" CR_TAB
3872 "sbiw r28,%o1-60");
3873
3874 return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3875 "sbci r29,hi8(-%o1)" CR_TAB
3876 "ld %A0,Y" CR_TAB
3877 "ldd %B0,Y+1" CR_TAB
3878 "ldd %C0,Y+2" CR_TAB
3879 "ldd %D0,Y+3" CR_TAB
3880 "subi r28,lo8(%o1)" CR_TAB
3881 "sbci r29,hi8(%o1)");
3882 }
3883
3884 reg_base = true_regnum (XEXP (base, 0));
3885 if (reg_base == REG_X)
3886 {
3887 /* R = (X + d) */
3888 if (reg_dest == REG_X)
3889 {
3890 *l = 7;
3891 /* "ld r26,-X" is undefined */
3892 return ("adiw r26,%o1+3" CR_TAB
3893 "ld r29,X" CR_TAB
3894 "ld r28,-X" CR_TAB
3895 "ld __tmp_reg__,-X" CR_TAB
3896 "sbiw r26,1" CR_TAB
3897 "ld r26,X" CR_TAB
3898 "mov r27,__tmp_reg__");
3899 }
3900 *l = 6;
3901 if (reg_dest == REG_X - 2)
3902 return ("adiw r26,%o1" CR_TAB
3903 "ld r24,X+" CR_TAB
3904 "ld r25,X+" CR_TAB
3905 "ld __tmp_reg__,X+" CR_TAB
3906 "ld r27,X" CR_TAB
3907 "mov r26,__tmp_reg__");
3908
3909 return ("adiw r26,%o1" CR_TAB
3910 "ld %A0,X+" CR_TAB
3911 "ld %B0,X+" CR_TAB
3912 "ld %C0,X+" CR_TAB
3913 "ld %D0,X" CR_TAB
3914 "sbiw r26,%o1+3");
3915 }
3916 if (reg_dest == reg_base)
3917 return *l=5, ("ldd %D0,%D1" CR_TAB
3918 "ldd %C0,%C1" CR_TAB
3919 "ldd __tmp_reg__,%B1" CR_TAB
3920 "ldd %A0,%A1" CR_TAB
3921 "mov %B0,__tmp_reg__");
3922 else if (reg_dest == reg_base - 2)
3923 return *l=5, ("ldd %A0,%A1" CR_TAB
3924 "ldd %B0,%B1" CR_TAB
3925 "ldd __tmp_reg__,%C1" CR_TAB
3926 "ldd %D0,%D1" CR_TAB
3927 "mov %C0,__tmp_reg__");
3928 return *l=4, ("ldd %A0,%A1" CR_TAB
3929 "ldd %B0,%B1" CR_TAB
3930 "ldd %C0,%C1" CR_TAB
3931 "ldd %D0,%D1");
3932 }
3933 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3934 return *l=4, ("ld %D0,%1" CR_TAB
3935 "ld %C0,%1" CR_TAB
3936 "ld %B0,%1" CR_TAB
3937 "ld %A0,%1");
3938 else if (GET_CODE (base) == POST_INC) /* (R++) */
3939 return *l=4, ("ld %A0,%1" CR_TAB
3940 "ld %B0,%1" CR_TAB
3941 "ld %C0,%1" CR_TAB
3942 "ld %D0,%1");
3943 else if (CONSTANT_ADDRESS_P (base))
3944 {
3945 if (io_address_operand (base, SImode))
3946 {
3947 *l = 4;
3948 return ("in %A0,%i1" CR_TAB
3949 "in %B0,%i1+1" CR_TAB
3950 "in %C0,%i1+2" CR_TAB
3951 "in %D0,%i1+3");
3952 }
3953 else
3954 {
3955 *l = AVR_TINY ? 4 : 8;
3956 return ("lds %A0,%m1" CR_TAB
3957 "lds %B0,%m1+1" CR_TAB
3958 "lds %C0,%m1+2" CR_TAB
3959 "lds %D0,%m1+3");
3960 }
3961 }
3962
3963 fatal_insn ("unknown move insn:",insn);
3964 return "";
3965 }
3966
3967 static const char*
3968 avr_out_movsi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3969 {
3970 rtx dest = op[0];
3971 rtx src = op[1];
3972 rtx base = XEXP (dest, 0);
3973 int reg_base = true_regnum (base);
3974 int reg_src = true_regnum (src);
3975
3976 if (reg_base == reg_src)
3977 {
3978 /* "ld r26,-X" is undefined */
3979 if (reg_unused_after (insn, base))
3980 {
3981 return *l = 7, ("mov __tmp_reg__, %B1" CR_TAB
3982 "st %0,%A1" CR_TAB
3983 TINY_ADIW (%E0, %F0, 1) CR_TAB
3984 "st %0+,__tmp_reg__" CR_TAB
3985 "st %0+,%C1" CR_TAB
3986 "st %0+,%D1");
3987 }
3988 else
3989 {
3990 return *l = 9, ("mov __tmp_reg__, %B1" CR_TAB
3991 "st %0,%A1" CR_TAB
3992 TINY_ADIW (%E0, %F0, 1) CR_TAB
3993 "st %0+,__tmp_reg__" CR_TAB
3994 "st %0+,%C1" CR_TAB
3995 "st %0+,%D1" CR_TAB
3996 TINY_SBIW (%E0, %F0, 3));
3997 }
3998 }
3999 else if (reg_base == reg_src + 2)
4000 {
4001 if (reg_unused_after (insn, base))
4002 return *l = 7, ("mov __zero_reg__,%C1" CR_TAB
4003 "mov __tmp_reg__,%D1" CR_TAB
4004 "st %0+,%A1" CR_TAB
4005 "st %0+,%B1" CR_TAB
4006 "st %0+,__zero_reg__" CR_TAB
4007 "st %0,__tmp_reg__" CR_TAB
4008 "clr __zero_reg__");
4009 else
4010 return *l = 9, ("mov __zero_reg__,%C1" CR_TAB
4011 "mov __tmp_reg__,%D1" CR_TAB
4012 "st %0+,%A1" CR_TAB
4013 "st %0+,%B1" CR_TAB
4014 "st %0+,__zero_reg__" CR_TAB
4015 "st %0,__tmp_reg__" CR_TAB
4016 "clr __zero_reg__" CR_TAB
4017 TINY_SBIW (%E0, %F0, 3));
4018 }
4019
4020 return *l = 6, ("st %0+,%A1" CR_TAB
4021 "st %0+,%B1" CR_TAB
4022 "st %0+,%C1" CR_TAB
4023 "st %0,%D1" CR_TAB
4024 TINY_SBIW (%E0, %F0, 3));
4025 }
4026
4027 static const char*
4028 avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
4029 {
4030 rtx dest = op[0];
4031 rtx src = op[1];
4032 rtx base = XEXP (dest, 0);
4033 int reg_base = REGNO (XEXP (base, 0));
4034 int reg_src =true_regnum (src);
4035
4036 if (reg_base == reg_src)
4037 {
4038 *l = 11;
4039 return ("mov __tmp_reg__,%A2" CR_TAB
4040 "mov __zero_reg__,%B2" CR_TAB
4041 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4042 "st %b0+,__tmp_reg__" CR_TAB
4043 "st %b0+,__zero_reg__" CR_TAB
4044 "st %b0+,%C2" CR_TAB
4045 "st %b0,%D2" CR_TAB
4046 "clr __zero_reg__" CR_TAB
4047 TINY_SBIW (%I0, %J0, %o0+3));
4048 }
4049 else if (reg_src == reg_base - 2)
4050 {
4051 *l = 11;
4052 return ("mov __tmp_reg__,%C2" CR_TAB
4053 "mov __zero_reg__,%D2" CR_TAB
4054 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4055 "st %b0+,%A0" CR_TAB
4056 "st %b0+,%B0" CR_TAB
4057 "st %b0+,__tmp_reg__" CR_TAB
4058 "st %b0,__zero_reg__" CR_TAB
4059 "clr __zero_reg__" CR_TAB
4060 TINY_SBIW (%I0, %J0, %o0+3));
4061 }
4062 *l = 8;
4063 return (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4064 "st %b0+,%A1" CR_TAB
4065 "st %b0+,%B1" CR_TAB
4066 "st %b0+,%C1" CR_TAB
4067 "st %b0,%D1" CR_TAB
4068 TINY_SBIW (%I0, %J0, %o0+3));
4069 }
4070
4071 static const char*
4072 out_movsi_mr_r (rtx_insn *insn, rtx op[], int *l)
4073 {
4074 rtx dest = op[0];
4075 rtx src = op[1];
4076 rtx base = XEXP (dest, 0);
4077 int reg_base = true_regnum (base);
4078 int reg_src = true_regnum (src);
4079 int tmp;
4080
4081 if (!l)
4082 l = &tmp;
4083
4084 if (CONSTANT_ADDRESS_P (base))
4085 {
4086 if (io_address_operand (base, SImode))
4087 {
4088 return *l=4,("out %i0, %A1" CR_TAB
4089 "out %i0+1,%B1" CR_TAB
4090 "out %i0+2,%C1" CR_TAB
4091 "out %i0+3,%D1");
4092 }
4093 else
4094 {
4095 *l = AVR_TINY ? 4 : 8;
4096 return ("sts %m0,%A1" CR_TAB
4097 "sts %m0+1,%B1" CR_TAB
4098 "sts %m0+2,%C1" CR_TAB
4099 "sts %m0+3,%D1");
4100 }
4101 }
4102
4103 if (reg_base > 0) /* (r) */
4104 {
4105 if (AVR_TINY)
4106 return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l);
4107
4108 if (reg_base == REG_X) /* (R26) */
4109 {
4110 if (reg_src == REG_X)
4111 {
4112 /* "st X+,r26" is undefined */
4113 if (reg_unused_after (insn, base))
4114 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
4115 "st X,r26" CR_TAB
4116 "adiw r26,1" CR_TAB
4117 "st X+,__tmp_reg__" CR_TAB
4118 "st X+,r28" CR_TAB
4119 "st X,r29");
4120 else
4121 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
4122 "st X,r26" CR_TAB
4123 "adiw r26,1" CR_TAB
4124 "st X+,__tmp_reg__" CR_TAB
4125 "st X+,r28" CR_TAB
4126 "st X,r29" CR_TAB
4127 "sbiw r26,3");
4128 }
4129 else if (reg_base == reg_src + 2)
4130 {
4131 if (reg_unused_after (insn, base))
4132 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
4133 "mov __tmp_reg__,%D1" CR_TAB
4134 "st %0+,%A1" CR_TAB
4135 "st %0+,%B1" CR_TAB
4136 "st %0+,__zero_reg__" CR_TAB
4137 "st %0,__tmp_reg__" CR_TAB
4138 "clr __zero_reg__");
4139 else
4140 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
4141 "mov __tmp_reg__,%D1" CR_TAB
4142 "st %0+,%A1" CR_TAB
4143 "st %0+,%B1" CR_TAB
4144 "st %0+,__zero_reg__" CR_TAB
4145 "st %0,__tmp_reg__" CR_TAB
4146 "clr __zero_reg__" CR_TAB
4147 "sbiw r26,3");
4148 }
4149 return *l=5, ("st %0+,%A1" CR_TAB
4150 "st %0+,%B1" CR_TAB
4151 "st %0+,%C1" CR_TAB
4152 "st %0,%D1" CR_TAB
4153 "sbiw r26,3");
4154 }
4155 else
4156 return *l=4, ("st %0,%A1" CR_TAB
4157 "std %0+1,%B1" CR_TAB
4158 "std %0+2,%C1" CR_TAB
4159 "std %0+3,%D1");
4160 }
4161 else if (GET_CODE (base) == PLUS) /* (R + i) */
4162 {
4163 int disp = INTVAL (XEXP (base, 1));
4164
4165 if (AVR_TINY)
4166 return avr_out_movsi_mr_r_reg_disp_tiny (op, l);
4167
4168 reg_base = REGNO (XEXP (base, 0));
4169 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4170 {
4171 if (reg_base != REG_Y)
4172 fatal_insn ("incorrect insn:",insn);
4173
4174 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4175 return *l = 6, ("adiw r28,%o0-60" CR_TAB
4176 "std Y+60,%A1" CR_TAB
4177 "std Y+61,%B1" CR_TAB
4178 "std Y+62,%C1" CR_TAB
4179 "std Y+63,%D1" CR_TAB
4180 "sbiw r28,%o0-60");
4181
4182 return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
4183 "sbci r29,hi8(-%o0)" CR_TAB
4184 "st Y,%A1" CR_TAB
4185 "std Y+1,%B1" CR_TAB
4186 "std Y+2,%C1" CR_TAB
4187 "std Y+3,%D1" CR_TAB
4188 "subi r28,lo8(%o0)" CR_TAB
4189 "sbci r29,hi8(%o0)");
4190 }
4191 if (reg_base == REG_X)
4192 {
4193 /* (X + d) = R */
4194 if (reg_src == REG_X)
4195 {
4196 *l = 9;
4197 return ("mov __tmp_reg__,r26" CR_TAB
4198 "mov __zero_reg__,r27" CR_TAB
4199 "adiw r26,%o0" CR_TAB
4200 "st X+,__tmp_reg__" CR_TAB
4201 "st X+,__zero_reg__" CR_TAB
4202 "st X+,r28" CR_TAB
4203 "st X,r29" CR_TAB
4204 "clr __zero_reg__" CR_TAB
4205 "sbiw r26,%o0+3");
4206 }
4207 else if (reg_src == REG_X - 2)
4208 {
4209 *l = 9;
4210 return ("mov __tmp_reg__,r26" CR_TAB
4211 "mov __zero_reg__,r27" CR_TAB
4212 "adiw r26,%o0" CR_TAB
4213 "st X+,r24" CR_TAB
4214 "st X+,r25" CR_TAB
4215 "st X+,__tmp_reg__" CR_TAB
4216 "st X,__zero_reg__" CR_TAB
4217 "clr __zero_reg__" CR_TAB
4218 "sbiw r26,%o0+3");
4219 }
4220 *l = 6;
4221 return ("adiw r26,%o0" CR_TAB
4222 "st X+,%A1" CR_TAB
4223 "st X+,%B1" CR_TAB
4224 "st X+,%C1" CR_TAB
4225 "st X,%D1" CR_TAB
4226 "sbiw r26,%o0+3");
4227 }
4228 return *l=4, ("std %A0,%A1" CR_TAB
4229 "std %B0,%B1" CR_TAB
4230 "std %C0,%C1" CR_TAB
4231 "std %D0,%D1");
4232 }
4233 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4234 return *l=4, ("st %0,%D1" CR_TAB
4235 "st %0,%C1" CR_TAB
4236 "st %0,%B1" CR_TAB
4237 "st %0,%A1");
4238 else if (GET_CODE (base) == POST_INC) /* (R++) */
4239 return *l=4, ("st %0,%A1" CR_TAB
4240 "st %0,%B1" CR_TAB
4241 "st %0,%C1" CR_TAB
4242 "st %0,%D1");
4243 fatal_insn ("unknown move insn:",insn);
4244 return "";
4245 }
4246
4247 const char *
4248 output_movsisf (rtx_insn *insn, rtx operands[], int *l)
4249 {
4250 int dummy;
4251 rtx dest = operands[0];
4252 rtx src = operands[1];
4253 int *real_l = l;
4254
4255 if (avr_mem_flash_p (src)
4256 || avr_mem_flash_p (dest))
4257 {
4258 return avr_out_lpm (insn, operands, real_l);
4259 }
4260
4261 if (!l)
4262 l = &dummy;
4263
4264 gcc_assert (4 == GET_MODE_SIZE (GET_MODE (dest)));
4265 if (REG_P (dest))
4266 {
4267 if (REG_P (src)) /* mov r,r */
4268 {
4269 if (true_regnum (dest) > true_regnum (src))
4270 {
4271 if (AVR_HAVE_MOVW)
4272 {
4273 *l = 2;
4274 return ("movw %C0,%C1" CR_TAB
4275 "movw %A0,%A1");
4276 }
4277 *l = 4;
4278 return ("mov %D0,%D1" CR_TAB
4279 "mov %C0,%C1" CR_TAB
4280 "mov %B0,%B1" CR_TAB
4281 "mov %A0,%A1");
4282 }
4283 else
4284 {
4285 if (AVR_HAVE_MOVW)
4286 {
4287 *l = 2;
4288 return ("movw %A0,%A1" CR_TAB
4289 "movw %C0,%C1");
4290 }
4291 *l = 4;
4292 return ("mov %A0,%A1" CR_TAB
4293 "mov %B0,%B1" CR_TAB
4294 "mov %C0,%C1" CR_TAB
4295 "mov %D0,%D1");
4296 }
4297 }
4298 else if (CONSTANT_P (src))
4299 {
4300 return output_reload_insisf (operands, NULL_RTX, real_l);
4301 }
4302 else if (MEM_P (src))
4303 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
4304 }
4305 else if (MEM_P (dest))
4306 {
4307 const char *templ;
4308
4309 if (src == CONST0_RTX (GET_MODE (dest)))
4310 operands[1] = zero_reg_rtx;
4311
4312 templ = out_movsi_mr_r (insn, operands, real_l);
4313
4314 if (!real_l)
4315 output_asm_insn (templ, operands);
4316
4317 operands[1] = src;
4318 return "";
4319 }
4320 fatal_insn ("invalid insn:", insn);
4321 return "";
4322 }
4323
4324
4325 /* Handle loads of 24-bit types from memory to register. */
4326
4327 static const char*
4328 avr_out_load_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4329 {
4330 rtx dest = op[0];
4331 rtx src = op[1];
4332 rtx base = XEXP (src, 0);
4333 int reg_dest = true_regnum (dest);
4334 int reg_base = true_regnum (base);
4335
4336 if (reg_base == reg_dest)
4337 {
4338 return avr_asm_len (TINY_ADIW (%E1, %F1, 2) CR_TAB
4339 "ld %C0,%1" CR_TAB
4340 "ld __tmp_reg__,-%1" CR_TAB
4341 TINY_SBIW (%E1, %F1, 1) CR_TAB
4342 "ld %A0,%1" CR_TAB
4343 "mov %B0,__tmp_reg__", op, plen, -8);
4344 }
4345 else
4346 {
4347 avr_asm_len ("ld %A0,%1+" CR_TAB
4348 "ld %B0,%1+" CR_TAB
4349 "ld %C0,%1", op, plen, -3);
4350
4351 if (reg_dest != reg_base - 2 &&
4352 !reg_unused_after (insn, base))
4353 {
4354 avr_asm_len (TINY_SBIW (%E1, %F1, 2), op, plen, 2);
4355 }
4356 return "";
4357 }
4358 }
4359
4360 static const char*
4361 avr_out_load_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4362 {
4363 rtx dest = op[0];
4364 rtx src = op[1];
4365 rtx base = XEXP (src, 0);
4366 int reg_dest = true_regnum (dest);
4367 int reg_base = true_regnum (base);
4368
4369 reg_base = true_regnum (XEXP (base, 0));
4370 if (reg_base == reg_dest)
4371 {
4372 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1+2) CR_TAB
4373 "ld %C0,%b1" CR_TAB
4374 "ld __tmp_reg__,-%b1" CR_TAB
4375 TINY_SBIW (%I1, %J1, 1) CR_TAB
4376 "ld %A0,%b1" CR_TAB
4377 "mov %B0,__tmp_reg__", op, plen, -8);
4378 }
4379 else
4380 {
4381 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
4382 "ld %A0,%b1+" CR_TAB
4383 "ld %B0,%b1+" CR_TAB
4384 "ld %C0,%b1", op, plen, -5);
4385
4386 if (reg_dest != (reg_base - 2)
4387 && !reg_unused_after (insn, XEXP (base, 0)))
4388 avr_asm_len (TINY_SBIW (%I1, %J1, %o1+2), op, plen, 2);
4389
4390 return "";
4391 }
4392 }
4393
4394 static const char*
4395 avr_out_load_psi (rtx_insn *insn, rtx *op, int *plen)
4396 {
4397 rtx dest = op[0];
4398 rtx src = op[1];
4399 rtx base = XEXP (src, 0);
4400 int reg_dest = true_regnum (dest);
4401 int reg_base = true_regnum (base);
4402
4403 if (reg_base > 0)
4404 {
4405 if (AVR_TINY)
4406 return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen);
4407
4408 if (reg_base == REG_X) /* (R26) */
4409 {
4410 if (reg_dest == REG_X)
4411 /* "ld r26,-X" is undefined */
4412 return avr_asm_len ("adiw r26,2" CR_TAB
4413 "ld r28,X" CR_TAB
4414 "ld __tmp_reg__,-X" CR_TAB
4415 "sbiw r26,1" CR_TAB
4416 "ld r26,X" CR_TAB
4417 "mov r27,__tmp_reg__", op, plen, -6);
4418 else
4419 {
4420 avr_asm_len ("ld %A0,X+" CR_TAB
4421 "ld %B0,X+" CR_TAB
4422 "ld %C0,X", op, plen, -3);
4423
4424 if (reg_dest != REG_X - 2
4425 && !reg_unused_after (insn, base))
4426 {
4427 avr_asm_len ("sbiw r26,2", op, plen, 1);
4428 }
4429
4430 return "";
4431 }
4432 }
4433 else /* reg_base != REG_X */
4434 {
4435 if (reg_dest == reg_base)
4436 return avr_asm_len ("ldd %C0,%1+2" CR_TAB
4437 "ldd __tmp_reg__,%1+1" CR_TAB
4438 "ld %A0,%1" CR_TAB
4439 "mov %B0,__tmp_reg__", op, plen, -4);
4440 else
4441 return avr_asm_len ("ld %A0,%1" CR_TAB
4442 "ldd %B0,%1+1" CR_TAB
4443 "ldd %C0,%1+2", op, plen, -3);
4444 }
4445 }
4446 else if (GET_CODE (base) == PLUS) /* (R + i) */
4447 {
4448 int disp = INTVAL (XEXP (base, 1));
4449
4450 if (AVR_TINY)
4451 return avr_out_load_psi_reg_disp_tiny (insn, op, plen);
4452
4453 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
4454 {
4455 if (REGNO (XEXP (base, 0)) != REG_Y)
4456 fatal_insn ("incorrect insn:",insn);
4457
4458 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
4459 return avr_asm_len ("adiw r28,%o1-61" CR_TAB
4460 "ldd %A0,Y+61" CR_TAB
4461 "ldd %B0,Y+62" CR_TAB
4462 "ldd %C0,Y+63" CR_TAB
4463 "sbiw r28,%o1-61", op, plen, -5);
4464
4465 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
4466 "sbci r29,hi8(-%o1)" CR_TAB
4467 "ld %A0,Y" CR_TAB
4468 "ldd %B0,Y+1" CR_TAB
4469 "ldd %C0,Y+2" CR_TAB
4470 "subi r28,lo8(%o1)" CR_TAB
4471 "sbci r29,hi8(%o1)", op, plen, -7);
4472 }
4473
4474 reg_base = true_regnum (XEXP (base, 0));
4475 if (reg_base == REG_X)
4476 {
4477 /* R = (X + d) */
4478 if (reg_dest == REG_X)
4479 {
4480 /* "ld r26,-X" is undefined */
4481 return avr_asm_len ("adiw r26,%o1+2" CR_TAB
4482 "ld r28,X" CR_TAB
4483 "ld __tmp_reg__,-X" CR_TAB
4484 "sbiw r26,1" CR_TAB
4485 "ld r26,X" CR_TAB
4486 "mov r27,__tmp_reg__", op, plen, -6);
4487 }
4488
4489 avr_asm_len ("adiw r26,%o1" CR_TAB
4490 "ld %A0,X+" CR_TAB
4491 "ld %B0,X+" CR_TAB
4492 "ld %C0,X", op, plen, -4);
4493
4494 if (reg_dest != REG_W
4495 && !reg_unused_after (insn, XEXP (base, 0)))
4496 avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
4497
4498 return "";
4499 }
4500
4501 if (reg_dest == reg_base)
4502 return avr_asm_len ("ldd %C0,%C1" CR_TAB
4503 "ldd __tmp_reg__,%B1" CR_TAB
4504 "ldd %A0,%A1" CR_TAB
4505 "mov %B0,__tmp_reg__", op, plen, -4);
4506
4507 return avr_asm_len ("ldd %A0,%A1" CR_TAB
4508 "ldd %B0,%B1" CR_TAB
4509 "ldd %C0,%C1", op, plen, -3);
4510 }
4511 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4512 return avr_asm_len ("ld %C0,%1" CR_TAB
4513 "ld %B0,%1" CR_TAB
4514 "ld %A0,%1", op, plen, -3);
4515 else if (GET_CODE (base) == POST_INC) /* (R++) */
4516 return avr_asm_len ("ld %A0,%1" CR_TAB
4517 "ld %B0,%1" CR_TAB
4518 "ld %C0,%1", op, plen, -3);
4519
4520 else if (CONSTANT_ADDRESS_P (base))
4521 {
4522 int n_words = AVR_TINY ? 3 : 6;
4523 return avr_asm_len ("lds %A0,%m1" CR_TAB
4524 "lds %B0,%m1+1" CR_TAB
4525 "lds %C0,%m1+2", op, plen , -n_words);
4526 }
4527
4528 fatal_insn ("unknown move insn:",insn);
4529 return "";
4530 }
4531
4532
4533 static const char*
4534 avr_out_store_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4535 {
4536 rtx dest = op[0];
4537 rtx src = op[1];
4538 rtx base = XEXP (dest, 0);
4539 int reg_base = true_regnum (base);
4540 int reg_src = true_regnum (src);
4541
4542 if (reg_base == reg_src)
4543 {
4544 avr_asm_len ("st %0,%A1" CR_TAB
4545 "mov __tmp_reg__,%B1" CR_TAB
4546 TINY_ADIW (%E0, %F0, 1) CR_TAB /* st X+, r27 is undefined */
4547 "st %0+,__tmp_reg__" CR_TAB
4548 "st %0,%C1", op, plen, -6);
4549
4550 }
4551 else if (reg_src == reg_base - 2)
4552 {
4553 avr_asm_len ("st %0,%A1" CR_TAB
4554 "mov __tmp_reg__,%C1" CR_TAB
4555 TINY_ADIW (%E0, %F0, 1) CR_TAB
4556 "st %0+,%B1" CR_TAB
4557 "st %0,__tmp_reg__", op, plen, 6);
4558 }
4559 else
4560 {
4561 avr_asm_len ("st %0+,%A1" CR_TAB
4562 "st %0+,%B1" CR_TAB
4563 "st %0,%C1", op, plen, -3);
4564 }
4565
4566 if (!reg_unused_after (insn, base))
4567 avr_asm_len (TINY_SBIW (%E0, %F0, 2), op, plen, 2);
4568
4569 return "";
4570 }
4571
4572 static const char*
4573 avr_out_store_psi_reg_disp_tiny (rtx *op, int *plen)
4574 {
4575 rtx dest = op[0];
4576 rtx src = op[1];
4577 rtx base = XEXP (dest, 0);
4578 int reg_base = REGNO (XEXP (base, 0));
4579 int reg_src = true_regnum (src);
4580
4581 if (reg_src == reg_base)
4582 {
4583 return avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
4584 "mov __zero_reg__,%B1" CR_TAB
4585 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4586 "st %b0+,__tmp_reg__" CR_TAB
4587 "st %b0+,__zero_reg__" CR_TAB
4588 "st %b0,%C1" CR_TAB
4589 "clr __zero_reg__" CR_TAB
4590 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -10);
4591 }
4592 else if (reg_src == reg_base - 2)
4593 {
4594 return avr_asm_len ("mov __tmp_reg__,%C1" CR_TAB
4595 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4596 "st %b0+,%A1" CR_TAB
4597 "st %b0+,%B1" CR_TAB
4598 "st %b0,__tmp_reg__" CR_TAB
4599 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -8);
4600 }
4601
4602 return avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4603 "st %b0+,%A1" CR_TAB
4604 "st %b0+,%B1" CR_TAB
4605 "st %b0,%C1" CR_TAB
4606 TINY_SBIW (%I0, %J0, %o0+2), op, plen, -7);
4607 }
4608
4609 /* Handle store of 24-bit type from register or zero to memory. */
4610
4611 static const char*
4612 avr_out_store_psi (rtx_insn *insn, rtx *op, int *plen)
4613 {
4614 rtx dest = op[0];
4615 rtx src = op[1];
4616 rtx base = XEXP (dest, 0);
4617 int reg_base = true_regnum (base);
4618
4619 if (CONSTANT_ADDRESS_P (base))
4620 {
4621 int n_words = AVR_TINY ? 3 : 6;
4622 return avr_asm_len ("sts %m0,%A1" CR_TAB
4623 "sts %m0+1,%B1" CR_TAB
4624 "sts %m0+2,%C1", op, plen, -n_words);
4625 }
4626
4627 if (reg_base > 0) /* (r) */
4628 {
4629 if (AVR_TINY)
4630 return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen);
4631
4632 if (reg_base == REG_X) /* (R26) */
4633 {
4634 gcc_assert (!reg_overlap_mentioned_p (base, src));
4635
4636 avr_asm_len ("st %0+,%A1" CR_TAB
4637 "st %0+,%B1" CR_TAB
4638 "st %0,%C1", op, plen, -3);
4639
4640 if (!reg_unused_after (insn, base))
4641 avr_asm_len ("sbiw r26,2", op, plen, 1);
4642
4643 return "";
4644 }
4645 else
4646 return avr_asm_len ("st %0,%A1" CR_TAB
4647 "std %0+1,%B1" CR_TAB
4648 "std %0+2,%C1", op, plen, -3);
4649 }
4650 else if (GET_CODE (base) == PLUS) /* (R + i) */
4651 {
4652 int disp = INTVAL (XEXP (base, 1));
4653
4654 if (AVR_TINY)
4655 return avr_out_store_psi_reg_disp_tiny (op, plen);
4656
4657 reg_base = REGNO (XEXP (base, 0));
4658
4659 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4660 {
4661 if (reg_base != REG_Y)
4662 fatal_insn ("incorrect insn:",insn);
4663
4664 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4665 return avr_asm_len ("adiw r28,%o0-61" CR_TAB
4666 "std Y+61,%A1" CR_TAB
4667 "std Y+62,%B1" CR_TAB
4668 "std Y+63,%C1" CR_TAB
4669 "sbiw r28,%o0-61", op, plen, -5);
4670
4671 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4672 "sbci r29,hi8(-%o0)" CR_TAB
4673 "st Y,%A1" CR_TAB
4674 "std Y+1,%B1" CR_TAB
4675 "std Y+2,%C1" CR_TAB
4676 "subi r28,lo8(%o0)" CR_TAB
4677 "sbci r29,hi8(%o0)", op, plen, -7);
4678 }
4679 if (reg_base == REG_X)
4680 {
4681 /* (X + d) = R */
4682 gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
4683
4684 avr_asm_len ("adiw r26,%o0" CR_TAB
4685 "st X+,%A1" CR_TAB
4686 "st X+,%B1" CR_TAB
4687 "st X,%C1", op, plen, -4);
4688
4689 if (!reg_unused_after (insn, XEXP (base, 0)))
4690 avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
4691
4692 return "";
4693 }
4694
4695 return avr_asm_len ("std %A0,%A1" CR_TAB
4696 "std %B0,%B1" CR_TAB
4697 "std %C0,%C1", op, plen, -3);
4698 }
4699 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4700 return avr_asm_len ("st %0,%C1" CR_TAB
4701 "st %0,%B1" CR_TAB
4702 "st %0,%A1", op, plen, -3);
4703 else if (GET_CODE (base) == POST_INC) /* (R++) */
4704 return avr_asm_len ("st %0,%A1" CR_TAB
4705 "st %0,%B1" CR_TAB
4706 "st %0,%C1", op, plen, -3);
4707
4708 fatal_insn ("unknown move insn:",insn);
4709 return "";
4710 }
4711
4712
4713 /* Move around 24-bit stuff. */
4714
4715 const char *
4716 avr_out_movpsi (rtx_insn *insn, rtx *op, int *plen)
4717 {
4718 rtx dest = op[0];
4719 rtx src = op[1];
4720
4721 if (avr_mem_flash_p (src)
4722 || avr_mem_flash_p (dest))
4723 {
4724 return avr_out_lpm (insn, op, plen);
4725 }
4726
4727 if (register_operand (dest, VOIDmode))
4728 {
4729 if (register_operand (src, VOIDmode)) /* mov r,r */
4730 {
4731 if (true_regnum (dest) > true_regnum (src))
4732 {
4733 avr_asm_len ("mov %C0,%C1", op, plen, -1);
4734
4735 if (AVR_HAVE_MOVW)
4736 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
4737 else
4738 return avr_asm_len ("mov %B0,%B1" CR_TAB
4739 "mov %A0,%A1", op, plen, 2);
4740 }
4741 else
4742 {
4743 if (AVR_HAVE_MOVW)
4744 avr_asm_len ("movw %A0,%A1", op, plen, -1);
4745 else
4746 avr_asm_len ("mov %A0,%A1" CR_TAB
4747 "mov %B0,%B1", op, plen, -2);
4748
4749 return avr_asm_len ("mov %C0,%C1", op, plen, 1);
4750 }
4751 }
4752 else if (CONSTANT_P (src))
4753 {
4754 return avr_out_reload_inpsi (op, NULL_RTX, plen);
4755 }
4756 else if (MEM_P (src))
4757 return avr_out_load_psi (insn, op, plen); /* mov r,m */
4758 }
4759 else if (MEM_P (dest))
4760 {
4761 rtx xop[2];
4762
4763 xop[0] = dest;
4764 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4765
4766 return avr_out_store_psi (insn, xop, plen);
4767 }
4768
4769 fatal_insn ("invalid insn:", insn);
4770 return "";
4771 }
4772
4773 static const char*
4774 avr_out_movqi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4775 {
4776 rtx dest = op[0];
4777 rtx src = op[1];
4778 rtx x = XEXP (dest, 0);
4779
4780 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4781 {
4782 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4783 TINY_ADIW (%I0, %J0, %o0) CR_TAB
4784 "st %b0,__tmp_reg__", op, plen, -4);
4785 }
4786 else
4787 {
4788 avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4789 "st %b0,%1" , op, plen, -3);
4790 }
4791
4792 if (!reg_unused_after (insn, XEXP (x,0)))
4793 avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
4794
4795 return "";
4796 }
4797
4798 static const char*
4799 out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen)
4800 {
4801 rtx dest = op[0];
4802 rtx src = op[1];
4803 rtx x = XEXP (dest, 0);
4804
4805 if (CONSTANT_ADDRESS_P (x))
4806 {
4807 int n_words = AVR_TINY ? 1 : 2;
4808 return optimize > 0 && io_address_operand (x, QImode)
4809 ? avr_asm_len ("out %i0,%1", op, plen, -1)
4810 : avr_asm_len ("sts %m0,%1", op, plen, -n_words);
4811 }
4812 else if (GET_CODE (x) == PLUS
4813 && REG_P (XEXP (x, 0))
4814 && CONST_INT_P (XEXP (x, 1)))
4815 {
4816 /* memory access by reg+disp */
4817
4818 int disp = INTVAL (XEXP (x, 1));
4819
4820 if (AVR_TINY)
4821 return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen);
4822
4823 if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
4824 {
4825 if (REGNO (XEXP (x, 0)) != REG_Y)
4826 fatal_insn ("incorrect insn:",insn);
4827
4828 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4829 return avr_asm_len ("adiw r28,%o0-63" CR_TAB
4830 "std Y+63,%1" CR_TAB
4831 "sbiw r28,%o0-63", op, plen, -3);
4832
4833 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4834 "sbci r29,hi8(-%o0)" CR_TAB
4835 "st Y,%1" CR_TAB
4836 "subi r28,lo8(%o0)" CR_TAB
4837 "sbci r29,hi8(%o0)", op, plen, -5);
4838 }
4839 else if (REGNO (XEXP (x,0)) == REG_X)
4840 {
4841 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4842 {
4843 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4844 "adiw r26,%o0" CR_TAB
4845 "st X,__tmp_reg__", op, plen, -3);
4846 }
4847 else
4848 {
4849 avr_asm_len ("adiw r26,%o0" CR_TAB
4850 "st X,%1", op, plen, -2);
4851 }
4852
4853 if (!reg_unused_after (insn, XEXP (x,0)))
4854 avr_asm_len ("sbiw r26,%o0", op, plen, 1);
4855
4856 return "";
4857 }
4858
4859 return avr_asm_len ("std %0,%1", op, plen, -1);
4860 }
4861
4862 return avr_asm_len ("st %0,%1", op, plen, -1);
4863 }
4864
4865
4866 /* Helper for the next function for XMEGA. It does the same
4867 but with low byte first. */
4868
4869 static const char*
4870 avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen)
4871 {
4872 rtx dest = op[0];
4873 rtx src = op[1];
4874 rtx base = XEXP (dest, 0);
4875 int reg_base = true_regnum (base);
4876 int reg_src = true_regnum (src);
4877
4878 /* "volatile" forces writing low byte first, even if less efficient,
4879 for correct operation with 16-bit I/O registers like SP. */
4880 int mem_volatile_p = MEM_VOLATILE_P (dest);
4881
4882 if (CONSTANT_ADDRESS_P (base))
4883 {
4884 int n_words = AVR_TINY ? 2 : 4;
4885 return optimize > 0 && io_address_operand (base, HImode)
4886 ? avr_asm_len ("out %i0,%A1" CR_TAB
4887 "out %i0+1,%B1", op, plen, -2)
4888
4889 : avr_asm_len ("sts %m0,%A1" CR_TAB
4890 "sts %m0+1,%B1", op, plen, -n_words);
4891 }
4892
4893 if (reg_base > 0)
4894 {
4895 if (reg_base != REG_X)
4896 return avr_asm_len ("st %0,%A1" CR_TAB
4897 "std %0+1,%B1", op, plen, -2);
4898
4899 if (reg_src == REG_X)
4900 /* "st X+,r26" and "st -X,r26" are undefined. */
4901 avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4902 "st X,r26" CR_TAB
4903 "adiw r26,1" CR_TAB
4904 "st X,__tmp_reg__", op, plen, -4);
4905 else
4906 avr_asm_len ("st X+,%A1" CR_TAB
4907 "st X,%B1", op, plen, -2);
4908
4909 return reg_unused_after (insn, base)
4910 ? ""
4911 : avr_asm_len ("sbiw r26,1", op, plen, 1);
4912 }
4913 else if (GET_CODE (base) == PLUS)
4914 {
4915 int disp = INTVAL (XEXP (base, 1));
4916 reg_base = REGNO (XEXP (base, 0));
4917 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4918 {
4919 if (reg_base != REG_Y)
4920 fatal_insn ("incorrect insn:",insn);
4921
4922 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
4923 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
4924 "std Y+62,%A1" CR_TAB
4925 "std Y+63,%B1" CR_TAB
4926 "sbiw r28,%o0-62", op, plen, -4)
4927
4928 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4929 "sbci r29,hi8(-%o0)" CR_TAB
4930 "st Y,%A1" CR_TAB
4931 "std Y+1,%B1" CR_TAB
4932 "subi r28,lo8(%o0)" CR_TAB
4933 "sbci r29,hi8(%o0)", op, plen, -6);
4934 }
4935
4936 if (reg_base != REG_X)
4937 return avr_asm_len ("std %A0,%A1" CR_TAB
4938 "std %B0,%B1", op, plen, -2);
4939 /* (X + d) = R */
4940 return reg_src == REG_X
4941 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
4942 "mov __zero_reg__,r27" CR_TAB
4943 "adiw r26,%o0" CR_TAB
4944 "st X+,__tmp_reg__" CR_TAB
4945 "st X,__zero_reg__" CR_TAB
4946 "clr __zero_reg__" CR_TAB
4947 "sbiw r26,%o0+1", op, plen, -7)
4948
4949 : avr_asm_len ("adiw r26,%o0" CR_TAB
4950 "st X+,%A1" CR_TAB
4951 "st X,%B1" CR_TAB
4952 "sbiw r26,%o0+1", op, plen, -4);
4953 }
4954 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4955 {
4956 if (!mem_volatile_p)
4957 return avr_asm_len ("st %0,%B1" CR_TAB
4958 "st %0,%A1", op, plen, -2);
4959
4960 return REGNO (XEXP (base, 0)) == REG_X
4961 ? avr_asm_len ("sbiw r26,2" CR_TAB
4962 "st X+,%A1" CR_TAB
4963 "st X,%B1" CR_TAB
4964 "sbiw r26,1", op, plen, -4)
4965
4966 : avr_asm_len ("sbiw %r0,2" CR_TAB
4967 "st %p0,%A1" CR_TAB
4968 "std %p0+1,%B1", op, plen, -3);
4969 }
4970 else if (GET_CODE (base) == POST_INC) /* (R++) */
4971 {
4972 return avr_asm_len ("st %0,%A1" CR_TAB
4973 "st %0,%B1", op, plen, -2);
4974
4975 }
4976 fatal_insn ("unknown move insn:",insn);
4977 return "";
4978 }
4979
4980 static const char*
4981 avr_out_movhi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4982 {
4983 rtx dest = op[0];
4984 rtx src = op[1];
4985 rtx base = XEXP (dest, 0);
4986 int reg_base = true_regnum (base);
4987 int reg_src = true_regnum (src);
4988 int mem_volatile_p = MEM_VOLATILE_P (dest);
4989
4990 if (reg_base == reg_src)
4991 {
4992 return !mem_volatile_p && reg_unused_after (insn, src)
4993 ? avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
4994 "st %0,%A1" CR_TAB
4995 TINY_ADIW (%E0, %F0, 1) CR_TAB
4996 "st %0,__tmp_reg__", op, plen, -5)
4997 : avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
4998 TINY_ADIW (%E0, %F0, 1) CR_TAB
4999 "st %0,__tmp_reg__" CR_TAB
5000 TINY_SBIW (%E0, %F0, 1) CR_TAB
5001 "st %0, %A1", op, plen, -7);
5002 }
5003
5004 return !mem_volatile_p && reg_unused_after (insn, base)
5005 ? avr_asm_len ("st %0+,%A1" CR_TAB
5006 "st %0,%B1", op, plen, -2)
5007 : avr_asm_len (TINY_ADIW (%E0, %F0, 1) CR_TAB
5008 "st %0,%B1" CR_TAB
5009 "st -%0,%A1", op, plen, -4);
5010 }
5011
5012 static const char*
5013 avr_out_movhi_mr_r_reg_disp_tiny (rtx op[], int *plen)
5014 {
5015 rtx dest = op[0];
5016 rtx src = op[1];
5017 rtx base = XEXP (dest, 0);
5018 int reg_base = REGNO (XEXP (base, 0));
5019 int reg_src = true_regnum (src);
5020
5021 return reg_src == reg_base
5022 ? avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
5023 "mov __zero_reg__,%B1" CR_TAB
5024 TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
5025 "st %b0,__zero_reg__" CR_TAB
5026 "st -%b0,__tmp_reg__" CR_TAB
5027 "clr __zero_reg__" CR_TAB
5028 TINY_SBIW (%I0, %J0, %o0), op, plen, -9)
5029
5030 : avr_asm_len (TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
5031 "st %b0,%B1" CR_TAB
5032 "st -%b0,%A1" CR_TAB
5033 TINY_SBIW (%I0, %J0, %o0), op, plen, -6);
5034 }
5035
5036 static const char*
5037 avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen)
5038 {
5039 return avr_asm_len (TINY_ADIW (%I0, %J0, 1) CR_TAB
5040 "st %p0,%B1" CR_TAB
5041 "st -%p0,%A1" CR_TAB
5042 TINY_ADIW (%I0, %J0, 2), op, plen, -6);
5043 }
5044
5045 static const char*
5046 out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen)
5047 {
5048 rtx dest = op[0];
5049 rtx src = op[1];
5050 rtx base = XEXP (dest, 0);
5051 int reg_base = true_regnum (base);
5052 int reg_src = true_regnum (src);
5053 int mem_volatile_p;
5054
5055 /* "volatile" forces writing high-byte first (no-xmega) resp.
5056 low-byte first (xmega) even if less efficient, for correct
5057 operation with 16-bit I/O registers like. */
5058
5059 if (AVR_XMEGA)
5060 return avr_out_movhi_mr_r_xmega (insn, op, plen);
5061
5062 mem_volatile_p = MEM_VOLATILE_P (dest);
5063
5064 if (CONSTANT_ADDRESS_P (base))
5065 {
5066 int n_words = AVR_TINY ? 2 : 4;
5067 return optimize > 0 && io_address_operand (base, HImode)
5068 ? avr_asm_len ("out %i0+1,%B1" CR_TAB
5069 "out %i0,%A1", op, plen, -2)
5070
5071 : avr_asm_len ("sts %m0+1,%B1" CR_TAB
5072 "sts %m0,%A1", op, plen, -n_words);
5073 }
5074
5075 if (reg_base > 0)
5076 {
5077 if (AVR_TINY)
5078 return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen);
5079
5080 if (reg_base != REG_X)
5081 return avr_asm_len ("std %0+1,%B1" CR_TAB
5082 "st %0,%A1", op, plen, -2);
5083
5084 if (reg_src == REG_X)
5085 /* "st X+,r26" and "st -X,r26" are undefined. */
5086 return !mem_volatile_p && reg_unused_after (insn, src)
5087 ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5088 "st X,r26" CR_TAB
5089 "adiw r26,1" CR_TAB
5090 "st X,__tmp_reg__", op, plen, -4)
5091
5092 : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5093 "adiw r26,1" CR_TAB
5094 "st X,__tmp_reg__" CR_TAB
5095 "sbiw r26,1" CR_TAB
5096 "st X,r26", op, plen, -5);
5097
5098 return !mem_volatile_p && reg_unused_after (insn, base)
5099 ? avr_asm_len ("st X+,%A1" CR_TAB
5100 "st X,%B1", op, plen, -2)
5101 : avr_asm_len ("adiw r26,1" CR_TAB
5102 "st X,%B1" CR_TAB
5103 "st -X,%A1", op, plen, -3);
5104 }
5105 else if (GET_CODE (base) == PLUS)
5106 {
5107 int disp = INTVAL (XEXP (base, 1));
5108
5109 if (AVR_TINY)
5110 return avr_out_movhi_mr_r_reg_disp_tiny (op, plen);
5111
5112 reg_base = REGNO (XEXP (base, 0));
5113 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
5114 {
5115 if (reg_base != REG_Y)
5116 fatal_insn ("incorrect insn:",insn);
5117
5118 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
5119 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
5120 "std Y+63,%B1" CR_TAB
5121 "std Y+62,%A1" CR_TAB
5122 "sbiw r28,%o0-62", op, plen, -4)
5123
5124 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
5125 "sbci r29,hi8(-%o0)" CR_TAB
5126 "std Y+1,%B1" CR_TAB
5127 "st Y,%A1" CR_TAB
5128 "subi r28,lo8(%o0)" CR_TAB
5129 "sbci r29,hi8(%o0)", op, plen, -6);
5130 }
5131
5132 if (reg_base != REG_X)
5133 return avr_asm_len ("std %B0,%B1" CR_TAB
5134 "std %A0,%A1", op, plen, -2);
5135 /* (X + d) = R */
5136 return reg_src == REG_X
5137 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
5138 "mov __zero_reg__,r27" CR_TAB
5139 "adiw r26,%o0+1" CR_TAB
5140 "st X,__zero_reg__" CR_TAB
5141 "st -X,__tmp_reg__" CR_TAB
5142 "clr __zero_reg__" CR_TAB
5143 "sbiw r26,%o0", op, plen, -7)
5144
5145 : avr_asm_len ("adiw r26,%o0+1" CR_TAB
5146 "st X,%B1" CR_TAB
5147 "st -X,%A1" CR_TAB
5148 "sbiw r26,%o0", op, plen, -4);
5149 }
5150 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5151 {
5152 return avr_asm_len ("st %0,%B1" CR_TAB
5153 "st %0,%A1", op, plen, -2);
5154 }
5155 else if (GET_CODE (base) == POST_INC) /* (R++) */
5156 {
5157 if (!mem_volatile_p)
5158 return avr_asm_len ("st %0,%A1" CR_TAB
5159 "st %0,%B1", op, plen, -2);
5160
5161 if (AVR_TINY)
5162 return avr_out_movhi_mr_r_post_inc_tiny (op, plen);
5163
5164 return REGNO (XEXP (base, 0)) == REG_X
5165 ? avr_asm_len ("adiw r26,1" CR_TAB
5166 "st X,%B1" CR_TAB
5167 "st -X,%A1" CR_TAB
5168 "adiw r26,2", op, plen, -4)
5169
5170 : avr_asm_len ("std %p0+1,%B1" CR_TAB
5171 "st %p0,%A1" CR_TAB
5172 "adiw %r0,2", op, plen, -3);
5173 }
5174 fatal_insn ("unknown move insn:",insn);
5175 return "";
5176 }
5177
5178 /* Return 1 if frame pointer for current function required. */
5179
5180 static bool
5181 avr_frame_pointer_required_p (void)
5182 {
5183 return (cfun->calls_alloca
5184 || cfun->calls_setjmp
5185 || cfun->has_nonlocal_label
5186 || crtl->args.info.nregs == 0
5187 || get_frame_size () > 0);
5188 }
5189
5190 /* Returns the condition of compare insn INSN, or UNKNOWN. */
5191
5192 static RTX_CODE
5193 compare_condition (rtx_insn *insn)
5194 {
5195 rtx_insn *next = next_real_insn (insn);
5196
5197 if (next && JUMP_P (next))
5198 {
5199 rtx pat = PATTERN (next);
5200 rtx src = SET_SRC (pat);
5201
5202 if (IF_THEN_ELSE == GET_CODE (src))
5203 return GET_CODE (XEXP (src, 0));
5204 }
5205
5206 return UNKNOWN;
5207 }
5208
5209
5210 /* Returns true iff INSN is a tst insn that only tests the sign. */
5211
5212 static bool
5213 compare_sign_p (rtx_insn *insn)
5214 {
5215 RTX_CODE cond = compare_condition (insn);
5216 return (cond == GE || cond == LT);
5217 }
5218
5219
5220 /* Returns true iff the next insn is a JUMP_INSN with a condition
5221 that needs to be swapped (GT, GTU, LE, LEU). */
5222
5223 static bool
5224 compare_diff_p (rtx_insn *insn)
5225 {
5226 RTX_CODE cond = compare_condition (insn);
5227 return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
5228 }
5229
5230 /* Returns true iff INSN is a compare insn with the EQ or NE condition. */
5231
5232 static bool
5233 compare_eq_p (rtx_insn *insn)
5234 {
5235 RTX_CODE cond = compare_condition (insn);
5236 return (cond == EQ || cond == NE);
5237 }
5238
5239
5240 /* Output compare instruction
5241
5242 compare (XOP[0], XOP[1])
5243
5244 for a register XOP[0] and a compile-time constant XOP[1]. Return "".
5245 XOP[2] is an 8-bit scratch register as needed.
5246
5247 PLEN == NULL: Output instructions.
5248 PLEN != NULL: Set *PLEN to the length (in words) of the sequence.
5249 Don't output anything. */
5250
5251 const char*
5252 avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
5253 {
5254 /* Register to compare and value to compare against. */
5255 rtx xreg = xop[0];
5256 rtx xval = xop[1];
5257
5258 /* MODE of the comparison. */
5259 machine_mode mode;
5260
5261 /* Number of bytes to operate on. */
5262 int i, n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
5263
5264 /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown. */
5265 int clobber_val = -1;
5266
5267 /* Map fixed mode operands to integer operands with the same binary
5268 representation. They are easier to handle in the remainder. */
5269
5270 if (CONST_FIXED_P (xval))
5271 {
5272 xreg = avr_to_int_mode (xop[0]);
5273 xval = avr_to_int_mode (xop[1]);
5274 }
5275
5276 mode = GET_MODE (xreg);
5277
5278 gcc_assert (REG_P (xreg));
5279 gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
5280 || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
5281
5282 if (plen)
5283 *plen = 0;
5284
5285 /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
5286 against 0 by ORing the bytes. This is one instruction shorter.
5287 Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
5288 and therefore don't use this. */
5289
5290 if (!test_hard_reg_class (LD_REGS, xreg)
5291 && compare_eq_p (insn)
5292 && reg_unused_after (insn, xreg))
5293 {
5294 if (xval == const1_rtx)
5295 {
5296 avr_asm_len ("dec %A0" CR_TAB
5297 "or %A0,%B0", xop, plen, 2);
5298
5299 if (n_bytes >= 3)
5300 avr_asm_len ("or %A0,%C0", xop, plen, 1);
5301
5302 if (n_bytes >= 4)
5303 avr_asm_len ("or %A0,%D0", xop, plen, 1);
5304
5305 return "";
5306 }
5307 else if (xval == constm1_rtx)
5308 {
5309 if (n_bytes >= 4)
5310 avr_asm_len ("and %A0,%D0", xop, plen, 1);
5311
5312 if (n_bytes >= 3)
5313 avr_asm_len ("and %A0,%C0", xop, plen, 1);
5314
5315 return avr_asm_len ("and %A0,%B0" CR_TAB
5316 "com %A0", xop, plen, 2);
5317 }
5318 }
5319
5320 for (i = 0; i < n_bytes; i++)
5321 {
5322 /* We compare byte-wise. */
5323 rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
5324 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
5325
5326 /* 8-bit value to compare with this byte. */
5327 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
5328
5329 /* Registers R16..R31 can operate with immediate. */
5330 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
5331
5332 xop[0] = reg8;
5333 xop[1] = gen_int_mode (val8, QImode);
5334
5335 /* Word registers >= R24 can use SBIW/ADIW with 0..63. */
5336
5337 if (i == 0
5338 && test_hard_reg_class (ADDW_REGS, reg8))
5339 {
5340 int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
5341
5342 if (IN_RANGE (val16, 0, 63)
5343 && (val8 == 0
5344 || reg_unused_after (insn, xreg)))
5345 {
5346 if (AVR_TINY)
5347 avr_asm_len (TINY_SBIW (%A0, %B0, %1), xop, plen, 2);
5348 else
5349 avr_asm_len ("sbiw %0,%1", xop, plen, 1);
5350
5351 i++;
5352 continue;
5353 }
5354
5355 if (n_bytes == 2
5356 && IN_RANGE (val16, -63, -1)
5357 && compare_eq_p (insn)
5358 && reg_unused_after (insn, xreg))
5359 {
5360 return AVR_TINY
5361 ? avr_asm_len (TINY_ADIW (%A0, %B0, %n1), xop, plen, 2)
5362 : avr_asm_len ("adiw %0,%n1", xop, plen, 1);
5363 }
5364 }
5365
5366 /* Comparing against 0 is easy. */
5367
5368 if (val8 == 0)
5369 {
5370 avr_asm_len (i == 0
5371 ? "cp %0,__zero_reg__"
5372 : "cpc %0,__zero_reg__", xop, plen, 1);
5373 continue;
5374 }
5375
5376 /* Upper registers can compare and subtract-with-carry immediates.
5377 Notice that compare instructions do the same as respective subtract
5378 instruction; the only difference is that comparisons don't write
5379 the result back to the target register. */
5380
5381 if (ld_reg_p)
5382 {
5383 if (i == 0)
5384 {
5385 avr_asm_len ("cpi %0,%1", xop, plen, 1);
5386 continue;
5387 }
5388 else if (reg_unused_after (insn, xreg))
5389 {
5390 avr_asm_len ("sbci %0,%1", xop, plen, 1);
5391 continue;
5392 }
5393 }
5394
5395 /* Must load the value into the scratch register. */
5396
5397 gcc_assert (REG_P (xop[2]));
5398
5399 if (clobber_val != (int) val8)
5400 avr_asm_len ("ldi %2,%1", xop, plen, 1);
5401 clobber_val = (int) val8;
5402
5403 avr_asm_len (i == 0
5404 ? "cp %0,%2"
5405 : "cpc %0,%2", xop, plen, 1);
5406 }
5407
5408 return "";
5409 }
5410
5411
5412 /* Prepare operands of compare_const_di2 to be used with avr_out_compare. */
5413
5414 const char*
5415 avr_out_compare64 (rtx_insn *insn, rtx *op, int *plen)
5416 {
5417 rtx xop[3];
5418
5419 xop[0] = gen_rtx_REG (DImode, 18);
5420 xop[1] = op[0];
5421 xop[2] = op[1];
5422
5423 return avr_out_compare (insn, xop, plen);
5424 }
5425
5426 /* Output test instruction for HImode. */
5427
5428 const char*
5429 avr_out_tsthi (rtx_insn *insn, rtx *op, int *plen)
5430 {
5431 if (compare_sign_p (insn))
5432 {
5433 avr_asm_len ("tst %B0", op, plen, -1);
5434 }
5435 else if (reg_unused_after (insn, op[0])
5436 && compare_eq_p (insn))
5437 {
5438 /* Faster than sbiw if we can clobber the operand. */
5439 avr_asm_len ("or %A0,%B0", op, plen, -1);
5440 }
5441 else
5442 {
5443 avr_out_compare (insn, op, plen);
5444 }
5445
5446 return "";
5447 }
5448
5449
5450 /* Output test instruction for PSImode. */
5451
5452 const char*
5453 avr_out_tstpsi (rtx_insn *insn, rtx *op, int *plen)
5454 {
5455 if (compare_sign_p (insn))
5456 {
5457 avr_asm_len ("tst %C0", op, plen, -1);
5458 }
5459 else if (reg_unused_after (insn, op[0])
5460 && compare_eq_p (insn))
5461 {
5462 /* Faster than sbiw if we can clobber the operand. */
5463 avr_asm_len ("or %A0,%B0" CR_TAB
5464 "or %A0,%C0", op, plen, -2);
5465 }
5466 else
5467 {
5468 avr_out_compare (insn, op, plen);
5469 }
5470
5471 return "";
5472 }
5473
5474
5475 /* Output test instruction for SImode. */
5476
5477 const char*
5478 avr_out_tstsi (rtx_insn *insn, rtx *op, int *plen)
5479 {
5480 if (compare_sign_p (insn))
5481 {
5482 avr_asm_len ("tst %D0", op, plen, -1);
5483 }
5484 else if (reg_unused_after (insn, op[0])
5485 && compare_eq_p (insn))
5486 {
5487 /* Faster than sbiw if we can clobber the operand. */
5488 avr_asm_len ("or %A0,%B0" CR_TAB
5489 "or %A0,%C0" CR_TAB
5490 "or %A0,%D0", op, plen, -3);
5491 }
5492 else
5493 {
5494 avr_out_compare (insn, op, plen);
5495 }
5496
5497 return "";
5498 }
5499
5500
5501 /* Generate asm equivalent for various shifts. This only handles cases
5502 that are not already carefully hand-optimized in ?sh??i3_out.
5503
5504 OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
5505 OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
5506 OPERANDS[3] is a QImode scratch register from LD regs if
5507 available and SCRATCH, otherwise (no scratch available)
5508
5509 TEMPL is an assembler template that shifts by one position.
5510 T_LEN is the length of this template. */
5511
5512 void
5513 out_shift_with_cnt (const char *templ, rtx_insn *insn, rtx operands[],
5514 int *plen, int t_len)
5515 {
5516 bool second_label = true;
5517 bool saved_in_tmp = false;
5518 bool use_zero_reg = false;
5519 rtx op[5];
5520
5521 op[0] = operands[0];
5522 op[1] = operands[1];
5523 op[2] = operands[2];
5524 op[3] = operands[3];
5525
5526 if (plen)
5527 *plen = 0;
5528
5529 if (CONST_INT_P (operands[2]))
5530 {
5531 bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
5532 && REG_P (operands[3]));
5533 int count = INTVAL (operands[2]);
5534 int max_len = 10; /* If larger than this, always use a loop. */
5535
5536 if (count <= 0)
5537 return;
5538
5539 if (count < 8 && !scratch)
5540 use_zero_reg = true;
5541
5542 if (optimize_size)
5543 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
5544
5545 if (t_len * count <= max_len)
5546 {
5547 /* Output shifts inline with no loop - faster. */
5548
5549 while (count-- > 0)
5550 avr_asm_len (templ, op, plen, t_len);
5551
5552 return;
5553 }
5554
5555 if (scratch)
5556 {
5557 avr_asm_len ("ldi %3,%2", op, plen, 1);
5558 }
5559 else if (use_zero_reg)
5560 {
5561 /* Hack to save one word: use __zero_reg__ as loop counter.
5562 Set one bit, then shift in a loop until it is 0 again. */
5563
5564 op[3] = zero_reg_rtx;
5565
5566 avr_asm_len ("set" CR_TAB
5567 "bld %3,%2-1", op, plen, 2);
5568 }
5569 else
5570 {
5571 /* No scratch register available, use one from LD_REGS (saved in
5572 __tmp_reg__) that doesn't overlap with registers to shift. */
5573
5574 op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + 16];
5575 op[4] = tmp_reg_rtx;
5576 saved_in_tmp = true;
5577
5578 avr_asm_len ("mov %4,%3" CR_TAB
5579 "ldi %3,%2", op, plen, 2);
5580 }
5581
5582 second_label = false;
5583 }
5584 else if (MEM_P (op[2]))
5585 {
5586 rtx op_mov[2];
5587
5588 op_mov[0] = op[3] = tmp_reg_rtx;
5589 op_mov[1] = op[2];
5590
5591 out_movqi_r_mr (insn, op_mov, plen);
5592 }
5593 else if (register_operand (op[2], QImode))
5594 {
5595 op[3] = op[2];
5596
5597 if (!reg_unused_after (insn, op[2])
5598 || reg_overlap_mentioned_p (op[0], op[2]))
5599 {
5600 op[3] = tmp_reg_rtx;
5601 avr_asm_len ("mov %3,%2", op, plen, 1);
5602 }
5603 }
5604 else
5605 fatal_insn ("bad shift insn:", insn);
5606
5607 if (second_label)
5608 avr_asm_len ("rjmp 2f", op, plen, 1);
5609
5610 avr_asm_len ("1:", op, plen, 0);
5611 avr_asm_len (templ, op, plen, t_len);
5612
5613 if (second_label)
5614 avr_asm_len ("2:", op, plen, 0);
5615
5616 avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
5617 avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
5618
5619 if (saved_in_tmp)
5620 avr_asm_len ("mov %3,%4", op, plen, 1);
5621 }
5622
5623
5624 /* 8bit shift left ((char)x << i) */
5625
5626 const char *
5627 ashlqi3_out (rtx_insn *insn, rtx operands[], int *len)
5628 {
5629 if (GET_CODE (operands[2]) == CONST_INT)
5630 {
5631 int k;
5632
5633 if (!len)
5634 len = &k;
5635
5636 switch (INTVAL (operands[2]))
5637 {
5638 default:
5639 if (INTVAL (operands[2]) < 8)
5640 break;
5641
5642 *len = 1;
5643 return "clr %0";
5644
5645 case 1:
5646 *len = 1;
5647 return "lsl %0";
5648
5649 case 2:
5650 *len = 2;
5651 return ("lsl %0" CR_TAB
5652 "lsl %0");
5653
5654 case 3:
5655 *len = 3;
5656 return ("lsl %0" CR_TAB
5657 "lsl %0" CR_TAB
5658 "lsl %0");
5659
5660 case 4:
5661 if (test_hard_reg_class (LD_REGS, operands[0]))
5662 {
5663 *len = 2;
5664 return ("swap %0" CR_TAB
5665 "andi %0,0xf0");
5666 }
5667 *len = 4;
5668 return ("lsl %0" CR_TAB
5669 "lsl %0" CR_TAB
5670 "lsl %0" CR_TAB
5671 "lsl %0");
5672
5673 case 5:
5674 if (test_hard_reg_class (LD_REGS, operands[0]))
5675 {
5676 *len = 3;
5677 return ("swap %0" CR_TAB
5678 "lsl %0" CR_TAB
5679 "andi %0,0xe0");
5680 }
5681 *len = 5;
5682 return ("lsl %0" CR_TAB
5683 "lsl %0" CR_TAB
5684 "lsl %0" CR_TAB
5685 "lsl %0" CR_TAB
5686 "lsl %0");
5687
5688 case 6:
5689 if (test_hard_reg_class (LD_REGS, operands[0]))
5690 {
5691 *len = 4;
5692 return ("swap %0" CR_TAB
5693 "lsl %0" CR_TAB
5694 "lsl %0" CR_TAB
5695 "andi %0,0xc0");
5696 }
5697 *len = 6;
5698 return ("lsl %0" CR_TAB
5699 "lsl %0" CR_TAB
5700 "lsl %0" CR_TAB
5701 "lsl %0" CR_TAB
5702 "lsl %0" CR_TAB
5703 "lsl %0");
5704
5705 case 7:
5706 *len = 3;
5707 return ("ror %0" CR_TAB
5708 "clr %0" CR_TAB
5709 "ror %0");
5710 }
5711 }
5712 else if (CONSTANT_P (operands[2]))
5713 fatal_insn ("internal compiler error. Incorrect shift:", insn);
5714
5715 out_shift_with_cnt ("lsl %0",
5716 insn, operands, len, 1);
5717 return "";
5718 }
5719
5720
5721 /* 16bit shift left ((short)x << i) */
5722
5723 const char *
5724 ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
5725 {
5726 if (GET_CODE (operands[2]) == CONST_INT)
5727 {
5728 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5729 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5730 int k;
5731 int *t = len;
5732
5733 if (!len)
5734 len = &k;
5735
5736 switch (INTVAL (operands[2]))
5737 {
5738 default:
5739 if (INTVAL (operands[2]) < 16)
5740 break;
5741
5742 *len = 2;
5743 return ("clr %B0" CR_TAB
5744 "clr %A0");
5745
5746 case 4:
5747 if (optimize_size && scratch)
5748 break; /* 5 */
5749 if (ldi_ok)
5750 {
5751 *len = 6;
5752 return ("swap %A0" CR_TAB
5753 "swap %B0" CR_TAB
5754 "andi %B0,0xf0" CR_TAB
5755 "eor %B0,%A0" CR_TAB
5756 "andi %A0,0xf0" CR_TAB
5757 "eor %B0,%A0");
5758 }
5759 if (scratch)
5760 {
5761 *len = 7;
5762 return ("swap %A0" CR_TAB
5763 "swap %B0" CR_TAB
5764 "ldi %3,0xf0" CR_TAB
5765 "and %B0,%3" CR_TAB
5766 "eor %B0,%A0" CR_TAB
5767 "and %A0,%3" CR_TAB
5768 "eor %B0,%A0");
5769 }
5770 break; /* optimize_size ? 6 : 8 */
5771
5772 case 5:
5773 if (optimize_size)
5774 break; /* scratch ? 5 : 6 */
5775 if (ldi_ok)
5776 {
5777 *len = 8;
5778 return ("lsl %A0" CR_TAB
5779 "rol %B0" CR_TAB
5780 "swap %A0" CR_TAB
5781 "swap %B0" CR_TAB
5782 "andi %B0,0xf0" CR_TAB
5783 "eor %B0,%A0" CR_TAB
5784 "andi %A0,0xf0" CR_TAB
5785 "eor %B0,%A0");
5786 }
5787 if (scratch)
5788 {
5789 *len = 9;
5790 return ("lsl %A0" CR_TAB
5791 "rol %B0" CR_TAB
5792 "swap %A0" CR_TAB
5793 "swap %B0" CR_TAB
5794 "ldi %3,0xf0" CR_TAB
5795 "and %B0,%3" CR_TAB
5796 "eor %B0,%A0" CR_TAB
5797 "and %A0,%3" CR_TAB
5798 "eor %B0,%A0");
5799 }
5800 break; /* 10 */
5801
5802 case 6:
5803 if (optimize_size)
5804 break; /* scratch ? 5 : 6 */
5805 *len = 9;
5806 return ("clr __tmp_reg__" CR_TAB
5807 "lsr %B0" CR_TAB
5808 "ror %A0" CR_TAB
5809 "ror __tmp_reg__" CR_TAB
5810 "lsr %B0" CR_TAB
5811 "ror %A0" CR_TAB
5812 "ror __tmp_reg__" CR_TAB
5813 "mov %B0,%A0" CR_TAB
5814 "mov %A0,__tmp_reg__");
5815
5816 case 7:
5817 *len = 5;
5818 return ("lsr %B0" CR_TAB
5819 "mov %B0,%A0" CR_TAB
5820 "clr %A0" CR_TAB
5821 "ror %B0" CR_TAB
5822 "ror %A0");
5823
5824 case 8:
5825 return *len = 2, ("mov %B0,%A1" CR_TAB
5826 "clr %A0");
5827
5828 case 9:
5829 *len = 3;
5830 return ("mov %B0,%A0" CR_TAB
5831 "clr %A0" CR_TAB
5832 "lsl %B0");
5833
5834 case 10:
5835 *len = 4;
5836 return ("mov %B0,%A0" CR_TAB
5837 "clr %A0" CR_TAB
5838 "lsl %B0" CR_TAB
5839 "lsl %B0");
5840
5841 case 11:
5842 *len = 5;
5843 return ("mov %B0,%A0" CR_TAB
5844 "clr %A0" CR_TAB
5845 "lsl %B0" CR_TAB
5846 "lsl %B0" CR_TAB
5847 "lsl %B0");
5848
5849 case 12:
5850 if (ldi_ok)
5851 {
5852 *len = 4;
5853 return ("mov %B0,%A0" CR_TAB
5854 "clr %A0" CR_TAB
5855 "swap %B0" CR_TAB
5856 "andi %B0,0xf0");
5857 }
5858 if (scratch)
5859 {
5860 *len = 5;
5861 return ("mov %B0,%A0" CR_TAB
5862 "clr %A0" CR_TAB
5863 "swap %B0" CR_TAB
5864 "ldi %3,0xf0" CR_TAB
5865 "and %B0,%3");
5866 }
5867 *len = 6;
5868 return ("mov %B0,%A0" CR_TAB
5869 "clr %A0" CR_TAB
5870 "lsl %B0" CR_TAB
5871 "lsl %B0" CR_TAB
5872 "lsl %B0" CR_TAB
5873 "lsl %B0");
5874
5875 case 13:
5876 if (ldi_ok)
5877 {
5878 *len = 5;
5879 return ("mov %B0,%A0" CR_TAB
5880 "clr %A0" CR_TAB
5881 "swap %B0" CR_TAB
5882 "lsl %B0" CR_TAB
5883 "andi %B0,0xe0");
5884 }
5885 if (AVR_HAVE_MUL && scratch)
5886 {
5887 *len = 5;
5888 return ("ldi %3,0x20" CR_TAB
5889 "mul %A0,%3" CR_TAB
5890 "mov %B0,r0" CR_TAB
5891 "clr %A0" CR_TAB
5892 "clr __zero_reg__");
5893 }
5894 if (optimize_size && scratch)
5895 break; /* 5 */
5896 if (scratch)
5897 {
5898 *len = 6;
5899 return ("mov %B0,%A0" CR_TAB
5900 "clr %A0" CR_TAB
5901 "swap %B0" CR_TAB
5902 "lsl %B0" CR_TAB
5903 "ldi %3,0xe0" CR_TAB
5904 "and %B0,%3");
5905 }
5906 if (AVR_HAVE_MUL)
5907 {
5908 *len = 6;
5909 return ("set" CR_TAB
5910 "bld r1,5" CR_TAB
5911 "mul %A0,r1" CR_TAB
5912 "mov %B0,r0" CR_TAB
5913 "clr %A0" CR_TAB
5914 "clr __zero_reg__");
5915 }
5916 *len = 7;
5917 return ("mov %B0,%A0" CR_TAB
5918 "clr %A0" CR_TAB
5919 "lsl %B0" CR_TAB
5920 "lsl %B0" CR_TAB
5921 "lsl %B0" CR_TAB
5922 "lsl %B0" CR_TAB
5923 "lsl %B0");
5924
5925 case 14:
5926 if (AVR_HAVE_MUL && ldi_ok)
5927 {
5928 *len = 5;
5929 return ("ldi %B0,0x40" CR_TAB
5930 "mul %A0,%B0" CR_TAB
5931 "mov %B0,r0" CR_TAB
5932 "clr %A0" CR_TAB
5933 "clr __zero_reg__");
5934 }
5935 if (AVR_HAVE_MUL && scratch)
5936 {
5937 *len = 5;
5938 return ("ldi %3,0x40" CR_TAB
5939 "mul %A0,%3" CR_TAB
5940 "mov %B0,r0" CR_TAB
5941 "clr %A0" CR_TAB
5942 "clr __zero_reg__");
5943 }
5944 if (optimize_size && ldi_ok)
5945 {
5946 *len = 5;
5947 return ("mov %B0,%A0" CR_TAB
5948 "ldi %A0,6" "\n1:\t"
5949 "lsl %B0" CR_TAB
5950 "dec %A0" CR_TAB
5951 "brne 1b");
5952 }
5953 if (optimize_size && scratch)
5954 break; /* 5 */
5955 *len = 6;
5956 return ("clr %B0" CR_TAB
5957 "lsr %A0" CR_TAB
5958 "ror %B0" CR_TAB
5959 "lsr %A0" CR_TAB
5960 "ror %B0" CR_TAB
5961 "clr %A0");
5962
5963 case 15:
5964 *len = 4;
5965 return ("clr %B0" CR_TAB
5966 "lsr %A0" CR_TAB
5967 "ror %B0" CR_TAB
5968 "clr %A0");
5969 }
5970 len = t;
5971 }
5972 out_shift_with_cnt ("lsl %A0" CR_TAB
5973 "rol %B0", insn, operands, len, 2);
5974 return "";
5975 }
5976
5977
5978 /* 24-bit shift left */
5979
5980 const char*
5981 avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen)
5982 {
5983 if (plen)
5984 *plen = 0;
5985
5986 if (CONST_INT_P (op[2]))
5987 {
5988 switch (INTVAL (op[2]))
5989 {
5990 default:
5991 if (INTVAL (op[2]) < 24)
5992 break;
5993
5994 return avr_asm_len ("clr %A0" CR_TAB
5995 "clr %B0" CR_TAB
5996 "clr %C0", op, plen, 3);
5997
5998 case 8:
5999 {
6000 int reg0 = REGNO (op[0]);
6001 int reg1 = REGNO (op[1]);
6002
6003 if (reg0 >= reg1)
6004 return avr_asm_len ("mov %C0,%B1" CR_TAB
6005 "mov %B0,%A1" CR_TAB
6006 "clr %A0", op, plen, 3);
6007 else
6008 return avr_asm_len ("clr %A0" CR_TAB
6009 "mov %B0,%A1" CR_TAB
6010 "mov %C0,%B1", op, plen, 3);
6011 }
6012
6013 case 16:
6014 {
6015 int reg0 = REGNO (op[0]);
6016 int reg1 = REGNO (op[1]);
6017
6018 if (reg0 + 2 != reg1)
6019 avr_asm_len ("mov %C0,%A0", op, plen, 1);
6020
6021 return avr_asm_len ("clr %B0" CR_TAB
6022 "clr %A0", op, plen, 2);
6023 }
6024
6025 case 23:
6026 return avr_asm_len ("clr %C0" CR_TAB
6027 "lsr %A0" CR_TAB
6028 "ror %C0" CR_TAB
6029 "clr %B0" CR_TAB
6030 "clr %A0", op, plen, 5);
6031 }
6032 }
6033
6034 out_shift_with_cnt ("lsl %A0" CR_TAB
6035 "rol %B0" CR_TAB
6036 "rol %C0", insn, op, plen, 3);
6037 return "";
6038 }
6039
6040
6041 /* 32bit shift left ((long)x << i) */
6042
6043 const char *
6044 ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
6045 {
6046 if (GET_CODE (operands[2]) == CONST_INT)
6047 {
6048 int k;
6049 int *t = len;
6050
6051 if (!len)
6052 len = &k;
6053
6054 switch (INTVAL (operands[2]))
6055 {
6056 default:
6057 if (INTVAL (operands[2]) < 32)
6058 break;
6059
6060 if (AVR_HAVE_MOVW)
6061 return *len = 3, ("clr %D0" CR_TAB
6062 "clr %C0" CR_TAB
6063 "movw %A0,%C0");
6064 *len = 4;
6065 return ("clr %D0" CR_TAB
6066 "clr %C0" CR_TAB
6067 "clr %B0" CR_TAB
6068 "clr %A0");
6069
6070 case 8:
6071 {
6072 int reg0 = true_regnum (operands[0]);
6073 int reg1 = true_regnum (operands[1]);
6074 *len = 4;
6075 if (reg0 >= reg1)
6076 return ("mov %D0,%C1" CR_TAB
6077 "mov %C0,%B1" CR_TAB
6078 "mov %B0,%A1" CR_TAB
6079 "clr %A0");
6080 else
6081 return ("clr %A0" CR_TAB
6082 "mov %B0,%A1" CR_TAB
6083 "mov %C0,%B1" CR_TAB
6084 "mov %D0,%C1");
6085 }
6086
6087 case 16:
6088 {
6089 int reg0 = true_regnum (operands[0]);
6090 int reg1 = true_regnum (operands[1]);
6091 if (reg0 + 2 == reg1)
6092 return *len = 2, ("clr %B0" CR_TAB
6093 "clr %A0");
6094 if (AVR_HAVE_MOVW)
6095 return *len = 3, ("movw %C0,%A1" CR_TAB
6096 "clr %B0" CR_TAB
6097 "clr %A0");
6098 else
6099 return *len = 4, ("mov %C0,%A1" CR_TAB
6100 "mov %D0,%B1" CR_TAB
6101 "clr %B0" CR_TAB
6102 "clr %A0");
6103 }
6104
6105 case 24:
6106 *len = 4;
6107 return ("mov %D0,%A1" CR_TAB
6108 "clr %C0" CR_TAB
6109 "clr %B0" CR_TAB
6110 "clr %A0");
6111
6112 case 31:
6113 *len = 6;
6114 return ("clr %D0" CR_TAB
6115 "lsr %A0" CR_TAB
6116 "ror %D0" CR_TAB
6117 "clr %C0" CR_TAB
6118 "clr %B0" CR_TAB
6119 "clr %A0");
6120 }
6121 len = t;
6122 }
6123 out_shift_with_cnt ("lsl %A0" CR_TAB
6124 "rol %B0" CR_TAB
6125 "rol %C0" CR_TAB
6126 "rol %D0", insn, operands, len, 4);
6127 return "";
6128 }
6129
6130 /* 8bit arithmetic shift right ((signed char)x >> i) */
6131
6132 const char *
6133 ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6134 {
6135 if (GET_CODE (operands[2]) == CONST_INT)
6136 {
6137 int k;
6138
6139 if (!len)
6140 len = &k;
6141
6142 switch (INTVAL (operands[2]))
6143 {
6144 case 1:
6145 *len = 1;
6146 return "asr %0";
6147
6148 case 2:
6149 *len = 2;
6150 return ("asr %0" CR_TAB
6151 "asr %0");
6152
6153 case 3:
6154 *len = 3;
6155 return ("asr %0" CR_TAB
6156 "asr %0" CR_TAB
6157 "asr %0");
6158
6159 case 4:
6160 *len = 4;
6161 return ("asr %0" CR_TAB
6162 "asr %0" CR_TAB
6163 "asr %0" CR_TAB
6164 "asr %0");
6165
6166 case 5:
6167 *len = 5;
6168 return ("asr %0" CR_TAB
6169 "asr %0" CR_TAB
6170 "asr %0" CR_TAB
6171 "asr %0" CR_TAB
6172 "asr %0");
6173
6174 case 6:
6175 *len = 4;
6176 return ("bst %0,6" CR_TAB
6177 "lsl %0" CR_TAB
6178 "sbc %0,%0" CR_TAB
6179 "bld %0,0");
6180
6181 default:
6182 if (INTVAL (operands[2]) < 8)
6183 break;
6184
6185 /* fall through */
6186
6187 case 7:
6188 *len = 2;
6189 return ("lsl %0" CR_TAB
6190 "sbc %0,%0");
6191 }
6192 }
6193 else if (CONSTANT_P (operands[2]))
6194 fatal_insn ("internal compiler error. Incorrect shift:", insn);
6195
6196 out_shift_with_cnt ("asr %0",
6197 insn, operands, len, 1);
6198 return "";
6199 }
6200
6201
6202 /* 16bit arithmetic shift right ((signed short)x >> i) */
6203
6204 const char *
6205 ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6206 {
6207 if (GET_CODE (operands[2]) == CONST_INT)
6208 {
6209 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6210 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6211 int k;
6212 int *t = len;
6213
6214 if (!len)
6215 len = &k;
6216
6217 switch (INTVAL (operands[2]))
6218 {
6219 case 4:
6220 case 5:
6221 /* XXX try to optimize this too? */
6222 break;
6223
6224 case 6:
6225 if (optimize_size)
6226 break; /* scratch ? 5 : 6 */
6227 *len = 8;
6228 return ("mov __tmp_reg__,%A0" CR_TAB
6229 "mov %A0,%B0" CR_TAB
6230 "lsl __tmp_reg__" CR_TAB
6231 "rol %A0" CR_TAB
6232 "sbc %B0,%B0" CR_TAB
6233 "lsl __tmp_reg__" CR_TAB
6234 "rol %A0" CR_TAB
6235 "rol %B0");
6236
6237 case 7:
6238 *len = 4;
6239 return ("lsl %A0" CR_TAB
6240 "mov %A0,%B0" CR_TAB
6241 "rol %A0" CR_TAB
6242 "sbc %B0,%B0");
6243
6244 case 8:
6245 {
6246 int reg0 = true_regnum (operands[0]);
6247 int reg1 = true_regnum (operands[1]);
6248
6249 if (reg0 == reg1)
6250 return *len = 3, ("mov %A0,%B0" CR_TAB
6251 "lsl %B0" CR_TAB
6252 "sbc %B0,%B0");
6253 else
6254 return *len = 4, ("mov %A0,%B1" CR_TAB
6255 "clr %B0" CR_TAB
6256 "sbrc %A0,7" CR_TAB
6257 "dec %B0");
6258 }
6259
6260 case 9:
6261 *len = 4;
6262 return ("mov %A0,%B0" CR_TAB
6263 "lsl %B0" CR_TAB
6264 "sbc %B0,%B0" CR_TAB
6265 "asr %A0");
6266
6267 case 10:
6268 *len = 5;
6269 return ("mov %A0,%B0" CR_TAB
6270 "lsl %B0" CR_TAB
6271 "sbc %B0,%B0" CR_TAB
6272 "asr %A0" CR_TAB
6273 "asr %A0");
6274
6275 case 11:
6276 if (AVR_HAVE_MUL && ldi_ok)
6277 {
6278 *len = 5;
6279 return ("ldi %A0,0x20" CR_TAB
6280 "muls %B0,%A0" CR_TAB
6281 "mov %A0,r1" CR_TAB
6282 "sbc %B0,%B0" CR_TAB
6283 "clr __zero_reg__");
6284 }
6285 if (optimize_size && scratch)
6286 break; /* 5 */
6287 *len = 6;
6288 return ("mov %A0,%B0" CR_TAB
6289 "lsl %B0" CR_TAB
6290 "sbc %B0,%B0" CR_TAB
6291 "asr %A0" CR_TAB
6292 "asr %A0" CR_TAB
6293 "asr %A0");
6294
6295 case 12:
6296 if (AVR_HAVE_MUL && ldi_ok)
6297 {
6298 *len = 5;
6299 return ("ldi %A0,0x10" CR_TAB
6300 "muls %B0,%A0" CR_TAB
6301 "mov %A0,r1" CR_TAB
6302 "sbc %B0,%B0" CR_TAB
6303 "clr __zero_reg__");
6304 }
6305 if (optimize_size && scratch)
6306 break; /* 5 */
6307 *len = 7;
6308 return ("mov %A0,%B0" CR_TAB
6309 "lsl %B0" CR_TAB
6310 "sbc %B0,%B0" CR_TAB
6311 "asr %A0" CR_TAB
6312 "asr %A0" CR_TAB
6313 "asr %A0" CR_TAB
6314 "asr %A0");
6315
6316 case 13:
6317 if (AVR_HAVE_MUL && ldi_ok)
6318 {
6319 *len = 5;
6320 return ("ldi %A0,0x08" CR_TAB
6321 "muls %B0,%A0" CR_TAB
6322 "mov %A0,r1" CR_TAB
6323 "sbc %B0,%B0" CR_TAB
6324 "clr __zero_reg__");
6325 }
6326 if (optimize_size)
6327 break; /* scratch ? 5 : 7 */
6328 *len = 8;
6329 return ("mov %A0,%B0" CR_TAB
6330 "lsl %B0" CR_TAB
6331 "sbc %B0,%B0" CR_TAB
6332 "asr %A0" CR_TAB
6333 "asr %A0" CR_TAB
6334 "asr %A0" CR_TAB
6335 "asr %A0" CR_TAB
6336 "asr %A0");
6337
6338 case 14:
6339 *len = 5;
6340 return ("lsl %B0" CR_TAB
6341 "sbc %A0,%A0" CR_TAB
6342 "lsl %B0" CR_TAB
6343 "mov %B0,%A0" CR_TAB
6344 "rol %A0");
6345
6346 default:
6347 if (INTVAL (operands[2]) < 16)
6348 break;
6349
6350 /* fall through */
6351
6352 case 15:
6353 return *len = 3, ("lsl %B0" CR_TAB
6354 "sbc %A0,%A0" CR_TAB
6355 "mov %B0,%A0");
6356 }
6357 len = t;
6358 }
6359 out_shift_with_cnt ("asr %B0" CR_TAB
6360 "ror %A0", insn, operands, len, 2);
6361 return "";
6362 }
6363
6364
6365 /* 24-bit arithmetic shift right */
6366
6367 const char*
6368 avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6369 {
6370 int dest = REGNO (op[0]);
6371 int src = REGNO (op[1]);
6372
6373 if (CONST_INT_P (op[2]))
6374 {
6375 if (plen)
6376 *plen = 0;
6377
6378 switch (INTVAL (op[2]))
6379 {
6380 case 8:
6381 if (dest <= src)
6382 return avr_asm_len ("mov %A0,%B1" CR_TAB
6383 "mov %B0,%C1" CR_TAB
6384 "clr %C0" CR_TAB
6385 "sbrc %B0,7" CR_TAB
6386 "dec %C0", op, plen, 5);
6387 else
6388 return avr_asm_len ("clr %C0" CR_TAB
6389 "sbrc %C1,7" CR_TAB
6390 "dec %C0" CR_TAB
6391 "mov %B0,%C1" CR_TAB
6392 "mov %A0,%B1", op, plen, 5);
6393
6394 case 16:
6395 if (dest != src + 2)
6396 avr_asm_len ("mov %A0,%C1", op, plen, 1);
6397
6398 return avr_asm_len ("clr %B0" CR_TAB
6399 "sbrc %A0,7" CR_TAB
6400 "com %B0" CR_TAB
6401 "mov %C0,%B0", op, plen, 4);
6402
6403 default:
6404 if (INTVAL (op[2]) < 24)
6405 break;
6406
6407 /* fall through */
6408
6409 case 23:
6410 return avr_asm_len ("lsl %C0" CR_TAB
6411 "sbc %A0,%A0" CR_TAB
6412 "mov %B0,%A0" CR_TAB
6413 "mov %C0,%A0", op, plen, 4);
6414 } /* switch */
6415 }
6416
6417 out_shift_with_cnt ("asr %C0" CR_TAB
6418 "ror %B0" CR_TAB
6419 "ror %A0", insn, op, plen, 3);
6420 return "";
6421 }
6422
6423
6424 /* 32-bit arithmetic shift right ((signed long)x >> i) */
6425
6426 const char *
6427 ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6428 {
6429 if (GET_CODE (operands[2]) == CONST_INT)
6430 {
6431 int k;
6432 int *t = len;
6433
6434 if (!len)
6435 len = &k;
6436
6437 switch (INTVAL (operands[2]))
6438 {
6439 case 8:
6440 {
6441 int reg0 = true_regnum (operands[0]);
6442 int reg1 = true_regnum (operands[1]);
6443 *len=6;
6444 if (reg0 <= reg1)
6445 return ("mov %A0,%B1" CR_TAB
6446 "mov %B0,%C1" CR_TAB
6447 "mov %C0,%D1" CR_TAB
6448 "clr %D0" CR_TAB
6449 "sbrc %C0,7" CR_TAB
6450 "dec %D0");
6451 else
6452 return ("clr %D0" CR_TAB
6453 "sbrc %D1,7" CR_TAB
6454 "dec %D0" CR_TAB
6455 "mov %C0,%D1" CR_TAB
6456 "mov %B0,%C1" CR_TAB
6457 "mov %A0,%B1");
6458 }
6459
6460 case 16:
6461 {
6462 int reg0 = true_regnum (operands[0]);
6463 int reg1 = true_regnum (operands[1]);
6464
6465 if (reg0 == reg1 + 2)
6466 return *len = 4, ("clr %D0" CR_TAB
6467 "sbrc %B0,7" CR_TAB
6468 "com %D0" CR_TAB
6469 "mov %C0,%D0");
6470 if (AVR_HAVE_MOVW)
6471 return *len = 5, ("movw %A0,%C1" CR_TAB
6472 "clr %D0" CR_TAB
6473 "sbrc %B0,7" CR_TAB
6474 "com %D0" CR_TAB
6475 "mov %C0,%D0");
6476 else
6477 return *len = 6, ("mov %B0,%D1" CR_TAB
6478 "mov %A0,%C1" CR_TAB
6479 "clr %D0" CR_TAB
6480 "sbrc %B0,7" CR_TAB
6481 "com %D0" CR_TAB
6482 "mov %C0,%D0");
6483 }
6484
6485 case 24:
6486 return *len = 6, ("mov %A0,%D1" CR_TAB
6487 "clr %D0" CR_TAB
6488 "sbrc %A0,7" CR_TAB
6489 "com %D0" CR_TAB
6490 "mov %B0,%D0" CR_TAB
6491 "mov %C0,%D0");
6492
6493 default:
6494 if (INTVAL (operands[2]) < 32)
6495 break;
6496
6497 /* fall through */
6498
6499 case 31:
6500 if (AVR_HAVE_MOVW)
6501 return *len = 4, ("lsl %D0" CR_TAB
6502 "sbc %A0,%A0" CR_TAB
6503 "mov %B0,%A0" CR_TAB
6504 "movw %C0,%A0");
6505 else
6506 return *len = 5, ("lsl %D0" CR_TAB
6507 "sbc %A0,%A0" CR_TAB
6508 "mov %B0,%A0" CR_TAB
6509 "mov %C0,%A0" CR_TAB
6510 "mov %D0,%A0");
6511 }
6512 len = t;
6513 }
6514 out_shift_with_cnt ("asr %D0" CR_TAB
6515 "ror %C0" CR_TAB
6516 "ror %B0" CR_TAB
6517 "ror %A0", insn, operands, len, 4);
6518 return "";
6519 }
6520
6521 /* 8-bit logic shift right ((unsigned char)x >> i) */
6522
6523 const char *
6524 lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6525 {
6526 if (GET_CODE (operands[2]) == CONST_INT)
6527 {
6528 int k;
6529
6530 if (!len)
6531 len = &k;
6532
6533 switch (INTVAL (operands[2]))
6534 {
6535 default:
6536 if (INTVAL (operands[2]) < 8)
6537 break;
6538
6539 *len = 1;
6540 return "clr %0";
6541
6542 case 1:
6543 *len = 1;
6544 return "lsr %0";
6545
6546 case 2:
6547 *len = 2;
6548 return ("lsr %0" CR_TAB
6549 "lsr %0");
6550 case 3:
6551 *len = 3;
6552 return ("lsr %0" CR_TAB
6553 "lsr %0" CR_TAB
6554 "lsr %0");
6555
6556 case 4:
6557 if (test_hard_reg_class (LD_REGS, operands[0]))
6558 {
6559 *len=2;
6560 return ("swap %0" CR_TAB
6561 "andi %0,0x0f");
6562 }
6563 *len = 4;
6564 return ("lsr %0" CR_TAB
6565 "lsr %0" CR_TAB
6566 "lsr %0" CR_TAB
6567 "lsr %0");
6568
6569 case 5:
6570 if (test_hard_reg_class (LD_REGS, operands[0]))
6571 {
6572 *len = 3;
6573 return ("swap %0" CR_TAB
6574 "lsr %0" CR_TAB
6575 "andi %0,0x7");
6576 }
6577 *len = 5;
6578 return ("lsr %0" CR_TAB
6579 "lsr %0" CR_TAB
6580 "lsr %0" CR_TAB
6581 "lsr %0" CR_TAB
6582 "lsr %0");
6583
6584 case 6:
6585 if (test_hard_reg_class (LD_REGS, operands[0]))
6586 {
6587 *len = 4;
6588 return ("swap %0" CR_TAB
6589 "lsr %0" CR_TAB
6590 "lsr %0" CR_TAB
6591 "andi %0,0x3");
6592 }
6593 *len = 6;
6594 return ("lsr %0" CR_TAB
6595 "lsr %0" CR_TAB
6596 "lsr %0" CR_TAB
6597 "lsr %0" CR_TAB
6598 "lsr %0" CR_TAB
6599 "lsr %0");
6600
6601 case 7:
6602 *len = 3;
6603 return ("rol %0" CR_TAB
6604 "clr %0" CR_TAB
6605 "rol %0");
6606 }
6607 }
6608 else if (CONSTANT_P (operands[2]))
6609 fatal_insn ("internal compiler error. Incorrect shift:", insn);
6610
6611 out_shift_with_cnt ("lsr %0",
6612 insn, operands, len, 1);
6613 return "";
6614 }
6615
6616 /* 16-bit logic shift right ((unsigned short)x >> i) */
6617
6618 const char *
6619 lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6620 {
6621 if (GET_CODE (operands[2]) == CONST_INT)
6622 {
6623 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6624 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6625 int k;
6626 int *t = len;
6627
6628 if (!len)
6629 len = &k;
6630
6631 switch (INTVAL (operands[2]))
6632 {
6633 default:
6634 if (INTVAL (operands[2]) < 16)
6635 break;
6636
6637 *len = 2;
6638 return ("clr %B0" CR_TAB
6639 "clr %A0");
6640
6641 case 4:
6642 if (optimize_size && scratch)
6643 break; /* 5 */
6644 if (ldi_ok)
6645 {
6646 *len = 6;
6647 return ("swap %B0" CR_TAB
6648 "swap %A0" CR_TAB
6649 "andi %A0,0x0f" CR_TAB
6650 "eor %A0,%B0" CR_TAB
6651 "andi %B0,0x0f" CR_TAB
6652 "eor %A0,%B0");
6653 }
6654 if (scratch)
6655 {
6656 *len = 7;
6657 return ("swap %B0" CR_TAB
6658 "swap %A0" CR_TAB
6659 "ldi %3,0x0f" CR_TAB
6660 "and %A0,%3" CR_TAB
6661 "eor %A0,%B0" CR_TAB
6662 "and %B0,%3" CR_TAB
6663 "eor %A0,%B0");
6664 }
6665 break; /* optimize_size ? 6 : 8 */
6666
6667 case 5:
6668 if (optimize_size)
6669 break; /* scratch ? 5 : 6 */
6670 if (ldi_ok)
6671 {
6672 *len = 8;
6673 return ("lsr %B0" CR_TAB
6674 "ror %A0" CR_TAB
6675 "swap %B0" CR_TAB
6676 "swap %A0" CR_TAB
6677 "andi %A0,0x0f" CR_TAB
6678 "eor %A0,%B0" CR_TAB
6679 "andi %B0,0x0f" CR_TAB
6680 "eor %A0,%B0");
6681 }
6682 if (scratch)
6683 {
6684 *len = 9;
6685 return ("lsr %B0" CR_TAB
6686 "ror %A0" CR_TAB
6687 "swap %B0" CR_TAB
6688 "swap %A0" CR_TAB
6689 "ldi %3,0x0f" CR_TAB
6690 "and %A0,%3" CR_TAB
6691 "eor %A0,%B0" CR_TAB
6692 "and %B0,%3" CR_TAB
6693 "eor %A0,%B0");
6694 }
6695 break; /* 10 */
6696
6697 case 6:
6698 if (optimize_size)
6699 break; /* scratch ? 5 : 6 */
6700 *len = 9;
6701 return ("clr __tmp_reg__" CR_TAB
6702 "lsl %A0" CR_TAB
6703 "rol %B0" CR_TAB
6704 "rol __tmp_reg__" CR_TAB
6705 "lsl %A0" CR_TAB
6706 "rol %B0" CR_TAB
6707 "rol __tmp_reg__" CR_TAB
6708 "mov %A0,%B0" CR_TAB
6709 "mov %B0,__tmp_reg__");
6710
6711 case 7:
6712 *len = 5;
6713 return ("lsl %A0" CR_TAB
6714 "mov %A0,%B0" CR_TAB
6715 "rol %A0" CR_TAB
6716 "sbc %B0,%B0" CR_TAB
6717 "neg %B0");
6718
6719 case 8:
6720 return *len = 2, ("mov %A0,%B1" CR_TAB
6721 "clr %B0");
6722
6723 case 9:
6724 *len = 3;
6725 return ("mov %A0,%B0" CR_TAB
6726 "clr %B0" CR_TAB
6727 "lsr %A0");
6728
6729 case 10:
6730 *len = 4;
6731 return ("mov %A0,%B0" CR_TAB
6732 "clr %B0" CR_TAB
6733 "lsr %A0" CR_TAB
6734 "lsr %A0");
6735
6736 case 11:
6737 *len = 5;
6738 return ("mov %A0,%B0" CR_TAB
6739 "clr %B0" CR_TAB
6740 "lsr %A0" CR_TAB
6741 "lsr %A0" CR_TAB
6742 "lsr %A0");
6743
6744 case 12:
6745 if (ldi_ok)
6746 {
6747 *len = 4;
6748 return ("mov %A0,%B0" CR_TAB
6749 "clr %B0" CR_TAB
6750 "swap %A0" CR_TAB
6751 "andi %A0,0x0f");
6752 }
6753 if (scratch)
6754 {
6755 *len = 5;
6756 return ("mov %A0,%B0" CR_TAB
6757 "clr %B0" CR_TAB
6758 "swap %A0" CR_TAB
6759 "ldi %3,0x0f" CR_TAB
6760 "and %A0,%3");
6761 }
6762 *len = 6;
6763 return ("mov %A0,%B0" CR_TAB
6764 "clr %B0" CR_TAB
6765 "lsr %A0" CR_TAB
6766 "lsr %A0" CR_TAB
6767 "lsr %A0" CR_TAB
6768 "lsr %A0");
6769
6770 case 13:
6771 if (ldi_ok)
6772 {
6773 *len = 5;
6774 return ("mov %A0,%B0" CR_TAB
6775 "clr %B0" CR_TAB
6776 "swap %A0" CR_TAB
6777 "lsr %A0" CR_TAB
6778 "andi %A0,0x07");
6779 }
6780 if (AVR_HAVE_MUL && scratch)
6781 {
6782 *len = 5;
6783 return ("ldi %3,0x08" CR_TAB
6784 "mul %B0,%3" CR_TAB
6785 "mov %A0,r1" CR_TAB
6786 "clr %B0" CR_TAB
6787 "clr __zero_reg__");
6788 }
6789 if (optimize_size && scratch)
6790 break; /* 5 */
6791 if (scratch)
6792 {
6793 *len = 6;
6794 return ("mov %A0,%B0" CR_TAB
6795 "clr %B0" CR_TAB
6796 "swap %A0" CR_TAB
6797 "lsr %A0" CR_TAB
6798 "ldi %3,0x07" CR_TAB
6799 "and %A0,%3");
6800 }
6801 if (AVR_HAVE_MUL)
6802 {
6803 *len = 6;
6804 return ("set" CR_TAB
6805 "bld r1,3" CR_TAB
6806 "mul %B0,r1" CR_TAB
6807 "mov %A0,r1" CR_TAB
6808 "clr %B0" CR_TAB
6809 "clr __zero_reg__");
6810 }
6811 *len = 7;
6812 return ("mov %A0,%B0" CR_TAB
6813 "clr %B0" CR_TAB
6814 "lsr %A0" CR_TAB
6815 "lsr %A0" CR_TAB
6816 "lsr %A0" CR_TAB
6817 "lsr %A0" CR_TAB
6818 "lsr %A0");
6819
6820 case 14:
6821 if (AVR_HAVE_MUL && ldi_ok)
6822 {
6823 *len = 5;
6824 return ("ldi %A0,0x04" CR_TAB
6825 "mul %B0,%A0" CR_TAB
6826 "mov %A0,r1" CR_TAB
6827 "clr %B0" CR_TAB
6828 "clr __zero_reg__");
6829 }
6830 if (AVR_HAVE_MUL && scratch)
6831 {
6832 *len = 5;
6833 return ("ldi %3,0x04" CR_TAB
6834 "mul %B0,%3" CR_TAB
6835 "mov %A0,r1" CR_TAB
6836 "clr %B0" CR_TAB
6837 "clr __zero_reg__");
6838 }
6839 if (optimize_size && ldi_ok)
6840 {
6841 *len = 5;
6842 return ("mov %A0,%B0" CR_TAB
6843 "ldi %B0,6" "\n1:\t"
6844 "lsr %A0" CR_TAB
6845 "dec %B0" CR_TAB
6846 "brne 1b");
6847 }
6848 if (optimize_size && scratch)
6849 break; /* 5 */
6850 *len = 6;
6851 return ("clr %A0" CR_TAB
6852 "lsl %B0" CR_TAB
6853 "rol %A0" CR_TAB
6854 "lsl %B0" CR_TAB
6855 "rol %A0" CR_TAB
6856 "clr %B0");
6857
6858 case 15:
6859 *len = 4;
6860 return ("clr %A0" CR_TAB
6861 "lsl %B0" CR_TAB
6862 "rol %A0" CR_TAB
6863 "clr %B0");
6864 }
6865 len = t;
6866 }
6867 out_shift_with_cnt ("lsr %B0" CR_TAB
6868 "ror %A0", insn, operands, len, 2);
6869 return "";
6870 }
6871
6872
6873 /* 24-bit logic shift right */
6874
6875 const char*
6876 avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6877 {
6878 int dest = REGNO (op[0]);
6879 int src = REGNO (op[1]);
6880
6881 if (CONST_INT_P (op[2]))
6882 {
6883 if (plen)
6884 *plen = 0;
6885
6886 switch (INTVAL (op[2]))
6887 {
6888 case 8:
6889 if (dest <= src)
6890 return avr_asm_len ("mov %A0,%B1" CR_TAB
6891 "mov %B0,%C1" CR_TAB
6892 "clr %C0", op, plen, 3);
6893 else
6894 return avr_asm_len ("clr %C0" CR_TAB
6895 "mov %B0,%C1" CR_TAB
6896 "mov %A0,%B1", op, plen, 3);
6897
6898 case 16:
6899 if (dest != src + 2)
6900 avr_asm_len ("mov %A0,%C1", op, plen, 1);
6901
6902 return avr_asm_len ("clr %B0" CR_TAB
6903 "clr %C0", op, plen, 2);
6904
6905 default:
6906 if (INTVAL (op[2]) < 24)
6907 break;
6908
6909 /* fall through */
6910
6911 case 23:
6912 return avr_asm_len ("clr %A0" CR_TAB
6913 "sbrc %C0,7" CR_TAB
6914 "inc %A0" CR_TAB
6915 "clr %B0" CR_TAB
6916 "clr %C0", op, plen, 5);
6917 } /* switch */
6918 }
6919
6920 out_shift_with_cnt ("lsr %C0" CR_TAB
6921 "ror %B0" CR_TAB
6922 "ror %A0", insn, op, plen, 3);
6923 return "";
6924 }
6925
6926
6927 /* 32-bit logic shift right ((unsigned int)x >> i) */
6928
6929 const char *
6930 lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6931 {
6932 if (GET_CODE (operands[2]) == CONST_INT)
6933 {
6934 int k;
6935 int *t = len;
6936
6937 if (!len)
6938 len = &k;
6939
6940 switch (INTVAL (operands[2]))
6941 {
6942 default:
6943 if (INTVAL (operands[2]) < 32)
6944 break;
6945
6946 if (AVR_HAVE_MOVW)
6947 return *len = 3, ("clr %D0" CR_TAB
6948 "clr %C0" CR_TAB
6949 "movw %A0,%C0");
6950 *len = 4;
6951 return ("clr %D0" CR_TAB
6952 "clr %C0" CR_TAB
6953 "clr %B0" CR_TAB
6954 "clr %A0");
6955
6956 case 8:
6957 {
6958 int reg0 = true_regnum (operands[0]);
6959 int reg1 = true_regnum (operands[1]);
6960 *len = 4;
6961 if (reg0 <= reg1)
6962 return ("mov %A0,%B1" CR_TAB
6963 "mov %B0,%C1" CR_TAB
6964 "mov %C0,%D1" CR_TAB
6965 "clr %D0");
6966 else
6967 return ("clr %D0" CR_TAB
6968 "mov %C0,%D1" CR_TAB
6969 "mov %B0,%C1" CR_TAB
6970 "mov %A0,%B1");
6971 }
6972
6973 case 16:
6974 {
6975 int reg0 = true_regnum (operands[0]);
6976 int reg1 = true_regnum (operands[1]);
6977
6978 if (reg0 == reg1 + 2)
6979 return *len = 2, ("clr %C0" CR_TAB
6980 "clr %D0");
6981 if (AVR_HAVE_MOVW)
6982 return *len = 3, ("movw %A0,%C1" CR_TAB
6983 "clr %C0" CR_TAB
6984 "clr %D0");
6985 else
6986 return *len = 4, ("mov %B0,%D1" CR_TAB
6987 "mov %A0,%C1" CR_TAB
6988 "clr %C0" CR_TAB
6989 "clr %D0");
6990 }
6991
6992 case 24:
6993 return *len = 4, ("mov %A0,%D1" CR_TAB
6994 "clr %B0" CR_TAB
6995 "clr %C0" CR_TAB
6996 "clr %D0");
6997
6998 case 31:
6999 *len = 6;
7000 return ("clr %A0" CR_TAB
7001 "sbrc %D0,7" CR_TAB
7002 "inc %A0" CR_TAB
7003 "clr %B0" CR_TAB
7004 "clr %C0" CR_TAB
7005 "clr %D0");
7006 }
7007 len = t;
7008 }
7009 out_shift_with_cnt ("lsr %D0" CR_TAB
7010 "ror %C0" CR_TAB
7011 "ror %B0" CR_TAB
7012 "ror %A0", insn, operands, len, 4);
7013 return "";
7014 }
7015
7016
7017 /* Output addition of register XOP[0] and compile time constant XOP[2].
7018 CODE == PLUS: perform addition by using ADD instructions or
7019 CODE == MINUS: perform addition by using SUB instructions:
7020
7021 XOP[0] = XOP[0] + XOP[2]
7022
7023 Or perform addition/subtraction with register XOP[2] depending on CODE:
7024
7025 XOP[0] = XOP[0] +/- XOP[2]
7026
7027 If PLEN == NULL, print assembler instructions to perform the operation;
7028 otherwise, set *PLEN to the length of the instruction sequence (in words)
7029 printed with PLEN == NULL. XOP[3] is an 8-bit scratch register or NULL_RTX.
7030 Set *PCC to effect on cc0 according to respective CC_* insn attribute.
7031
7032 CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
7033 CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
7034 If CODE_SAT != UNKNOWN then SIGN contains the sign of the summand resp.
7035 the subtrahend in the original insn, provided it is a compile time constant.
7036 In all other cases, SIGN is 0.
7037
7038 If OUT_LABEL is true, print the final 0: label which is needed for
7039 saturated addition / subtraction. The only case where OUT_LABEL = false
7040 is useful is for saturated addition / subtraction performed during
7041 fixed-point rounding, cf. `avr_out_round'. */
7042
7043 static void
7044 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
7045 enum rtx_code code_sat, int sign, bool out_label)
7046 {
7047 /* MODE of the operation. */
7048 machine_mode mode = GET_MODE (xop[0]);
7049
7050 /* INT_MODE of the same size. */
7051 machine_mode imode = int_mode_for_mode (mode);
7052
7053 /* Number of bytes to operate on. */
7054 int i, n_bytes = GET_MODE_SIZE (mode);
7055
7056 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
7057 int clobber_val = -1;
7058
7059 /* op[0]: 8-bit destination register
7060 op[1]: 8-bit const int
7061 op[2]: 8-bit scratch register */
7062 rtx op[3];
7063
7064 /* Started the operation? Before starting the operation we may skip
7065 adding 0. This is no more true after the operation started because
7066 carry must be taken into account. */
7067 bool started = false;
7068
7069 /* Value to add. There are two ways to add VAL: R += VAL and R -= -VAL. */
7070 rtx xval = xop[2];
7071
7072 /* Output a BRVC instruction. Only needed with saturation. */
7073 bool out_brvc = true;
7074
7075 if (plen)
7076 *plen = 0;
7077
7078 if (REG_P (xop[2]))
7079 {
7080 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_CLOBBER;
7081
7082 for (i = 0; i < n_bytes; i++)
7083 {
7084 /* We operate byte-wise on the destination. */
7085 op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
7086 op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
7087
7088 if (i == 0)
7089 avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
7090 op, plen, 1);
7091 else
7092 avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
7093 op, plen, 1);
7094 }
7095
7096 if (reg_overlap_mentioned_p (xop[0], xop[2]))
7097 {
7098 gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
7099
7100 if (MINUS == code)
7101 return;
7102 }
7103
7104 goto saturate;
7105 }
7106
7107 /* Except in the case of ADIW with 16-bit register (see below)
7108 addition does not set cc0 in a usable way. */
7109
7110 *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER;
7111
7112 if (CONST_FIXED_P (xval))
7113 xval = avr_to_int_mode (xval);
7114
7115 /* Adding/Subtracting zero is a no-op. */
7116
7117 if (xval == const0_rtx)
7118 {
7119 *pcc = CC_NONE;
7120 return;
7121 }
7122
7123 if (MINUS == code)
7124 xval = simplify_unary_operation (NEG, imode, xval, imode);
7125
7126 op[2] = xop[3];
7127
7128 if (SS_PLUS == code_sat && MINUS == code
7129 && sign < 0
7130 && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
7131 & GET_MODE_MASK (QImode)))
7132 {
7133 /* We compute x + 0x80 by means of SUB instructions. We negated the
7134 constant subtrahend above and are left with x - (-128) so that we
7135 need something like SUBI r,128 which does not exist because SUBI sets
7136 V according to the sign of the subtrahend. Notice the only case
7137 where this must be done is when NEG overflowed in case [2s] because
7138 the V computation needs the right sign of the subtrahend. */
7139
7140 rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7141
7142 avr_asm_len ("subi %0,128" CR_TAB
7143 "brmi 0f", &msb, plen, 2);
7144 out_brvc = false;
7145
7146 goto saturate;
7147 }
7148
7149 for (i = 0; i < n_bytes; i++)
7150 {
7151 /* We operate byte-wise on the destination. */
7152 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7153 rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
7154
7155 /* 8-bit value to operate with this byte. */
7156 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7157
7158 /* Registers R16..R31 can operate with immediate. */
7159 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7160
7161 op[0] = reg8;
7162 op[1] = gen_int_mode (val8, QImode);
7163
7164 /* To get usable cc0 no low-bytes must have been skipped. */
7165
7166 if (i && !started)
7167 *pcc = CC_CLOBBER;
7168
7169 if (!started
7170 && i % 2 == 0
7171 && i + 2 <= n_bytes
7172 && test_hard_reg_class (ADDW_REGS, reg8))
7173 {
7174 rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
7175 unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
7176
7177 /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
7178 i.e. operate word-wise. */
7179
7180 if (val16 < 64)
7181 {
7182 if (val16 != 0)
7183 {
7184 started = true;
7185 avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
7186 op, plen, 1);
7187
7188 if (n_bytes == 2 && PLUS == code)
7189 *pcc = CC_SET_CZN;
7190 }
7191
7192 i++;
7193 continue;
7194 }
7195 }
7196
7197 if (val8 == 0)
7198 {
7199 if (started)
7200 avr_asm_len (code == PLUS
7201 ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
7202 op, plen, 1);
7203 continue;
7204 }
7205 else if ((val8 == 1 || val8 == 0xff)
7206 && UNKNOWN == code_sat
7207 && !started
7208 && i == n_bytes - 1)
7209 {
7210 avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
7211 op, plen, 1);
7212 *pcc = CC_CLOBBER;
7213 break;
7214 }
7215
7216 switch (code)
7217 {
7218 case PLUS:
7219
7220 gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
7221
7222 if (plen != NULL && UNKNOWN != code_sat)
7223 {
7224 /* This belongs to the x + 0x80 corner case. The code with
7225 ADD instruction is not smaller, thus make this case
7226 expensive so that the caller won't pick it. */
7227
7228 *plen += 10;
7229 break;
7230 }
7231
7232 if (clobber_val != (int) val8)
7233 avr_asm_len ("ldi %2,%1", op, plen, 1);
7234 clobber_val = (int) val8;
7235
7236 avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
7237
7238 break; /* PLUS */
7239
7240 case MINUS:
7241
7242 if (ld_reg_p)
7243 avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
7244 else
7245 {
7246 gcc_assert (plen != NULL || REG_P (op[2]));
7247
7248 if (clobber_val != (int) val8)
7249 avr_asm_len ("ldi %2,%1", op, plen, 1);
7250 clobber_val = (int) val8;
7251
7252 avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
7253 }
7254
7255 break; /* MINUS */
7256
7257 default:
7258 /* Unknown code */
7259 gcc_unreachable();
7260 }
7261
7262 started = true;
7263
7264 } /* for all sub-bytes */
7265
7266 saturate:
7267
7268 if (UNKNOWN == code_sat)
7269 return;
7270
7271 *pcc = (int) CC_CLOBBER;
7272
7273 /* Vanilla addition/subtraction is done. We are left with saturation.
7274
7275 We have to compute A = A <op> B where A is a register and
7276 B is a register or a non-zero compile time constant CONST.
7277 A is register class "r" if unsigned && B is REG. Otherwise, A is in "d".
7278 B stands for the original operand $2 in INSN. In the case of B = CONST,
7279 SIGN in { -1, 1 } is the sign of B. Otherwise, SIGN is 0.
7280
7281 CODE is the instruction flavor we use in the asm sequence to perform <op>.
7282
7283
7284 unsigned
7285 operation | code | sat if | b is | sat value | case
7286 -----------------+-------+----------+--------------+-----------+-------
7287 + as a + b | add | C == 1 | const, reg | u+ = 0xff | [1u]
7288 + as a - (-b) | sub | C == 0 | const | u+ = 0xff | [2u]
7289 - as a - b | sub | C == 1 | const, reg | u- = 0 | [3u]
7290 - as a + (-b) | add | C == 0 | const | u- = 0 | [4u]
7291
7292
7293 signed
7294 operation | code | sat if | b is | sat value | case
7295 -----------------+-------+----------+--------------+-----------+-------
7296 + as a + b | add | V == 1 | const, reg | s+ | [1s]
7297 + as a - (-b) | sub | V == 1 | const | s+ | [2s]
7298 - as a - b | sub | V == 1 | const, reg | s- | [3s]
7299 - as a + (-b) | add | V == 1 | const | s- | [4s]
7300
7301 s+ = b < 0 ? -0x80 : 0x7f
7302 s- = b < 0 ? 0x7f : -0x80
7303
7304 The cases a - b actually perform a - (-(-b)) if B is CONST.
7305 */
7306
7307 op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7308 op[1] = n_bytes > 1
7309 ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
7310 : NULL_RTX;
7311
7312 bool need_copy = true;
7313 int len_call = 1 + AVR_HAVE_JMP_CALL;
7314
7315 switch (code_sat)
7316 {
7317 default:
7318 gcc_unreachable();
7319
7320 case SS_PLUS:
7321 case SS_MINUS:
7322
7323 if (out_brvc)
7324 avr_asm_len ("brvc 0f", op, plen, 1);
7325
7326 if (reg_overlap_mentioned_p (xop[0], xop[2]))
7327 {
7328 /* [1s,reg] */
7329
7330 if (n_bytes == 1)
7331 avr_asm_len ("ldi %0,0x7f" CR_TAB
7332 "adc %0,__zero_reg__", op, plen, 2);
7333 else
7334 avr_asm_len ("ldi %0,0x7f" CR_TAB
7335 "ldi %1,0xff" CR_TAB
7336 "adc %1,__zero_reg__" CR_TAB
7337 "adc %0,__zero_reg__", op, plen, 4);
7338 }
7339 else if (sign == 0 && PLUS == code)
7340 {
7341 /* [1s,reg] */
7342
7343 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7344
7345 if (n_bytes == 1)
7346 avr_asm_len ("ldi %0,0x80" CR_TAB
7347 "sbrs %2,7" CR_TAB
7348 "dec %0", op, plen, 3);
7349 else
7350 avr_asm_len ("ldi %0,0x80" CR_TAB
7351 "cp %2,%0" CR_TAB
7352 "sbc %1,%1" CR_TAB
7353 "sbci %0,0", op, plen, 4);
7354 }
7355 else if (sign == 0 && MINUS == code)
7356 {
7357 /* [3s,reg] */
7358
7359 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7360
7361 if (n_bytes == 1)
7362 avr_asm_len ("ldi %0,0x7f" CR_TAB
7363 "sbrs %2,7" CR_TAB
7364 "inc %0", op, plen, 3);
7365 else
7366 avr_asm_len ("ldi %0,0x7f" CR_TAB
7367 "cp %0,%2" CR_TAB
7368 "sbc %1,%1" CR_TAB
7369 "sbci %0,-1", op, plen, 4);
7370 }
7371 else if ((sign < 0) ^ (SS_MINUS == code_sat))
7372 {
7373 /* [1s,const,B < 0] [2s,B < 0] */
7374 /* [3s,const,B > 0] [4s,B > 0] */
7375
7376 if (n_bytes == 8)
7377 {
7378 avr_asm_len ("%~call __clr_8", op, plen, len_call);
7379 need_copy = false;
7380 }
7381
7382 avr_asm_len ("ldi %0,0x80", op, plen, 1);
7383 if (n_bytes > 1 && need_copy)
7384 avr_asm_len ("clr %1", op, plen, 1);
7385 }
7386 else if ((sign > 0) ^ (SS_MINUS == code_sat))
7387 {
7388 /* [1s,const,B > 0] [2s,B > 0] */
7389 /* [3s,const,B < 0] [4s,B < 0] */
7390
7391 if (n_bytes == 8)
7392 {
7393 avr_asm_len ("sec" CR_TAB
7394 "%~call __sbc_8", op, plen, 1 + len_call);
7395 need_copy = false;
7396 }
7397
7398 avr_asm_len ("ldi %0,0x7f", op, plen, 1);
7399 if (n_bytes > 1 && need_copy)
7400 avr_asm_len ("ldi %1,0xff", op, plen, 1);
7401 }
7402 else
7403 gcc_unreachable();
7404
7405 break;
7406
7407 case US_PLUS:
7408 /* [1u] : [2u] */
7409
7410 avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
7411
7412 if (n_bytes == 8)
7413 {
7414 if (MINUS == code)
7415 avr_asm_len ("sec", op, plen, 1);
7416 avr_asm_len ("%~call __sbc_8", op, plen, len_call);
7417
7418 need_copy = false;
7419 }
7420 else
7421 {
7422 if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
7423 avr_asm_len ("sec" CR_TAB
7424 "sbc %0,%0", op, plen, 2);
7425 else
7426 avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
7427 op, plen, 1);
7428 }
7429 break; /* US_PLUS */
7430
7431 case US_MINUS:
7432 /* [4u] : [3u] */
7433
7434 avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
7435
7436 if (n_bytes == 8)
7437 {
7438 avr_asm_len ("%~call __clr_8", op, plen, len_call);
7439 need_copy = false;
7440 }
7441 else
7442 avr_asm_len ("clr %0", op, plen, 1);
7443
7444 break;
7445 }
7446
7447 /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
7448 Now copy the right value to the LSBs. */
7449
7450 if (need_copy && n_bytes > 1)
7451 {
7452 if (US_MINUS == code_sat || US_PLUS == code_sat)
7453 {
7454 avr_asm_len ("mov %1,%0", op, plen, 1);
7455
7456 if (n_bytes > 2)
7457 {
7458 op[0] = xop[0];
7459 if (AVR_HAVE_MOVW)
7460 avr_asm_len ("movw %0,%1", op, plen, 1);
7461 else
7462 avr_asm_len ("mov %A0,%1" CR_TAB
7463 "mov %B0,%1", op, plen, 2);
7464 }
7465 }
7466 else if (n_bytes > 2)
7467 {
7468 op[0] = xop[0];
7469 avr_asm_len ("mov %A0,%1" CR_TAB
7470 "mov %B0,%1", op, plen, 2);
7471 }
7472 }
7473
7474 if (need_copy && n_bytes == 8)
7475 {
7476 if (AVR_HAVE_MOVW)
7477 avr_asm_len ("movw %r0+2,%0" CR_TAB
7478 "movw %r0+4,%0", xop, plen, 2);
7479 else
7480 avr_asm_len ("mov %r0+2,%0" CR_TAB
7481 "mov %r0+3,%0" CR_TAB
7482 "mov %r0+4,%0" CR_TAB
7483 "mov %r0+5,%0", xop, plen, 4);
7484 }
7485
7486 if (out_label)
7487 avr_asm_len ("0:", op, plen, 0);
7488 }
7489
7490
7491 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
7492 is ont a compile-time constant:
7493
7494 XOP[0] = XOP[0] +/- XOP[2]
7495
7496 This is a helper for the function below. The only insns that need this
7497 are additions/subtraction for pointer modes, i.e. HImode and PSImode. */
7498
7499 static const char*
7500 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
7501 {
7502 machine_mode mode = GET_MODE (xop[0]);
7503
7504 /* Only pointer modes want to add symbols. */
7505
7506 gcc_assert (mode == HImode || mode == PSImode);
7507
7508 *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
7509
7510 avr_asm_len (PLUS == code
7511 ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
7512 : "subi %A0,lo8(%2)" CR_TAB "sbci %B0,hi8(%2)",
7513 xop, plen, -2);
7514
7515 if (PSImode == mode)
7516 avr_asm_len (PLUS == code
7517 ? "sbci %C0,hlo8(-(%2))"
7518 : "sbci %C0,hlo8(%2)", xop, plen, 1);
7519 return "";
7520 }
7521
7522
7523 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
7524
7525 INSN is a single_set insn or an insn pattern with a binary operation as
7526 SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
7527
7528 XOP are the operands of INSN. In the case of 64-bit operations with
7529 constant XOP[] has just one element: The summand/subtrahend in XOP[0].
7530 The non-saturating insns up to 32 bits may or may not supply a "d" class
7531 scratch as XOP[3].
7532
7533 If PLEN == NULL output the instructions.
7534 If PLEN != NULL set *PLEN to the length of the sequence in words.
7535
7536 PCC is a pointer to store the instructions' effect on cc0.
7537 PCC may be NULL.
7538
7539 PLEN and PCC default to NULL.
7540
7541 OUT_LABEL defaults to TRUE. For a description, see AVR_OUT_PLUS_1.
7542
7543 Return "" */
7544
7545 const char*
7546 avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label)
7547 {
7548 int cc_plus, cc_minus, cc_dummy;
7549 int len_plus, len_minus;
7550 rtx op[4];
7551 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7552 rtx xdest = SET_DEST (xpattern);
7553 machine_mode mode = GET_MODE (xdest);
7554 machine_mode imode = int_mode_for_mode (mode);
7555 int n_bytes = GET_MODE_SIZE (mode);
7556 enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
7557 enum rtx_code code
7558 = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
7559 ? PLUS : MINUS);
7560
7561 if (!pcc)
7562 pcc = &cc_dummy;
7563
7564 /* PLUS and MINUS don't saturate: Use modular wrap-around. */
7565
7566 if (PLUS == code_sat || MINUS == code_sat)
7567 code_sat = UNKNOWN;
7568
7569 if (n_bytes <= 4 && REG_P (xop[2]))
7570 {
7571 avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
7572 return "";
7573 }
7574
7575 if (8 == n_bytes)
7576 {
7577 op[0] = gen_rtx_REG (DImode, ACC_A);
7578 op[1] = gen_rtx_REG (DImode, ACC_A);
7579 op[2] = avr_to_int_mode (xop[0]);
7580 }
7581 else
7582 {
7583 if (!REG_P (xop[2])
7584 && !CONST_INT_P (xop[2])
7585 && !CONST_FIXED_P (xop[2]))
7586 {
7587 return avr_out_plus_symbol (xop, code, plen, pcc);
7588 }
7589
7590 op[0] = avr_to_int_mode (xop[0]);
7591 op[1] = avr_to_int_mode (xop[1]);
7592 op[2] = avr_to_int_mode (xop[2]);
7593 }
7594
7595 /* Saturations and 64-bit operations don't have a clobber operand.
7596 For the other cases, the caller will provide a proper XOP[3]. */
7597
7598 xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
7599 op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
7600
7601 /* Saturation will need the sign of the original operand. */
7602
7603 rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
7604 int sign = INTVAL (xmsb) < 0 ? -1 : 1;
7605
7606 /* If we subtract and the subtrahend is a constant, then negate it
7607 so that avr_out_plus_1 can be used. */
7608
7609 if (MINUS == code)
7610 op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
7611
7612 /* Work out the shortest sequence. */
7613
7614 avr_out_plus_1 (op, &len_minus, MINUS, &cc_minus, code_sat, sign, out_label);
7615 avr_out_plus_1 (op, &len_plus, PLUS, &cc_plus, code_sat, sign, out_label);
7616
7617 if (plen)
7618 {
7619 *plen = (len_minus <= len_plus) ? len_minus : len_plus;
7620 *pcc = (len_minus <= len_plus) ? cc_minus : cc_plus;
7621 }
7622 else if (len_minus <= len_plus)
7623 avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label);
7624 else
7625 avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label);
7626
7627 return "";
7628 }
7629
7630
7631 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
7632 time constant XOP[2]:
7633
7634 XOP[0] = XOP[0] <op> XOP[2]
7635
7636 and return "". If PLEN == NULL, print assembler instructions to perform the
7637 operation; otherwise, set *PLEN to the length of the instruction sequence
7638 (in words) printed with PLEN == NULL. XOP[3] is either an 8-bit clobber
7639 register or SCRATCH if no clobber register is needed for the operation.
7640 INSN is an INSN_P or a pattern of an insn. */
7641
7642 const char*
7643 avr_out_bitop (rtx insn, rtx *xop, int *plen)
7644 {
7645 /* CODE and MODE of the operation. */
7646 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7647 enum rtx_code code = GET_CODE (SET_SRC (xpattern));
7648 machine_mode mode = GET_MODE (xop[0]);
7649
7650 /* Number of bytes to operate on. */
7651 int i, n_bytes = GET_MODE_SIZE (mode);
7652
7653 /* Value of T-flag (0 or 1) or -1 if unknow. */
7654 int set_t = -1;
7655
7656 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
7657 int clobber_val = -1;
7658
7659 /* op[0]: 8-bit destination register
7660 op[1]: 8-bit const int
7661 op[2]: 8-bit clobber register or SCRATCH
7662 op[3]: 8-bit register containing 0xff or NULL_RTX */
7663 rtx op[4];
7664
7665 op[2] = xop[3];
7666 op[3] = NULL_RTX;
7667
7668 if (plen)
7669 *plen = 0;
7670
7671 for (i = 0; i < n_bytes; i++)
7672 {
7673 /* We operate byte-wise on the destination. */
7674 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7675 rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
7676
7677 /* 8-bit value to operate with this byte. */
7678 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7679
7680 /* Number of bits set in the current byte of the constant. */
7681 int pop8 = avr_popcount (val8);
7682
7683 /* Registers R16..R31 can operate with immediate. */
7684 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7685
7686 op[0] = reg8;
7687 op[1] = GEN_INT (val8);
7688
7689 switch (code)
7690 {
7691 case IOR:
7692
7693 if (0 == pop8)
7694 continue;
7695 else if (ld_reg_p)
7696 avr_asm_len ("ori %0,%1", op, plen, 1);
7697 else if (1 == pop8)
7698 {
7699 if (set_t != 1)
7700 avr_asm_len ("set", op, plen, 1);
7701 set_t = 1;
7702
7703 op[1] = GEN_INT (exact_log2 (val8));
7704 avr_asm_len ("bld %0,%1", op, plen, 1);
7705 }
7706 else if (8 == pop8)
7707 {
7708 if (op[3] != NULL_RTX)
7709 avr_asm_len ("mov %0,%3", op, plen, 1);
7710 else
7711 avr_asm_len ("clr %0" CR_TAB
7712 "dec %0", op, plen, 2);
7713
7714 op[3] = op[0];
7715 }
7716 else
7717 {
7718 if (clobber_val != (int) val8)
7719 avr_asm_len ("ldi %2,%1", op, plen, 1);
7720 clobber_val = (int) val8;
7721
7722 avr_asm_len ("or %0,%2", op, plen, 1);
7723 }
7724
7725 continue; /* IOR */
7726
7727 case AND:
7728
7729 if (8 == pop8)
7730 continue;
7731 else if (0 == pop8)
7732 avr_asm_len ("clr %0", op, plen, 1);
7733 else if (ld_reg_p)
7734 avr_asm_len ("andi %0,%1", op, plen, 1);
7735 else if (7 == pop8)
7736 {
7737 if (set_t != 0)
7738 avr_asm_len ("clt", op, plen, 1);
7739 set_t = 0;
7740
7741 op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
7742 avr_asm_len ("bld %0,%1", op, plen, 1);
7743 }
7744 else
7745 {
7746 if (clobber_val != (int) val8)
7747 avr_asm_len ("ldi %2,%1", op, plen, 1);
7748 clobber_val = (int) val8;
7749
7750 avr_asm_len ("and %0,%2", op, plen, 1);
7751 }
7752
7753 continue; /* AND */
7754
7755 case XOR:
7756
7757 if (0 == pop8)
7758 continue;
7759 else if (8 == pop8)
7760 avr_asm_len ("com %0", op, plen, 1);
7761 else if (ld_reg_p && val8 == (1 << 7))
7762 avr_asm_len ("subi %0,%1", op, plen, 1);
7763 else
7764 {
7765 if (clobber_val != (int) val8)
7766 avr_asm_len ("ldi %2,%1", op, plen, 1);
7767 clobber_val = (int) val8;
7768
7769 avr_asm_len ("eor %0,%2", op, plen, 1);
7770 }
7771
7772 continue; /* XOR */
7773
7774 default:
7775 /* Unknown rtx_code */
7776 gcc_unreachable();
7777 }
7778 } /* for all sub-bytes */
7779
7780 return "";
7781 }
7782
7783
7784 /* Output sign extension from XOP[1] to XOP[0] and return "".
7785 If PLEN == NULL, print assembler instructions to perform the operation;
7786 otherwise, set *PLEN to the length of the instruction sequence (in words)
7787 as printed with PLEN == NULL. */
7788
7789 const char*
7790 avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen)
7791 {
7792 // Size in bytes of source resp. destination operand.
7793 unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1]));
7794 unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0]));
7795 rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1];
7796
7797 if (plen)
7798 *plen = 0;
7799
7800 // Copy destination to source
7801
7802 if (REGNO (xop[0]) != REGNO (xop[1]))
7803 {
7804 gcc_assert (n_src <= 2);
7805
7806 if (n_src == 2)
7807 avr_asm_len (AVR_HAVE_MOVW
7808 ? "movw %0,%1"
7809 : "mov %B0,%B1", xop, plen, 1);
7810 if (n_src == 1 || !AVR_HAVE_MOVW)
7811 avr_asm_len ("mov %A0,%A1", xop, plen, 1);
7812 }
7813
7814 // Set Carry to the sign bit MSB.7...
7815
7816 if (REGNO (xop[0]) == REGNO (xop[1])
7817 || !reg_unused_after (insn, r_msb))
7818 {
7819 avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1);
7820 r_msb = tmp_reg_rtx;
7821 }
7822
7823 avr_asm_len ("lsl %0", &r_msb, plen, 1);
7824
7825 // ...and propagate it to all the new sign bits
7826
7827 for (unsigned n = n_src; n < n_dest; n++)
7828 avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1);
7829
7830 return "";
7831 }
7832
7833
7834 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
7835 PLEN != NULL: Set *PLEN to the length of that sequence.
7836 Return "". */
7837
7838 const char*
7839 avr_out_addto_sp (rtx *op, int *plen)
7840 {
7841 int pc_len = AVR_2_BYTE_PC ? 2 : 3;
7842 int addend = INTVAL (op[0]);
7843
7844 if (plen)
7845 *plen = 0;
7846
7847 if (addend < 0)
7848 {
7849 if (flag_verbose_asm || flag_print_asm_name)
7850 avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
7851
7852 while (addend <= -pc_len)
7853 {
7854 addend += pc_len;
7855 avr_asm_len ("rcall .", op, plen, 1);
7856 }
7857
7858 while (addend++ < 0)
7859 avr_asm_len ("push __zero_reg__", op, plen, 1);
7860 }
7861 else if (addend > 0)
7862 {
7863 if (flag_verbose_asm || flag_print_asm_name)
7864 avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
7865
7866 while (addend-- > 0)
7867 avr_asm_len ("pop __tmp_reg__", op, plen, 1);
7868 }
7869
7870 return "";
7871 }
7872
7873
7874 /* Outputs instructions needed for fixed point type conversion.
7875 This includes converting between any fixed point type, as well
7876 as converting to any integer type. Conversion between integer
7877 types is not supported.
7878
7879 Converting signed fractional types requires a bit shift if converting
7880 to or from any unsigned fractional type because the decimal place is
7881 shifted by 1 bit. When the destination is a signed fractional, the sign
7882 is stored in either the carry or T bit. */
7883
7884 const char*
7885 avr_out_fract (rtx_insn *insn, rtx operands[], bool intsigned, int *plen)
7886 {
7887 size_t i;
7888 rtx xop[6];
7889 RTX_CODE shift = UNKNOWN;
7890 bool sign_in_carry = false;
7891 bool msb_in_carry = false;
7892 bool lsb_in_tmp_reg = false;
7893 bool lsb_in_carry = false;
7894 bool frac_rounded = false;
7895 const char *code_ashift = "lsl %0";
7896
7897
7898 #define MAY_CLOBBER(RR) \
7899 /* Shorthand used below. */ \
7900 ((sign_bytes \
7901 && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb)) \
7902 || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb)) \
7903 || (reg_unused_after (insn, all_regs_rtx[RR]) \
7904 && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
7905
7906 struct
7907 {
7908 /* bytes : Length of operand in bytes.
7909 ibyte : Length of integral part in bytes.
7910 fbyte, fbit : Length of fractional part in bytes, bits. */
7911
7912 bool sbit;
7913 unsigned fbit, bytes, ibyte, fbyte;
7914 unsigned regno, regno_msb;
7915 } dest, src, *val[2] = { &dest, &src };
7916
7917 if (plen)
7918 *plen = 0;
7919
7920 /* Step 0: Determine information on source and destination operand we
7921 ====== will need in the remainder. */
7922
7923 for (i = 0; i < sizeof (val) / sizeof (*val); i++)
7924 {
7925 machine_mode mode;
7926
7927 xop[i] = operands[i];
7928
7929 mode = GET_MODE (xop[i]);
7930
7931 val[i]->bytes = GET_MODE_SIZE (mode);
7932 val[i]->regno = REGNO (xop[i]);
7933 val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
7934
7935 if (SCALAR_INT_MODE_P (mode))
7936 {
7937 val[i]->sbit = intsigned;
7938 val[i]->fbit = 0;
7939 }
7940 else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
7941 {
7942 val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
7943 val[i]->fbit = GET_MODE_FBIT (mode);
7944 }
7945 else
7946 fatal_insn ("unsupported fixed-point conversion", insn);
7947
7948 val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
7949 val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
7950 }
7951
7952 // Byte offset of the decimal point taking into account different place
7953 // of the decimal point in input and output and different register numbers
7954 // of input and output.
7955 int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
7956
7957 // Number of destination bytes that will come from sign / zero extension.
7958 int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
7959
7960 // Number of bytes at the low end to be filled with zeros.
7961 int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
7962
7963 // Do we have a 16-Bit register that is cleared?
7964 rtx clrw = NULL_RTX;
7965
7966 bool sign_extend = src.sbit && sign_bytes;
7967
7968 if (0 == dest.fbit % 8 && 7 == src.fbit % 8)
7969 shift = ASHIFT;
7970 else if (7 == dest.fbit % 8 && 0 == src.fbit % 8)
7971 shift = ASHIFTRT;
7972 else if (dest.fbit % 8 == src.fbit % 8)
7973 shift = UNKNOWN;
7974 else
7975 gcc_unreachable();
7976
7977 /* If we need to round the fraction part, we might need to save/round it
7978 before clobbering any of it in Step 1. Also, we might want to do
7979 the rounding now to make use of LD_REGS. */
7980 if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
7981 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
7982 && !TARGET_FRACT_CONV_TRUNC)
7983 {
7984 bool overlap
7985 = (src.regno <=
7986 (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1)
7987 && dest.regno - offset -1 >= dest.regno);
7988 unsigned s0 = dest.regno - offset -1;
7989 bool use_src = true;
7990 unsigned sn;
7991 unsigned copied_msb = src.regno_msb;
7992 bool have_carry = false;
7993
7994 if (src.ibyte > dest.ibyte)
7995 copied_msb -= src.ibyte - dest.ibyte;
7996
7997 for (sn = s0; sn <= copied_msb; sn++)
7998 if (!IN_RANGE (sn, dest.regno, dest.regno_msb)
7999 && !reg_unused_after (insn, all_regs_rtx[sn]))
8000 use_src = false;
8001 if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0))
8002 {
8003 avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8004 &all_regs_rtx[src.regno_msb], plen, 2);
8005 sn = src.regno;
8006 if (sn < s0)
8007 {
8008 if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn))
8009 avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1);
8010 else
8011 avr_asm_len ("sec" CR_TAB
8012 "cpc %0,__zero_reg__",
8013 &all_regs_rtx[sn], plen, 2);
8014 have_carry = true;
8015 }
8016 while (++sn < s0)
8017 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8018
8019 avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129",
8020 &all_regs_rtx[s0], plen, 1);
8021 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8022 avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1);
8023 avr_asm_len ("\n0:", NULL, plen, 0);
8024 frac_rounded = true;
8025 }
8026 else if (use_src && overlap)
8027 {
8028 avr_asm_len ("clr __tmp_reg__" CR_TAB
8029 "sbrc %1,0" CR_TAB
8030 "dec __tmp_reg__", xop, plen, 1);
8031 sn = src.regno;
8032 if (sn < s0)
8033 {
8034 avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8035 have_carry = true;
8036 }
8037
8038 while (++sn < s0)
8039 avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8040
8041 if (have_carry)
8042 avr_asm_len ("clt" CR_TAB
8043 "bld __tmp_reg__,7" CR_TAB
8044 "adc %0,__tmp_reg__",
8045 &all_regs_rtx[s0], plen, 1);
8046 else
8047 avr_asm_len ("lsr __tmp_reg" CR_TAB
8048 "add %0,__tmp_reg__",
8049 &all_regs_rtx[s0], plen, 2);
8050 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8051 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8052 frac_rounded = true;
8053 }
8054 else if (overlap)
8055 {
8056 bool use_src
8057 = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)
8058 && (IN_RANGE (s0, dest.regno, dest.regno_msb)
8059 || reg_unused_after (insn, all_regs_rtx[s0])));
8060 xop[2] = all_regs_rtx[s0];
8061 unsigned sn = src.regno;
8062 if (!use_src || sn == s0)
8063 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8064 /* We need to consider to-be-discarded bits
8065 if the value is negative. */
8066 if (sn < s0)
8067 {
8068 avr_asm_len ("tst %0" CR_TAB
8069 "brpl 0f",
8070 &all_regs_rtx[src.regno_msb], plen, 2);
8071 /* Test to-be-discarded bytes for any nozero bits.
8072 ??? Could use OR or SBIW to test two registers at once. */
8073 if (sn < s0)
8074 avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8075
8076 while (++sn < s0)
8077 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8078 /* Set bit 0 in __tmp_reg__ if any of the lower bits was set. */
8079 if (use_src)
8080 avr_asm_len ("breq 0f" CR_TAB
8081 "ori %2,1"
8082 "\n0:\t" "mov __tmp_reg__,%2",
8083 xop, plen, 3);
8084 else
8085 avr_asm_len ("breq 0f" CR_TAB
8086 "set" CR_TAB
8087 "bld __tmp_reg__,0\n0:",
8088 xop, plen, 3);
8089 }
8090 lsb_in_tmp_reg = true;
8091 }
8092 }
8093
8094 /* Step 1: Clear bytes at the low end and copy payload bits from source
8095 ====== to destination. */
8096
8097 int step = offset < 0 ? 1 : -1;
8098 unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
8099
8100 // We cleared at least that number of registers.
8101 int clr_n = 0;
8102
8103 for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
8104 {
8105 // Next regno of destination is needed for MOVW
8106 unsigned d1 = d0 + step;
8107
8108 // Current and next regno of source
8109 signed s0 = d0 - offset;
8110 signed s1 = s0 + step;
8111
8112 // Must current resp. next regno be CLRed? This applies to the low
8113 // bytes of the destination that have no associated source bytes.
8114 bool clr0 = s0 < (signed) src.regno;
8115 bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
8116
8117 // First gather what code to emit (if any) and additional step to
8118 // apply if a MOVW is in use. xop[2] is destination rtx and xop[3]
8119 // is the source rtx for the current loop iteration.
8120 const char *code = NULL;
8121 int stepw = 0;
8122
8123 if (clr0)
8124 {
8125 if (AVR_HAVE_MOVW && clr1 && clrw)
8126 {
8127 xop[2] = all_regs_rtx[d0 & ~1];
8128 xop[3] = clrw;
8129 code = "movw %2,%3";
8130 stepw = step;
8131 }
8132 else
8133 {
8134 xop[2] = all_regs_rtx[d0];
8135 code = "clr %2";
8136
8137 if (++clr_n >= 2
8138 && !clrw
8139 && d0 % 2 == (step > 0))
8140 {
8141 clrw = all_regs_rtx[d0 & ~1];
8142 }
8143 }
8144 }
8145 else if (offset && s0 <= (signed) src.regno_msb)
8146 {
8147 int movw = AVR_HAVE_MOVW && offset % 2 == 0
8148 && d0 % 2 == (offset > 0)
8149 && d1 <= dest.regno_msb && d1 >= dest.regno
8150 && s1 <= (signed) src.regno_msb && s1 >= (signed) src.regno;
8151
8152 xop[2] = all_regs_rtx[d0 & ~movw];
8153 xop[3] = all_regs_rtx[s0 & ~movw];
8154 code = movw ? "movw %2,%3" : "mov %2,%3";
8155 stepw = step * movw;
8156 }
8157
8158 if (code)
8159 {
8160 if (sign_extend && shift != ASHIFT && !sign_in_carry
8161 && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
8162 {
8163 /* We are going to override the sign bit. If we sign-extend,
8164 store the sign in the Carry flag. This is not needed if
8165 the destination will be ASHIFT in the remainder because
8166 the ASHIFT will set Carry without extra instruction. */
8167
8168 avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
8169 sign_in_carry = true;
8170 }
8171
8172 unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
8173
8174 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8175 && src.ibyte > dest.ibyte
8176 && (d0 == src_msb || d0 + stepw == src_msb))
8177 {
8178 /* We are going to override the MSB. If we shift right,
8179 store the MSB in the Carry flag. This is only needed if
8180 we don't sign-extend becaue with sign-extension the MSB
8181 (the sign) will be produced by the sign extension. */
8182
8183 avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
8184 msb_in_carry = true;
8185 }
8186
8187 unsigned src_lsb = dest.regno - offset -1;
8188
8189 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
8190 && !lsb_in_tmp_reg
8191 && (d0 == src_lsb || d0 + stepw == src_lsb))
8192 {
8193 /* We are going to override the new LSB; store it into carry. */
8194
8195 avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
8196 code_ashift = "rol %0";
8197 lsb_in_carry = true;
8198 }
8199
8200 avr_asm_len (code, xop, plen, 1);
8201 d0 += stepw;
8202 }
8203 }
8204
8205 /* Step 2: Shift destination left by 1 bit position. This might be needed
8206 ====== for signed input and unsigned output. */
8207
8208 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
8209 {
8210 unsigned s0 = dest.regno - offset -1;
8211
8212 /* n1169 4.1.4 says:
8213 "Conversions from a fixed-point to an integer type round toward zero."
8214 Hence, converting a fract type to integer only gives a non-zero result
8215 for -1. */
8216 if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8217 && SCALAR_FRACT_MODE_P (GET_MODE (xop[1]))
8218 && !TARGET_FRACT_CONV_TRUNC)
8219 {
8220 gcc_assert (s0 == src.regno_msb);
8221 /* Check if the input is -1. We do that by checking if negating
8222 the input causes an integer overflow. */
8223 unsigned sn = src.regno;
8224 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8225 while (sn <= s0)
8226 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8227
8228 /* Overflow goes with set carry. Clear carry otherwise. */
8229 avr_asm_len ("brvs 0f" CR_TAB
8230 "clc\n0:", NULL, plen, 2);
8231 }
8232 /* Likewise, when converting from accumulator types to integer, we
8233 need to round up negative values. */
8234 else if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8235 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
8236 && !TARGET_FRACT_CONV_TRUNC
8237 && !frac_rounded)
8238 {
8239 bool have_carry = false;
8240
8241 xop[2] = all_regs_rtx[s0];
8242 if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0))
8243 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8244 avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8245 &all_regs_rtx[src.regno_msb], plen, 2);
8246 if (!lsb_in_tmp_reg)
8247 {
8248 unsigned sn = src.regno;
8249 if (sn < s0)
8250 {
8251 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn],
8252 plen, 1);
8253 have_carry = true;
8254 }
8255 while (++sn < s0)
8256 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1);
8257 lsb_in_tmp_reg = !MAY_CLOBBER (s0);
8258 }
8259 /* Add in C and the rounding value 127. */
8260 /* If the destination msb is a sign byte, and in LD_REGS,
8261 grab it as a temporary. */
8262 if (sign_bytes
8263 && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS],
8264 dest.regno_msb))
8265 {
8266 xop[3] = all_regs_rtx[dest.regno_msb];
8267 avr_asm_len ("ldi %3,127", xop, plen, 1);
8268 avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3"
8269 : have_carry ? "adc %2,%3"
8270 : lsb_in_tmp_reg ? "add __tmp_reg__,%3"
8271 : "add %2,%3"),
8272 xop, plen, 1);
8273 }
8274 else
8275 {
8276 /* Fall back to use __zero_reg__ as a temporary. */
8277 avr_asm_len ("dec __zero_reg__", NULL, plen, 1);
8278 if (have_carry)
8279 avr_asm_len ("clt" CR_TAB
8280 "bld __zero_reg__,7", NULL, plen, 2);
8281 else
8282 avr_asm_len ("lsr __zero_reg__", NULL, plen, 1);
8283 avr_asm_len (have_carry && lsb_in_tmp_reg
8284 ? "adc __tmp_reg__,__zero_reg__"
8285 : have_carry ? "adc %2,__zero_reg__"
8286 : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__"
8287 : "add %2,__zero_reg__",
8288 xop, plen, 1);
8289 avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1);
8290 }
8291
8292 for (d0 = dest.regno + zero_bytes;
8293 d0 <= dest.regno_msb - sign_bytes; d0++)
8294 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1);
8295
8296 avr_asm_len (lsb_in_tmp_reg
8297 ? "\n0:\t" "lsl __tmp_reg__"
8298 : "\n0:\t" "lsl %2",
8299 xop, plen, 1);
8300 }
8301 else if (MAY_CLOBBER (s0))
8302 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8303 else
8304 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8305 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8306
8307 code_ashift = "rol %0";
8308 lsb_in_carry = true;
8309 }
8310
8311 if (shift == ASHIFT)
8312 {
8313 for (d0 = dest.regno + zero_bytes;
8314 d0 <= dest.regno_msb - sign_bytes; d0++)
8315 {
8316 avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
8317 code_ashift = "rol %0";
8318 }
8319
8320 lsb_in_carry = false;
8321 sign_in_carry = true;
8322 }
8323
8324 /* Step 4a: Store MSB in carry if we don't already have it or will produce
8325 ======= it in sign-extension below. */
8326
8327 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8328 && src.ibyte > dest.ibyte)
8329 {
8330 unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
8331
8332 if (MAY_CLOBBER (s0))
8333 avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
8334 else
8335 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8336 "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8337
8338 msb_in_carry = true;
8339 }
8340
8341 /* Step 3: Sign-extend or zero-extend the destination as needed.
8342 ====== */
8343
8344 if (sign_extend && !sign_in_carry)
8345 {
8346 unsigned s0 = src.regno_msb;
8347
8348 if (MAY_CLOBBER (s0))
8349 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8350 else
8351 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8352 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8353
8354 sign_in_carry = true;
8355 }
8356
8357 gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
8358
8359 unsigned copies = 0;
8360 rtx movw = sign_extend ? NULL_RTX : clrw;
8361
8362 for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
8363 {
8364 if (AVR_HAVE_MOVW && movw
8365 && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
8366 {
8367 xop[2] = all_regs_rtx[d0];
8368 xop[3] = movw;
8369 avr_asm_len ("movw %2,%3", xop, plen, 1);
8370 d0++;
8371 }
8372 else
8373 {
8374 avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
8375 &all_regs_rtx[d0], plen, 1);
8376
8377 if (++copies >= 2 && !movw && d0 % 2 == 1)
8378 movw = all_regs_rtx[d0-1];
8379 }
8380 } /* for */
8381
8382
8383 /* Step 4: Right shift the destination. This might be needed for
8384 ====== conversions from unsigned to signed. */
8385
8386 if (shift == ASHIFTRT)
8387 {
8388 const char *code_ashiftrt = "lsr %0";
8389
8390 if (sign_extend || msb_in_carry)
8391 code_ashiftrt = "ror %0";
8392
8393 if (src.sbit && src.ibyte == dest.ibyte)
8394 code_ashiftrt = "asr %0";
8395
8396 for (d0 = dest.regno_msb - sign_bytes;
8397 d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
8398 {
8399 avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
8400 code_ashiftrt = "ror %0";
8401 }
8402 }
8403
8404 #undef MAY_CLOBBER
8405
8406 return "";
8407 }
8408
8409
8410 /* Output fixed-point rounding. XOP[0] = XOP[1] is the operand to round.
8411 XOP[2] is the rounding point, a CONST_INT. The function prints the
8412 instruction sequence if PLEN = NULL and computes the length in words
8413 of the sequence if PLEN != NULL. Most of this function deals with
8414 preparing operands for calls to `avr_out_plus' and `avr_out_bitop'. */
8415
8416 const char*
8417 avr_out_round (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
8418 {
8419 machine_mode mode = GET_MODE (xop[0]);
8420 machine_mode imode = int_mode_for_mode (mode);
8421 // The smallest fractional bit not cleared by the rounding is 2^(-RP).
8422 int fbit = (int) GET_MODE_FBIT (mode);
8423 double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
8424 wide_int wi_add = wi::set_bit_in_zero (fbit-1 - INTVAL (xop[2]),
8425 GET_MODE_PRECISION (imode));
8426 // Lengths of PLUS and AND parts.
8427 int len_add = 0, *plen_add = plen ? &len_add : NULL;
8428 int len_and = 0, *plen_and = plen ? &len_and : NULL;
8429
8430 // Add-Saturate 1/2 * 2^(-RP). Don't print the label "0:" when printing
8431 // the saturated addition so that we can emit the "rjmp 1f" before the
8432 // "0:" below.
8433
8434 rtx xadd = const_fixed_from_double_int (i_add, mode);
8435 rtx xpattern, xsrc, op[4];
8436
8437 xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
8438 ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
8439 : gen_rtx_US_PLUS (mode, xop[1], xadd);
8440 xpattern = gen_rtx_SET (xop[0], xsrc);
8441
8442 op[0] = xop[0];
8443 op[1] = xop[1];
8444 op[2] = xadd;
8445 avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */);
8446
8447 avr_asm_len ("rjmp 1f" CR_TAB
8448 "0:", NULL, plen_add, 1);
8449
8450 // Keep all bits from RP and higher: ... 2^(-RP)
8451 // Clear all bits from RP+1 and lower: 2^(-RP-1) ...
8452 // Rounding point ^^^^^^^
8453 // Added above ^^^^^^^^^
8454 rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
8455 rtx xmask = immed_wide_int_const (-wi_add - wi_add, imode);
8456
8457 xpattern = gen_rtx_SET (xreg, gen_rtx_AND (imode, xreg, xmask));
8458
8459 op[0] = xreg;
8460 op[1] = xreg;
8461 op[2] = xmask;
8462 op[3] = gen_rtx_SCRATCH (QImode);
8463 avr_out_bitop (xpattern, op, plen_and);
8464 avr_asm_len ("1:", NULL, plen, 0);
8465
8466 if (plen)
8467 *plen = len_add + len_and;
8468
8469 return "";
8470 }
8471
8472
8473 /* Create RTL split patterns for byte sized rotate expressions. This
8474 produces a series of move instructions and considers overlap situations.
8475 Overlapping non-HImode operands need a scratch register. */
8476
8477 bool
8478 avr_rotate_bytes (rtx operands[])
8479 {
8480 int i, j;
8481 machine_mode mode = GET_MODE (operands[0]);
8482 bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
8483 bool same_reg = rtx_equal_p (operands[0], operands[1]);
8484 int num = INTVAL (operands[2]);
8485 rtx scratch = operands[3];
8486 /* Work out if byte or word move is needed. Odd byte rotates need QImode.
8487 Word move if no scratch is needed, otherwise use size of scratch. */
8488 machine_mode move_mode = QImode;
8489 int move_size, offset, size;
8490
8491 if (num & 0xf)
8492 move_mode = QImode;
8493 else if ((mode == SImode && !same_reg) || !overlapped)
8494 move_mode = HImode;
8495 else
8496 move_mode = GET_MODE (scratch);
8497
8498 /* Force DI rotate to use QI moves since other DI moves are currently split
8499 into QI moves so forward propagation works better. */
8500 if (mode == DImode)
8501 move_mode = QImode;
8502 /* Make scratch smaller if needed. */
8503 if (SCRATCH != GET_CODE (scratch)
8504 && HImode == GET_MODE (scratch)
8505 && QImode == move_mode)
8506 scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
8507
8508 move_size = GET_MODE_SIZE (move_mode);
8509 /* Number of bytes/words to rotate. */
8510 offset = (num >> 3) / move_size;
8511 /* Number of moves needed. */
8512 size = GET_MODE_SIZE (mode) / move_size;
8513 /* Himode byte swap is special case to avoid a scratch register. */
8514 if (mode == HImode && same_reg)
8515 {
8516 /* HImode byte swap, using xor. This is as quick as using scratch. */
8517 rtx src, dst;
8518 src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
8519 dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
8520 if (!rtx_equal_p (dst, src))
8521 {
8522 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8523 emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
8524 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8525 }
8526 }
8527 else
8528 {
8529 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode) */
8530 /* Create linked list of moves to determine move order. */
8531 struct {
8532 rtx src, dst;
8533 int links;
8534 } move[MAX_SIZE + 8];
8535 int blocked, moves;
8536
8537 gcc_assert (size <= MAX_SIZE);
8538 /* Generate list of subreg moves. */
8539 for (i = 0; i < size; i++)
8540 {
8541 int from = i;
8542 int to = (from + offset) % size;
8543 move[i].src = simplify_gen_subreg (move_mode, operands[1],
8544 mode, from * move_size);
8545 move[i].dst = simplify_gen_subreg (move_mode, operands[0],
8546 mode, to * move_size);
8547 move[i].links = -1;
8548 }
8549 /* Mark dependence where a dst of one move is the src of another move.
8550 The first move is a conflict as it must wait until second is
8551 performed. We ignore moves to self - we catch this later. */
8552 if (overlapped)
8553 for (i = 0; i < size; i++)
8554 if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
8555 for (j = 0; j < size; j++)
8556 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
8557 {
8558 /* The dst of move i is the src of move j. */
8559 move[i].links = j;
8560 break;
8561 }
8562
8563 blocked = -1;
8564 moves = 0;
8565 /* Go through move list and perform non-conflicting moves. As each
8566 non-overlapping move is made, it may remove other conflicts
8567 so the process is repeated until no conflicts remain. */
8568 do
8569 {
8570 blocked = -1;
8571 moves = 0;
8572 /* Emit move where dst is not also a src or we have used that
8573 src already. */
8574 for (i = 0; i < size; i++)
8575 if (move[i].src != NULL_RTX)
8576 {
8577 if (move[i].links == -1
8578 || move[move[i].links].src == NULL_RTX)
8579 {
8580 moves++;
8581 /* Ignore NOP moves to self. */
8582 if (!rtx_equal_p (move[i].dst, move[i].src))
8583 emit_move_insn (move[i].dst, move[i].src);
8584
8585 /* Remove conflict from list. */
8586 move[i].src = NULL_RTX;
8587 }
8588 else
8589 blocked = i;
8590 }
8591
8592 /* Check for deadlock. This is when no moves occurred and we have
8593 at least one blocked move. */
8594 if (moves == 0 && blocked != -1)
8595 {
8596 /* Need to use scratch register to break deadlock.
8597 Add move to put dst of blocked move into scratch.
8598 When this move occurs, it will break chain deadlock.
8599 The scratch register is substituted for real move. */
8600
8601 gcc_assert (SCRATCH != GET_CODE (scratch));
8602
8603 move[size].src = move[blocked].dst;
8604 move[size].dst = scratch;
8605 /* Scratch move is never blocked. */
8606 move[size].links = -1;
8607 /* Make sure we have valid link. */
8608 gcc_assert (move[blocked].links != -1);
8609 /* Replace src of blocking move with scratch reg. */
8610 move[move[blocked].links].src = scratch;
8611 /* Make dependent on scratch move occurring. */
8612 move[blocked].links = size;
8613 size=size+1;
8614 }
8615 }
8616 while (blocked != -1);
8617 }
8618 return true;
8619 }
8620
8621
8622 /* Worker function for `ADJUST_INSN_LENGTH'. */
8623 /* Modifies the length assigned to instruction INSN
8624 LEN is the initially computed length of the insn. */
8625
8626 int
8627 avr_adjust_insn_length (rtx_insn *insn, int len)
8628 {
8629 rtx *op = recog_data.operand;
8630 enum attr_adjust_len adjust_len;
8631
8632 /* Some complex insns don't need length adjustment and therefore
8633 the length need not/must not be adjusted for these insns.
8634 It is easier to state this in an insn attribute "adjust_len" than
8635 to clutter up code here... */
8636
8637 if (!NONDEBUG_INSN_P (insn)
8638 || -1 == recog_memoized (insn))
8639 {
8640 return len;
8641 }
8642
8643 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */
8644
8645 adjust_len = get_attr_adjust_len (insn);
8646
8647 if (adjust_len == ADJUST_LEN_NO)
8648 {
8649 /* Nothing to adjust: The length from attribute "length" is fine.
8650 This is the default. */
8651
8652 return len;
8653 }
8654
8655 /* Extract insn's operands. */
8656
8657 extract_constrain_insn_cached (insn);
8658
8659 /* Dispatch to right function. */
8660
8661 switch (adjust_len)
8662 {
8663 case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
8664 case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
8665 case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
8666
8667 case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
8668
8669 case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
8670 case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
8671
8672 case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break;
8673 case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
8674 case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
8675 case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
8676 case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
8677 case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
8678 case ADJUST_LEN_LPM: avr_out_lpm (insn, op, &len); break;
8679 case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break;
8680
8681 case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
8682 case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
8683 case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
8684
8685 case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
8686 case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
8687 case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
8688 case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
8689 case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
8690
8691 case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
8692 case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
8693 case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
8694
8695 case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
8696 case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
8697 case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
8698
8699 case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
8700 case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
8701 case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
8702
8703 case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
8704 case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
8705 case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
8706
8707 case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
8708
8709 case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
8710
8711 default:
8712 gcc_unreachable();
8713 }
8714
8715 return len;
8716 }
8717
8718 /* Return nonzero if register REG dead after INSN. */
8719
8720 int
8721 reg_unused_after (rtx_insn *insn, rtx reg)
8722 {
8723 return (dead_or_set_p (insn, reg)
8724 || (REG_P(reg) && _reg_unused_after (insn, reg)));
8725 }
8726
8727 /* Return nonzero if REG is not used after INSN.
8728 We assume REG is a reload reg, and therefore does
8729 not live past labels. It may live past calls or jumps though. */
8730
8731 int
8732 _reg_unused_after (rtx_insn *insn, rtx reg)
8733 {
8734 enum rtx_code code;
8735 rtx set;
8736
8737 /* If the reg is set by this instruction, then it is safe for our
8738 case. Disregard the case where this is a store to memory, since
8739 we are checking a register used in the store address. */
8740 set = single_set (insn);
8741 if (set && GET_CODE (SET_DEST (set)) != MEM
8742 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8743 return 1;
8744
8745 while ((insn = NEXT_INSN (insn)))
8746 {
8747 rtx set;
8748 code = GET_CODE (insn);
8749
8750 #if 0
8751 /* If this is a label that existed before reload, then the register
8752 if dead here. However, if this is a label added by reorg, then
8753 the register may still be live here. We can't tell the difference,
8754 so we just ignore labels completely. */
8755 if (code == CODE_LABEL)
8756 return 1;
8757 /* else */
8758 #endif
8759
8760 if (!INSN_P (insn))
8761 continue;
8762
8763 if (code == JUMP_INSN)
8764 return 0;
8765
8766 /* If this is a sequence, we must handle them all at once.
8767 We could have for instance a call that sets the target register,
8768 and an insn in a delay slot that uses the register. In this case,
8769 we must return 0. */
8770 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
8771 {
8772 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
8773 int i;
8774 int retval = 0;
8775
8776 for (i = 0; i < seq->len (); i++)
8777 {
8778 rtx_insn *this_insn = seq->insn (i);
8779 rtx set = single_set (this_insn);
8780
8781 if (CALL_P (this_insn))
8782 code = CALL_INSN;
8783 else if (JUMP_P (this_insn))
8784 {
8785 if (INSN_ANNULLED_BRANCH_P (this_insn))
8786 return 0;
8787 code = JUMP_INSN;
8788 }
8789
8790 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8791 return 0;
8792 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8793 {
8794 if (GET_CODE (SET_DEST (set)) != MEM)
8795 retval = 1;
8796 else
8797 return 0;
8798 }
8799 if (set == 0
8800 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
8801 return 0;
8802 }
8803 if (retval == 1)
8804 return 1;
8805 else if (code == JUMP_INSN)
8806 return 0;
8807 }
8808
8809 if (code == CALL_INSN)
8810 {
8811 rtx tem;
8812 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
8813 if (GET_CODE (XEXP (tem, 0)) == USE
8814 && REG_P (XEXP (XEXP (tem, 0), 0))
8815 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
8816 return 0;
8817 if (call_used_regs[REGNO (reg)])
8818 return 1;
8819 }
8820
8821 set = single_set (insn);
8822
8823 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8824 return 0;
8825 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8826 return GET_CODE (SET_DEST (set)) != MEM;
8827 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
8828 return 0;
8829 }
8830 return 1;
8831 }
8832
8833
8834 /* Implement `TARGET_ASM_INTEGER'. */
8835 /* Target hook for assembling integer objects. The AVR version needs
8836 special handling for references to certain labels. */
8837
8838 static bool
8839 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
8840 {
8841 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
8842 && text_segment_operand (x, VOIDmode))
8843 {
8844 fputs ("\t.word\tgs(", asm_out_file);
8845 output_addr_const (asm_out_file, x);
8846 fputs (")\n", asm_out_file);
8847
8848 return true;
8849 }
8850 else if (GET_MODE (x) == PSImode)
8851 {
8852 /* This needs binutils 2.23+, see PR binutils/13503 */
8853
8854 fputs ("\t.byte\tlo8(", asm_out_file);
8855 output_addr_const (asm_out_file, x);
8856 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8857
8858 fputs ("\t.byte\thi8(", asm_out_file);
8859 output_addr_const (asm_out_file, x);
8860 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8861
8862 fputs ("\t.byte\thh8(", asm_out_file);
8863 output_addr_const (asm_out_file, x);
8864 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8865
8866 return true;
8867 }
8868 else if (CONST_FIXED_P (x))
8869 {
8870 unsigned n;
8871
8872 /* varasm fails to handle big fixed modes that don't fit in hwi. */
8873
8874 for (n = 0; n < size; n++)
8875 {
8876 rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
8877 default_assemble_integer (xn, 1, aligned_p);
8878 }
8879
8880 return true;
8881 }
8882
8883 return default_assemble_integer (x, size, aligned_p);
8884 }
8885
8886
8887 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'. */
8888 /* Return value is nonzero if pseudos that have been
8889 assigned to registers of class CLASS would likely be spilled
8890 because registers of CLASS are needed for spill registers. */
8891
8892 static bool
8893 avr_class_likely_spilled_p (reg_class_t c)
8894 {
8895 return (c != ALL_REGS &&
8896 (AVR_TINY ? 1 : c != ADDW_REGS));
8897 }
8898
8899
8900 /* Valid attributes:
8901 progmem - Put data to program memory.
8902 signal - Make a function to be hardware interrupt.
8903 After function prologue interrupts remain disabled.
8904 interrupt - Make a function to be hardware interrupt. Before function
8905 prologue interrupts are enabled by means of SEI.
8906 naked - Don't generate function prologue/epilogue and RET
8907 instruction. */
8908
8909 /* Handle a "progmem" attribute; arguments as in
8910 struct attribute_spec.handler. */
8911
8912 static tree
8913 avr_handle_progmem_attribute (tree *node, tree name,
8914 tree args ATTRIBUTE_UNUSED,
8915 int flags ATTRIBUTE_UNUSED,
8916 bool *no_add_attrs)
8917 {
8918 if (DECL_P (*node))
8919 {
8920 if (TREE_CODE (*node) == TYPE_DECL)
8921 {
8922 /* This is really a decl attribute, not a type attribute,
8923 but try to handle it for GCC 3.0 backwards compatibility. */
8924
8925 tree type = TREE_TYPE (*node);
8926 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
8927 tree newtype = build_type_attribute_variant (type, attr);
8928
8929 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
8930 TREE_TYPE (*node) = newtype;
8931 *no_add_attrs = true;
8932 }
8933 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
8934 {
8935 *no_add_attrs = false;
8936 }
8937 else
8938 {
8939 warning (OPT_Wattributes, "%qE attribute ignored",
8940 name);
8941 *no_add_attrs = true;
8942 }
8943 }
8944
8945 return NULL_TREE;
8946 }
8947
8948 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
8949 struct attribute_spec.handler. */
8950
8951 static tree
8952 avr_handle_fndecl_attribute (tree *node, tree name,
8953 tree args ATTRIBUTE_UNUSED,
8954 int flags ATTRIBUTE_UNUSED,
8955 bool *no_add_attrs)
8956 {
8957 if (TREE_CODE (*node) != FUNCTION_DECL)
8958 {
8959 warning (OPT_Wattributes, "%qE attribute only applies to functions",
8960 name);
8961 *no_add_attrs = true;
8962 }
8963
8964 return NULL_TREE;
8965 }
8966
8967 static tree
8968 avr_handle_fntype_attribute (tree *node, tree name,
8969 tree args ATTRIBUTE_UNUSED,
8970 int flags ATTRIBUTE_UNUSED,
8971 bool *no_add_attrs)
8972 {
8973 if (TREE_CODE (*node) != FUNCTION_TYPE)
8974 {
8975 warning (OPT_Wattributes, "%qE attribute only applies to functions",
8976 name);
8977 *no_add_attrs = true;
8978 }
8979
8980 return NULL_TREE;
8981 }
8982
8983 static tree
8984 avr_handle_addr_attribute (tree *node, tree name, tree args,
8985 int flags ATTRIBUTE_UNUSED, bool *no_add)
8986 {
8987 bool io_p = (strncmp (IDENTIFIER_POINTER (name), "io", 2) == 0);
8988 location_t loc = DECL_SOURCE_LOCATION (*node);
8989
8990 if (TREE_CODE (*node) != VAR_DECL)
8991 {
8992 warning_at (loc, 0, "%qE attribute only applies to variables", name);
8993 *no_add = true;
8994 }
8995
8996 if (args != NULL_TREE)
8997 {
8998 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
8999 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
9000 tree arg = TREE_VALUE (args);
9001 if (TREE_CODE (arg) != INTEGER_CST)
9002 {
9003 warning (0, "%qE attribute allows only an integer constant argument",
9004 name);
9005 *no_add = true;
9006 }
9007 else if (io_p
9008 && (!tree_fits_shwi_p (arg)
9009 || !(strcmp (IDENTIFIER_POINTER (name), "io_low") == 0
9010 ? low_io_address_operand : io_address_operand)
9011 (GEN_INT (TREE_INT_CST_LOW (arg)), QImode)))
9012 {
9013 warning_at (loc, 0, "%qE attribute address out of range", name);
9014 *no_add = true;
9015 }
9016 else
9017 {
9018 tree attribs = DECL_ATTRIBUTES (*node);
9019 const char *names[] = { "io", "io_low", "address", NULL } ;
9020 for (const char **p = names; *p; p++)
9021 {
9022 tree other = lookup_attribute (*p, attribs);
9023 if (other && TREE_VALUE (other))
9024 {
9025 warning_at (loc, 0,
9026 "both %s and %qE attribute provide address",
9027 *p, name);
9028 *no_add = true;
9029 break;
9030 }
9031 }
9032 }
9033 }
9034
9035 if (*no_add == false && io_p && !TREE_THIS_VOLATILE (*node))
9036 warning_at (loc, 0, "%qE attribute on non-volatile variable", name);
9037
9038 return NULL_TREE;
9039 }
9040
9041 rtx
9042 avr_eval_addr_attrib (rtx x)
9043 {
9044 if (GET_CODE (x) == SYMBOL_REF
9045 && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_ADDRESS))
9046 {
9047 tree decl = SYMBOL_REF_DECL (x);
9048 tree attr = NULL_TREE;
9049
9050 if (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO)
9051 {
9052 attr = lookup_attribute ("io", DECL_ATTRIBUTES (decl));
9053 if (!attr || !TREE_VALUE (attr))
9054 attr = lookup_attribute ("io_low", DECL_ATTRIBUTES (decl));
9055 gcc_assert (attr);
9056 }
9057 if (!attr || !TREE_VALUE (attr))
9058 attr = lookup_attribute ("address", DECL_ATTRIBUTES (decl));
9059 gcc_assert (attr && TREE_VALUE (attr) && TREE_VALUE (TREE_VALUE (attr)));
9060 return GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))));
9061 }
9062 return x;
9063 }
9064
9065
9066 /* AVR attributes. */
9067 static const struct attribute_spec
9068 avr_attribute_table[] =
9069 {
9070 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
9071 affects_type_identity } */
9072 { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute,
9073 false },
9074 { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute,
9075 false },
9076 { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute,
9077 false },
9078 { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute,
9079 false },
9080 { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute,
9081 false },
9082 { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute,
9083 false },
9084 { "io", 0, 1, false, false, false, avr_handle_addr_attribute,
9085 false },
9086 { "io_low", 0, 1, false, false, false, avr_handle_addr_attribute,
9087 false },
9088 { "address", 1, 1, false, false, false, avr_handle_addr_attribute,
9089 false },
9090 { NULL, 0, 0, false, false, false, NULL, false }
9091 };
9092
9093
9094 /* Look if DECL shall be placed in program memory space by
9095 means of attribute `progmem' or some address-space qualifier.
9096 Return non-zero if DECL is data that must end up in Flash and
9097 zero if the data lives in RAM (.bss, .data, .rodata, ...).
9098
9099 Return 2 if DECL is located in 24-bit flash address-space
9100 Return 1 if DECL is located in 16-bit flash address-space
9101 Return -1 if attribute `progmem' occurs in DECL or ATTRIBUTES
9102 Return 0 otherwise */
9103
9104 int
9105 avr_progmem_p (tree decl, tree attributes)
9106 {
9107 tree a;
9108
9109 if (TREE_CODE (decl) != VAR_DECL)
9110 return 0;
9111
9112 if (avr_decl_memx_p (decl))
9113 return 2;
9114
9115 if (avr_decl_flash_p (decl))
9116 return 1;
9117
9118 if (NULL_TREE
9119 != lookup_attribute ("progmem", attributes))
9120 return -1;
9121
9122 a = decl;
9123
9124 do
9125 a = TREE_TYPE(a);
9126 while (TREE_CODE (a) == ARRAY_TYPE);
9127
9128 if (a == error_mark_node)
9129 return 0;
9130
9131 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
9132 return -1;
9133
9134 return 0;
9135 }
9136
9137
9138 /* Scan type TYP for pointer references to address space ASn.
9139 Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
9140 the AS are also declared to be CONST.
9141 Otherwise, return the respective address space, i.e. a value != 0. */
9142
9143 static addr_space_t
9144 avr_nonconst_pointer_addrspace (tree typ)
9145 {
9146 while (ARRAY_TYPE == TREE_CODE (typ))
9147 typ = TREE_TYPE (typ);
9148
9149 if (POINTER_TYPE_P (typ))
9150 {
9151 addr_space_t as;
9152 tree target = TREE_TYPE (typ);
9153
9154 /* Pointer to function: Test the function's return type. */
9155
9156 if (FUNCTION_TYPE == TREE_CODE (target))
9157 return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
9158
9159 /* "Ordinary" pointers... */
9160
9161 while (TREE_CODE (target) == ARRAY_TYPE)
9162 target = TREE_TYPE (target);
9163
9164 /* Pointers to non-generic address space must be const.
9165 Refuse address spaces outside the device's flash. */
9166
9167 as = TYPE_ADDR_SPACE (target);
9168
9169 if (!ADDR_SPACE_GENERIC_P (as)
9170 && (!TYPE_READONLY (target)
9171 || avr_addrspace[as].segment >= avr_n_flash
9172 /* Also refuse __memx address space if we can't support it. */
9173 || (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)))
9174 {
9175 return as;
9176 }
9177
9178 /* Scan pointer's target type. */
9179
9180 return avr_nonconst_pointer_addrspace (target);
9181 }
9182
9183 return ADDR_SPACE_GENERIC;
9184 }
9185
9186
9187 /* Sanity check NODE so that all pointers targeting non-generic address spaces
9188 go along with CONST qualifier. Writing to these address spaces should
9189 be detected and complained about as early as possible. */
9190
9191 static bool
9192 avr_pgm_check_var_decl (tree node)
9193 {
9194 const char *reason = NULL;
9195
9196 addr_space_t as = ADDR_SPACE_GENERIC;
9197
9198 gcc_assert (as == 0);
9199
9200 if (avr_log.progmem)
9201 avr_edump ("%?: %t\n", node);
9202
9203 switch (TREE_CODE (node))
9204 {
9205 default:
9206 break;
9207
9208 case VAR_DECL:
9209 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9210 reason = "variable";
9211 break;
9212
9213 case PARM_DECL:
9214 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9215 reason = "function parameter";
9216 break;
9217
9218 case FIELD_DECL:
9219 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9220 reason = "structure field";
9221 break;
9222
9223 case FUNCTION_DECL:
9224 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
9225 as)
9226 reason = "return type of function";
9227 break;
9228
9229 case POINTER_TYPE:
9230 if (as = avr_nonconst_pointer_addrspace (node), as)
9231 reason = "pointer";
9232 break;
9233 }
9234
9235 if (reason)
9236 {
9237 if (avr_addrspace[as].segment >= avr_n_flash)
9238 {
9239 if (TYPE_P (node))
9240 error ("%qT uses address space %qs beyond flash of %d KiB",
9241 node, avr_addrspace[as].name, 64 * avr_n_flash);
9242 else
9243 error ("%s %q+D uses address space %qs beyond flash of %d KiB",
9244 reason, node, avr_addrspace[as].name, 64 * avr_n_flash);
9245 }
9246 else
9247 {
9248 if (TYPE_P (node))
9249 error ("pointer targeting address space %qs must be const in %qT",
9250 avr_addrspace[as].name, node);
9251 else
9252 error ("pointer targeting address space %qs must be const"
9253 " in %s %q+D",
9254 avr_addrspace[as].name, reason, node);
9255 }
9256 }
9257
9258 return reason == NULL;
9259 }
9260
9261
9262 /* Add the section attribute if the variable is in progmem. */
9263
9264 static void
9265 avr_insert_attributes (tree node, tree *attributes)
9266 {
9267 avr_pgm_check_var_decl (node);
9268
9269 if (TREE_CODE (node) == VAR_DECL
9270 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
9271 && avr_progmem_p (node, *attributes))
9272 {
9273 addr_space_t as;
9274 tree node0 = node;
9275
9276 /* For C++, we have to peel arrays in order to get correct
9277 determination of readonlyness. */
9278
9279 do
9280 node0 = TREE_TYPE (node0);
9281 while (TREE_CODE (node0) == ARRAY_TYPE);
9282
9283 if (error_mark_node == node0)
9284 return;
9285
9286 as = TYPE_ADDR_SPACE (TREE_TYPE (node));
9287
9288 if (avr_addrspace[as].segment >= avr_n_flash)
9289 {
9290 error ("variable %q+D located in address space %qs beyond flash "
9291 "of %d KiB", node, avr_addrspace[as].name, 64 * avr_n_flash);
9292 }
9293 else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)
9294 {
9295 error ("variable %q+D located in address space %qs"
9296 " which is not supported for architecture %qs",
9297 node, avr_addrspace[as].name, avr_arch->name);
9298 }
9299
9300 if (!TYPE_READONLY (node0)
9301 && !TREE_READONLY (node))
9302 {
9303 const char *reason = "__attribute__((progmem))";
9304
9305 if (!ADDR_SPACE_GENERIC_P (as))
9306 reason = avr_addrspace[as].name;
9307
9308 if (avr_log.progmem)
9309 avr_edump ("\n%?: %t\n%t\n", node, node0);
9310
9311 error ("variable %q+D must be const in order to be put into"
9312 " read-only section by means of %qs", node, reason);
9313 }
9314 }
9315 }
9316
9317
9318 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */
9319 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */
9320 /* Track need of __do_clear_bss. */
9321
9322 void
9323 avr_asm_output_aligned_decl_common (FILE * stream,
9324 tree decl,
9325 const char *name,
9326 unsigned HOST_WIDE_INT size,
9327 unsigned int align, bool local_p)
9328 {
9329 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9330 rtx symbol;
9331
9332 if (mem != NULL_RTX && MEM_P (mem)
9333 && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9334 && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9335 {
9336
9337 if (!local_p)
9338 {
9339 fprintf (stream, "\t.globl\t");
9340 assemble_name (stream, name);
9341 fprintf (stream, "\n");
9342 }
9343 if (SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS)
9344 {
9345 assemble_name (stream, name);
9346 fprintf (stream, " = %ld\n",
9347 (long) INTVAL (avr_eval_addr_attrib (symbol)));
9348 }
9349 else if (local_p)
9350 error_at (DECL_SOURCE_LOCATION (decl),
9351 "static IO declaration for %q+D needs an address", decl);
9352 return;
9353 }
9354
9355 /* __gnu_lto_v1 etc. are just markers for the linker injected by toplev.c.
9356 There is no need to trigger __do_clear_bss code for them. */
9357
9358 if (!STR_PREFIX_P (name, "__gnu_lto"))
9359 avr_need_clear_bss_p = true;
9360
9361 if (local_p)
9362 ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
9363 else
9364 ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
9365 }
9366
9367 void
9368 avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
9369 unsigned HOST_WIDE_INT size, int align,
9370 void (*default_func)
9371 (FILE *, tree, const char *,
9372 unsigned HOST_WIDE_INT, int))
9373 {
9374 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9375 rtx symbol;
9376
9377 if (mem != NULL_RTX && MEM_P (mem)
9378 && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9379 && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9380 {
9381 if (!(SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS))
9382 error_at (DECL_SOURCE_LOCATION (decl),
9383 "IO definition for %q+D needs an address", decl);
9384 avr_asm_output_aligned_decl_common (file, decl, name, size, align, false);
9385 }
9386 else
9387 default_func (file, decl, name, size, align);
9388 }
9389
9390
9391 /* Unnamed section callback for data_section
9392 to track need of __do_copy_data. */
9393
9394 static void
9395 avr_output_data_section_asm_op (const void *data)
9396 {
9397 avr_need_copy_data_p = true;
9398
9399 /* Dispatch to default. */
9400 output_section_asm_op (data);
9401 }
9402
9403
9404 /* Unnamed section callback for bss_section
9405 to track need of __do_clear_bss. */
9406
9407 static void
9408 avr_output_bss_section_asm_op (const void *data)
9409 {
9410 avr_need_clear_bss_p = true;
9411
9412 /* Dispatch to default. */
9413 output_section_asm_op (data);
9414 }
9415
9416
9417 /* Unnamed section callback for progmem*.data sections. */
9418
9419 static void
9420 avr_output_progmem_section_asm_op (const void *data)
9421 {
9422 fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
9423 (const char*) data);
9424 }
9425
9426
9427 /* Implement `TARGET_ASM_INIT_SECTIONS'. */
9428
9429 static void
9430 avr_asm_init_sections (void)
9431 {
9432 /* Set up a section for jump tables. Alignment is handled by
9433 ASM_OUTPUT_BEFORE_CASE_LABEL. */
9434
9435 if (AVR_HAVE_JMP_CALL)
9436 {
9437 progmem_swtable_section
9438 = get_unnamed_section (0, output_section_asm_op,
9439 "\t.section\t.progmem.gcc_sw_table"
9440 ",\"a\",@progbits");
9441 }
9442 else
9443 {
9444 progmem_swtable_section
9445 = get_unnamed_section (SECTION_CODE, output_section_asm_op,
9446 "\t.section\t.progmem.gcc_sw_table"
9447 ",\"ax\",@progbits");
9448 }
9449
9450 /* Override section callbacks to keep track of `avr_need_clear_bss_p'
9451 resp. `avr_need_copy_data_p'. */
9452
9453 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
9454 data_section->unnamed.callback = avr_output_data_section_asm_op;
9455 bss_section->unnamed.callback = avr_output_bss_section_asm_op;
9456 }
9457
9458
9459 /* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'. */
9460
9461 static section*
9462 avr_asm_function_rodata_section (tree decl)
9463 {
9464 /* If a function is unused and optimized out by -ffunction-sections
9465 and --gc-sections, ensure that the same will happen for its jump
9466 tables by putting them into individual sections. */
9467
9468 unsigned int flags;
9469 section * frodata;
9470
9471 /* Get the frodata section from the default function in varasm.c
9472 but treat function-associated data-like jump tables as code
9473 rather than as user defined data. AVR has no constant pools. */
9474 {
9475 int fdata = flag_data_sections;
9476
9477 flag_data_sections = flag_function_sections;
9478 frodata = default_function_rodata_section (decl);
9479 flag_data_sections = fdata;
9480 flags = frodata->common.flags;
9481 }
9482
9483 if (frodata != readonly_data_section
9484 && flags & SECTION_NAMED)
9485 {
9486 /* Adjust section flags and replace section name prefix. */
9487
9488 unsigned int i;
9489
9490 static const char* const prefix[] =
9491 {
9492 ".rodata", ".progmem.gcc_sw_table",
9493 ".gnu.linkonce.r.", ".gnu.linkonce.t."
9494 };
9495
9496 for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2)
9497 {
9498 const char * old_prefix = prefix[i];
9499 const char * new_prefix = prefix[i+1];
9500 const char * name = frodata->named.name;
9501
9502 if (STR_PREFIX_P (name, old_prefix))
9503 {
9504 const char *rname = ACONCAT ((new_prefix,
9505 name + strlen (old_prefix), NULL));
9506 flags &= ~SECTION_CODE;
9507 flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE;
9508
9509 return get_section (rname, flags, frodata->named.decl);
9510 }
9511 }
9512 }
9513
9514 return progmem_swtable_section;
9515 }
9516
9517
9518 /* Implement `TARGET_ASM_NAMED_SECTION'. */
9519 /* Track need of __do_clear_bss, __do_copy_data for named sections. */
9520
9521 static void
9522 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
9523 {
9524 if (flags & AVR_SECTION_PROGMEM)
9525 {
9526 addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
9527 const char *old_prefix = ".rodata";
9528 const char *new_prefix = avr_addrspace[as].section_name;
9529
9530 if (STR_PREFIX_P (name, old_prefix))
9531 {
9532 const char *sname = ACONCAT ((new_prefix,
9533 name + strlen (old_prefix), NULL));
9534 default_elf_asm_named_section (sname, flags, decl);
9535 return;
9536 }
9537
9538 default_elf_asm_named_section (new_prefix, flags, decl);
9539 return;
9540 }
9541
9542 if (!avr_need_copy_data_p)
9543 avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
9544 || STR_PREFIX_P (name, ".rodata")
9545 || STR_PREFIX_P (name, ".gnu.linkonce.d"));
9546
9547 if (!avr_need_clear_bss_p)
9548 avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
9549
9550 default_elf_asm_named_section (name, flags, decl);
9551 }
9552
9553
9554 /* Implement `TARGET_SECTION_TYPE_FLAGS'. */
9555
9556 static unsigned int
9557 avr_section_type_flags (tree decl, const char *name, int reloc)
9558 {
9559 unsigned int flags = default_section_type_flags (decl, name, reloc);
9560
9561 if (STR_PREFIX_P (name, ".noinit"))
9562 {
9563 if (decl && TREE_CODE (decl) == VAR_DECL
9564 && DECL_INITIAL (decl) == NULL_TREE)
9565 flags |= SECTION_BSS; /* @nobits */
9566 else
9567 warning (0, "only uninitialized variables can be placed in the "
9568 ".noinit section");
9569 }
9570
9571 if (decl && DECL_P (decl)
9572 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9573 {
9574 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9575
9576 /* Attribute progmem puts data in generic address space.
9577 Set section flags as if it was in __flash to get the right
9578 section prefix in the remainder. */
9579
9580 if (ADDR_SPACE_GENERIC_P (as))
9581 as = ADDR_SPACE_FLASH;
9582
9583 flags |= as * SECTION_MACH_DEP;
9584 flags &= ~SECTION_WRITE;
9585 flags &= ~SECTION_BSS;
9586 }
9587
9588 return flags;
9589 }
9590
9591
9592 /* Implement `TARGET_ENCODE_SECTION_INFO'. */
9593
9594 static void
9595 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
9596 {
9597 /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
9598 readily available, see PR34734. So we postpone the warning
9599 about uninitialized data in program memory section until here. */
9600
9601 if (new_decl_p
9602 && decl && DECL_P (decl)
9603 && NULL_TREE == DECL_INITIAL (decl)
9604 && !DECL_EXTERNAL (decl)
9605 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9606 {
9607 warning (OPT_Wuninitialized,
9608 "uninitialized variable %q+D put into "
9609 "program memory area", decl);
9610 }
9611
9612 default_encode_section_info (decl, rtl, new_decl_p);
9613
9614 if (decl && DECL_P (decl)
9615 && TREE_CODE (decl) != FUNCTION_DECL
9616 && MEM_P (rtl)
9617 && SYMBOL_REF == GET_CODE (XEXP (rtl, 0)))
9618 {
9619 rtx sym = XEXP (rtl, 0);
9620 tree type = TREE_TYPE (decl);
9621 tree attr = DECL_ATTRIBUTES (decl);
9622 if (type == error_mark_node)
9623 return;
9624
9625 addr_space_t as = TYPE_ADDR_SPACE (type);
9626
9627 /* PSTR strings are in generic space but located in flash:
9628 patch address space. */
9629
9630 if (-1 == avr_progmem_p (decl, attr))
9631 as = ADDR_SPACE_FLASH;
9632
9633 AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
9634
9635 tree io_low_attr = lookup_attribute ("io_low", attr);
9636 tree io_attr = lookup_attribute ("io", attr);
9637 tree addr_attr;
9638 if (io_low_attr
9639 && TREE_VALUE (io_low_attr) && TREE_VALUE (TREE_VALUE (io_low_attr)))
9640 addr_attr = io_attr;
9641 else if (io_attr
9642 && TREE_VALUE (io_attr) && TREE_VALUE (TREE_VALUE (io_attr)))
9643 addr_attr = io_attr;
9644 else
9645 addr_attr = lookup_attribute ("address", attr);
9646 if (io_low_attr
9647 || (io_attr && addr_attr
9648 && low_io_address_operand
9649 (GEN_INT (TREE_INT_CST_LOW
9650 (TREE_VALUE (TREE_VALUE (addr_attr)))), QImode)))
9651 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO_LOW;
9652 if (io_attr || io_low_attr)
9653 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO;
9654 /* If we have an (io) address attribute specification, but the variable
9655 is external, treat the address as only a tentative definition
9656 to be used to determine if an io port is in the lower range, but
9657 don't use the exact value for constant propagation. */
9658 if (addr_attr && !DECL_EXTERNAL (decl))
9659 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS;
9660 }
9661 }
9662
9663
9664 /* Implement `TARGET_ASM_SELECT_SECTION' */
9665
9666 static section *
9667 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
9668 {
9669 section * sect = default_elf_select_section (decl, reloc, align);
9670
9671 if (decl && DECL_P (decl)
9672 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9673 {
9674 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9675
9676 /* __progmem__ goes in generic space but shall be allocated to
9677 .progmem.data */
9678
9679 if (ADDR_SPACE_GENERIC_P (as))
9680 as = ADDR_SPACE_FLASH;
9681
9682 if (sect->common.flags & SECTION_NAMED)
9683 {
9684 const char * name = sect->named.name;
9685 const char * old_prefix = ".rodata";
9686 const char * new_prefix = avr_addrspace[as].section_name;
9687
9688 if (STR_PREFIX_P (name, old_prefix))
9689 {
9690 const char *sname = ACONCAT ((new_prefix,
9691 name + strlen (old_prefix), NULL));
9692 return get_section (sname, sect->common.flags, sect->named.decl);
9693 }
9694 }
9695
9696 if (!progmem_section[as])
9697 {
9698 progmem_section[as]
9699 = get_unnamed_section (0, avr_output_progmem_section_asm_op,
9700 avr_addrspace[as].section_name);
9701 }
9702
9703 return progmem_section[as];
9704 }
9705
9706 return sect;
9707 }
9708
9709 /* Implement `TARGET_ASM_FILE_START'. */
9710 /* Outputs some text at the start of each assembler file. */
9711
9712 static void
9713 avr_file_start (void)
9714 {
9715 int sfr_offset = avr_arch->sfr_offset;
9716
9717 if (avr_arch->asm_only)
9718 error ("architecture %qs supported for assembler only", avr_mmcu);
9719
9720 default_file_start ();
9721
9722 /* Print I/O addresses of some SFRs used with IN and OUT. */
9723
9724 if (AVR_HAVE_SPH)
9725 fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
9726
9727 fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
9728 fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
9729 if (AVR_HAVE_RAMPZ)
9730 fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
9731 if (AVR_HAVE_RAMPY)
9732 fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
9733 if (AVR_HAVE_RAMPX)
9734 fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
9735 if (AVR_HAVE_RAMPD)
9736 fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
9737 if (AVR_XMEGA || AVR_TINY)
9738 fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
9739 fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO);
9740 fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO);
9741 }
9742
9743
9744 /* Implement `TARGET_ASM_FILE_END'. */
9745 /* Outputs to the stdio stream FILE some
9746 appropriate text to go at the end of an assembler file. */
9747
9748 static void
9749 avr_file_end (void)
9750 {
9751 /* Output these only if there is anything in the
9752 .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
9753 input section(s) - some code size can be saved by not
9754 linking in the initialization code from libgcc if resp.
9755 sections are empty, see PR18145. */
9756
9757 if (avr_need_copy_data_p)
9758 fputs (".global __do_copy_data\n", asm_out_file);
9759
9760 if (avr_need_clear_bss_p)
9761 fputs (".global __do_clear_bss\n", asm_out_file);
9762 }
9763
9764
9765 /* Worker function for `ADJUST_REG_ALLOC_ORDER'. */
9766 /* Choose the order in which to allocate hard registers for
9767 pseudo-registers local to a basic block.
9768
9769 Store the desired register order in the array `reg_alloc_order'.
9770 Element 0 should be the register to allocate first; element 1, the
9771 next register; and so on. */
9772
9773 void
9774 avr_adjust_reg_alloc_order (void)
9775 {
9776 unsigned int i;
9777 static const int order_0[] =
9778 {
9779 24, 25,
9780 18, 19, 20, 21, 22, 23,
9781 30, 31,
9782 26, 27, 28, 29,
9783 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9784 0, 1,
9785 32, 33, 34, 35
9786 };
9787 static const int tiny_order_0[] = {
9788 20, 21,
9789 22, 23,
9790 24, 25,
9791 30, 31,
9792 26, 27,
9793 28, 29,
9794 19, 18,
9795 16, 17,
9796 32, 33, 34, 35,
9797 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9798 };
9799 static const int order_1[] =
9800 {
9801 18, 19, 20, 21, 22, 23, 24, 25,
9802 30, 31,
9803 26, 27, 28, 29,
9804 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9805 0, 1,
9806 32, 33, 34, 35
9807 };
9808 static const int tiny_order_1[] = {
9809 22, 23,
9810 24, 25,
9811 30, 31,
9812 26, 27,
9813 28, 29,
9814 21, 20, 19, 18,
9815 16, 17,
9816 32, 33, 34, 35,
9817 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9818 };
9819 static const int order_2[] =
9820 {
9821 25, 24, 23, 22, 21, 20, 19, 18,
9822 30, 31,
9823 26, 27, 28, 29,
9824 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9825 1, 0,
9826 32, 33, 34, 35
9827 };
9828
9829 /* Select specific register allocation order.
9830 Tiny Core (ATtiny4/5/9/10/20/40) devices have only 16 registers,
9831 so different allocation order should be used. */
9832
9833 const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1)
9834 : TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_0 : order_2)
9835 : (AVR_TINY ? tiny_order_0 : order_0));
9836
9837 for (i = 0; i < ARRAY_SIZE (order_0); ++i)
9838 reg_alloc_order[i] = order[i];
9839 }
9840
9841
9842 /* Implement `TARGET_REGISTER_MOVE_COST' */
9843
9844 static int
9845 avr_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
9846 reg_class_t from, reg_class_t to)
9847 {
9848 return (from == STACK_REG ? 6
9849 : to == STACK_REG ? 12
9850 : 2);
9851 }
9852
9853
9854 /* Implement `TARGET_MEMORY_MOVE_COST' */
9855
9856 static int
9857 avr_memory_move_cost (machine_mode mode,
9858 reg_class_t rclass ATTRIBUTE_UNUSED,
9859 bool in ATTRIBUTE_UNUSED)
9860 {
9861 return (mode == QImode ? 2
9862 : mode == HImode ? 4
9863 : mode == SImode ? 8
9864 : mode == SFmode ? 8
9865 : 16);
9866 }
9867
9868
9869 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
9870 cost of an RTX operand given its context. X is the rtx of the
9871 operand, MODE is its mode, and OUTER is the rtx_code of this
9872 operand's parent operator. */
9873
9874 static int
9875 avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer,
9876 int opno, bool speed)
9877 {
9878 enum rtx_code code = GET_CODE (x);
9879 int total;
9880
9881 switch (code)
9882 {
9883 case REG:
9884 case SUBREG:
9885 return 0;
9886
9887 case CONST_INT:
9888 case CONST_FIXED:
9889 case CONST_DOUBLE:
9890 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
9891
9892 default:
9893 break;
9894 }
9895
9896 total = 0;
9897 avr_rtx_costs (x, mode, outer, opno, &total, speed);
9898 return total;
9899 }
9900
9901 /* Worker function for AVR backend's rtx_cost function.
9902 X is rtx expression whose cost is to be calculated.
9903 Return true if the complete cost has been computed.
9904 Return false if subexpressions should be scanned.
9905 In either case, *TOTAL contains the cost result. */
9906
9907 static bool
9908 avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
9909 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
9910 {
9911 enum rtx_code code = GET_CODE (x);
9912 HOST_WIDE_INT val;
9913
9914 switch (code)
9915 {
9916 case CONST_INT:
9917 case CONST_FIXED:
9918 case CONST_DOUBLE:
9919 case SYMBOL_REF:
9920 case CONST:
9921 case LABEL_REF:
9922 /* Immediate constants are as cheap as registers. */
9923 *total = 0;
9924 return true;
9925
9926 case MEM:
9927 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9928 return true;
9929
9930 case NEG:
9931 switch (mode)
9932 {
9933 case QImode:
9934 case SFmode:
9935 *total = COSTS_N_INSNS (1);
9936 break;
9937
9938 case HImode:
9939 case PSImode:
9940 case SImode:
9941 *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
9942 break;
9943
9944 default:
9945 return false;
9946 }
9947 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9948 return true;
9949
9950 case ABS:
9951 switch (mode)
9952 {
9953 case QImode:
9954 case SFmode:
9955 *total = COSTS_N_INSNS (1);
9956 break;
9957
9958 default:
9959 return false;
9960 }
9961 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9962 return true;
9963
9964 case NOT:
9965 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9966 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9967 return true;
9968
9969 case ZERO_EXTEND:
9970 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
9971 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
9972 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
9973 code, 0, speed);
9974 return true;
9975
9976 case SIGN_EXTEND:
9977 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
9978 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
9979 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
9980 code, 0, speed);
9981 return true;
9982
9983 case PLUS:
9984 switch (mode)
9985 {
9986 case QImode:
9987 if (AVR_HAVE_MUL
9988 && MULT == GET_CODE (XEXP (x, 0))
9989 && register_operand (XEXP (x, 1), QImode))
9990 {
9991 /* multiply-add */
9992 *total = COSTS_N_INSNS (speed ? 4 : 3);
9993 /* multiply-add with constant: will be split and load constant. */
9994 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
9995 *total = COSTS_N_INSNS (1) + *total;
9996 return true;
9997 }
9998 *total = COSTS_N_INSNS (1);
9999 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10000 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10001 break;
10002
10003 case HImode:
10004 if (AVR_HAVE_MUL
10005 && (MULT == GET_CODE (XEXP (x, 0))
10006 || ASHIFT == GET_CODE (XEXP (x, 0)))
10007 && register_operand (XEXP (x, 1), HImode)
10008 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
10009 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
10010 {
10011 /* multiply-add */
10012 *total = COSTS_N_INSNS (speed ? 5 : 4);
10013 /* multiply-add with constant: will be split and load constant. */
10014 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10015 *total = COSTS_N_INSNS (1) + *total;
10016 return true;
10017 }
10018 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10019 {
10020 *total = COSTS_N_INSNS (2);
10021 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10022 speed);
10023 }
10024 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10025 *total = COSTS_N_INSNS (1);
10026 else
10027 *total = COSTS_N_INSNS (2);
10028 break;
10029
10030 case PSImode:
10031 if (!CONST_INT_P (XEXP (x, 1)))
10032 {
10033 *total = COSTS_N_INSNS (3);
10034 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10035 speed);
10036 }
10037 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10038 *total = COSTS_N_INSNS (2);
10039 else
10040 *total = COSTS_N_INSNS (3);
10041 break;
10042
10043 case SImode:
10044 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10045 {
10046 *total = COSTS_N_INSNS (4);
10047 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10048 speed);
10049 }
10050 else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10051 *total = COSTS_N_INSNS (1);
10052 else
10053 *total = COSTS_N_INSNS (4);
10054 break;
10055
10056 default:
10057 return false;
10058 }
10059 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10060 return true;
10061
10062 case MINUS:
10063 if (AVR_HAVE_MUL
10064 && QImode == mode
10065 && register_operand (XEXP (x, 0), QImode)
10066 && MULT == GET_CODE (XEXP (x, 1)))
10067 {
10068 /* multiply-sub */
10069 *total = COSTS_N_INSNS (speed ? 4 : 3);
10070 /* multiply-sub with constant: will be split and load constant. */
10071 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10072 *total = COSTS_N_INSNS (1) + *total;
10073 return true;
10074 }
10075 if (AVR_HAVE_MUL
10076 && HImode == mode
10077 && register_operand (XEXP (x, 0), HImode)
10078 && (MULT == GET_CODE (XEXP (x, 1))
10079 || ASHIFT == GET_CODE (XEXP (x, 1)))
10080 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
10081 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
10082 {
10083 /* multiply-sub */
10084 *total = COSTS_N_INSNS (speed ? 5 : 4);
10085 /* multiply-sub with constant: will be split and load constant. */
10086 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10087 *total = COSTS_N_INSNS (1) + *total;
10088 return true;
10089 }
10090 /* FALLTHRU */
10091 case AND:
10092 case IOR:
10093 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10094 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10095 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10096 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10097 return true;
10098
10099 case XOR:
10100 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10101 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10102 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10103 return true;
10104
10105 case MULT:
10106 switch (mode)
10107 {
10108 case QImode:
10109 if (AVR_HAVE_MUL)
10110 *total = COSTS_N_INSNS (!speed ? 3 : 4);
10111 else if (!speed)
10112 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10113 else
10114 return false;
10115 break;
10116
10117 case HImode:
10118 if (AVR_HAVE_MUL)
10119 {
10120 rtx op0 = XEXP (x, 0);
10121 rtx op1 = XEXP (x, 1);
10122 enum rtx_code code0 = GET_CODE (op0);
10123 enum rtx_code code1 = GET_CODE (op1);
10124 bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
10125 bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
10126
10127 if (ex0
10128 && (u8_operand (op1, HImode)
10129 || s8_operand (op1, HImode)))
10130 {
10131 *total = COSTS_N_INSNS (!speed ? 4 : 6);
10132 return true;
10133 }
10134 if (ex0
10135 && register_operand (op1, HImode))
10136 {
10137 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10138 return true;
10139 }
10140 else if (ex0 || ex1)
10141 {
10142 *total = COSTS_N_INSNS (!speed ? 3 : 5);
10143 return true;
10144 }
10145 else if (register_operand (op0, HImode)
10146 && (u8_operand (op1, HImode)
10147 || s8_operand (op1, HImode)))
10148 {
10149 *total = COSTS_N_INSNS (!speed ? 6 : 9);
10150 return true;
10151 }
10152 else
10153 *total = COSTS_N_INSNS (!speed ? 7 : 10);
10154 }
10155 else if (!speed)
10156 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10157 else
10158 return false;
10159 break;
10160
10161 case PSImode:
10162 if (!speed)
10163 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10164 else
10165 *total = 10;
10166 break;
10167
10168 case SImode:
10169 if (AVR_HAVE_MUL)
10170 {
10171 if (!speed)
10172 {
10173 /* Add some additional costs besides CALL like moves etc. */
10174
10175 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10176 }
10177 else
10178 {
10179 /* Just a rough estimate. Even with -O2 we don't want bulky
10180 code expanded inline. */
10181
10182 *total = COSTS_N_INSNS (25);
10183 }
10184 }
10185 else
10186 {
10187 if (speed)
10188 *total = COSTS_N_INSNS (300);
10189 else
10190 /* Add some additional costs besides CALL like moves etc. */
10191 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10192 }
10193
10194 return true;
10195
10196 default:
10197 return false;
10198 }
10199 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10200 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10201 return true;
10202
10203 case DIV:
10204 case MOD:
10205 case UDIV:
10206 case UMOD:
10207 if (!speed)
10208 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10209 else
10210 *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
10211 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10212 /* For div/mod with const-int divisor we have at least the cost of
10213 loading the divisor. */
10214 if (CONST_INT_P (XEXP (x, 1)))
10215 *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
10216 /* Add some overall penaly for clobbering and moving around registers */
10217 *total += COSTS_N_INSNS (2);
10218 return true;
10219
10220 case ROTATE:
10221 switch (mode)
10222 {
10223 case QImode:
10224 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
10225 *total = COSTS_N_INSNS (1);
10226
10227 break;
10228
10229 case HImode:
10230 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
10231 *total = COSTS_N_INSNS (3);
10232
10233 break;
10234
10235 case SImode:
10236 if (CONST_INT_P (XEXP (x, 1)))
10237 switch (INTVAL (XEXP (x, 1)))
10238 {
10239 case 8:
10240 case 24:
10241 *total = COSTS_N_INSNS (5);
10242 break;
10243 case 16:
10244 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
10245 break;
10246 }
10247 break;
10248
10249 default:
10250 return false;
10251 }
10252 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10253 return true;
10254
10255 case ASHIFT:
10256 switch (mode)
10257 {
10258 case QImode:
10259 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10260 {
10261 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10262 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10263 speed);
10264 }
10265 else
10266 {
10267 val = INTVAL (XEXP (x, 1));
10268 if (val == 7)
10269 *total = COSTS_N_INSNS (3);
10270 else if (val >= 0 && val <= 7)
10271 *total = COSTS_N_INSNS (val);
10272 else
10273 *total = COSTS_N_INSNS (1);
10274 }
10275 break;
10276
10277 case HImode:
10278 if (AVR_HAVE_MUL)
10279 {
10280 if (const_2_to_7_operand (XEXP (x, 1), HImode)
10281 && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
10282 || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
10283 {
10284 *total = COSTS_N_INSNS (!speed ? 4 : 6);
10285 return true;
10286 }
10287 }
10288
10289 if (const1_rtx == (XEXP (x, 1))
10290 && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
10291 {
10292 *total = COSTS_N_INSNS (2);
10293 return true;
10294 }
10295
10296 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10297 {
10298 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10299 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10300 speed);
10301 }
10302 else
10303 switch (INTVAL (XEXP (x, 1)))
10304 {
10305 case 0:
10306 *total = 0;
10307 break;
10308 case 1:
10309 case 8:
10310 *total = COSTS_N_INSNS (2);
10311 break;
10312 case 9:
10313 *total = COSTS_N_INSNS (3);
10314 break;
10315 case 2:
10316 case 3:
10317 case 10:
10318 case 15:
10319 *total = COSTS_N_INSNS (4);
10320 break;
10321 case 7:
10322 case 11:
10323 case 12:
10324 *total = COSTS_N_INSNS (5);
10325 break;
10326 case 4:
10327 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10328 break;
10329 case 6:
10330 *total = COSTS_N_INSNS (!speed ? 5 : 9);
10331 break;
10332 case 5:
10333 *total = COSTS_N_INSNS (!speed ? 5 : 10);
10334 break;
10335 default:
10336 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10337 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10338 speed);
10339 }
10340 break;
10341
10342 case PSImode:
10343 if (!CONST_INT_P (XEXP (x, 1)))
10344 {
10345 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10346 }
10347 else
10348 switch (INTVAL (XEXP (x, 1)))
10349 {
10350 case 0:
10351 *total = 0;
10352 break;
10353 case 1:
10354 case 8:
10355 case 16:
10356 *total = COSTS_N_INSNS (3);
10357 break;
10358 case 23:
10359 *total = COSTS_N_INSNS (5);
10360 break;
10361 default:
10362 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10363 break;
10364 }
10365 break;
10366
10367 case SImode:
10368 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10369 {
10370 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10371 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10372 speed);
10373 }
10374 else
10375 switch (INTVAL (XEXP (x, 1)))
10376 {
10377 case 0:
10378 *total = 0;
10379 break;
10380 case 24:
10381 *total = COSTS_N_INSNS (3);
10382 break;
10383 case 1:
10384 case 8:
10385 case 16:
10386 *total = COSTS_N_INSNS (4);
10387 break;
10388 case 31:
10389 *total = COSTS_N_INSNS (6);
10390 break;
10391 case 2:
10392 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10393 break;
10394 default:
10395 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10396 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10397 speed);
10398 }
10399 break;
10400
10401 default:
10402 return false;
10403 }
10404 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10405 return true;
10406
10407 case ASHIFTRT:
10408 switch (mode)
10409 {
10410 case QImode:
10411 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10412 {
10413 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10414 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10415 speed);
10416 }
10417 else
10418 {
10419 val = INTVAL (XEXP (x, 1));
10420 if (val == 6)
10421 *total = COSTS_N_INSNS (4);
10422 else if (val == 7)
10423 *total = COSTS_N_INSNS (2);
10424 else if (val >= 0 && val <= 7)
10425 *total = COSTS_N_INSNS (val);
10426 else
10427 *total = COSTS_N_INSNS (1);
10428 }
10429 break;
10430
10431 case HImode:
10432 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10433 {
10434 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10435 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10436 speed);
10437 }
10438 else
10439 switch (INTVAL (XEXP (x, 1)))
10440 {
10441 case 0:
10442 *total = 0;
10443 break;
10444 case 1:
10445 *total = COSTS_N_INSNS (2);
10446 break;
10447 case 15:
10448 *total = COSTS_N_INSNS (3);
10449 break;
10450 case 2:
10451 case 7:
10452 case 8:
10453 case 9:
10454 *total = COSTS_N_INSNS (4);
10455 break;
10456 case 10:
10457 case 14:
10458 *total = COSTS_N_INSNS (5);
10459 break;
10460 case 11:
10461 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10462 break;
10463 case 12:
10464 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10465 break;
10466 case 6:
10467 case 13:
10468 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10469 break;
10470 default:
10471 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10472 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10473 speed);
10474 }
10475 break;
10476
10477 case PSImode:
10478 if (!CONST_INT_P (XEXP (x, 1)))
10479 {
10480 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10481 }
10482 else
10483 switch (INTVAL (XEXP (x, 1)))
10484 {
10485 case 0:
10486 *total = 0;
10487 break;
10488 case 1:
10489 *total = COSTS_N_INSNS (3);
10490 break;
10491 case 16:
10492 case 8:
10493 *total = COSTS_N_INSNS (5);
10494 break;
10495 case 23:
10496 *total = COSTS_N_INSNS (4);
10497 break;
10498 default:
10499 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10500 break;
10501 }
10502 break;
10503
10504 case SImode:
10505 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10506 {
10507 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10508 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10509 speed);
10510 }
10511 else
10512 switch (INTVAL (XEXP (x, 1)))
10513 {
10514 case 0:
10515 *total = 0;
10516 break;
10517 case 1:
10518 *total = COSTS_N_INSNS (4);
10519 break;
10520 case 8:
10521 case 16:
10522 case 24:
10523 *total = COSTS_N_INSNS (6);
10524 break;
10525 case 2:
10526 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10527 break;
10528 case 31:
10529 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
10530 break;
10531 default:
10532 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10533 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10534 speed);
10535 }
10536 break;
10537
10538 default:
10539 return false;
10540 }
10541 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10542 return true;
10543
10544 case LSHIFTRT:
10545 switch (mode)
10546 {
10547 case QImode:
10548 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10549 {
10550 *total = COSTS_N_INSNS (!speed ? 4 : 17);
10551 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10552 speed);
10553 }
10554 else
10555 {
10556 val = INTVAL (XEXP (x, 1));
10557 if (val == 7)
10558 *total = COSTS_N_INSNS (3);
10559 else if (val >= 0 && val <= 7)
10560 *total = COSTS_N_INSNS (val);
10561 else
10562 *total = COSTS_N_INSNS (1);
10563 }
10564 break;
10565
10566 case HImode:
10567 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10568 {
10569 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10570 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10571 speed);
10572 }
10573 else
10574 switch (INTVAL (XEXP (x, 1)))
10575 {
10576 case 0:
10577 *total = 0;
10578 break;
10579 case 1:
10580 case 8:
10581 *total = COSTS_N_INSNS (2);
10582 break;
10583 case 9:
10584 *total = COSTS_N_INSNS (3);
10585 break;
10586 case 2:
10587 case 10:
10588 case 15:
10589 *total = COSTS_N_INSNS (4);
10590 break;
10591 case 7:
10592 case 11:
10593 *total = COSTS_N_INSNS (5);
10594 break;
10595 case 3:
10596 case 12:
10597 case 13:
10598 case 14:
10599 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10600 break;
10601 case 4:
10602 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10603 break;
10604 case 5:
10605 case 6:
10606 *total = COSTS_N_INSNS (!speed ? 5 : 9);
10607 break;
10608 default:
10609 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10610 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10611 speed);
10612 }
10613 break;
10614
10615 case PSImode:
10616 if (!CONST_INT_P (XEXP (x, 1)))
10617 {
10618 *total = COSTS_N_INSNS (!speed ? 6 : 73);
10619 }
10620 else
10621 switch (INTVAL (XEXP (x, 1)))
10622 {
10623 case 0:
10624 *total = 0;
10625 break;
10626 case 1:
10627 case 8:
10628 case 16:
10629 *total = COSTS_N_INSNS (3);
10630 break;
10631 case 23:
10632 *total = COSTS_N_INSNS (5);
10633 break;
10634 default:
10635 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10636 break;
10637 }
10638 break;
10639
10640 case SImode:
10641 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10642 {
10643 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10644 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10645 speed);
10646 }
10647 else
10648 switch (INTVAL (XEXP (x, 1)))
10649 {
10650 case 0:
10651 *total = 0;
10652 break;
10653 case 1:
10654 *total = COSTS_N_INSNS (4);
10655 break;
10656 case 2:
10657 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10658 break;
10659 case 8:
10660 case 16:
10661 case 24:
10662 *total = COSTS_N_INSNS (4);
10663 break;
10664 case 31:
10665 *total = COSTS_N_INSNS (6);
10666 break;
10667 default:
10668 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10669 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10670 speed);
10671 }
10672 break;
10673
10674 default:
10675 return false;
10676 }
10677 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10678 return true;
10679
10680 case COMPARE:
10681 switch (GET_MODE (XEXP (x, 0)))
10682 {
10683 case QImode:
10684 *total = COSTS_N_INSNS (1);
10685 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10686 *total += avr_operand_rtx_cost (XEXP (x, 1), QImode, code,
10687 1, speed);
10688 break;
10689
10690 case HImode:
10691 *total = COSTS_N_INSNS (2);
10692 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10693 *total += avr_operand_rtx_cost (XEXP (x, 1), HImode, code,
10694 1, speed);
10695 else if (INTVAL (XEXP (x, 1)) != 0)
10696 *total += COSTS_N_INSNS (1);
10697 break;
10698
10699 case PSImode:
10700 *total = COSTS_N_INSNS (3);
10701 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
10702 *total += COSTS_N_INSNS (2);
10703 break;
10704
10705 case SImode:
10706 *total = COSTS_N_INSNS (4);
10707 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10708 *total += avr_operand_rtx_cost (XEXP (x, 1), SImode, code,
10709 1, speed);
10710 else if (INTVAL (XEXP (x, 1)) != 0)
10711 *total += COSTS_N_INSNS (3);
10712 break;
10713
10714 default:
10715 return false;
10716 }
10717 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
10718 code, 0, speed);
10719 return true;
10720
10721 case TRUNCATE:
10722 if (AVR_HAVE_MUL
10723 && LSHIFTRT == GET_CODE (XEXP (x, 0))
10724 && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
10725 && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10726 {
10727 if (QImode == mode || HImode == mode)
10728 {
10729 *total = COSTS_N_INSNS (2);
10730 return true;
10731 }
10732 }
10733 break;
10734
10735 default:
10736 break;
10737 }
10738 return false;
10739 }
10740
10741
10742 /* Implement `TARGET_RTX_COSTS'. */
10743
10744 static bool
10745 avr_rtx_costs (rtx x, machine_mode mode, int outer_code,
10746 int opno, int *total, bool speed)
10747 {
10748 bool done = avr_rtx_costs_1 (x, mode, outer_code,
10749 opno, total, speed);
10750
10751 if (avr_log.rtx_costs)
10752 {
10753 avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
10754 done, speed ? "speed" : "size", *total, outer_code, x);
10755 }
10756
10757 return done;
10758 }
10759
10760
10761 /* Implement `TARGET_ADDRESS_COST'. */
10762
10763 static int
10764 avr_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
10765 addr_space_t as ATTRIBUTE_UNUSED,
10766 bool speed ATTRIBUTE_UNUSED)
10767 {
10768 int cost = 4;
10769
10770 if (GET_CODE (x) == PLUS
10771 && CONST_INT_P (XEXP (x, 1))
10772 && (REG_P (XEXP (x, 0))
10773 || GET_CODE (XEXP (x, 0)) == SUBREG))
10774 {
10775 if (INTVAL (XEXP (x, 1)) >= 61)
10776 cost = 18;
10777 }
10778 else if (CONSTANT_ADDRESS_P (x))
10779 {
10780 if (optimize > 0
10781 && io_address_operand (x, QImode))
10782 cost = 2;
10783 }
10784
10785 if (avr_log.address_cost)
10786 avr_edump ("\n%?: %d = %r\n", cost, x);
10787
10788 return cost;
10789 }
10790
10791 /* Test for extra memory constraint 'Q'.
10792 It's a memory address based on Y or Z pointer with valid displacement. */
10793
10794 int
10795 extra_constraint_Q (rtx x)
10796 {
10797 int ok = 0;
10798
10799 if (GET_CODE (XEXP (x,0)) == PLUS
10800 && REG_P (XEXP (XEXP (x,0), 0))
10801 && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
10802 && (INTVAL (XEXP (XEXP (x,0), 1))
10803 <= MAX_LD_OFFSET (GET_MODE (x))))
10804 {
10805 rtx xx = XEXP (XEXP (x,0), 0);
10806 int regno = REGNO (xx);
10807
10808 ok = (/* allocate pseudos */
10809 regno >= FIRST_PSEUDO_REGISTER
10810 /* strictly check */
10811 || regno == REG_Z || regno == REG_Y
10812 /* XXX frame & arg pointer checks */
10813 || xx == frame_pointer_rtx
10814 || xx == arg_pointer_rtx);
10815
10816 if (avr_log.constraints)
10817 avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
10818 ok, reload_completed, reload_in_progress, x);
10819 }
10820
10821 return ok;
10822 }
10823
10824 /* Convert condition code CONDITION to the valid AVR condition code. */
10825
10826 RTX_CODE
10827 avr_normalize_condition (RTX_CODE condition)
10828 {
10829 switch (condition)
10830 {
10831 case GT:
10832 return GE;
10833 case GTU:
10834 return GEU;
10835 case LE:
10836 return LT;
10837 case LEU:
10838 return LTU;
10839 default:
10840 gcc_unreachable ();
10841 }
10842 }
10843
10844 /* Helper function for `avr_reorg'. */
10845
10846 static rtx
10847 avr_compare_pattern (rtx_insn *insn)
10848 {
10849 rtx pattern = single_set (insn);
10850
10851 if (pattern
10852 && NONJUMP_INSN_P (insn)
10853 && SET_DEST (pattern) == cc0_rtx
10854 && GET_CODE (SET_SRC (pattern)) == COMPARE)
10855 {
10856 machine_mode mode0 = GET_MODE (XEXP (SET_SRC (pattern), 0));
10857 machine_mode mode1 = GET_MODE (XEXP (SET_SRC (pattern), 1));
10858
10859 /* The 64-bit comparisons have fixed operands ACC_A and ACC_B.
10860 They must not be swapped, thus skip them. */
10861
10862 if ((mode0 == VOIDmode || GET_MODE_SIZE (mode0) <= 4)
10863 && (mode1 == VOIDmode || GET_MODE_SIZE (mode1) <= 4))
10864 return pattern;
10865 }
10866
10867 return NULL_RTX;
10868 }
10869
10870 /* Helper function for `avr_reorg'. */
10871
10872 /* Expansion of switch/case decision trees leads to code like
10873
10874 cc0 = compare (Reg, Num)
10875 if (cc0 == 0)
10876 goto L1
10877
10878 cc0 = compare (Reg, Num)
10879 if (cc0 > 0)
10880 goto L2
10881
10882 The second comparison is superfluous and can be deleted.
10883 The second jump condition can be transformed from a
10884 "difficult" one to a "simple" one because "cc0 > 0" and
10885 "cc0 >= 0" will have the same effect here.
10886
10887 This function relies on the way switch/case is being expaned
10888 as binary decision tree. For example code see PR 49903.
10889
10890 Return TRUE if optimization performed.
10891 Return FALSE if nothing changed.
10892
10893 INSN1 is a comparison, i.e. avr_compare_pattern != 0.
10894
10895 We don't want to do this in text peephole because it is
10896 tedious to work out jump offsets there and the second comparison
10897 might have been transormed by `avr_reorg'.
10898
10899 RTL peephole won't do because peephole2 does not scan across
10900 basic blocks. */
10901
10902 static bool
10903 avr_reorg_remove_redundant_compare (rtx_insn *insn1)
10904 {
10905 rtx comp1, ifelse1, xcond1;
10906 rtx_insn *branch1;
10907 rtx comp2, ifelse2, xcond2;
10908 rtx_insn *branch2, *insn2;
10909 enum rtx_code code;
10910 rtx_insn *jump;
10911 rtx target, cond;
10912
10913 /* Look out for: compare1 - branch1 - compare2 - branch2 */
10914
10915 branch1 = next_nonnote_nondebug_insn (insn1);
10916 if (!branch1 || !JUMP_P (branch1))
10917 return false;
10918
10919 insn2 = next_nonnote_nondebug_insn (branch1);
10920 if (!insn2 || !avr_compare_pattern (insn2))
10921 return false;
10922
10923 branch2 = next_nonnote_nondebug_insn (insn2);
10924 if (!branch2 || !JUMP_P (branch2))
10925 return false;
10926
10927 comp1 = avr_compare_pattern (insn1);
10928 comp2 = avr_compare_pattern (insn2);
10929 xcond1 = single_set (branch1);
10930 xcond2 = single_set (branch2);
10931
10932 if (!comp1 || !comp2
10933 || !rtx_equal_p (comp1, comp2)
10934 || !xcond1 || SET_DEST (xcond1) != pc_rtx
10935 || !xcond2 || SET_DEST (xcond2) != pc_rtx
10936 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
10937 || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
10938 {
10939 return false;
10940 }
10941
10942 comp1 = SET_SRC (comp1);
10943 ifelse1 = SET_SRC (xcond1);
10944 ifelse2 = SET_SRC (xcond2);
10945
10946 /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE. */
10947
10948 if (EQ != GET_CODE (XEXP (ifelse1, 0))
10949 || !REG_P (XEXP (comp1, 0))
10950 || !CONST_INT_P (XEXP (comp1, 1))
10951 || XEXP (ifelse1, 2) != pc_rtx
10952 || XEXP (ifelse2, 2) != pc_rtx
10953 || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
10954 || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
10955 || !COMPARISON_P (XEXP (ifelse2, 0))
10956 || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
10957 || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
10958 || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
10959 || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
10960 {
10961 return false;
10962 }
10963
10964 /* We filtered the insn sequence to look like
10965
10966 (set (cc0)
10967 (compare (reg:M N)
10968 (const_int VAL)))
10969 (set (pc)
10970 (if_then_else (eq (cc0)
10971 (const_int 0))
10972 (label_ref L1)
10973 (pc)))
10974
10975 (set (cc0)
10976 (compare (reg:M N)
10977 (const_int VAL)))
10978 (set (pc)
10979 (if_then_else (CODE (cc0)
10980 (const_int 0))
10981 (label_ref L2)
10982 (pc)))
10983 */
10984
10985 code = GET_CODE (XEXP (ifelse2, 0));
10986
10987 /* Map GT/GTU to GE/GEU which is easier for AVR.
10988 The first two instructions compare/branch on EQ
10989 so we may replace the difficult
10990
10991 if (x == VAL) goto L1;
10992 if (x > VAL) goto L2;
10993
10994 with easy
10995
10996 if (x == VAL) goto L1;
10997 if (x >= VAL) goto L2;
10998
10999 Similarly, replace LE/LEU by LT/LTU. */
11000
11001 switch (code)
11002 {
11003 case EQ:
11004 case LT: case LTU:
11005 case GE: case GEU:
11006 break;
11007
11008 case LE: case LEU:
11009 case GT: case GTU:
11010 code = avr_normalize_condition (code);
11011 break;
11012
11013 default:
11014 return false;
11015 }
11016
11017 /* Wrap the branches into UNSPECs so they won't be changed or
11018 optimized in the remainder. */
11019
11020 target = XEXP (XEXP (ifelse1, 1), 0);
11021 cond = XEXP (ifelse1, 0);
11022 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
11023
11024 JUMP_LABEL (jump) = JUMP_LABEL (branch1);
11025
11026 target = XEXP (XEXP (ifelse2, 1), 0);
11027 cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
11028 jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
11029
11030 JUMP_LABEL (jump) = JUMP_LABEL (branch2);
11031
11032 /* The comparisons in insn1 and insn2 are exactly the same;
11033 insn2 is superfluous so delete it. */
11034
11035 delete_insn (insn2);
11036 delete_insn (branch1);
11037 delete_insn (branch2);
11038
11039 return true;
11040 }
11041
11042
11043 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'. */
11044 /* Optimize conditional jumps. */
11045
11046 static void
11047 avr_reorg (void)
11048 {
11049 rtx_insn *insn = get_insns();
11050
11051 for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
11052 {
11053 rtx pattern = avr_compare_pattern (insn);
11054
11055 if (!pattern)
11056 continue;
11057
11058 if (optimize
11059 && avr_reorg_remove_redundant_compare (insn))
11060 {
11061 continue;
11062 }
11063
11064 if (compare_diff_p (insn))
11065 {
11066 /* Now we work under compare insn with difficult branch. */
11067
11068 rtx_insn *next = next_real_insn (insn);
11069 rtx pat = PATTERN (next);
11070
11071 pattern = SET_SRC (pattern);
11072
11073 if (true_regnum (XEXP (pattern, 0)) >= 0
11074 && true_regnum (XEXP (pattern, 1)) >= 0)
11075 {
11076 rtx x = XEXP (pattern, 0);
11077 rtx src = SET_SRC (pat);
11078 rtx t = XEXP (src,0);
11079 PUT_CODE (t, swap_condition (GET_CODE (t)));
11080 XEXP (pattern, 0) = XEXP (pattern, 1);
11081 XEXP (pattern, 1) = x;
11082 INSN_CODE (next) = -1;
11083 }
11084 else if (true_regnum (XEXP (pattern, 0)) >= 0
11085 && XEXP (pattern, 1) == const0_rtx)
11086 {
11087 /* This is a tst insn, we can reverse it. */
11088 rtx src = SET_SRC (pat);
11089 rtx t = XEXP (src,0);
11090
11091 PUT_CODE (t, swap_condition (GET_CODE (t)));
11092 XEXP (pattern, 1) = XEXP (pattern, 0);
11093 XEXP (pattern, 0) = const0_rtx;
11094 INSN_CODE (next) = -1;
11095 INSN_CODE (insn) = -1;
11096 }
11097 else if (true_regnum (XEXP (pattern, 0)) >= 0
11098 && CONST_INT_P (XEXP (pattern, 1)))
11099 {
11100 rtx x = XEXP (pattern, 1);
11101 rtx src = SET_SRC (pat);
11102 rtx t = XEXP (src,0);
11103 machine_mode mode = GET_MODE (XEXP (pattern, 0));
11104
11105 if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
11106 {
11107 XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
11108 PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
11109 INSN_CODE (next) = -1;
11110 INSN_CODE (insn) = -1;
11111 }
11112 }
11113 }
11114 }
11115 }
11116
11117 /* Returns register number for function return value.*/
11118
11119 static inline unsigned int
11120 avr_ret_register (void)
11121 {
11122 return 24;
11123 }
11124
11125
11126 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'. */
11127
11128 static bool
11129 avr_function_value_regno_p (const unsigned int regno)
11130 {
11131 return (regno == avr_ret_register ());
11132 }
11133
11134
11135 /* Implement `TARGET_LIBCALL_VALUE'. */
11136 /* Create an RTX representing the place where a
11137 library function returns a value of mode MODE. */
11138
11139 static rtx
11140 avr_libcall_value (machine_mode mode,
11141 const_rtx func ATTRIBUTE_UNUSED)
11142 {
11143 int offs = GET_MODE_SIZE (mode);
11144
11145 if (offs <= 4)
11146 offs = (offs + 1) & ~1;
11147
11148 return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
11149 }
11150
11151
11152 /* Implement `TARGET_FUNCTION_VALUE'. */
11153 /* Create an RTX representing the place where a
11154 function returns a value of data type VALTYPE. */
11155
11156 static rtx
11157 avr_function_value (const_tree type,
11158 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
11159 bool outgoing ATTRIBUTE_UNUSED)
11160 {
11161 unsigned int offs;
11162
11163 if (TYPE_MODE (type) != BLKmode)
11164 return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
11165
11166 offs = int_size_in_bytes (type);
11167 if (offs < 2)
11168 offs = 2;
11169 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
11170 offs = GET_MODE_SIZE (SImode);
11171 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
11172 offs = GET_MODE_SIZE (DImode);
11173
11174 return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
11175 }
11176
11177 int
11178 test_hard_reg_class (enum reg_class rclass, rtx x)
11179 {
11180 int regno = true_regnum (x);
11181 if (regno < 0)
11182 return 0;
11183
11184 if (TEST_HARD_REG_CLASS (rclass, regno))
11185 return 1;
11186
11187 return 0;
11188 }
11189
11190
11191 /* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction
11192 and thus is suitable to be skipped by CPSE, SBRC, etc. */
11193
11194 static bool
11195 avr_2word_insn_p (rtx_insn *insn)
11196 {
11197 if (TARGET_SKIP_BUG
11198 || !insn
11199 || 2 != get_attr_length (insn))
11200 {
11201 return false;
11202 }
11203
11204 switch (INSN_CODE (insn))
11205 {
11206 default:
11207 return false;
11208
11209 case CODE_FOR_movqi_insn:
11210 case CODE_FOR_movuqq_insn:
11211 case CODE_FOR_movqq_insn:
11212 {
11213 rtx set = single_set (insn);
11214 rtx src = SET_SRC (set);
11215 rtx dest = SET_DEST (set);
11216
11217 /* Factor out LDS and STS from movqi_insn. */
11218
11219 if (MEM_P (dest)
11220 && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
11221 {
11222 return CONSTANT_ADDRESS_P (XEXP (dest, 0));
11223 }
11224 else if (REG_P (dest)
11225 && MEM_P (src))
11226 {
11227 return CONSTANT_ADDRESS_P (XEXP (src, 0));
11228 }
11229
11230 return false;
11231 }
11232
11233 case CODE_FOR_call_insn:
11234 case CODE_FOR_call_value_insn:
11235 return true;
11236 }
11237 }
11238
11239
11240 int
11241 jump_over_one_insn_p (rtx_insn *insn, rtx dest)
11242 {
11243 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
11244 ? XEXP (dest, 0)
11245 : dest);
11246 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
11247 int dest_addr = INSN_ADDRESSES (uid);
11248 int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
11249
11250 return (jump_offset == 1
11251 || (jump_offset == 2
11252 && avr_2word_insn_p (next_active_insn (insn))));
11253 }
11254
11255
11256 /* Worker function for `HARD_REGNO_MODE_OK'. */
11257 /* Returns 1 if a value of mode MODE can be stored starting with hard
11258 register number REGNO. On the enhanced core, anything larger than
11259 1 byte must start in even numbered register for "movw" to work
11260 (this way we don't have to check for odd registers everywhere). */
11261
11262 int
11263 avr_hard_regno_mode_ok (int regno, machine_mode mode)
11264 {
11265 /* NOTE: 8-bit values must not be disallowed for R28 or R29.
11266 Disallowing QI et al. in these regs might lead to code like
11267 (set (subreg:QI (reg:HI 28) n) ...)
11268 which will result in wrong code because reload does not
11269 handle SUBREGs of hard regsisters like this.
11270 This could be fixed in reload. However, it appears
11271 that fixing reload is not wanted by reload people. */
11272
11273 /* Any GENERAL_REGS register can hold 8-bit values. */
11274
11275 if (GET_MODE_SIZE (mode) == 1)
11276 return 1;
11277
11278 /* FIXME: Ideally, the following test is not needed.
11279 However, it turned out that it can reduce the number
11280 of spill fails. AVR and it's poor endowment with
11281 address registers is extreme stress test for reload. */
11282
11283 if (GET_MODE_SIZE (mode) >= 4
11284 && regno >= REG_X)
11285 return 0;
11286
11287 /* All modes larger than 8 bits should start in an even register. */
11288
11289 return !(regno & 1);
11290 }
11291
11292
11293 /* Implement `HARD_REGNO_CALL_PART_CLOBBERED'. */
11294
11295 int
11296 avr_hard_regno_call_part_clobbered (unsigned regno, machine_mode mode)
11297 {
11298 /* FIXME: This hook gets called with MODE:REGNO combinations that don't
11299 represent valid hard registers like, e.g. HI:29. Returning TRUE
11300 for such registers can lead to performance degradation as mentioned
11301 in PR53595. Thus, report invalid hard registers as FALSE. */
11302
11303 if (!avr_hard_regno_mode_ok (regno, mode))
11304 return 0;
11305
11306 /* Return true if any of the following boundaries is crossed:
11307 17/18 or 19/20 (if AVR_TINY), 27/28 and 29/30. */
11308
11309 return ((regno <= LAST_CALLEE_SAVED_REG &&
11310 regno + GET_MODE_SIZE (mode) > (LAST_CALLEE_SAVED_REG + 1))
11311 || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
11312 || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
11313 }
11314
11315
11316 /* Implement `MODE_CODE_BASE_REG_CLASS'. */
11317
11318 enum reg_class
11319 avr_mode_code_base_reg_class (machine_mode mode ATTRIBUTE_UNUSED,
11320 addr_space_t as, RTX_CODE outer_code,
11321 RTX_CODE index_code ATTRIBUTE_UNUSED)
11322 {
11323 if (!ADDR_SPACE_GENERIC_P (as))
11324 {
11325 return POINTER_Z_REGS;
11326 }
11327
11328 if (!avr_strict_X)
11329 return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
11330
11331 return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
11332 }
11333
11334
11335 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */
11336
11337 bool
11338 avr_regno_mode_code_ok_for_base_p (int regno,
11339 machine_mode mode ATTRIBUTE_UNUSED,
11340 addr_space_t as ATTRIBUTE_UNUSED,
11341 RTX_CODE outer_code,
11342 RTX_CODE index_code ATTRIBUTE_UNUSED)
11343 {
11344 bool ok = false;
11345
11346 if (!ADDR_SPACE_GENERIC_P (as))
11347 {
11348 if (regno < FIRST_PSEUDO_REGISTER
11349 && regno == REG_Z)
11350 {
11351 return true;
11352 }
11353
11354 if (reg_renumber)
11355 {
11356 regno = reg_renumber[regno];
11357
11358 if (regno == REG_Z)
11359 {
11360 return true;
11361 }
11362 }
11363
11364 return false;
11365 }
11366
11367 if (regno < FIRST_PSEUDO_REGISTER
11368 && (regno == REG_X
11369 || regno == REG_Y
11370 || regno == REG_Z
11371 || regno == ARG_POINTER_REGNUM))
11372 {
11373 ok = true;
11374 }
11375 else if (reg_renumber)
11376 {
11377 regno = reg_renumber[regno];
11378
11379 if (regno == REG_X
11380 || regno == REG_Y
11381 || regno == REG_Z
11382 || regno == ARG_POINTER_REGNUM)
11383 {
11384 ok = true;
11385 }
11386 }
11387
11388 if (avr_strict_X
11389 && PLUS == outer_code
11390 && regno == REG_X)
11391 {
11392 ok = false;
11393 }
11394
11395 return ok;
11396 }
11397
11398
11399 /* A helper for `output_reload_insisf' and `output_reload_inhi'. */
11400 /* Set 32-bit register OP[0] to compile-time constant OP[1].
11401 CLOBBER_REG is a QI clobber register or NULL_RTX.
11402 LEN == NULL: output instructions.
11403 LEN != NULL: set *LEN to the length of the instruction sequence
11404 (in words) printed with LEN = NULL.
11405 If CLEAR_P is true, OP[0] had been cleard to Zero already.
11406 If CLEAR_P is false, nothing is known about OP[0].
11407
11408 The effect on cc0 is as follows:
11409
11410 Load 0 to any register except ZERO_REG : NONE
11411 Load ld register with any value : NONE
11412 Anything else: : CLOBBER */
11413
11414 static void
11415 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
11416 {
11417 rtx src = op[1];
11418 rtx dest = op[0];
11419 rtx xval, xdest[4];
11420 int ival[4];
11421 int clobber_val = 1234;
11422 bool cooked_clobber_p = false;
11423 bool set_p = false;
11424 machine_mode mode = GET_MODE (dest);
11425 int n, n_bytes = GET_MODE_SIZE (mode);
11426
11427 gcc_assert (REG_P (dest)
11428 && CONSTANT_P (src));
11429
11430 if (len)
11431 *len = 0;
11432
11433 /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
11434 but has some subregs that are in LD_REGS. Use the MSB (REG:QI 17). */
11435
11436 if (REGNO (dest) < 16
11437 && REGNO (dest) + GET_MODE_SIZE (mode) > 16)
11438 {
11439 clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
11440 }
11441
11442 /* We might need a clobber reg but don't have one. Look at the value to
11443 be loaded more closely. A clobber is only needed if it is a symbol
11444 or contains a byte that is neither 0, -1 or a power of 2. */
11445
11446 if (NULL_RTX == clobber_reg
11447 && !test_hard_reg_class (LD_REGS, dest)
11448 && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
11449 || !avr_popcount_each_byte (src, n_bytes,
11450 (1 << 0) | (1 << 1) | (1 << 8))))
11451 {
11452 /* We have no clobber register but need one. Cook one up.
11453 That's cheaper than loading from constant pool. */
11454
11455 cooked_clobber_p = true;
11456 clobber_reg = all_regs_rtx[REG_Z + 1];
11457 avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
11458 }
11459
11460 /* Now start filling DEST from LSB to MSB. */
11461
11462 for (n = 0; n < n_bytes; n++)
11463 {
11464 int ldreg_p;
11465 bool done_byte = false;
11466 int j;
11467 rtx xop[3];
11468
11469 /* Crop the n-th destination byte. */
11470
11471 xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
11472 ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
11473
11474 if (!CONST_INT_P (src)
11475 && !CONST_FIXED_P (src)
11476 && !CONST_DOUBLE_P (src))
11477 {
11478 static const char* const asm_code[][2] =
11479 {
11480 { "ldi %2,lo8(%1)" CR_TAB "mov %0,%2", "ldi %0,lo8(%1)" },
11481 { "ldi %2,hi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hi8(%1)" },
11482 { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2", "ldi %0,hlo8(%1)" },
11483 { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hhi8(%1)" }
11484 };
11485
11486 xop[0] = xdest[n];
11487 xop[1] = src;
11488 xop[2] = clobber_reg;
11489
11490 avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
11491
11492 continue;
11493 }
11494
11495 /* Crop the n-th source byte. */
11496
11497 xval = simplify_gen_subreg (QImode, src, mode, n);
11498 ival[n] = INTVAL (xval);
11499
11500 /* Look if we can reuse the low word by means of MOVW. */
11501
11502 if (n == 2
11503 && n_bytes >= 4
11504 && AVR_HAVE_MOVW)
11505 {
11506 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
11507 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
11508
11509 if (INTVAL (lo16) == INTVAL (hi16))
11510 {
11511 if (0 != INTVAL (lo16)
11512 || !clear_p)
11513 {
11514 avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
11515 }
11516
11517 break;
11518 }
11519 }
11520
11521 /* Don't use CLR so that cc0 is set as expected. */
11522
11523 if (ival[n] == 0)
11524 {
11525 if (!clear_p)
11526 avr_asm_len (ldreg_p ? "ldi %0,0"
11527 : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
11528 : "mov %0,__zero_reg__",
11529 &xdest[n], len, 1);
11530 continue;
11531 }
11532
11533 if (clobber_val == ival[n]
11534 && REGNO (clobber_reg) == REGNO (xdest[n]))
11535 {
11536 continue;
11537 }
11538
11539 /* LD_REGS can use LDI to move a constant value */
11540
11541 if (ldreg_p)
11542 {
11543 xop[0] = xdest[n];
11544 xop[1] = xval;
11545 avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
11546 continue;
11547 }
11548
11549 /* Try to reuse value already loaded in some lower byte. */
11550
11551 for (j = 0; j < n; j++)
11552 if (ival[j] == ival[n])
11553 {
11554 xop[0] = xdest[n];
11555 xop[1] = xdest[j];
11556
11557 avr_asm_len ("mov %0,%1", xop, len, 1);
11558 done_byte = true;
11559 break;
11560 }
11561
11562 if (done_byte)
11563 continue;
11564
11565 /* Need no clobber reg for -1: Use CLR/DEC */
11566
11567 if (-1 == ival[n])
11568 {
11569 if (!clear_p)
11570 avr_asm_len ("clr %0", &xdest[n], len, 1);
11571
11572 avr_asm_len ("dec %0", &xdest[n], len, 1);
11573 continue;
11574 }
11575 else if (1 == ival[n])
11576 {
11577 if (!clear_p)
11578 avr_asm_len ("clr %0", &xdest[n], len, 1);
11579
11580 avr_asm_len ("inc %0", &xdest[n], len, 1);
11581 continue;
11582 }
11583
11584 /* Use T flag or INC to manage powers of 2 if we have
11585 no clobber reg. */
11586
11587 if (NULL_RTX == clobber_reg
11588 && single_one_operand (xval, QImode))
11589 {
11590 xop[0] = xdest[n];
11591 xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
11592
11593 gcc_assert (constm1_rtx != xop[1]);
11594
11595 if (!set_p)
11596 {
11597 set_p = true;
11598 avr_asm_len ("set", xop, len, 1);
11599 }
11600
11601 if (!clear_p)
11602 avr_asm_len ("clr %0", xop, len, 1);
11603
11604 avr_asm_len ("bld %0,%1", xop, len, 1);
11605 continue;
11606 }
11607
11608 /* We actually need the LD_REGS clobber reg. */
11609
11610 gcc_assert (NULL_RTX != clobber_reg);
11611
11612 xop[0] = xdest[n];
11613 xop[1] = xval;
11614 xop[2] = clobber_reg;
11615 clobber_val = ival[n];
11616
11617 avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
11618 "mov %0,%2", xop, len, 2);
11619 }
11620
11621 /* If we cooked up a clobber reg above, restore it. */
11622
11623 if (cooked_clobber_p)
11624 {
11625 avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
11626 }
11627 }
11628
11629
11630 /* Reload the constant OP[1] into the HI register OP[0].
11631 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11632 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
11633 need a clobber reg or have to cook one up.
11634
11635 PLEN == NULL: Output instructions.
11636 PLEN != NULL: Output nothing. Set *PLEN to number of words occupied
11637 by the insns printed.
11638
11639 Return "". */
11640
11641 const char*
11642 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
11643 {
11644 output_reload_in_const (op, clobber_reg, plen, false);
11645 return "";
11646 }
11647
11648
11649 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
11650 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11651 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
11652 need a clobber reg or have to cook one up.
11653
11654 LEN == NULL: Output instructions.
11655
11656 LEN != NULL: Output nothing. Set *LEN to number of words occupied
11657 by the insns printed.
11658
11659 Return "". */
11660
11661 const char *
11662 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
11663 {
11664 if (AVR_HAVE_MOVW
11665 && !test_hard_reg_class (LD_REGS, op[0])
11666 && (CONST_INT_P (op[1])
11667 || CONST_FIXED_P (op[1])
11668 || CONST_DOUBLE_P (op[1])))
11669 {
11670 int len_clr, len_noclr;
11671
11672 /* In some cases it is better to clear the destination beforehand, e.g.
11673
11674 CLR R2 CLR R3 MOVW R4,R2 INC R2
11675
11676 is shorther than
11677
11678 CLR R2 INC R2 CLR R3 CLR R4 CLR R5
11679
11680 We find it too tedious to work that out in the print function.
11681 Instead, we call the print function twice to get the lengths of
11682 both methods and use the shortest one. */
11683
11684 output_reload_in_const (op, clobber_reg, &len_clr, true);
11685 output_reload_in_const (op, clobber_reg, &len_noclr, false);
11686
11687 if (len_noclr - len_clr == 4)
11688 {
11689 /* Default needs 4 CLR instructions: clear register beforehand. */
11690
11691 avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
11692 "mov %B0,__zero_reg__" CR_TAB
11693 "movw %C0,%A0", &op[0], len, 3);
11694
11695 output_reload_in_const (op, clobber_reg, len, true);
11696
11697 if (len)
11698 *len += 3;
11699
11700 return "";
11701 }
11702 }
11703
11704 /* Default: destination not pre-cleared. */
11705
11706 output_reload_in_const (op, clobber_reg, len, false);
11707 return "";
11708 }
11709
11710 const char*
11711 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
11712 {
11713 output_reload_in_const (op, clobber_reg, len, false);
11714 return "";
11715 }
11716
11717
11718 /* Worker function for `ASM_OUTPUT_ADDR_VEC_ELT'. */
11719
11720 void
11721 avr_output_addr_vec_elt (FILE *stream, int value)
11722 {
11723 if (AVR_HAVE_JMP_CALL)
11724 fprintf (stream, "\t.word gs(.L%d)\n", value);
11725 else
11726 fprintf (stream, "\trjmp .L%d\n", value);
11727 }
11728
11729 static void
11730 avr_conditional_register_usage(void)
11731 {
11732 if (AVR_TINY)
11733 {
11734 unsigned int i;
11735
11736 const int tiny_reg_alloc_order[] = {
11737 24, 25,
11738 22, 23,
11739 30, 31,
11740 26, 27,
11741 28, 29,
11742 21, 20, 19, 18,
11743 16, 17,
11744 32, 33, 34, 35,
11745 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
11746 };
11747
11748 /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
11749 - R0-R15 are not available in Tiny Core devices
11750 - R16 and R17 are fixed registers. */
11751
11752 for (i = 0; i <= 17; i++)
11753 {
11754 fixed_regs[i] = 1;
11755 call_used_regs[i] = 1;
11756 }
11757
11758 /* Set R18 to R21 as callee saved registers
11759 - R18, R19, R20 and R21 are the callee saved registers in
11760 Tiny Core devices */
11761
11762 for (i = 18; i <= LAST_CALLEE_SAVED_REG; i++)
11763 {
11764 call_used_regs[i] = 0;
11765 }
11766
11767 /* Update register allocation order for Tiny Core devices */
11768
11769 for (i = 0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++)
11770 {
11771 reg_alloc_order[i] = tiny_reg_alloc_order[i];
11772 }
11773
11774 CLEAR_HARD_REG_SET (reg_class_contents[(int) ADDW_REGS]);
11775 CLEAR_HARD_REG_SET (reg_class_contents[(int) NO_LD_REGS]);
11776 }
11777 }
11778
11779 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'. */
11780 /* Returns true if SCRATCH are safe to be allocated as a scratch
11781 registers (for a define_peephole2) in the current function. */
11782
11783 static bool
11784 avr_hard_regno_scratch_ok (unsigned int regno)
11785 {
11786 /* Interrupt functions can only use registers that have already been saved
11787 by the prologue, even if they would normally be call-clobbered. */
11788
11789 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11790 && !df_regs_ever_live_p (regno))
11791 return false;
11792
11793 /* Don't allow hard registers that might be part of the frame pointer.
11794 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11795 and don't care for a frame pointer that spans more than one register. */
11796
11797 if ((!reload_completed || frame_pointer_needed)
11798 && (regno == REG_Y || regno == REG_Y + 1))
11799 {
11800 return false;
11801 }
11802
11803 return true;
11804 }
11805
11806
11807 /* Worker function for `HARD_REGNO_RENAME_OK'. */
11808 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
11809
11810 int
11811 avr_hard_regno_rename_ok (unsigned int old_reg,
11812 unsigned int new_reg)
11813 {
11814 /* Interrupt functions can only use registers that have already been
11815 saved by the prologue, even if they would normally be
11816 call-clobbered. */
11817
11818 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11819 && !df_regs_ever_live_p (new_reg))
11820 return 0;
11821
11822 /* Don't allow hard registers that might be part of the frame pointer.
11823 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11824 and don't care for a frame pointer that spans more than one register. */
11825
11826 if ((!reload_completed || frame_pointer_needed)
11827 && (old_reg == REG_Y || old_reg == REG_Y + 1
11828 || new_reg == REG_Y || new_reg == REG_Y + 1))
11829 {
11830 return 0;
11831 }
11832
11833 return 1;
11834 }
11835
11836 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
11837 or memory location in the I/O space (QImode only).
11838
11839 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
11840 Operand 1: register operand to test, or CONST_INT memory address.
11841 Operand 2: bit number.
11842 Operand 3: label to jump to if the test is true. */
11843
11844 const char*
11845 avr_out_sbxx_branch (rtx_insn *insn, rtx operands[])
11846 {
11847 enum rtx_code comp = GET_CODE (operands[0]);
11848 bool long_jump = get_attr_length (insn) >= 4;
11849 bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
11850
11851 if (comp == GE)
11852 comp = EQ;
11853 else if (comp == LT)
11854 comp = NE;
11855
11856 if (reverse)
11857 comp = reverse_condition (comp);
11858
11859 switch (GET_CODE (operands[1]))
11860 {
11861 default:
11862 gcc_unreachable();
11863
11864 case CONST_INT:
11865 case CONST:
11866 case SYMBOL_REF:
11867
11868 if (low_io_address_operand (operands[1], QImode))
11869 {
11870 if (comp == EQ)
11871 output_asm_insn ("sbis %i1,%2", operands);
11872 else
11873 output_asm_insn ("sbic %i1,%2", operands);
11874 }
11875 else
11876 {
11877 gcc_assert (io_address_operand (operands[1], QImode));
11878 output_asm_insn ("in __tmp_reg__,%i1", operands);
11879 if (comp == EQ)
11880 output_asm_insn ("sbrs __tmp_reg__,%2", operands);
11881 else
11882 output_asm_insn ("sbrc __tmp_reg__,%2", operands);
11883 }
11884
11885 break; /* CONST_INT */
11886
11887 case REG:
11888
11889 if (comp == EQ)
11890 output_asm_insn ("sbrs %T1%T2", operands);
11891 else
11892 output_asm_insn ("sbrc %T1%T2", operands);
11893
11894 break; /* REG */
11895 } /* switch */
11896
11897 if (long_jump)
11898 return ("rjmp .+4" CR_TAB
11899 "jmp %x3");
11900
11901 if (!reverse)
11902 return "rjmp %x3";
11903
11904 return "";
11905 }
11906
11907 /* Worker function for `TARGET_ASM_CONSTRUCTOR'. */
11908
11909 static void
11910 avr_asm_out_ctor (rtx symbol, int priority)
11911 {
11912 fputs ("\t.global __do_global_ctors\n", asm_out_file);
11913 default_ctor_section_asm_out_constructor (symbol, priority);
11914 }
11915
11916
11917 /* Worker function for `TARGET_ASM_DESTRUCTOR'. */
11918
11919 static void
11920 avr_asm_out_dtor (rtx symbol, int priority)
11921 {
11922 fputs ("\t.global __do_global_dtors\n", asm_out_file);
11923 default_dtor_section_asm_out_destructor (symbol, priority);
11924 }
11925
11926
11927 /* Worker function for `TARGET_RETURN_IN_MEMORY'. */
11928
11929 static bool
11930 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
11931 {
11932 HOST_WIDE_INT size = int_size_in_bytes (type);
11933 HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
11934
11935 /* In avr, there are 8 return registers. But, for Tiny Core
11936 (ATtiny4/5/9/10/20/40) devices, only 4 registers are available.
11937 Return true if size is unknown or greater than the limit. */
11938
11939 if (size == -1 || size > ret_size_limit)
11940 {
11941 return true;
11942 }
11943 else
11944 {
11945 return false;
11946 }
11947 }
11948
11949
11950 /* Implement `CASE_VALUES_THRESHOLD'. */
11951 /* Supply the default for --param case-values-threshold=0 */
11952
11953 static unsigned int
11954 avr_case_values_threshold (void)
11955 {
11956 /* The exact break-even point between a jump table and an if-else tree
11957 depends on several factors not available here like, e.g. if 8-bit
11958 comparisons can be used in the if-else tree or not, on the
11959 range of the case values, if the case value can be reused, on the
11960 register allocation, etc. '7' appears to be a good choice. */
11961
11962 return 7;
11963 }
11964
11965
11966 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'. */
11967
11968 static machine_mode
11969 avr_addr_space_address_mode (addr_space_t as)
11970 {
11971 return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
11972 }
11973
11974
11975 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'. */
11976
11977 static machine_mode
11978 avr_addr_space_pointer_mode (addr_space_t as)
11979 {
11980 return avr_addr_space_address_mode (as);
11981 }
11982
11983
11984 /* Helper for following function. */
11985
11986 static bool
11987 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
11988 {
11989 gcc_assert (REG_P (reg));
11990
11991 if (strict)
11992 {
11993 return REGNO (reg) == REG_Z;
11994 }
11995
11996 /* Avoid combine to propagate hard regs. */
11997
11998 if (can_create_pseudo_p()
11999 && REGNO (reg) < REG_Z)
12000 {
12001 return false;
12002 }
12003
12004 return true;
12005 }
12006
12007
12008 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'. */
12009
12010 static bool
12011 avr_addr_space_legitimate_address_p (machine_mode mode, rtx x,
12012 bool strict, addr_space_t as)
12013 {
12014 bool ok = false;
12015
12016 switch (as)
12017 {
12018 default:
12019 gcc_unreachable();
12020
12021 case ADDR_SPACE_GENERIC:
12022 return avr_legitimate_address_p (mode, x, strict);
12023
12024 case ADDR_SPACE_FLASH:
12025 case ADDR_SPACE_FLASH1:
12026 case ADDR_SPACE_FLASH2:
12027 case ADDR_SPACE_FLASH3:
12028 case ADDR_SPACE_FLASH4:
12029 case ADDR_SPACE_FLASH5:
12030
12031 switch (GET_CODE (x))
12032 {
12033 case REG:
12034 ok = avr_reg_ok_for_pgm_addr (x, strict);
12035 break;
12036
12037 case POST_INC:
12038 ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
12039 break;
12040
12041 default:
12042 break;
12043 }
12044
12045 break; /* FLASH */
12046
12047 case ADDR_SPACE_MEMX:
12048 if (REG_P (x))
12049 ok = (!strict
12050 && can_create_pseudo_p());
12051
12052 if (LO_SUM == GET_CODE (x))
12053 {
12054 rtx hi = XEXP (x, 0);
12055 rtx lo = XEXP (x, 1);
12056
12057 ok = (REG_P (hi)
12058 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
12059 && REG_P (lo)
12060 && REGNO (lo) == REG_Z);
12061 }
12062
12063 break; /* MEMX */
12064 }
12065
12066 if (avr_log.legitimate_address_p)
12067 {
12068 avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
12069 "reload_completed=%d reload_in_progress=%d %s:",
12070 ok, mode, strict, reload_completed, reload_in_progress,
12071 reg_renumber ? "(reg_renumber)" : "");
12072
12073 if (GET_CODE (x) == PLUS
12074 && REG_P (XEXP (x, 0))
12075 && CONST_INT_P (XEXP (x, 1))
12076 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
12077 && reg_renumber)
12078 {
12079 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
12080 true_regnum (XEXP (x, 0)));
12081 }
12082
12083 avr_edump ("\n%r\n", x);
12084 }
12085
12086 return ok;
12087 }
12088
12089
12090 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'. */
12091
12092 static rtx
12093 avr_addr_space_legitimize_address (rtx x, rtx old_x,
12094 machine_mode mode, addr_space_t as)
12095 {
12096 if (ADDR_SPACE_GENERIC_P (as))
12097 return avr_legitimize_address (x, old_x, mode);
12098
12099 if (avr_log.legitimize_address)
12100 {
12101 avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
12102 }
12103
12104 return old_x;
12105 }
12106
12107
12108 /* Implement `TARGET_ADDR_SPACE_CONVERT'. */
12109
12110 static rtx
12111 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
12112 {
12113 addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
12114 addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
12115
12116 if (avr_log.progmem)
12117 avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
12118 src, type_from, type_to);
12119
12120 /* Up-casting from 16-bit to 24-bit pointer. */
12121
12122 if (as_from != ADDR_SPACE_MEMX
12123 && as_to == ADDR_SPACE_MEMX)
12124 {
12125 int msb;
12126 rtx sym = src;
12127 rtx reg = gen_reg_rtx (PSImode);
12128
12129 while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
12130 sym = XEXP (sym, 0);
12131
12132 /* Look at symbol flags: avr_encode_section_info set the flags
12133 also if attribute progmem was seen so that we get the right
12134 promotion for, e.g. PSTR-like strings that reside in generic space
12135 but are located in flash. In that case we patch the incoming
12136 address space. */
12137
12138 if (SYMBOL_REF == GET_CODE (sym)
12139 && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
12140 {
12141 as_from = ADDR_SPACE_FLASH;
12142 }
12143
12144 /* Linearize memory: RAM has bit 23 set. */
12145
12146 msb = ADDR_SPACE_GENERIC_P (as_from)
12147 ? 0x80
12148 : avr_addrspace[as_from].segment;
12149
12150 src = force_reg (Pmode, src);
12151
12152 emit_insn (msb == 0
12153 ? gen_zero_extendhipsi2 (reg, src)
12154 : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
12155
12156 return reg;
12157 }
12158
12159 /* Down-casting from 24-bit to 16-bit throws away the high byte. */
12160
12161 if (as_from == ADDR_SPACE_MEMX
12162 && as_to != ADDR_SPACE_MEMX)
12163 {
12164 rtx new_src = gen_reg_rtx (Pmode);
12165
12166 src = force_reg (PSImode, src);
12167
12168 emit_move_insn (new_src,
12169 simplify_gen_subreg (Pmode, src, PSImode, 0));
12170 return new_src;
12171 }
12172
12173 return src;
12174 }
12175
12176
12177 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'. */
12178
12179 static bool
12180 avr_addr_space_subset_p (addr_space_t subset ATTRIBUTE_UNUSED,
12181 addr_space_t superset ATTRIBUTE_UNUSED)
12182 {
12183 /* Allow any kind of pointer mess. */
12184
12185 return true;
12186 }
12187
12188
12189 /* Implement `TARGET_CONVERT_TO_TYPE'. */
12190
12191 static tree
12192 avr_convert_to_type (tree type, tree expr)
12193 {
12194 /* Print a diagnose for pointer conversion that changes the address
12195 space of the pointer target to a non-enclosing address space,
12196 provided -Waddr-space-convert is on.
12197
12198 FIXME: Filter out cases where the target object is known to
12199 be located in the right memory, like in
12200
12201 (const __flash*) PSTR ("text")
12202
12203 Also try to distinguish between explicit casts requested by
12204 the user and implicit casts like
12205
12206 void f (const __flash char*);
12207
12208 void g (const char *p)
12209 {
12210 f ((const __flash*) p);
12211 }
12212
12213 under the assumption that an explicit casts means that the user
12214 knows what he is doing, e.g. interface with PSTR or old style
12215 code with progmem and pgm_read_xxx.
12216 */
12217
12218 if (avr_warn_addr_space_convert
12219 && expr != error_mark_node
12220 && POINTER_TYPE_P (type)
12221 && POINTER_TYPE_P (TREE_TYPE (expr)))
12222 {
12223 addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
12224 addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
12225
12226 if (avr_log.progmem)
12227 avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
12228
12229 if (as_new != ADDR_SPACE_MEMX
12230 && as_new != as_old)
12231 {
12232 location_t loc = EXPR_LOCATION (expr);
12233 const char *name_old = avr_addrspace[as_old].name;
12234 const char *name_new = avr_addrspace[as_new].name;
12235
12236 warning (OPT_Waddr_space_convert,
12237 "conversion from address space %qs to address space %qs",
12238 ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
12239 ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
12240
12241 return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
12242 }
12243 }
12244
12245 return NULL_TREE;
12246 }
12247
12248
12249 /* PR63633: The middle-end might come up with hard regs as input operands.
12250
12251 RMASK is a bit mask representing a subset of hard registers R0...R31:
12252 Rn is an element of that set iff bit n of RMASK is set.
12253 OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
12254 OP[n] has to be fixed; otherwise OP[n] is left alone.
12255
12256 For each element of OPMASK which is a hard register overlapping RMASK,
12257 replace OP[n] with a newly created pseudo register
12258
12259 HREG == 0: Also emit a move insn that copies the contents of that
12260 hard register into the new pseudo.
12261
12262 HREG != 0: Also set HREG[n] to the hard register. */
12263
12264 static void
12265 avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask)
12266 {
12267 for (; opmask; opmask >>= 1, op++)
12268 {
12269 rtx reg = *op;
12270
12271 if (hreg)
12272 *hreg = NULL_RTX;
12273
12274 if ((opmask & 1)
12275 && REG_P (reg)
12276 && REGNO (reg) < FIRST_PSEUDO_REGISTER
12277 // This hard-reg overlaps other prohibited hard regs?
12278 && (rmask & regmask (GET_MODE (reg), REGNO (reg))))
12279 {
12280 *op = gen_reg_rtx (GET_MODE (reg));
12281 if (hreg == NULL)
12282 emit_move_insn (*op, reg);
12283 else
12284 *hreg = reg;
12285 }
12286
12287 if (hreg)
12288 hreg++;
12289 }
12290 }
12291
12292
12293 void
12294 avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask)
12295 {
12296 avr_fix_operands (op, NULL, opmask, rmask);
12297 }
12298
12299
12300 /* Helper for the function below: If bit n of MASK is set and
12301 HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n].
12302 Otherwise do nothing for that n. Return TRUE. */
12303
12304 static bool
12305 avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask)
12306 {
12307 for (; mask; mask >>= 1, op++, hreg++)
12308 if ((mask & 1)
12309 && *hreg)
12310 emit_move_insn (*hreg, *op);
12311
12312 return true;
12313 }
12314
12315
12316 /* PR63633: The middle-end might come up with hard regs as output operands.
12317
12318 GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[].
12319 RMASK is a bit mask representing a subset of hard registers R0...R31:
12320 Rn is an element of that set iff bit n of RMASK is set.
12321 OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
12322 OP[n] has to be fixed; otherwise OP[n] is left alone.
12323
12324 Emit the insn sequence as generated by GEN() with all elements of OPMASK
12325 which are hard registers overlapping RMASK replaced by newly created
12326 pseudo registers. After the sequence has been emitted, emit insns that
12327 move the contents of respective pseudos to their hard regs. */
12328
12329 bool
12330 avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
12331 unsigned opmask, unsigned rmask)
12332 {
12333 const int n = 3;
12334 rtx hreg[n];
12335
12336 /* It is letigimate for GEN to call this function, and in order not to
12337 get self-recursive we use the following static kludge. This is the
12338 only way not to duplicate all expanders and to avoid ugly and
12339 hard-to-maintain C-code instead of the much more appreciated RTL
12340 representation as supplied by define_expand. */
12341 static bool lock = false;
12342
12343 gcc_assert (opmask < (1u << n));
12344
12345 if (lock)
12346 return false;
12347
12348 avr_fix_operands (op, hreg, opmask, rmask);
12349
12350 lock = true;
12351 emit_insn (gen (op[0], op[1], op[2]));
12352 lock = false;
12353
12354 return avr_move_fixed_operands (op, hreg, opmask);
12355 }
12356
12357
12358 /* Worker function for movmemhi expander.
12359 XOP[0] Destination as MEM:BLK
12360 XOP[1] Source " "
12361 XOP[2] # Bytes to copy
12362
12363 Return TRUE if the expansion is accomplished.
12364 Return FALSE if the operand compination is not supported. */
12365
12366 bool
12367 avr_emit_movmemhi (rtx *xop)
12368 {
12369 HOST_WIDE_INT count;
12370 machine_mode loop_mode;
12371 addr_space_t as = MEM_ADDR_SPACE (xop[1]);
12372 rtx loop_reg, addr1, a_src, a_dest, insn, xas;
12373 rtx a_hi8 = NULL_RTX;
12374
12375 if (avr_mem_flash_p (xop[0]))
12376 return false;
12377
12378 if (!CONST_INT_P (xop[2]))
12379 return false;
12380
12381 count = INTVAL (xop[2]);
12382 if (count <= 0)
12383 return false;
12384
12385 a_src = XEXP (xop[1], 0);
12386 a_dest = XEXP (xop[0], 0);
12387
12388 if (PSImode == GET_MODE (a_src))
12389 {
12390 gcc_assert (as == ADDR_SPACE_MEMX);
12391
12392 loop_mode = (count < 0x100) ? QImode : HImode;
12393 loop_reg = gen_rtx_REG (loop_mode, 24);
12394 emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
12395
12396 addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
12397 a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
12398 }
12399 else
12400 {
12401 int segment = avr_addrspace[as].segment;
12402
12403 if (segment
12404 && avr_n_flash > 1)
12405 {
12406 a_hi8 = GEN_INT (segment);
12407 emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
12408 }
12409 else if (!ADDR_SPACE_GENERIC_P (as))
12410 {
12411 as = ADDR_SPACE_FLASH;
12412 }
12413
12414 addr1 = a_src;
12415
12416 loop_mode = (count <= 0x100) ? QImode : HImode;
12417 loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
12418 }
12419
12420 xas = GEN_INT (as);
12421
12422 /* FIXME: Register allocator might come up with spill fails if it is left
12423 on its own. Thus, we allocate the pointer registers by hand:
12424 Z = source address
12425 X = destination address */
12426
12427 emit_move_insn (lpm_addr_reg_rtx, addr1);
12428 emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
12429
12430 /* FIXME: Register allocator does a bad job and might spill address
12431 register(s) inside the loop leading to additional move instruction
12432 to/from stack which could clobber tmp_reg. Thus, do *not* emit
12433 load and store as separate insns. Instead, we perform the copy
12434 by means of one monolithic insn. */
12435
12436 gcc_assert (TMP_REGNO == LPM_REGNO);
12437
12438 if (as != ADDR_SPACE_MEMX)
12439 {
12440 /* Load instruction ([E]LPM or LD) is known at compile time:
12441 Do the copy-loop inline. */
12442
12443 rtx (*fun) (rtx, rtx, rtx)
12444 = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
12445
12446 insn = fun (xas, loop_reg, loop_reg);
12447 }
12448 else
12449 {
12450 rtx (*fun) (rtx, rtx)
12451 = QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi;
12452
12453 emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
12454
12455 insn = fun (xas, GEN_INT (avr_addr.rampz));
12456 }
12457
12458 set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
12459 emit_insn (insn);
12460
12461 return true;
12462 }
12463
12464
12465 /* Print assembler for movmem_qi, movmem_hi insns...
12466 $0 : Address Space
12467 $1, $2 : Loop register
12468 Z : Source address
12469 X : Destination address
12470 */
12471
12472 const char*
12473 avr_out_movmem (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
12474 {
12475 addr_space_t as = (addr_space_t) INTVAL (op[0]);
12476 machine_mode loop_mode = GET_MODE (op[1]);
12477 bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]);
12478 rtx xop[3];
12479
12480 if (plen)
12481 *plen = 0;
12482
12483 xop[0] = op[0];
12484 xop[1] = op[1];
12485 xop[2] = tmp_reg_rtx;
12486
12487 /* Loop label */
12488
12489 avr_asm_len ("0:", xop, plen, 0);
12490
12491 /* Load with post-increment */
12492
12493 switch (as)
12494 {
12495 default:
12496 gcc_unreachable();
12497
12498 case ADDR_SPACE_GENERIC:
12499
12500 avr_asm_len ("ld %2,Z+", xop, plen, 1);
12501 break;
12502
12503 case ADDR_SPACE_FLASH:
12504
12505 if (AVR_HAVE_LPMX)
12506 avr_asm_len ("lpm %2,Z+", xop, plen, 1);
12507 else
12508 avr_asm_len ("lpm" CR_TAB
12509 "adiw r30,1", xop, plen, 2);
12510 break;
12511
12512 case ADDR_SPACE_FLASH1:
12513 case ADDR_SPACE_FLASH2:
12514 case ADDR_SPACE_FLASH3:
12515 case ADDR_SPACE_FLASH4:
12516 case ADDR_SPACE_FLASH5:
12517
12518 if (AVR_HAVE_ELPMX)
12519 avr_asm_len ("elpm %2,Z+", xop, plen, 1);
12520 else
12521 avr_asm_len ("elpm" CR_TAB
12522 "adiw r30,1", xop, plen, 2);
12523 break;
12524 }
12525
12526 /* Store with post-increment */
12527
12528 avr_asm_len ("st X+,%2", xop, plen, 1);
12529
12530 /* Decrement loop-counter and set Z-flag */
12531
12532 if (QImode == loop_mode)
12533 {
12534 avr_asm_len ("dec %1", xop, plen, 1);
12535 }
12536 else if (sbiw_p)
12537 {
12538 avr_asm_len ("sbiw %1,1", xop, plen, 1);
12539 }
12540 else
12541 {
12542 avr_asm_len ("subi %A1,1" CR_TAB
12543 "sbci %B1,0", xop, plen, 2);
12544 }
12545
12546 /* Loop until zero */
12547
12548 return avr_asm_len ("brne 0b", xop, plen, 1);
12549 }
12550
12551
12552 \f
12553 /* Helper for __builtin_avr_delay_cycles */
12554
12555 static rtx
12556 avr_mem_clobber (void)
12557 {
12558 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12559 MEM_VOLATILE_P (mem) = 1;
12560 return mem;
12561 }
12562
12563 static void
12564 avr_expand_delay_cycles (rtx operands0)
12565 {
12566 unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
12567 unsigned HOST_WIDE_INT cycles_used;
12568 unsigned HOST_WIDE_INT loop_count;
12569
12570 if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
12571 {
12572 loop_count = ((cycles - 9) / 6) + 1;
12573 cycles_used = ((loop_count - 1) * 6) + 9;
12574 emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
12575 avr_mem_clobber()));
12576 cycles -= cycles_used;
12577 }
12578
12579 if (IN_RANGE (cycles, 262145, 83886081))
12580 {
12581 loop_count = ((cycles - 7) / 5) + 1;
12582 if (loop_count > 0xFFFFFF)
12583 loop_count = 0xFFFFFF;
12584 cycles_used = ((loop_count - 1) * 5) + 7;
12585 emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
12586 avr_mem_clobber()));
12587 cycles -= cycles_used;
12588 }
12589
12590 if (IN_RANGE (cycles, 768, 262144))
12591 {
12592 loop_count = ((cycles - 5) / 4) + 1;
12593 if (loop_count > 0xFFFF)
12594 loop_count = 0xFFFF;
12595 cycles_used = ((loop_count - 1) * 4) + 5;
12596 emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
12597 avr_mem_clobber()));
12598 cycles -= cycles_used;
12599 }
12600
12601 if (IN_RANGE (cycles, 6, 767))
12602 {
12603 loop_count = cycles / 3;
12604 if (loop_count > 255)
12605 loop_count = 255;
12606 cycles_used = loop_count * 3;
12607 emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
12608 avr_mem_clobber()));
12609 cycles -= cycles_used;
12610 }
12611
12612 while (cycles >= 2)
12613 {
12614 emit_insn (gen_nopv (GEN_INT(2)));
12615 cycles -= 2;
12616 }
12617
12618 if (cycles == 1)
12619 {
12620 emit_insn (gen_nopv (GEN_INT(1)));
12621 cycles--;
12622 }
12623 }
12624
12625
12626 /* Compute the image of x under f, i.e. perform x --> f(x) */
12627
12628 static int
12629 avr_map (unsigned int f, int x)
12630 {
12631 return x < 8 ? (f >> (4 * x)) & 0xf : 0;
12632 }
12633
12634
12635 /* Return some metrics of map A. */
12636
12637 enum
12638 {
12639 /* Number of fixed points in { 0 ... 7 } */
12640 MAP_FIXED_0_7,
12641
12642 /* Size of preimage of non-fixed points in { 0 ... 7 } */
12643 MAP_NONFIXED_0_7,
12644
12645 /* Mask representing the fixed points in { 0 ... 7 } */
12646 MAP_MASK_FIXED_0_7,
12647
12648 /* Size of the preimage of { 0 ... 7 } */
12649 MAP_PREIMAGE_0_7,
12650
12651 /* Mask that represents the preimage of { f } */
12652 MAP_MASK_PREIMAGE_F
12653 };
12654
12655 static unsigned
12656 avr_map_metric (unsigned int a, int mode)
12657 {
12658 unsigned i, metric = 0;
12659
12660 for (i = 0; i < 8; i++)
12661 {
12662 unsigned ai = avr_map (a, i);
12663
12664 if (mode == MAP_FIXED_0_7)
12665 metric += ai == i;
12666 else if (mode == MAP_NONFIXED_0_7)
12667 metric += ai < 8 && ai != i;
12668 else if (mode == MAP_MASK_FIXED_0_7)
12669 metric |= ((unsigned) (ai == i)) << i;
12670 else if (mode == MAP_PREIMAGE_0_7)
12671 metric += ai < 8;
12672 else if (mode == MAP_MASK_PREIMAGE_F)
12673 metric |= ((unsigned) (ai == 0xf)) << i;
12674 else
12675 gcc_unreachable();
12676 }
12677
12678 return metric;
12679 }
12680
12681
12682 /* Return true if IVAL has a 0xf in its hexadecimal representation
12683 and false, otherwise. Only nibbles 0..7 are taken into account.
12684 Used as constraint helper for C0f and Cxf. */
12685
12686 bool
12687 avr_has_nibble_0xf (rtx ival)
12688 {
12689 unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode);
12690 return 0 != avr_map_metric (map, MAP_MASK_PREIMAGE_F);
12691 }
12692
12693
12694 /* We have a set of bits that are mapped by a function F.
12695 Try to decompose F by means of a second function G so that
12696
12697 F = F o G^-1 o G
12698
12699 and
12700
12701 cost (F o G^-1) + cost (G) < cost (F)
12702
12703 Example: Suppose builtin insert_bits supplies us with the map
12704 F = 0x3210ffff. Instead of doing 4 bit insertions to get the high
12705 nibble of the result, we can just as well rotate the bits before inserting
12706 them and use the map 0x7654ffff which is cheaper than the original map.
12707 For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff. */
12708
12709 typedef struct
12710 {
12711 /* tree code of binary function G */
12712 enum tree_code code;
12713
12714 /* The constant second argument of G */
12715 int arg;
12716
12717 /* G^-1, the inverse of G (*, arg) */
12718 unsigned ginv;
12719
12720 /* The cost of appplying G (*, arg) */
12721 int cost;
12722
12723 /* The composition F o G^-1 (*, arg) for some function F */
12724 unsigned int map;
12725
12726 /* For debug purpose only */
12727 const char *str;
12728 } avr_map_op_t;
12729
12730 static const avr_map_op_t avr_map_op[] =
12731 {
12732 { LROTATE_EXPR, 0, 0x76543210, 0, 0, "id" },
12733 { LROTATE_EXPR, 1, 0x07654321, 2, 0, "<<<" },
12734 { LROTATE_EXPR, 2, 0x10765432, 4, 0, "<<<" },
12735 { LROTATE_EXPR, 3, 0x21076543, 4, 0, "<<<" },
12736 { LROTATE_EXPR, 4, 0x32107654, 1, 0, "<<<" },
12737 { LROTATE_EXPR, 5, 0x43210765, 3, 0, "<<<" },
12738 { LROTATE_EXPR, 6, 0x54321076, 5, 0, "<<<" },
12739 { LROTATE_EXPR, 7, 0x65432107, 3, 0, "<<<" },
12740 { RSHIFT_EXPR, 1, 0x6543210c, 1, 0, ">>" },
12741 { RSHIFT_EXPR, 1, 0x7543210c, 1, 0, ">>" },
12742 { RSHIFT_EXPR, 2, 0x543210cc, 2, 0, ">>" },
12743 { RSHIFT_EXPR, 2, 0x643210cc, 2, 0, ">>" },
12744 { RSHIFT_EXPR, 2, 0x743210cc, 2, 0, ">>" },
12745 { LSHIFT_EXPR, 1, 0xc7654321, 1, 0, "<<" },
12746 { LSHIFT_EXPR, 2, 0xcc765432, 2, 0, "<<" }
12747 };
12748
12749
12750 /* Try to decompose F as F = (F o G^-1) o G as described above.
12751 The result is a struct representing F o G^-1 and G.
12752 If result.cost < 0 then such a decomposition does not exist. */
12753
12754 static avr_map_op_t
12755 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p)
12756 {
12757 int i;
12758 bool val_used_p = 0 != avr_map_metric (f, MAP_MASK_PREIMAGE_F);
12759 avr_map_op_t f_ginv = *g;
12760 unsigned int ginv = g->ginv;
12761
12762 f_ginv.cost = -1;
12763
12764 /* Step 1: Computing F o G^-1 */
12765
12766 for (i = 7; i >= 0; i--)
12767 {
12768 int x = avr_map (f, i);
12769
12770 if (x <= 7)
12771 {
12772 x = avr_map (ginv, x);
12773
12774 /* The bit is no element of the image of G: no avail (cost = -1) */
12775
12776 if (x > 7)
12777 return f_ginv;
12778 }
12779
12780 f_ginv.map = (f_ginv.map << 4) + x;
12781 }
12782
12783 /* Step 2: Compute the cost of the operations.
12784 The overall cost of doing an operation prior to the insertion is
12785 the cost of the insertion plus the cost of the operation. */
12786
12787 /* Step 2a: Compute cost of F o G^-1 */
12788
12789 if (0 == avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7))
12790 {
12791 /* The mapping consists only of fixed points and can be folded
12792 to AND/OR logic in the remainder. Reasonable cost is 3. */
12793
12794 f_ginv.cost = 2 + (val_used_p && !val_const_p);
12795 }
12796 else
12797 {
12798 rtx xop[4];
12799
12800 /* Get the cost of the insn by calling the output worker with some
12801 fake values. Mimic effect of reloading xop[3]: Unused operands
12802 are mapped to 0 and used operands are reloaded to xop[0]. */
12803
12804 xop[0] = all_regs_rtx[24];
12805 xop[1] = gen_int_mode (f_ginv.map, SImode);
12806 xop[2] = all_regs_rtx[25];
12807 xop[3] = val_used_p ? xop[0] : const0_rtx;
12808
12809 avr_out_insert_bits (xop, &f_ginv.cost);
12810
12811 f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
12812 }
12813
12814 /* Step 2b: Add cost of G */
12815
12816 f_ginv.cost += g->cost;
12817
12818 if (avr_log.builtin)
12819 avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
12820
12821 return f_ginv;
12822 }
12823
12824
12825 /* Insert bits from XOP[1] into XOP[0] according to MAP.
12826 XOP[0] and XOP[1] don't overlap.
12827 If FIXP_P = true: Move all bits according to MAP using BLD/BST sequences.
12828 If FIXP_P = false: Just move the bit if its position in the destination
12829 is different to its source position. */
12830
12831 static void
12832 avr_move_bits (rtx *xop, unsigned int map, bool fixp_p, int *plen)
12833 {
12834 int bit_dest, b;
12835
12836 /* T-flag contains this bit of the source, i.e. of XOP[1] */
12837 int t_bit_src = -1;
12838
12839 /* We order the operations according to the requested source bit b. */
12840
12841 for (b = 0; b < 8; b++)
12842 for (bit_dest = 0; bit_dest < 8; bit_dest++)
12843 {
12844 int bit_src = avr_map (map, bit_dest);
12845
12846 if (b != bit_src
12847 || bit_src >= 8
12848 /* Same position: No need to copy as requested by FIXP_P. */
12849 || (bit_dest == bit_src && !fixp_p))
12850 continue;
12851
12852 if (t_bit_src != bit_src)
12853 {
12854 /* Source bit is not yet in T: Store it to T. */
12855
12856 t_bit_src = bit_src;
12857
12858 xop[3] = GEN_INT (bit_src);
12859 avr_asm_len ("bst %T1%T3", xop, plen, 1);
12860 }
12861
12862 /* Load destination bit with T. */
12863
12864 xop[3] = GEN_INT (bit_dest);
12865 avr_asm_len ("bld %T0%T3", xop, plen, 1);
12866 }
12867 }
12868
12869
12870 /* PLEN == 0: Print assembler code for `insert_bits'.
12871 PLEN != 0: Compute code length in bytes.
12872
12873 OP[0]: Result
12874 OP[1]: The mapping composed of nibbles. If nibble no. N is
12875 0: Bit N of result is copied from bit OP[2].0
12876 ... ...
12877 7: Bit N of result is copied from bit OP[2].7
12878 0xf: Bit N of result is copied from bit OP[3].N
12879 OP[2]: Bits to be inserted
12880 OP[3]: Target value */
12881
12882 const char*
12883 avr_out_insert_bits (rtx *op, int *plen)
12884 {
12885 unsigned int map = UINTVAL (op[1]) & GET_MODE_MASK (SImode);
12886 unsigned mask_fixed;
12887 bool fixp_p = true;
12888 rtx xop[4];
12889
12890 xop[0] = op[0];
12891 xop[1] = op[2];
12892 xop[2] = op[3];
12893
12894 gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
12895
12896 if (plen)
12897 *plen = 0;
12898 else if (flag_print_asm_name)
12899 fprintf (asm_out_file, ASM_COMMENT_START "map = 0x%08x\n", map);
12900
12901 /* If MAP has fixed points it might be better to initialize the result
12902 with the bits to be inserted instead of moving all bits by hand. */
12903
12904 mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
12905
12906 if (REGNO (xop[0]) == REGNO (xop[1]))
12907 {
12908 /* Avoid early-clobber conflicts */
12909
12910 avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
12911 xop[1] = tmp_reg_rtx;
12912 fixp_p = false;
12913 }
12914
12915 if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
12916 {
12917 /* XOP[2] is used and reloaded to XOP[0] already */
12918
12919 int n_fix = 0, n_nofix = 0;
12920
12921 gcc_assert (REG_P (xop[2]));
12922
12923 /* Get the code size of the bit insertions; once with all bits
12924 moved and once with fixed points omitted. */
12925
12926 avr_move_bits (xop, map, true, &n_fix);
12927 avr_move_bits (xop, map, false, &n_nofix);
12928
12929 if (fixp_p && n_fix - n_nofix > 3)
12930 {
12931 xop[3] = gen_int_mode (~mask_fixed, QImode);
12932
12933 avr_asm_len ("eor %0,%1" CR_TAB
12934 "andi %0,%3" CR_TAB
12935 "eor %0,%1", xop, plen, 3);
12936 fixp_p = false;
12937 }
12938 }
12939 else
12940 {
12941 /* XOP[2] is unused */
12942
12943 if (fixp_p && mask_fixed)
12944 {
12945 avr_asm_len ("mov %0,%1", xop, plen, 1);
12946 fixp_p = false;
12947 }
12948 }
12949
12950 /* Move/insert remaining bits. */
12951
12952 avr_move_bits (xop, map, fixp_p, plen);
12953
12954 return "";
12955 }
12956
12957
12958 /* IDs for all the AVR builtins. */
12959
12960 enum avr_builtin_id
12961 {
12962 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
12963 AVR_BUILTIN_ ## NAME,
12964 #include "builtins.def"
12965 #undef DEF_BUILTIN
12966
12967 AVR_BUILTIN_COUNT
12968 };
12969
12970 struct GTY(()) avr_builtin_description
12971 {
12972 enum insn_code icode;
12973 int n_args;
12974 tree fndecl;
12975 };
12976
12977
12978 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
12979 that a built-in's ID can be used to access the built-in by means of
12980 avr_bdesc[ID] */
12981
12982 static GTY(()) struct avr_builtin_description
12983 avr_bdesc[AVR_BUILTIN_COUNT] =
12984 {
12985 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME) \
12986 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
12987 #include "builtins.def"
12988 #undef DEF_BUILTIN
12989 };
12990
12991
12992 /* Implement `TARGET_BUILTIN_DECL'. */
12993
12994 static tree
12995 avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
12996 {
12997 if (id < AVR_BUILTIN_COUNT)
12998 return avr_bdesc[id].fndecl;
12999
13000 return error_mark_node;
13001 }
13002
13003
13004 static void
13005 avr_init_builtin_int24 (void)
13006 {
13007 tree int24_type = make_signed_type (GET_MODE_BITSIZE (PSImode));
13008 tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
13009
13010 lang_hooks.types.register_builtin_type (int24_type, "__int24");
13011 lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
13012 }
13013
13014
13015 /* Implement `TARGET_INIT_BUILTINS' */
13016 /* Set up all builtin functions for this target. */
13017
13018 static void
13019 avr_init_builtins (void)
13020 {
13021 tree void_ftype_void
13022 = build_function_type_list (void_type_node, NULL_TREE);
13023 tree uchar_ftype_uchar
13024 = build_function_type_list (unsigned_char_type_node,
13025 unsigned_char_type_node,
13026 NULL_TREE);
13027 tree uint_ftype_uchar_uchar
13028 = build_function_type_list (unsigned_type_node,
13029 unsigned_char_type_node,
13030 unsigned_char_type_node,
13031 NULL_TREE);
13032 tree int_ftype_char_char
13033 = build_function_type_list (integer_type_node,
13034 char_type_node,
13035 char_type_node,
13036 NULL_TREE);
13037 tree int_ftype_char_uchar
13038 = build_function_type_list (integer_type_node,
13039 char_type_node,
13040 unsigned_char_type_node,
13041 NULL_TREE);
13042 tree void_ftype_ulong
13043 = build_function_type_list (void_type_node,
13044 long_unsigned_type_node,
13045 NULL_TREE);
13046
13047 tree uchar_ftype_ulong_uchar_uchar
13048 = build_function_type_list (unsigned_char_type_node,
13049 long_unsigned_type_node,
13050 unsigned_char_type_node,
13051 unsigned_char_type_node,
13052 NULL_TREE);
13053
13054 tree const_memx_void_node
13055 = build_qualified_type (void_type_node,
13056 TYPE_QUAL_CONST
13057 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
13058
13059 tree const_memx_ptr_type_node
13060 = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
13061
13062 tree char_ftype_const_memx_ptr
13063 = build_function_type_list (char_type_node,
13064 const_memx_ptr_type_node,
13065 NULL);
13066
13067 #define ITYP(T) \
13068 lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
13069
13070 #define FX_FTYPE_FX(fx) \
13071 tree fx##r_ftype_##fx##r \
13072 = build_function_type_list (node_##fx##r, node_##fx##r, NULL); \
13073 tree fx##k_ftype_##fx##k \
13074 = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
13075
13076 #define FX_FTYPE_FX_INT(fx) \
13077 tree fx##r_ftype_##fx##r_int \
13078 = build_function_type_list (node_##fx##r, node_##fx##r, \
13079 integer_type_node, NULL); \
13080 tree fx##k_ftype_##fx##k_int \
13081 = build_function_type_list (node_##fx##k, node_##fx##k, \
13082 integer_type_node, NULL)
13083
13084 #define INT_FTYPE_FX(fx) \
13085 tree int_ftype_##fx##r \
13086 = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
13087 tree int_ftype_##fx##k \
13088 = build_function_type_list (integer_type_node, node_##fx##k, NULL)
13089
13090 #define INTX_FTYPE_FX(fx) \
13091 tree int##fx##r_ftype_##fx##r \
13092 = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
13093 tree int##fx##k_ftype_##fx##k \
13094 = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
13095
13096 #define FX_FTYPE_INTX(fx) \
13097 tree fx##r_ftype_int##fx##r \
13098 = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
13099 tree fx##k_ftype_int##fx##k \
13100 = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
13101
13102 tree node_hr = short_fract_type_node;
13103 tree node_nr = fract_type_node;
13104 tree node_lr = long_fract_type_node;
13105 tree node_llr = long_long_fract_type_node;
13106
13107 tree node_uhr = unsigned_short_fract_type_node;
13108 tree node_unr = unsigned_fract_type_node;
13109 tree node_ulr = unsigned_long_fract_type_node;
13110 tree node_ullr = unsigned_long_long_fract_type_node;
13111
13112 tree node_hk = short_accum_type_node;
13113 tree node_nk = accum_type_node;
13114 tree node_lk = long_accum_type_node;
13115 tree node_llk = long_long_accum_type_node;
13116
13117 tree node_uhk = unsigned_short_accum_type_node;
13118 tree node_unk = unsigned_accum_type_node;
13119 tree node_ulk = unsigned_long_accum_type_node;
13120 tree node_ullk = unsigned_long_long_accum_type_node;
13121
13122
13123 /* For absfx builtins. */
13124
13125 FX_FTYPE_FX (h);
13126 FX_FTYPE_FX (n);
13127 FX_FTYPE_FX (l);
13128 FX_FTYPE_FX (ll);
13129
13130 /* For roundfx builtins. */
13131
13132 FX_FTYPE_FX_INT (h);
13133 FX_FTYPE_FX_INT (n);
13134 FX_FTYPE_FX_INT (l);
13135 FX_FTYPE_FX_INT (ll);
13136
13137 FX_FTYPE_FX_INT (uh);
13138 FX_FTYPE_FX_INT (un);
13139 FX_FTYPE_FX_INT (ul);
13140 FX_FTYPE_FX_INT (ull);
13141
13142 /* For countlsfx builtins. */
13143
13144 INT_FTYPE_FX (h);
13145 INT_FTYPE_FX (n);
13146 INT_FTYPE_FX (l);
13147 INT_FTYPE_FX (ll);
13148
13149 INT_FTYPE_FX (uh);
13150 INT_FTYPE_FX (un);
13151 INT_FTYPE_FX (ul);
13152 INT_FTYPE_FX (ull);
13153
13154 /* For bitsfx builtins. */
13155
13156 INTX_FTYPE_FX (h);
13157 INTX_FTYPE_FX (n);
13158 INTX_FTYPE_FX (l);
13159 INTX_FTYPE_FX (ll);
13160
13161 INTX_FTYPE_FX (uh);
13162 INTX_FTYPE_FX (un);
13163 INTX_FTYPE_FX (ul);
13164 INTX_FTYPE_FX (ull);
13165
13166 /* For fxbits builtins. */
13167
13168 FX_FTYPE_INTX (h);
13169 FX_FTYPE_INTX (n);
13170 FX_FTYPE_INTX (l);
13171 FX_FTYPE_INTX (ll);
13172
13173 FX_FTYPE_INTX (uh);
13174 FX_FTYPE_INTX (un);
13175 FX_FTYPE_INTX (ul);
13176 FX_FTYPE_INTX (ull);
13177
13178
13179 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
13180 { \
13181 int id = AVR_BUILTIN_ ## NAME; \
13182 const char *Name = "__builtin_avr_" #NAME; \
13183 char *name = (char*) alloca (1 + strlen (Name)); \
13184 \
13185 gcc_assert (id < AVR_BUILTIN_COUNT); \
13186 avr_bdesc[id].fndecl \
13187 = add_builtin_function (avr_tolower (name, Name), TYPE, id, \
13188 BUILT_IN_MD, LIBNAME, NULL_TREE); \
13189 }
13190 #include "builtins.def"
13191 #undef DEF_BUILTIN
13192
13193 avr_init_builtin_int24 ();
13194 }
13195
13196
13197 /* Subroutine of avr_expand_builtin to expand vanilla builtins
13198 with non-void result and 1 ... 3 arguments. */
13199
13200 static rtx
13201 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
13202 {
13203 rtx pat, xop[3];
13204 int n, n_args = call_expr_nargs (exp);
13205 machine_mode tmode = insn_data[icode].operand[0].mode;
13206
13207 gcc_assert (n_args >= 1 && n_args <= 3);
13208
13209 if (target == NULL_RTX
13210 || GET_MODE (target) != tmode
13211 || !insn_data[icode].operand[0].predicate (target, tmode))
13212 {
13213 target = gen_reg_rtx (tmode);
13214 }
13215
13216 for (n = 0; n < n_args; n++)
13217 {
13218 tree arg = CALL_EXPR_ARG (exp, n);
13219 rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13220 machine_mode opmode = GET_MODE (op);
13221 machine_mode mode = insn_data[icode].operand[n+1].mode;
13222
13223 if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
13224 {
13225 opmode = HImode;
13226 op = gen_lowpart (HImode, op);
13227 }
13228
13229 /* In case the insn wants input operands in modes different from
13230 the result, abort. */
13231
13232 gcc_assert (opmode == mode || opmode == VOIDmode);
13233
13234 if (!insn_data[icode].operand[n+1].predicate (op, mode))
13235 op = copy_to_mode_reg (mode, op);
13236
13237 xop[n] = op;
13238 }
13239
13240 switch (n_args)
13241 {
13242 case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
13243 case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
13244 case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
13245
13246 default:
13247 gcc_unreachable();
13248 }
13249
13250 if (pat == NULL_RTX)
13251 return NULL_RTX;
13252
13253 emit_insn (pat);
13254
13255 return target;
13256 }
13257
13258
13259 /* Implement `TARGET_EXPAND_BUILTIN'. */
13260 /* Expand an expression EXP that calls a built-in function,
13261 with result going to TARGET if that's convenient
13262 (and in mode MODE if that's convenient).
13263 SUBTARGET may be used as the target for computing one of EXP's operands.
13264 IGNORE is nonzero if the value is to be ignored. */
13265
13266 static rtx
13267 avr_expand_builtin (tree exp, rtx target,
13268 rtx subtarget ATTRIBUTE_UNUSED,
13269 machine_mode mode ATTRIBUTE_UNUSED,
13270 int ignore)
13271 {
13272 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
13273 const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
13274 unsigned int id = DECL_FUNCTION_CODE (fndecl);
13275 const struct avr_builtin_description *d = &avr_bdesc[id];
13276 tree arg0;
13277 rtx op0;
13278
13279 gcc_assert (id < AVR_BUILTIN_COUNT);
13280
13281 switch (id)
13282 {
13283 case AVR_BUILTIN_NOP:
13284 emit_insn (gen_nopv (GEN_INT(1)));
13285 return 0;
13286
13287 case AVR_BUILTIN_DELAY_CYCLES:
13288 {
13289 arg0 = CALL_EXPR_ARG (exp, 0);
13290 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13291
13292 if (!CONST_INT_P (op0))
13293 error ("%s expects a compile time integer constant", bname);
13294 else
13295 avr_expand_delay_cycles (op0);
13296
13297 return NULL_RTX;
13298 }
13299
13300 case AVR_BUILTIN_INSERT_BITS:
13301 {
13302 arg0 = CALL_EXPR_ARG (exp, 0);
13303 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13304
13305 if (!CONST_INT_P (op0))
13306 {
13307 error ("%s expects a compile time long integer constant"
13308 " as first argument", bname);
13309 return target;
13310 }
13311
13312 break;
13313 }
13314
13315 case AVR_BUILTIN_ROUNDHR: case AVR_BUILTIN_ROUNDUHR:
13316 case AVR_BUILTIN_ROUNDR: case AVR_BUILTIN_ROUNDUR:
13317 case AVR_BUILTIN_ROUNDLR: case AVR_BUILTIN_ROUNDULR:
13318 case AVR_BUILTIN_ROUNDLLR: case AVR_BUILTIN_ROUNDULLR:
13319
13320 case AVR_BUILTIN_ROUNDHK: case AVR_BUILTIN_ROUNDUHK:
13321 case AVR_BUILTIN_ROUNDK: case AVR_BUILTIN_ROUNDUK:
13322 case AVR_BUILTIN_ROUNDLK: case AVR_BUILTIN_ROUNDULK:
13323 case AVR_BUILTIN_ROUNDLLK: case AVR_BUILTIN_ROUNDULLK:
13324
13325 /* Warn about odd rounding. Rounding points >= FBIT will have
13326 no effect. */
13327
13328 if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
13329 break;
13330
13331 int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
13332
13333 if (rbit >= (int) GET_MODE_FBIT (mode))
13334 {
13335 warning (OPT_Wextra, "rounding to %d bits has no effect for "
13336 "fixed-point value with %d fractional bits",
13337 rbit, GET_MODE_FBIT (mode));
13338
13339 return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
13340 EXPAND_NORMAL);
13341 }
13342 else if (rbit <= - (int) GET_MODE_IBIT (mode))
13343 {
13344 warning (0, "rounding result will always be 0");
13345 return CONST0_RTX (mode);
13346 }
13347
13348 /* The rounding points RP satisfies now: -IBIT < RP < FBIT.
13349
13350 TR 18037 only specifies results for RP > 0. However, the
13351 remaining cases of -IBIT < RP <= 0 can easily be supported
13352 without any additional overhead. */
13353
13354 break; /* round */
13355 }
13356
13357 /* No fold found and no insn: Call support function from libgcc. */
13358
13359 if (d->icode == CODE_FOR_nothing
13360 && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
13361 {
13362 return expand_call (exp, target, ignore);
13363 }
13364
13365 /* No special treatment needed: vanilla expand. */
13366
13367 gcc_assert (d->icode != CODE_FOR_nothing);
13368 gcc_assert (d->n_args == call_expr_nargs (exp));
13369
13370 if (d->n_args == 0)
13371 {
13372 emit_insn ((GEN_FCN (d->icode)) (target));
13373 return NULL_RTX;
13374 }
13375
13376 return avr_default_expand_builtin (d->icode, exp, target);
13377 }
13378
13379
13380 /* Helper for `avr_fold_builtin' that folds absfx (FIXED_CST). */
13381
13382 static tree
13383 avr_fold_absfx (tree tval)
13384 {
13385 if (FIXED_CST != TREE_CODE (tval))
13386 return NULL_TREE;
13387
13388 /* Our fixed-points have no padding: Use double_int payload directly. */
13389
13390 FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
13391 unsigned int bits = GET_MODE_BITSIZE (fval.mode);
13392 double_int ival = fval.data.sext (bits);
13393
13394 if (!ival.is_negative())
13395 return tval;
13396
13397 /* ISO/IEC TR 18037, 7.18a.6.2: The absfx functions are saturating. */
13398
13399 fval.data = (ival == double_int::min_value (bits, false).sext (bits))
13400 ? double_int::max_value (bits, false)
13401 : -ival;
13402
13403 return build_fixed (TREE_TYPE (tval), fval);
13404 }
13405
13406
13407 /* Implement `TARGET_FOLD_BUILTIN'. */
13408
13409 static tree
13410 avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
13411 bool ignore ATTRIBUTE_UNUSED)
13412 {
13413 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
13414 tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
13415
13416 if (!optimize)
13417 return NULL_TREE;
13418
13419 switch (fcode)
13420 {
13421 default:
13422 break;
13423
13424 case AVR_BUILTIN_SWAP:
13425 {
13426 return fold_build2 (LROTATE_EXPR, val_type, arg[0],
13427 build_int_cst (val_type, 4));
13428 }
13429
13430 case AVR_BUILTIN_ABSHR:
13431 case AVR_BUILTIN_ABSR:
13432 case AVR_BUILTIN_ABSLR:
13433 case AVR_BUILTIN_ABSLLR:
13434
13435 case AVR_BUILTIN_ABSHK:
13436 case AVR_BUILTIN_ABSK:
13437 case AVR_BUILTIN_ABSLK:
13438 case AVR_BUILTIN_ABSLLK:
13439 /* GCC is not good with folding ABS for fixed-point. Do it by hand. */
13440
13441 return avr_fold_absfx (arg[0]);
13442
13443 case AVR_BUILTIN_BITSHR: case AVR_BUILTIN_HRBITS:
13444 case AVR_BUILTIN_BITSHK: case AVR_BUILTIN_HKBITS:
13445 case AVR_BUILTIN_BITSUHR: case AVR_BUILTIN_UHRBITS:
13446 case AVR_BUILTIN_BITSUHK: case AVR_BUILTIN_UHKBITS:
13447
13448 case AVR_BUILTIN_BITSR: case AVR_BUILTIN_RBITS:
13449 case AVR_BUILTIN_BITSK: case AVR_BUILTIN_KBITS:
13450 case AVR_BUILTIN_BITSUR: case AVR_BUILTIN_URBITS:
13451 case AVR_BUILTIN_BITSUK: case AVR_BUILTIN_UKBITS:
13452
13453 case AVR_BUILTIN_BITSLR: case AVR_BUILTIN_LRBITS:
13454 case AVR_BUILTIN_BITSLK: case AVR_BUILTIN_LKBITS:
13455 case AVR_BUILTIN_BITSULR: case AVR_BUILTIN_ULRBITS:
13456 case AVR_BUILTIN_BITSULK: case AVR_BUILTIN_ULKBITS:
13457
13458 case AVR_BUILTIN_BITSLLR: case AVR_BUILTIN_LLRBITS:
13459 case AVR_BUILTIN_BITSLLK: case AVR_BUILTIN_LLKBITS:
13460 case AVR_BUILTIN_BITSULLR: case AVR_BUILTIN_ULLRBITS:
13461 case AVR_BUILTIN_BITSULLK: case AVR_BUILTIN_ULLKBITS:
13462
13463 gcc_assert (TYPE_PRECISION (val_type)
13464 == TYPE_PRECISION (TREE_TYPE (arg[0])));
13465
13466 return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
13467
13468 case AVR_BUILTIN_INSERT_BITS:
13469 {
13470 tree tbits = arg[1];
13471 tree tval = arg[2];
13472 tree tmap;
13473 tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
13474 unsigned int map;
13475 bool changed = false;
13476 unsigned i;
13477 avr_map_op_t best_g;
13478
13479 if (TREE_CODE (arg[0]) != INTEGER_CST)
13480 {
13481 /* No constant as first argument: Don't fold this and run into
13482 error in avr_expand_builtin. */
13483
13484 break;
13485 }
13486
13487 tmap = wide_int_to_tree (map_type, arg[0]);
13488 map = TREE_INT_CST_LOW (tmap);
13489
13490 if (TREE_CODE (tval) != INTEGER_CST
13491 && 0 == avr_map_metric (map, MAP_MASK_PREIMAGE_F))
13492 {
13493 /* There are no F in the map, i.e. 3rd operand is unused.
13494 Replace that argument with some constant to render
13495 respective input unused. */
13496
13497 tval = build_int_cst (val_type, 0);
13498 changed = true;
13499 }
13500
13501 if (TREE_CODE (tbits) != INTEGER_CST
13502 && 0 == avr_map_metric (map, MAP_PREIMAGE_0_7))
13503 {
13504 /* Similar for the bits to be inserted. If they are unused,
13505 we can just as well pass 0. */
13506
13507 tbits = build_int_cst (val_type, 0);
13508 }
13509
13510 if (TREE_CODE (tbits) == INTEGER_CST)
13511 {
13512 /* Inserting bits known at compile time is easy and can be
13513 performed by AND and OR with appropriate masks. */
13514
13515 int bits = TREE_INT_CST_LOW (tbits);
13516 int mask_ior = 0, mask_and = 0xff;
13517
13518 for (i = 0; i < 8; i++)
13519 {
13520 int mi = avr_map (map, i);
13521
13522 if (mi < 8)
13523 {
13524 if (bits & (1 << mi)) mask_ior |= (1 << i);
13525 else mask_and &= ~(1 << i);
13526 }
13527 }
13528
13529 tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
13530 build_int_cst (val_type, mask_ior));
13531 return fold_build2 (BIT_AND_EXPR, val_type, tval,
13532 build_int_cst (val_type, mask_and));
13533 }
13534
13535 if (changed)
13536 return build_call_expr (fndecl, 3, tmap, tbits, tval);
13537
13538 /* If bits don't change their position we can use vanilla logic
13539 to merge the two arguments. */
13540
13541 if (0 == avr_map_metric (map, MAP_NONFIXED_0_7))
13542 {
13543 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
13544 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
13545
13546 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
13547 tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
13548 return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
13549 }
13550
13551 /* Try to decomposing map to reduce overall cost. */
13552
13553 if (avr_log.builtin)
13554 avr_edump ("\n%?: %x\n%?: ROL cost: ", map);
13555
13556 best_g = avr_map_op[0];
13557 best_g.cost = 1000;
13558
13559 for (i = 0; i < sizeof (avr_map_op) / sizeof (*avr_map_op); i++)
13560 {
13561 avr_map_op_t g
13562 = avr_map_decompose (map, avr_map_op + i,
13563 TREE_CODE (tval) == INTEGER_CST);
13564
13565 if (g.cost >= 0 && g.cost < best_g.cost)
13566 best_g = g;
13567 }
13568
13569 if (avr_log.builtin)
13570 avr_edump ("\n");
13571
13572 if (best_g.arg == 0)
13573 /* No optimization found */
13574 break;
13575
13576 /* Apply operation G to the 2nd argument. */
13577
13578 if (avr_log.builtin)
13579 avr_edump ("%?: using OP(%s%d, %x) cost %d\n",
13580 best_g.str, best_g.arg, best_g.map, best_g.cost);
13581
13582 /* Do right-shifts arithmetically: They copy the MSB instead of
13583 shifting in a non-usable value (0) as with logic right-shift. */
13584
13585 tbits = fold_convert (signed_char_type_node, tbits);
13586 tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
13587 build_int_cst (val_type, best_g.arg));
13588 tbits = fold_convert (val_type, tbits);
13589
13590 /* Use map o G^-1 instead of original map to undo the effect of G. */
13591
13592 tmap = wide_int_to_tree (map_type, best_g.map);
13593
13594 return build_call_expr (fndecl, 3, tmap, tbits, tval);
13595 } /* AVR_BUILTIN_INSERT_BITS */
13596 }
13597
13598 return NULL_TREE;
13599 }
13600
13601 \f
13602
13603 /* Initialize the GCC target structure. */
13604
13605 #undef TARGET_ASM_ALIGNED_HI_OP
13606 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
13607 #undef TARGET_ASM_ALIGNED_SI_OP
13608 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
13609 #undef TARGET_ASM_UNALIGNED_HI_OP
13610 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
13611 #undef TARGET_ASM_UNALIGNED_SI_OP
13612 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
13613 #undef TARGET_ASM_INTEGER
13614 #define TARGET_ASM_INTEGER avr_assemble_integer
13615 #undef TARGET_ASM_FILE_START
13616 #define TARGET_ASM_FILE_START avr_file_start
13617 #undef TARGET_ASM_FILE_END
13618 #define TARGET_ASM_FILE_END avr_file_end
13619
13620 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
13621 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
13622 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
13623 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
13624
13625 #undef TARGET_FUNCTION_VALUE
13626 #define TARGET_FUNCTION_VALUE avr_function_value
13627 #undef TARGET_LIBCALL_VALUE
13628 #define TARGET_LIBCALL_VALUE avr_libcall_value
13629 #undef TARGET_FUNCTION_VALUE_REGNO_P
13630 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
13631
13632 #undef TARGET_ATTRIBUTE_TABLE
13633 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
13634 #undef TARGET_INSERT_ATTRIBUTES
13635 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
13636 #undef TARGET_SECTION_TYPE_FLAGS
13637 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
13638
13639 #undef TARGET_ASM_NAMED_SECTION
13640 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
13641 #undef TARGET_ASM_INIT_SECTIONS
13642 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
13643 #undef TARGET_ENCODE_SECTION_INFO
13644 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
13645 #undef TARGET_ASM_SELECT_SECTION
13646 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
13647
13648 #undef TARGET_REGISTER_MOVE_COST
13649 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
13650 #undef TARGET_MEMORY_MOVE_COST
13651 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
13652 #undef TARGET_RTX_COSTS
13653 #define TARGET_RTX_COSTS avr_rtx_costs
13654 #undef TARGET_ADDRESS_COST
13655 #define TARGET_ADDRESS_COST avr_address_cost
13656 #undef TARGET_MACHINE_DEPENDENT_REORG
13657 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
13658 #undef TARGET_FUNCTION_ARG
13659 #define TARGET_FUNCTION_ARG avr_function_arg
13660 #undef TARGET_FUNCTION_ARG_ADVANCE
13661 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
13662
13663 #undef TARGET_SET_CURRENT_FUNCTION
13664 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
13665
13666 #undef TARGET_RETURN_IN_MEMORY
13667 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
13668
13669 #undef TARGET_STRICT_ARGUMENT_NAMING
13670 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
13671
13672 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
13673 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
13674
13675 #undef TARGET_CONDITIONAL_REGISTER_USAGE
13676 #define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage
13677
13678 #undef TARGET_HARD_REGNO_SCRATCH_OK
13679 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
13680 #undef TARGET_CASE_VALUES_THRESHOLD
13681 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
13682
13683 #undef TARGET_FRAME_POINTER_REQUIRED
13684 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
13685 #undef TARGET_CAN_ELIMINATE
13686 #define TARGET_CAN_ELIMINATE avr_can_eliminate
13687
13688 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
13689 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
13690
13691 #undef TARGET_WARN_FUNC_RETURN
13692 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
13693
13694 #undef TARGET_CLASS_LIKELY_SPILLED_P
13695 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
13696
13697 #undef TARGET_OPTION_OVERRIDE
13698 #define TARGET_OPTION_OVERRIDE avr_option_override
13699
13700 #undef TARGET_CANNOT_MODIFY_JUMPS_P
13701 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
13702
13703 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
13704 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
13705
13706 #undef TARGET_INIT_BUILTINS
13707 #define TARGET_INIT_BUILTINS avr_init_builtins
13708
13709 #undef TARGET_BUILTIN_DECL
13710 #define TARGET_BUILTIN_DECL avr_builtin_decl
13711
13712 #undef TARGET_EXPAND_BUILTIN
13713 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
13714
13715 #undef TARGET_FOLD_BUILTIN
13716 #define TARGET_FOLD_BUILTIN avr_fold_builtin
13717
13718 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
13719 #define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section
13720
13721 #undef TARGET_SCALAR_MODE_SUPPORTED_P
13722 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
13723
13724 #undef TARGET_BUILD_BUILTIN_VA_LIST
13725 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
13726
13727 #undef TARGET_FIXED_POINT_SUPPORTED_P
13728 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
13729
13730 #undef TARGET_CONVERT_TO_TYPE
13731 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
13732
13733 #undef TARGET_ADDR_SPACE_SUBSET_P
13734 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
13735
13736 #undef TARGET_ADDR_SPACE_CONVERT
13737 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
13738
13739 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
13740 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
13741
13742 #undef TARGET_ADDR_SPACE_POINTER_MODE
13743 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
13744
13745 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
13746 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
13747 avr_addr_space_legitimate_address_p
13748
13749 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
13750 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
13751
13752 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
13753 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
13754
13755 #undef TARGET_SECONDARY_RELOAD
13756 #define TARGET_SECONDARY_RELOAD avr_secondary_reload
13757
13758 #undef TARGET_PRINT_OPERAND
13759 #define TARGET_PRINT_OPERAND avr_print_operand
13760 #undef TARGET_PRINT_OPERAND_ADDRESS
13761 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
13762 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
13763 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
13764
13765 struct gcc_target targetm = TARGET_INITIALIZER;
13766
13767 \f
13768 #include "gt-avr.h"